static void test_greet_authz_data(gss_name_t *name) { OM_uint32 major, minor; gss_buffer_desc attr; gss_buffer_desc value; gss_name_t canon; major = gss_canonicalize_name(&minor, *name, &mech_krb5, &canon); check_gsserr("gss_canonicalize_name", major, minor); attr.value = "greet:greeting"; attr.length = strlen((char *)attr.value); value.value = "Hello, acceptor world!"; value.length = strlen((char *)value.value); major = gss_set_name_attribute(&minor, canon, 1, &attr, &value); if (major == GSS_S_UNAVAILABLE) { (void)gss_release_name(&minor, &canon); return; } check_gsserr("gss_set_name_attribute", major, minor); gss_release_name(&minor, name); *name = canon; }
static OM_uint32 displayCanonName(OM_uint32 *minor, gss_name_t name, char *tag) { gss_name_t canon; OM_uint32 major, tmp_minor; gss_buffer_desc buf; major = gss_canonicalize_name(minor, name, (gss_OID)gss_mech_krb5, &canon); if (GSS_ERROR(major)) { displayStatus("gss_canonicalize_name", major, *minor); return major; } major = gss_display_name(minor, canon, &buf, NULL); if (GSS_ERROR(major)) { displayStatus("gss_display_name", major, *minor); gss_release_name(&tmp_minor, &canon); return major; } printf("%s:\t%s\n", tag, (char *)buf.value); gss_release_buffer(&tmp_minor, &buf); gss_release_name(&tmp_minor, &canon); return GSS_S_COMPLETE; }
/* * Equality based local login authorization. */ static OM_uint32 compare_names_authorize_localname(OM_uint32 *minor, const gss_union_name_t unionName, const gss_name_t user) { OM_uint32 status, tmpMinor; gss_name_t canonName; int match = 0; status = gss_canonicalize_name(minor, user, unionName->mech_type, &canonName); if (status != GSS_S_COMPLETE) return (status); status = gss_compare_name(minor, (gss_name_t)unionName, canonName, &match); if (status == GSS_S_COMPLETE && match == 0) status = GSS_S_UNAUTHORIZED; (void) gss_release_name(&tmpMinor, &canonName); return (status); }
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; }
static OM_uint32 compare_names(OM_uint32 *minor, const gss_OID mech_type, const gss_name_t name, const char *user, int *user_ok) { OM_uint32 status, tmpMinor; gss_name_t imported_name; gss_name_t canon_name; gss_buffer_desc gss_user; int match = 0; *user_ok = 0; gss_user.value = (void *)user; if (!gss_user.value || !name || !mech_type) return (GSS_S_BAD_NAME); gss_user.length = strlen(gss_user.value); status = gss_import_name(minor, &gss_user, GSS_C_NT_USER_NAME, &imported_name); if (status != GSS_S_COMPLETE) { goto out; } status = gss_canonicalize_name(minor, imported_name, mech_type, &canon_name); if (status != GSS_S_COMPLETE) { (void) gss_release_name(&tmpMinor, &imported_name); goto out; } status = gss_compare_name(minor, canon_name, name, &match); (void) gss_release_name(&tmpMinor, &canon_name); (void) gss_release_name(&tmpMinor, &imported_name); if (status == GSS_S_COMPLETE) { if (match) *user_ok = 1; /* remote user is a-ok */ } out: return (status); }
void display_canon_name(const char *tag, gss_name_t name, gss_OID mech) { gss_name_t canon; OM_uint32 major, minor; gss_buffer_desc buf; major = gss_canonicalize_name(&minor, name, mech, &canon); check_gsserr("gss_canonicalize_name", major, minor); major = gss_display_name(&minor, canon, &buf, NULL); check_gsserr("gss_display_name", major, minor); printf("%s:\t%.*s\n", tag, (int)buf.length, (char *)buf.value); (void)gss_release_name(&minor, &canon); (void)gss_release_buffer(&minor, &buf); }
uint32_t sapgss_canonicalize_name( uint32_t *minor_status, gss_name_t input_name, sapgss_OID mech_type, gss_name_t *output_name) { gss_OID mech_type_loc; uint32_t major_status; int ret; ret = gss_OID_sap_to_loc(mech_type, &mech_type_loc); if (ret != 0) { *minor_status = ret; return GSS_S_FAILURE; } major_status = gss_canonicalize_name(minor_status, input_name, mech_type_loc, output_name); /* Comply with the gss_OID_sap_to_loc contract and free mech_type_loc */ gss_OID_loc_release(&mech_type_loc); return major_status; }
OM_uint32 ntlm_gss_acquire_cred( OM_uint32 *minor_status, gss_name_t desired_name, OM_uint32 time_req, gss_OID_set desired_mechs, gss_cred_usage_t cred_usage, gss_cred_id_t *output_cred_handle, gss_OID_set *actual_mechs, OM_uint32 *time_rec) { OM_uint32 major = 0; OM_uint32 minor = 0; ntlm_gss_cred_id_t ntlm_cred = NULL; gss_name_t gss_krb5_name_buf = NULL; /* Allocate the cred structure */ ntlm_cred = (ntlm_gss_cred_id_t) xmalloc(sizeof(*ntlm_cred)); if (!ntlm_cred) { minor = ENOMEM; major = GSS_S_FAILURE; goto error; } memset(ntlm_cred, 0, sizeof(*ntlm_cred)); /* Allocate/set the mech OID; must be NTLM for this method to be called */ ntlm_cred->ntlm_mech_oid = (gss_OID) xmalloc(sizeof(*ntlm_cred->ntlm_mech_oid)); if (!ntlm_cred) { minor = ENOMEM; major = GSS_S_FAILURE; goto error; } memset(ntlm_cred->ntlm_mech_oid, 0, sizeof(*ntlm_cred->ntlm_mech_oid)); ntlm_cred->ntlm_mech_oid->elements = (void *) xmalloc(GSS_NTLM_MECH_OID_LEN); if (!ntlm_cred) { minor = ENOMEM; major = GSS_S_FAILURE; goto error; } ntlm_cred->ntlm_mech_oid->length = GSS_NTLM_MECH_OID_LEN; memcpy(ntlm_cred->ntlm_mech_oid->elements, NTLM_OID, GSS_NTLM_MECH_OID_LEN); if (desired_name) { /* Really, use krb5 mech OID for name, as the desired output is a UPN */ major = gss_canonicalize_name(&minor, desired_name, (gss_OID) gss_mech_krb5, &gss_krb5_name_buf); if (major) { goto error; } ntlm_cred->name = gss_krb5_name_buf, gss_krb5_name_buf = NULL; } *output_cred_handle = (gss_cred_id_t) ntlm_cred; error: if (major || minor) { *minor_status = minor; if (ntlm_cred->ntlm_mech_oid->elements) { free(ntlm_cred->ntlm_mech_oid->elements); } if (ntlm_cred->ntlm_mech_oid) { free(ntlm_cred->ntlm_mech_oid); } if (ntlm_cred) { free(ntlm_cred); } } return major; }
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; }
int gp_import_and_canon_name(struct gp_call_ctx *gpcall, union gp_rpc_arg *arg, union gp_rpc_res *res) { struct gssx_arg_import_and_canon_name *icna; struct gssx_res_import_and_canon_name *icnr; gss_OID mech = GSS_C_NO_OID; gss_name_t import_name = GSS_C_NO_NAME; gss_name_t output_name = GSS_C_NO_NAME; uint32_t ret_maj = 0; uint32_t ret_min = 0; int ret; icna = &arg->import_and_canon_name; icnr = &res->import_and_canon_name; if (icna->input_name.display_name.octet_string_len == 0 && icna->input_name.exported_name.octet_string_len == 0) { ret = EINVAL; goto done; } ret_maj = gp_conv_gssx_to_name(&ret_min, &icna->input_name, &import_name); if (ret_maj) { goto done; } if (icna->mech.octet_string_len != 0) { ret = gp_conv_gssx_to_oid_alloc(&icna->mech, &mech); if (ret) { ret_maj = GSS_S_FAILURE; ret_min = ret; goto done; } ret_maj = gss_canonicalize_name(&ret_min, import_name, mech, &output_name); if (ret_maj) { goto done; } ret_maj = gp_conv_name_to_gssx_alloc(&ret_min, output_name, &icnr->output_name); } else { ret_maj = gp_conv_name_to_gssx_alloc(&ret_min, import_name, &icnr->output_name); } /* TODO: check also icna->input_name.exported_composite_name */ /* TODO: icna->name_attributes */ done: ret = gp_conv_status_to_gssx(&icna->call_ctx, ret_maj, ret_min, mech, &icnr->status); gss_release_oid(&ret_min, &mech); gss_release_name(&ret_min, &import_name); gss_release_name(&ret_min, &output_name); return ret; }
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; }