📄 gssapi.c
字号:
GSS_C_QOP_DEFAULT, input_token, NULL, output_token); if (GSS_ERROR(maj_stat)) { sasl_gss_seterror(text->utils, maj_stat, min_stat); if (output_token->value) (*p_krb5_gss_release_buffer)(&min_stat, output_token); return SASL_FAIL; } if (output_token->value && output) { int len; ret = _plug_buf_alloc(text->utils, &(text->encode_buf), &(text->encode_buf_len), output_token->length + 4); if (ret != SASL_OK) { (*p_krb5_gss_release_buffer)(&min_stat, output_token); return ret; } len = htonl(output_token->length); memcpy(text->encode_buf, &len, 4); memcpy(text->encode_buf + 4, output_token->value, output_token->length); } if (outputlen) { *outputlen = output_token->length + 4; } *output = text->encode_buf; if (output_token->value) (*p_krb5_gss_release_buffer)(&min_stat, output_token); return SASL_OK;}static int gssapi_privacy_encode(void *context, const struct iovec *invec, unsigned numiov, const char **output, unsigned *outputlen){ return sasl_gss_encode(context,invec,numiov,output,outputlen,1);}static int gssapi_integrity_encode(void *context, const struct iovec *invec, unsigned numiov, const char **output, unsigned *outputlen) { return sasl_gss_encode(context,invec,numiov,output,outputlen,0);}static int gssapi_decode_packet(void *context, const char *input, unsigned inputlen, char **output, unsigned *outputlen){ context_t *text = (context_t *) context; OM_uint32 maj_stat, min_stat; gss_buffer_t input_token, output_token; gss_buffer_desc real_input_token, real_output_token; int result; if (sasl_gss_lib_init(text->utils) != SASL_OK) return SASL_FAIL; if (text->state != SASL_GSSAPI_STATE_AUTHENTICATED) { SETERROR(text->utils, "GSSAPI Failure"); return SASL_NOTDONE; } input_token = &real_input_token; real_input_token.value = (char *) input; real_input_token.length = inputlen; output_token = &real_output_token; output_token->value = NULL; output_token->length = 0; maj_stat = (*p_krb5_gss_unwrap) (&min_stat, text->gss_ctx, input_token, output_token, NULL, NULL); if (GSS_ERROR(maj_stat)) { sasl_gss_seterror(text->utils,maj_stat,min_stat); if (output_token->value) (*p_krb5_gss_release_buffer)(&min_stat, output_token); return SASL_FAIL; } if (outputlen) *outputlen = output_token->length; if (output_token->value) { if (output) { result = _plug_buf_alloc(text->utils, &text->decode_once_buf, &text->decode_once_buf_len, *outputlen); if(result != SASL_OK) { (*p_krb5_gss_release_buffer)(&min_stat, output_token); return result; } *output = text->decode_once_buf; memcpy(*output, output_token->value, *outputlen); } (*p_krb5_gss_release_buffer)(&min_stat, output_token); } return SASL_OK;}static int gssapi_decode(void *context, const char *input, unsigned inputlen, const char **output, unsigned *outputlen){ context_t *text = (context_t *) context; int ret; ret = _plug_decode(&text->decode_context, input, inputlen, &text->decode_buf, &text->decode_buf_len, outputlen, gssapi_decode_packet, text); *output = text->decode_buf; return ret;}static context_t *gss_new_context(const sasl_utils_t *utils){ context_t *ret; ret = utils->malloc(sizeof(context_t)); if(!ret) return NULL; memset(ret,0,sizeof(context_t)); ret->utils = utils; return ret;}static void sasl_gss_free_context_contents(context_t *text){ OM_uint32 maj_stat, min_stat; if (!text) return; if (sasl_gss_lib_init(text->utils) != SASL_OK) return; if (text->gss_ctx != GSS_C_NO_CONTEXT) { maj_stat = (*p_krb5_gss_delete_sec_context)(&min_stat,&text->gss_ctx,GSS_C_NO_BUFFER); text->gss_ctx = GSS_C_NO_CONTEXT; } if (text->client_name != GSS_C_NO_NAME) { maj_stat = (*p_krb5_gss_release_name)(&min_stat,&text->client_name); text->client_name = GSS_C_NO_NAME; } if (text->server_name != GSS_C_NO_NAME) { maj_stat = (*p_krb5_gss_release_name)(&min_stat,&text->server_name); text->server_name = GSS_C_NO_NAME; } if ( text->server_creds != GSS_C_NO_CREDENTIAL) { maj_stat = (*p_krb5_gss_release_cred)(&min_stat, &text->server_creds); text->server_creds = GSS_C_NO_CREDENTIAL; } if (text->out_buf) { text->utils->free(text->out_buf); text->out_buf = NULL; } if (text->encode_buf) { text->utils->free(text->encode_buf); text->encode_buf = NULL; } if (text->decode_buf) { text->utils->free(text->decode_buf); text->decode_buf = NULL; } if (text->decode_once_buf) { text->utils->free(text->decode_once_buf); text->decode_once_buf = NULL; } if (text->enc_in_buf) { if(text->enc_in_buf->data) text->utils->free(text->enc_in_buf->data); text->utils->free(text->enc_in_buf); text->enc_in_buf = NULL; } _plug_decode_free(&text->decode_context); if (text->authid) { /* works for both client and server */ text->utils->free(text->authid); text->authid = NULL; }}static void gssapi_common_mech_dispose(void *conn_context, const sasl_utils_t *utils){ sasl_gss_free_context_contents((context_t *)(conn_context)); utils->free(conn_context);}/***************************** Server Section *****************************/static int gssapi_server_mech_new(void *glob_context __attribute__((unused)), sasl_server_params_t *params, const char *challenge __attribute__((unused)), unsigned challen __attribute__((unused)), void **conn_context){ context_t *text; text = gss_new_context(params->utils); if (text == NULL) { MEMERROR(params->utils); return SASL_NOMEM; } text->gss_ctx = GSS_C_NO_CONTEXT; text->client_name = GSS_C_NO_NAME; text->server_name = GSS_C_NO_NAME; text->server_creds = GSS_C_NO_CREDENTIAL; text->state = SASL_GSSAPI_STATE_AUTHNEG; *conn_context = text; return SASL_OK;}static int gssapi_server_mech_step(void *conn_context, sasl_server_params_t *params, const char *clientin, unsigned clientinlen, const char **serverout, unsigned *serveroutlen, sasl_out_params_t *oparams){ context_t *text = (context_t *)conn_context; gss_buffer_t input_token, output_token; gss_buffer_desc real_input_token, real_output_token; OM_uint32 maj_stat = 0, min_stat = 0; OM_uint32 max_input; gss_buffer_desc name_token; int ret; input_token = &real_input_token; output_token = &real_output_token; output_token->value = NULL; output_token->length = 0; input_token->value = NULL; input_token->length = 0; if(!serverout) { PARAMERROR(text->utils); return SASL_BADPARAM; } *serverout = NULL; *serveroutlen = 0; if (sasl_gss_lib_init(text->utils) != SASL_OK) return SASL_FAIL; switch (text->state) { case SASL_GSSAPI_STATE_AUTHNEG: if (text->server_name == GSS_C_NO_NAME) { /* only once */ name_token.length = strlen(params->service) + 1 + strlen(params->serverFQDN); name_token.value = (char *)params->utils->malloc((name_token.length + 1) * sizeof(char)); if (name_token.value == NULL) { MEMERROR(text->utils); sasl_gss_free_context_contents(text); return SASL_NOMEM; } sprintf(name_token.value,"%s@%s", params->service, params->serverFQDN); maj_stat = (*p_krb5_gss_import_name) (&min_stat, &name_token, GSS_C_NT_HOSTBASED_SERVICE, &text->server_name); params->utils->free(name_token.value); name_token.value = NULL; if (GSS_ERROR(maj_stat)) { sasl_gss_seterror(text->utils, maj_stat, min_stat); sasl_gss_free_context_contents(text); return SASL_FAIL; } if ( text->server_creds != GSS_C_NO_CREDENTIAL) { maj_stat = (*p_krb5_gss_release_cred)(&min_stat, &text->server_creds); text->server_creds = GSS_C_NO_CREDENTIAL; } maj_stat = (*p_krb5_gss_acquire_cred)(&min_stat, text->server_name, GSS_C_INDEFINITE, GSS_C_NO_OID_SET, GSS_C_ACCEPT, &text->server_creds, NULL, NULL); if (GSS_ERROR(maj_stat)) { sasl_gss_seterror(text->utils, maj_stat, min_stat); sasl_gss_free_context_contents(text); return SASL_FAIL; } } if (clientinlen) { real_input_token.value = (void *)clientin; real_input_token.length = clientinlen; } maj_stat = (*p_krb5_gss_accept_sec_context)(&min_stat, &(text->gss_ctx), text->server_creds, input_token, GSS_C_NO_CHANNEL_BINDINGS, &text->client_name, NULL, output_token, NULL, NULL, NULL); if (GSS_ERROR(maj_stat)) { sasl_gss_log(text->utils, maj_stat, min_stat); text->utils->seterror(text->utils->conn, SASL_NOLOG, "GSSAPI Failure: gss_accept_sec_context"); if (output_token->value) { (*p_krb5_gss_release_buffer)(&min_stat, output_token); } sasl_gss_free_context_contents(text); return SASL_BADAUTH; } if (serveroutlen) *serveroutlen = output_token->length; if (output_token->value) { if (serverout) { ret = _plug_buf_alloc(text->utils, &(text->out_buf), &(text->out_buf_len), *serveroutlen); if(ret != SASL_OK) { (*p_krb5_gss_release_buffer)(&min_stat, output_token); return ret; } memcpy(text->out_buf, output_token->value, *serveroutlen); *serverout = text->out_buf; } (*p_krb5_gss_release_buffer)(&min_stat, output_token); } else { /* No output token, send an empty string */ *serverout = GSSAPI_BLANK_STRING; serveroutlen = 0; } if (maj_stat == GSS_S_COMPLETE) { /* Switch to ssf negotiation */ text->state = SASL_GSSAPI_STATE_SSFCAP; } return SASL_CONTINUE; case SASL_GSSAPI_STATE_SSFCAP: { unsigned char sasldata[4]; gss_buffer_desc name_token; gss_buffer_desc name_without_realm; gss_name_t without = NULL; int equal; name_token.value = NULL; name_without_realm.value = NULL; /* We ignore whatever the client sent us at this stage */ maj_stat = (*p_krb5_gss_display_name) (&min_stat, text->client_name, &name_token, NULL); if (GSS_ERROR(maj_stat)) { if (name_without_realm.value) params->utils->free(name_without_realm.value); if (name_token.value) (*p_krb5_gss_release_buffer)(&min_stat, &name_token); if (without) (*p_krb5_gss_release_name)(&min_stat, &without); SETERROR(text->utils, "GSSAPI Failure"); sasl_gss_free_context_contents(text); return SASL_BADAUTH; } /* If the id contains a realm get the identifier for the user without the realm and see if it's the same id (i.e. tmartin == tmartin@ANDREW.CMU.EDU. If this is the case we just want to return the id (i.e. just "tmartin" */ if (strchr((char *) name_token.value, (int) '@') != NULL) { /* NOTE: libc malloc, as it is freed below by a gssapi internal * function! */ name_without_realm.value = malloc(strlen(name_token.value)+1); if (name_without_realm.value == NULL) { MEMERROR(text->utils); return SASL_NOMEM; } strcpy(name_without_realm.value, name_token.value); /* cut off string at '@' */ (strchr(name_without_realm.value,'@'))[0] = '\0';
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -