int main(int argc, char *argv[]) { OM_uint32 minor, major; gss_OID mech = (gss_OID)gss_mech_krb5; gss_name_t name, mechname, impname; gss_buffer_desc buf, buf2; const char *name_arg; char opt; /* Parse arguments. */ while (argc > 1 && argv[1][0] == '-') { opt = argv[1][1]; argc--, argv++; if (opt == 'k') mech = &mech_krb5; else if (opt == 's') mech = &mech_spnego; else usage(); } if (argc != 2) usage(); name_arg = argv[1]; /* Import the name. */ name = import_name(name_arg); /* Canonicalize and export the name. */ major = gss_canonicalize_name(&minor, name, mech, &mechname); check_gsserr("gss_canonicalize_name", major, minor); major = gss_export_name(&minor, mechname, &buf); check_gsserr("gss_export_name", major, minor); /* Import and re-export the name, and compare the results. */ major = gss_import_name(&minor, &buf, GSS_C_NT_EXPORT_NAME, &impname); check_gsserr("gss_export_name", major, minor); major = gss_export_name(&minor, impname, &buf2); check_gsserr("gss_export_name", major, minor); if (buf.length != buf2.length || memcmp(buf.value, buf2.value, buf.length) != 0) { fprintf(stderr, "Mismatched results:\n"); print_hex(stderr, &buf); print_hex(stderr, &buf2); return 1; } print_hex(stdout, &buf); (void)gss_release_name(&minor, &name); (void)gss_release_name(&minor, &mechname); (void)gss_release_buffer(&minor, &buf); (void)gss_release_buffer(&minor, &buf2); return 0; }
uint32_t sapgss_export_name( uint32_t *minor_status, gss_name_t input_name, gss_buffer_t exported_name) { return gss_export_name(minor_status, input_name, exported_name); }
static void log_principal(gss_name_t server_name) { #if 0 /* FIXME: must call gss_canonicalize_name before gss_export_name */ OM_uint32 major_status = 0, minor_status = 0; gss_buffer_desc exported_name; /* Only for debugging purposes, check the gssapi internal representation */ major_status = gss_export_name(&minor_status, server_name, &exported_name); LOG(log_debug, logtype_uams, "log_principal: exported server name is %s", (char*) exported_name.value); gss_release_buffer( &minor_status, &exported_name ); #endif }
OM_uint32 GSSAPI_CALLCONV _gss_spnego_export_name (OM_uint32 * minor_status, gss_const_name_t input_name, gss_buffer_t exported_name ) { spnego_name name; *minor_status = 0; if (input_name == GSS_C_NO_NAME) return GSS_S_BAD_NAME; name = (spnego_name)input_name; if (name->mech == GSS_C_NO_NAME) return GSS_S_BAD_NAME; return gss_export_name(minor_status, name->mech, exported_name); }
/* Privileged (called from accept_secure_ctx) */ OM_uint32 ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) { int i = 0; gss_buffer_desc ename; client->mech = NULL; while (supported_mechs[i]->name != NULL) { if (supported_mechs[i]->oid.length == ctx->oid->length && (memcmp(supported_mechs[i]->oid.elements, ctx->oid->elements, ctx->oid->length) == 0)) client->mech = supported_mechs[i]; i++; } if (client->mech == NULL) return GSS_S_FAILURE; if ((ctx->major = gss_display_name(&ctx->minor, ctx->client, &client->displayname, NULL))) { ssh_gssapi_error(ctx); return (ctx->major); } if ((ctx->major = gss_export_name(&ctx->minor, ctx->client, &ename))) { ssh_gssapi_error(ctx); return (ctx->major); } if ((ctx->major = ssh_gssapi_parse_ename(ctx,&ename, &client->exportedname))) { return (ctx->major); } /* We can't copy this structure, so we just move the pointer to it */ client->creds = ctx->client_creds; ctx->client_creds = GSS_C_NO_CREDENTIAL; return (ctx->major); }
static gboolean daemon_socks_gssapi (struct pending_client *pc, gss_name_t username) { struct daemon_client *cd = pc->private_data; guint32 major_status, minor_status; gss_buffer_desc namebuf; namebuf.value = NULL; namebuf.length = 0; major_status = gss_export_name(&minor_status, username, &namebuf); if (GSS_ERROR(major_status)) { log_gssapi(pc->listener, LOG_WARNING, "releasing name", major_status, minor_status); return FALSE; } if (!daemon_client_connect_backend(cd, pc, namebuf.value)) return FALSE; major_status = gss_release_buffer(&minor_status, &namebuf); /* FIXME: Let the backend know somehow authentication is already done */ return TRUE; }
vchar_t * gssapi_get_id(struct ph1handle *iph1) { gss_buffer_desc id_buffer; gss_buffer_t id = &id_buffer; gss_name_t defname, canon_name; OM_uint32 min_stat, maj_stat; vchar_t *vmbuf; if (iph1->rmconf->proposal->gssid != NULL) return (vdup(iph1->rmconf->proposal->gssid)); if (gssapi_get_default_name(iph1, 0, &defname) < 0) return NULL; maj_stat = gss_canonicalize_name(&min_stat, defname, GSS_C_NO_OID, &canon_name); if (GSS_ERROR(maj_stat)) { gssapi_error(min_stat, LOCATION, "canonicalize name\n"); maj_stat = gss_release_name(&min_stat, &defname); if (GSS_ERROR(maj_stat)) gssapi_error(min_stat, LOCATION, "release default name\n"); return NULL; } maj_stat = gss_release_name(&min_stat, &defname); if (GSS_ERROR(maj_stat)) gssapi_error(min_stat, LOCATION, "release default name\n"); maj_stat = gss_export_name(&min_stat, canon_name, id); if (GSS_ERROR(maj_stat)) { gssapi_error(min_stat, LOCATION, "export name\n"); maj_stat = gss_release_name(&min_stat, &canon_name); if (GSS_ERROR(maj_stat)) gssapi_error(min_stat, LOCATION, "release canonical name\n"); return NULL; } maj_stat = gss_release_name(&min_stat, &canon_name); if (GSS_ERROR(maj_stat)) gssapi_error(min_stat, LOCATION, "release canonical name\n"); #if 0 /* * XXXJRT Did this debug message ever work? This is a GSS name * blob at this point. */ plog(LLV_DEBUG, LOCATION, NULL, "will try to acquire '%.*s' creds\n", id->length, id->value); #endif if (gssapi_gss2vmbuf(id, &vmbuf) < 0) { plog(LLV_ERROR, LOCATION, NULL, "gss2vmbuf failed\n"); maj_stat = gss_release_buffer(&min_stat, id); if (GSS_ERROR(maj_stat)) gssapi_error(min_stat, LOCATION, "release id buffer\n"); return NULL; } maj_stat = gss_release_buffer(&min_stat, id); if (GSS_ERROR(maj_stat)) gssapi_error(min_stat, LOCATION, "release id buffer\n"); return vmbuf; }
static int gssapi_init(struct ph1handle *iph1) { struct gssapi_ph1_state *gps; gss_buffer_desc id_token, cred_token; gss_buffer_t cred = &cred_token; gss_name_t princ, canon_princ; OM_uint32 maj_stat, min_stat; gps = racoon_calloc(1, sizeof (struct gssapi_ph1_state)); if (gps == NULL) { plog(LLV_ERROR, LOCATION, NULL, "racoon_calloc failed\n"); return -1; } gps->gss_context = GSS_C_NO_CONTEXT; gps->gss_cred = GSS_C_NO_CREDENTIAL; gssapi_set_state(iph1, gps); if (iph1->rmconf->proposal->gssid != NULL) { id_token.length = iph1->rmconf->proposal->gssid->l; id_token.value = iph1->rmconf->proposal->gssid->v; maj_stat = gss_import_name(&min_stat, &id_token, GSS_C_NO_OID, &princ); if (GSS_ERROR(maj_stat)) { gssapi_error(min_stat, LOCATION, "import name\n"); gssapi_free_state(iph1); return -1; } } else gssapi_get_default_name(iph1, 0, &princ); maj_stat = gss_canonicalize_name(&min_stat, princ, GSS_C_NO_OID, &canon_princ); if (GSS_ERROR(maj_stat)) { gssapi_error(min_stat, LOCATION, "canonicalize name\n"); maj_stat = gss_release_name(&min_stat, &princ); if (GSS_ERROR(maj_stat)) gssapi_error(min_stat, LOCATION, "release princ\n"); gssapi_free_state(iph1); return -1; } maj_stat = gss_release_name(&min_stat, &princ); if (GSS_ERROR(maj_stat)) gssapi_error(min_stat, LOCATION, "release princ\n"); maj_stat = gss_export_name(&min_stat, canon_princ, cred); if (GSS_ERROR(maj_stat)) { gssapi_error(min_stat, LOCATION, "export name\n"); maj_stat = gss_release_name(&min_stat, &canon_princ); if (GSS_ERROR(maj_stat)) gssapi_error(min_stat, LOCATION, "release canon_princ\n"); gssapi_free_state(iph1); return -1; } #if 0 /* * XXXJRT Did this debug message ever work? This is a GSS name * blob at this point. */ plog(LLV_DEBUG, LOCATION, NULL, "will try to acquire '%.*s' creds\n", cred->length, cred->value); #endif maj_stat = gss_release_buffer(&min_stat, cred); if (GSS_ERROR(maj_stat)) gssapi_error(min_stat, LOCATION, "release cred buffer\n"); maj_stat = gss_acquire_cred(&min_stat, canon_princ, GSS_C_INDEFINITE, GSS_C_NO_OID_SET, GSS_C_BOTH, &gps->gss_cred, NULL, NULL); if (GSS_ERROR(maj_stat)) { gssapi_error(min_stat, LOCATION, "acquire cred\n"); maj_stat = gss_release_name(&min_stat, &canon_princ); if (GSS_ERROR(maj_stat)) gssapi_error(min_stat, LOCATION, "release canon_princ\n"); gssapi_free_state(iph1); return -1; } maj_stat = gss_release_name(&min_stat, &canon_princ); if (GSS_ERROR(maj_stat)) gssapi_error(min_stat, LOCATION, "release canon_princ\n"); return 0; }
void mdsip_authenticate_cb( globus_xio_handle_t xio_handle, globus_result_t result, globus_byte_t *buffer, globus_size_t len, globus_size_t nbytes, globus_xio_data_descriptor_t data_desc, void *user_arg) { mdsip_client_t *ctx = (mdsip_client_t *)user_arg; char *remote_user = strncpy(malloc(nbytes+1),buffer,nbytes); remote_user[nbytes]=0; mdsip_test_result(xio_handle,result,ctx,"mdsip_authenticate_cb"); if (result == GLOBUS_SUCCESS) { int status; globus_result_t res; short dummy; mdsip_message_t *reply = (mdsip_message_t *)memset(malloc(sizeof(mdsip_message_t)),0,sizeof(mdsip_message_t)); char *contact; res = globus_xio_handle_cntl(xio_handle, (globus_xio_driver_t)ctx->options->tcp_driver, GLOBUS_XIO_TCP_GET_REMOTE_CONTACT, &contact); mdsip_test_result(xio_handle,res,ctx,"mdsip_authenticate_cb,GET_REMOTE_CONTACT"); ctx->host = strcpy(malloc(strlen(contact)+1),contact); ctx->host[strcspn(ctx->host,":")]=0; res = globus_xio_handle_cntl(xio_handle, (globus_xio_driver_t)ctx->options->tcp_driver, GLOBUS_XIO_TCP_GET_REMOTE_NUMERIC_CONTACT, &contact); mdsip_test_result(xio_handle,res,ctx,"mdsip_authenticate_cb,GETREMOTE_NUMERIC_CONTACT"); ctx->ipaddr = strcpy(malloc(strlen(contact)+1),contact); ctx->ipaddr[strcspn(ctx->ipaddr,":")]=0; mdsip_host_to_ipaddr(ctx->host,&ctx->addr,&dummy); if (ctx->options->security_level > 0) { gss_buffer_desc buffer_desc = GSS_C_EMPTY_BUFFER; gss_buffer_t buffer = &buffer_desc; OM_uint32 status; globus_xio_driver_t driver = (globus_xio_driver_t)ctx->options->gsi_driver; globus_result_t res; gss_name_t name; res = globus_xio_handle_cntl((globus_xio_handle_t)xio_handle, driver, GLOBUS_XIO_GSI_GET_PEER_NAME, &name); gss_export_name(&status, name, buffer); ctx->remote_user=strcpy(malloc(strlen((char *)buffer->value)+1),(char *)buffer->value); } else { ctx->remote_user=remote_user; } status = mdsip_find_user_mapping(ctx->options->hostfile, ctx->ipaddr,ctx->host,ctx->remote_user,&ctx->local_user); if (status & 1 && ctx->options->port_name == 0) status = mdsip_become_user(ctx->local_user,ctx->remote_user); reply->h.msglen = sizeof(mdsip_message_header_t); reply->h.status = status; if (status & 1) { if (ctx->options->security_level > 0) { fprintf(stdout,"%s, CONNECT - %s/%s@%s(%s)\n",mdsip_current_time(),ctx->remote_user,remote_user,ctx->host,ctx->ipaddr); free(remote_user); } else fprintf(stdout,"%s, CONNECT - %s@%s(%s)\n",mdsip_current_time(),ctx->remote_user,ctx->host,ctx->ipaddr); } else { fprintf(stdout,"%s, REJECT - %s@%s(%s)\n",mdsip_current_time(),ctx->remote_user,ctx->host,ctx->ipaddr); } free(ctx->message); mdsip_write((void *)xio_handle,ctx,reply,0); if (status & 1) { ctx->mdsip_read_cb = mdsip_do_message_cb; res = globus_xio_register_read(xio_handle,(globus_byte_t *)&ctx->header, sizeof(mdsip_message_header_t), sizeof(mdsip_message_header_t), NULL,mdsip_read_header_cb,ctx); mdsip_test_result(xio_handle,res,ctx,"mdsip_authenticate_cb,globus_xio_register_read"); } else globus_xio_register_close(xio_handle,NULL,mdsip_close_cb,ctx); } return; }
/* Privileged (called from accept_secure_ctx) */ OM_uint32 ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) { int i = 0; int equal = 0; gss_name_t new_name = GSS_C_NO_NAME; gss_buffer_desc ename = GSS_C_EMPTY_BUFFER; if (options.gss_store_rekey && client->used && ctx->client_creds) { if (client->mech->oid.length != ctx->oid->length || (memcmp(client->mech->oid.elements, ctx->oid->elements, ctx->oid->length) !=0)) { debug("Rekeyed credentials have different mechanism"); return GSS_S_COMPLETE; } if ((ctx->major = gss_inquire_cred_by_mech(&ctx->minor, ctx->client_creds, ctx->oid, &new_name, NULL, NULL, NULL))) { ssh_gssapi_error(ctx); return (ctx->major); } ctx->major = gss_compare_name(&ctx->minor, client->name, new_name, &equal); if (GSS_ERROR(ctx->major)) { ssh_gssapi_error(ctx); return (ctx->major); } if (!equal) { debug("Rekeyed credentials have different name"); return GSS_S_COMPLETE; } debug("Marking rekeyed credentials for export"); gss_release_name(&ctx->minor, &client->name); gss_release_cred(&ctx->minor, &client->creds); client->name = new_name; client->creds = ctx->client_creds; ctx->client_creds = GSS_C_NO_CREDENTIAL; client->updated = 1; return GSS_S_COMPLETE; } client->mech = NULL; while (supported_mechs[i]->name != NULL) { if (supported_mechs[i]->oid.length == ctx->oid->length && (memcmp(supported_mechs[i]->oid.elements, ctx->oid->elements, ctx->oid->length) == 0)) client->mech = supported_mechs[i]; i++; } if (client->mech == NULL) return GSS_S_FAILURE; if (ctx->client_creds && (ctx->major = gss_inquire_cred_by_mech(&ctx->minor, ctx->client_creds, ctx->oid, &client->name, NULL, NULL, NULL))) { ssh_gssapi_error(ctx); return (ctx->major); } if ((ctx->major = gss_display_name(&ctx->minor, ctx->client, &client->displayname, NULL))) { ssh_gssapi_error(ctx); return (ctx->major); } if ((ctx->major = gss_export_name(&ctx->minor, ctx->client, &ename))) { ssh_gssapi_error(ctx); return (ctx->major); } if ((ctx->major = ssh_gssapi_parse_ename(ctx,&ename, &client->exportedname))) { return (ctx->major); } gss_release_buffer(&ctx->minor, &ename); /* We can't copy this structure, so we just move the pointer to it */ client->creds = ctx->client_creds; ctx->client_creds = GSS_C_NO_CREDENTIAL; return (ctx->major); }
uint32_t gp_conv_name_to_gssx(uint32_t *min, gss_name_t in, gssx_name *_out) { uint32_t ret_maj; uint32_t ret_min; gss_buffer_desc name_buffer = GSS_C_EMPTY_BUFFER; gss_OID name_type; gss_buffer_desc exported_name = GSS_C_EMPTY_BUFFER; gss_buffer_desc exported_composite_name = GSS_C_EMPTY_BUFFER; gssx_name out = { .display_name.octet_string_len = 0 }; int ret; ret_maj = gss_display_name(&ret_min, in, &name_buffer, &name_type); if (ret_maj) { goto done; } ret = gp_conv_buffer_to_gssx(&name_buffer, &out.display_name); if (ret) { ret_maj = GSS_S_FAILURE; ret_min = ret; goto done; } ret = gp_conv_oid_to_gssx(name_type, &out.name_type); if (ret) { ret_maj = GSS_S_FAILURE; ret_min = ret; goto done; } ret_maj = gss_export_name(&ret_min, in, &exported_name); if (ret_maj == 0) { ret = gp_conv_buffer_to_gssx(&exported_name, &out.exported_name); if (ret) { ret_maj = GSS_S_FAILURE; ret_min = ret; goto done; } } else { /* In case the error is GSS_S_NAME_NOT_MN the name was not * canonicalized but that is ok we simply do not export the name * in this case */ if (ret_maj != GSS_S_NAME_NOT_MN) { goto done; } } ret_maj = gss_export_name_composite(&ret_min, in, &exported_composite_name); if (ret_maj == 0) { ret = gp_conv_buffer_to_gssx(&exported_composite_name, &out.exported_composite_name); if (ret) { ret_maj = GSS_S_FAILURE; ret_min = ret; goto done; } } else { /* In case the error is GSS_S_NAME_NOT_MN the name was not * canonicalized but that is ok we simply do not export the name * in this case */ if (ret_maj != GSS_S_NAME_NOT_MN && ret_maj != GSS_S_UNAVAILABLE) { goto done; } } ret_maj = GSS_S_COMPLETE; /* out->name_attributes */ done: *min = ret_min; gss_release_buffer(&ret_min, &name_buffer); gss_release_buffer(&ret_min, &exported_name); gss_release_buffer(&ret_min, &exported_composite_name); if (ret_maj) { xdr_free((xdrproc_t)xdr_gssx_buffer, (char *)&out.display_name); xdr_free((xdrproc_t)xdr_gssx_OID, (char *)&out.name_type); xdr_free((xdrproc_t)xdr_gssx_buffer, (char *)&out.exported_name); xdr_free((xdrproc_t)xdr_gssx_buffer, (char *)&out.exported_composite_name); } else { *_out = out; } return ret_maj; } uint32_t gp_conv_name_to_gssx_alloc(uint32_t *min, gss_name_t in, gssx_name **out) { gssx_name *o; uint32_t ret_maj; o = calloc(1, sizeof(gssx_name)); if (!o) { return ENOMEM; } ret_maj = gp_conv_name_to_gssx(min, in, o); if (ret_maj) { free(o); } else { *out = o; } return ret_maj; }
int main(int argc, char **argv) { gss_buffer_desc name_buffer; OM_uint32 maj_stat, min_stat; gss_name_t name, MNname, MNname2; int optidx = 0; char *str; int len, equal; setprogname(argv[0]); if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx)) usage(1); if (help_flag) usage (0); if(version_flag){ print_version(NULL); exit(0); } argc -= optidx; argv += optidx; gsskrb5_set_default_realm("MIT.EDU"); /* * test import/export */ str = NULL; len = asprintf(&str, "*****@*****.**"); if (len < 0 || str == NULL) errx(1, "asprintf"); name_buffer.value = str; name_buffer.length = len; maj_stat = gss_import_name(&min_stat, &name_buffer, GSS_C_NT_HOSTBASED_SERVICE, &name); if (maj_stat != GSS_S_COMPLETE) gss_err(1, min_stat, "import name error"); free(str); maj_stat = gss_canonicalize_name (&min_stat, name, GSS_KRB5_MECHANISM, &MNname); if (maj_stat != GSS_S_COMPLETE) gss_err(1, min_stat, "canonicalize name error"); maj_stat = gss_export_name(&min_stat, MNname, &name_buffer); if (maj_stat != GSS_S_COMPLETE) gss_err(1, min_stat, "export name error (KRB5)"); /* * Import the exported name and compare */ maj_stat = gss_import_name(&min_stat, &name_buffer, GSS_C_NT_EXPORT_NAME, &MNname2); if (maj_stat != GSS_S_COMPLETE) gss_err(1, min_stat, "import name error (exported KRB5 name)"); maj_stat = gss_compare_name(&min_stat, MNname, MNname2, &equal); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_compare_name"); if (!equal) errx(1, "names not equal"); gss_release_name(&min_stat, &MNname2); gss_release_buffer(&min_stat, &name_buffer); gss_release_name(&min_stat, &MNname); gss_release_name(&min_stat, &name); /* * Import oid less name and compare to mech name. * Dovecot SASL lib does this. */ str = NULL; len = asprintf(&str, "lha"); if (len < 0 || str == NULL) errx(1, "asprintf"); name_buffer.value = str; name_buffer.length = len; maj_stat = gss_import_name(&min_stat, &name_buffer, GSS_C_NO_OID, &name); if (maj_stat != GSS_S_COMPLETE) gss_err(1, min_stat, "import (no oid) name error"); maj_stat = gss_import_name(&min_stat, &name_buffer, GSS_KRB5_NT_USER_NAME, &MNname); if (maj_stat != GSS_S_COMPLETE) gss_err(1, min_stat, "import (krb5 mn) name error"); free(str); maj_stat = gss_compare_name(&min_stat, name, MNname, &equal); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_compare_name"); if (!equal) errx(1, "names not equal"); gss_release_name(&min_stat, &MNname); gss_release_name(&min_stat, &name); #if 0 maj_stat = gss_canonicalize_name (&min_stat, name, GSS_SPNEGO_MECHANISM, &MNname); if (maj_stat != GSS_S_COMPLETE) gss_err(1, min_stat, "canonicalize name error"); maj_stat = gss_export_name(&maj_stat, MNname, &name_buffer); if (maj_stat != GSS_S_COMPLETE) gss_err(1, min_stat, "export name error (SPNEGO)"); gss_release_name(&min_stat, &MNname); gss_release_buffer(&min_stat, &name_buffer); #endif return 0; }
int gss_check(int sock) { struct sockaddr_in remote, local; socklen_t addrlen; char *name; gss_buffer_desc input_token, output_token; gss_cred_id_t delegated_cred_handle = GSS_C_NO_CREDENTIAL; OM_uint32 maj_stat, min_stat; gss_name_t client_name; gss_buffer_desc export_name; gss_channel_bindings_t input_chan_bindings; tunnel_ctx_t* tunnel_ctx = createGssContext(sock); if( tunnel_ctx == NULL ) { return -1; } #ifndef MIT_KRB5 # if 0 /*VP This does not work neither with GT4 nor Heimdal */ delegated_cred_handle = malloc(sizeof(*delegated_cred_handle)); memset((char *) delegated_cred_handle, 0, sizeof(*delegated_cred_handle)); # endif #endif /* ! MIT_KRB5 */ addrlen = sizeof(local); if (getsockname(sock, (struct sockaddr *) & local, &addrlen) < 0 || addrlen != sizeof(local)) { #ifdef SHOW_ERROR perror("getsockname"); #endif return -1; } addrlen = sizeof(remote); if (getpeername(sock, (struct sockaddr *) & remote, &addrlen) < 0 || addrlen != sizeof(remote)) { #ifdef SHOW_ERROR perror("getpeername"); #endif return -1; } input_chan_bindings = malloc(sizeof(struct gss_channel_bindings_struct)); sockaddr_to_gss_address((struct sockaddr *) & local, &input_chan_bindings->initiator_addrtype, &input_chan_bindings->initiator_address); sockaddr_to_gss_address((struct sockaddr *) & remote, &input_chan_bindings->acceptor_addrtype, &input_chan_bindings->acceptor_address); input_chan_bindings->application_data.length = 0; input_chan_bindings->application_data.value = NULL; do { input_token.value = malloc(MAXBUF); input_token.length = eRead(sock, input_token.value, MAXBUF); maj_stat = gss_accept_sec_context(&min_stat, &tunnel_ctx->context_hdl, GSS_C_NO_CREDENTIAL, &input_token, input_chan_bindings, &client_name, NULL, &output_token, NULL, NULL, &delegated_cred_handle); if (GSS_ERROR(maj_stat)) { gss_print_errors(maj_stat); } gss_release_buffer(&min_stat, &input_token); if (output_token.length != 0) { eWrite(sock, output_token.value, output_token.length); printf("sended token %d\n", output_token.length); gss_release_buffer(&min_stat, &output_token); } if (maj_stat == GSS_S_COMPLETE) { printf("GSS OK\n"); if (GSS_ERROR(maj_stat)) { gss_print_errors(maj_stat); } maj_stat = gss_export_name(&min_stat, client_name, &export_name); if (GSS_ERROR(maj_stat)) { gss_print_errors(maj_stat); } name = realloc(export_name.value, export_name.length + 1); name[export_name.length] = '\0'; #if 0 printf("name = %s\n", name); fflush(stdout); #endif } } while( maj_stat == GSS_S_CONTINUE_NEEDED ) ; return 0; }