static int HandleOP(AcceptContext) { OM_uint32 maj_stat, min_stat, ret_flags; int32_t hContext, deleg_hcred, flags; krb5_data in_token; int32_t new_context_id = 0, gsm_error = 0; krb5_data out_token = { 0 , NULL }; gss_ctx_id_t ctx; gss_cred_id_t deleg_cred = GSS_C_NO_CREDENTIAL; gss_buffer_desc input_token, output_token; ret32(c, hContext); ret32(c, flags); retdata(c, in_token); ctx = find_handle(c->handles, hContext, handle_context); if (ctx == NULL) hContext = 0; if (in_token.length) { input_token.length = in_token.length; input_token.value = in_token.data; } else { input_token.length = 0; input_token.value = NULL; } maj_stat = gss_accept_sec_context(&min_stat, &ctx, GSS_C_NO_CREDENTIAL, &input_token, GSS_C_NO_CHANNEL_BINDINGS, NULL, NULL, &output_token, &ret_flags, NULL, &deleg_cred); if (GSS_ERROR(maj_stat)) { if (hContext != 0) del_handle(&c->handles, hContext); logmessage(c, __FILE__, __LINE__, 0, "gss_accept_sec_context returns code: %d/%d", maj_stat, min_stat); new_context_id = 0; } else { if (hContext == 0) new_context_id = add_handle(c, handle_context, ctx); else new_context_id = hContext; } if (output_token.length) { out_token.data = output_token.value; out_token.length = output_token.length; } if ((ret_flags & GSS_C_DCE_STYLE) != 0) logmessage(c, __FILE__, __LINE__, 0, "accept_sec_context dce-style"); if ((ret_flags & GSS_C_DELEG_FLAG) != 0) { deleg_hcred = add_handle(c, handle_cred, deleg_cred); logmessage(c, __FILE__, __LINE__, 0, "accept_context delegated handle: %d", deleg_hcred); } else { gss_release_cred(&min_stat, &deleg_cred); deleg_hcred = 0; } gsm_error = convert_gss_to_gsm(maj_stat); put32(c, new_context_id); put32(c, gsm_error); putdata(c, out_token); put32(c, deleg_hcred); if (output_token.length) gss_release_buffer(&min_stat, &output_token); krb5_data_free(&in_token); return 0; }
static int HandleOP(UnwrapExt) { OM_uint32 maj_stat, min_stat; int32_t hContext, flags, bflags; krb5_data token, header, trailer; gss_ctx_id_t ctx; gss_iov_buffer_desc iov[3]; int conf_state, iov_len; gss_qop_t qop_state; ret32(c, hContext); ret32(c, flags); ret32(c, bflags); retdata(c, header); retdata(c, token); retdata(c, trailer); iov_len = sizeof(iov)/sizeof(iov[0]); if (bflags & WRAP_EXP_ONLY_HEADER) iov_len -= 1; /* skip trailer and padding, aka dce-style */ ctx = find_handle(c->handles, hContext, handle_context); if (ctx == NULL) errx(1, "unwrap: reference to unknown context"); if (header.length != 0) { iov[0].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY; iov[0].buffer.length = header.length; iov[0].buffer.value = header.data; } else { iov[0].type = GSS_IOV_BUFFER_TYPE_EMPTY; } iov[1].type = GSS_IOV_BUFFER_TYPE_DATA; iov[1].buffer.length = token.length; iov[1].buffer.value = token.data; if (trailer.length != 0) { iov[2].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY; iov[2].buffer.length = trailer.length; iov[2].buffer.value = trailer.data; } else { iov[2].type = GSS_IOV_BUFFER_TYPE_EMPTY; } maj_stat = gss_unwrap_iov(&min_stat, ctx, &conf_state, &qop_state, iov, iov_len); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_unwrap failed: %d/%d", maj_stat, min_stat); if (maj_stat == GSS_S_COMPLETE) { token.data = iov[1].buffer.value; token.length = iov[1].buffer.length; } else { token.data = NULL; token.length = 0; } put32(c, 0); /* XXX fix gsm_error */ putdata(c, token); return 0; }
static int HandleOP(InitContext) { OM_uint32 maj_stat, min_stat, ret_flags; int32_t hContext, hCred, flags; krb5_data target_name, in_token; int32_t new_context_id = 0, gsm_error = 0; krb5_data out_token = { 0 , NULL }; gss_ctx_id_t ctx; gss_cred_id_t creds; gss_name_t gss_target_name; gss_buffer_desc input_token, output_token; gss_OID oid = GSS_C_NO_OID; gss_buffer_t input_token_ptr = GSS_C_NO_BUFFER; ret32(c, hContext); ret32(c, hCred); ret32(c, flags); retdata(c, target_name); retdata(c, in_token); logmessage(c, __FILE__, __LINE__, 0, "targetname: <%.*s>", (int)target_name.length, (char *)target_name.data); ctx = find_handle(c->handles, hContext, handle_context); if (ctx == NULL) hContext = 0; creds = find_handle(c->handles, hCred, handle_cred); if (creds == NULL) abort(); input_token.length = target_name.length; input_token.value = target_name.data; maj_stat = gss_import_name(&min_stat, &input_token, GSS_KRB5_NT_PRINCIPAL_NAME, &gss_target_name); if (GSS_ERROR(maj_stat)) { logmessage(c, __FILE__, __LINE__, 0, "import name creds failed with: %d", maj_stat); gsm_error = convert_gss_to_gsm(maj_stat); goto out; } /* oid from flags */ if (in_token.length) { input_token.length = in_token.length; input_token.value = in_token.data; input_token_ptr = &input_token; if (ctx == NULL) krb5_errx(context, 1, "initcreds, context NULL, but not first req"); } else { input_token.length = 0; input_token.value = NULL; if (ctx) krb5_errx(context, 1, "initcreds, context not NULL, but first req"); } if ((flags & GSS_C_DELEG_FLAG) != 0) logmessage(c, __FILE__, __LINE__, 0, "init_sec_context delegating"); if ((flags & GSS_C_DCE_STYLE) != 0) logmessage(c, __FILE__, __LINE__, 0, "init_sec_context dce-style"); maj_stat = gss_init_sec_context(&min_stat, creds, &ctx, gss_target_name, oid, flags & 0x7f, 0, NULL, input_token_ptr, NULL, &output_token, &ret_flags, NULL); if (GSS_ERROR(maj_stat)) { if (hContext != 0) del_handle(&c->handles, hContext); new_context_id = 0; logmessage(c, __FILE__, __LINE__, 0, "gss_init_sec_context returns code: %d/%d", maj_stat, min_stat); } else { if (input_token.length == 0) new_context_id = add_handle(c, handle_context, ctx); else new_context_id = hContext; } gsm_error = convert_gss_to_gsm(maj_stat); if (output_token.length) { out_token.data = output_token.value; out_token.length = output_token.length; } out: logmessage(c, __FILE__, __LINE__, 0, "InitContext return code: %d", gsm_error); put32(c, new_context_id); put32(c, gsm_error); putdata(c, out_token); gss_release_name(&min_stat, &gss_target_name); if (output_token.length) gss_release_buffer(&min_stat, &output_token); krb5_data_free(&in_token); krb5_data_free(&target_name); return 0; }
static int HandleOP(WrapExt) { OM_uint32 maj_stat, min_stat; int32_t hContext, flags, bflags; krb5_data token, header, trailer; gss_ctx_id_t ctx; unsigned char *p; int conf_state, iov_len; gss_iov_buffer_desc iov[6]; ret32(c, hContext); ret32(c, flags); ret32(c, bflags); retdata(c, header); retdata(c, token); retdata(c, trailer); ctx = find_handle(c->handles, hContext, handle_context); if (ctx == NULL) errx(1, "wrap: reference to unknown context"); memset(&iov, 0, sizeof(iov)); iov_len = sizeof(iov)/sizeof(iov[0]); if (bflags & WRAP_EXP_ONLY_HEADER) iov_len -= 2; /* skip trailer and padding, aka dce-style */ iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER | GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE; if (header.length != 0) { iov[1].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY; iov[1].buffer.length = header.length; iov[1].buffer.value = header.data; } else { iov[1].type = GSS_IOV_BUFFER_TYPE_EMPTY; } iov[2].type = GSS_IOV_BUFFER_TYPE_DATA; iov[2].buffer.length = token.length; iov[2].buffer.value = token.data; if (trailer.length != 0) { iov[3].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY; iov[3].buffer.length = trailer.length; iov[3].buffer.value = trailer.data; } else { iov[3].type = GSS_IOV_BUFFER_TYPE_EMPTY; } iov[4].type = GSS_IOV_BUFFER_TYPE_PADDING | GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE; iov[5].type = GSS_IOV_BUFFER_TYPE_TRAILER | GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE; maj_stat = gss_wrap_iov_length(&min_stat, ctx, flags, 0, &conf_state, iov, iov_len); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_wrap_iov_length failed"); maj_stat = gss_wrap_iov(&min_stat, ctx, flags, 0, &conf_state, iov, iov_len); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_wrap_iov failed"); krb5_data_free(&token); token.length = iov[0].buffer.length + iov[2].buffer.length + iov[4].buffer.length + iov[5].buffer.length; token.data = malloc(token.length); p = token.data; memcpy(p, iov[0].buffer.value, iov[0].buffer.length); p += iov[0].buffer.length; memcpy(p, iov[2].buffer.value, iov[2].buffer.length); p += iov[2].buffer.length; memcpy(p, iov[4].buffer.value, iov[4].buffer.length); p += iov[4].buffer.length; memcpy(p, iov[5].buffer.value, iov[5].buffer.length); p += iov[5].buffer.length; gss_release_iov_buffer(NULL, iov, iov_len); put32(c, 0); /* XXX fix gsm_error */ putdata(c, token); free(token.data); return 0; }