static void ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) { krb5_ccache ccache; krb5_error_code problem; krb5_principal princ; OM_uint32 maj_status, min_status; const char *errmsg; if (client->creds == NULL) { debug("No credentials stored"); return; } if (ssh_gssapi_krb5_init() == 0) return; if ((problem = krb5_cc_new_unique(krb_context, krb5_fcc_ops.prefix, NULL, &ccache)) != 0) { errmsg = krb5_get_error_message(krb_context, problem); logit("krb5_cc_new_unique(): %.100s", errmsg); krb5_free_error_message(krb_context, errmsg); return; } if ((problem = krb5_parse_name(krb_context, client->exportedname.value, &princ))) { errmsg = krb5_get_error_message(krb_context, problem); logit("krb5_parse_name(): %.100s", errmsg); krb5_free_error_message(krb_context, errmsg); krb5_cc_destroy(krb_context, ccache); return; } if ((problem = krb5_cc_initialize(krb_context, ccache, princ))) { errmsg = krb5_get_error_message(krb_context, problem); logit("krb5_cc_initialize(): %.100s", errmsg); krb5_free_error_message(krb_context, errmsg); krb5_free_principal(krb_context, princ); krb5_cc_destroy(krb_context, ccache); return; } krb5_free_principal(krb_context, princ); if ((maj_status = gss_krb5_copy_ccache(&min_status, client->creds, ccache))) { logit("gss_krb5_copy_ccache() failed"); krb5_cc_destroy(krb_context, ccache); return; } client->store.filename = xstrdup(krb5_cc_get_name(krb_context, ccache)); client->store.envvar = "KRB5CCNAME"; client->store.envval = xstrdup(client->store.filename); krb5_cc_close(krb_context, ccache); return; }
int cli_credentials_set_client_gss_creds(struct cli_credentials *cred, struct loadparm_context *lp_ctx, gss_cred_id_t gssapi_cred, enum credentials_obtained obtained, const char **error_string) { int ret; OM_uint32 maj_stat, min_stat; struct ccache_container *ccc; struct gssapi_creds_container *gcc; if (cred->client_gss_creds_obtained > obtained) { return 0; } gcc = talloc(cred, struct gssapi_creds_container); if (!gcc) { (*error_string) = error_message(ENOMEM); return ENOMEM; } ret = cli_credentials_new_ccache(cred, lp_ctx, NULL, &ccc, error_string); if (ret != 0) { return ret; } maj_stat = gss_krb5_copy_ccache(&min_stat, gssapi_cred, ccc->ccache); if (maj_stat) { if (min_stat) { ret = min_stat; } else { ret = EINVAL; } if (ret) { (*error_string) = error_message(ENOMEM); } } if (ret == 0) { ret = cli_credentials_set_from_ccache(cred, ccc, obtained, error_string); } cred->ccache = ccc; cred->ccache_obtained = obtained; if (ret == 0) { gcc->creds = gssapi_cred; talloc_set_destructor(gcc, free_gssapi_creds); /* set the clinet_gss_creds_obtained here, as it just got set to UNINITIALISED by the calls above */ cred->client_gss_creds_obtained = obtained; cred->client_gss_creds = gcc; } return ret; }
static void put_creds_in_ccache(char *name, gss_cred_id_t creds) { OM_uint32 maj_stat, min_stat; krb5_context context; krb5_principal me; krb5_ccache ccache; krb5_error_code retval; char buf[1024]; maj_stat = krb5_init_context(&context); if (maj_stat != GSS_S_COMPLETE) { gsslib_display_status(MSG_GSS_PRINTERROR_GETTINGKRB5CONTEXT, maj_stat, GSS_S_COMPLETE); return; } /* Set up ccache */ if ((retval = krb5_parse_name(context, name, &me))) { snprintf(buf, sizeof buf, MSG_GSS_PRINTERROR_KRB5PARSENAMERETURNEDX_I, retval); gsslib_print_error(buf); return; } /* Use default ccache */ if ((retval = krb5_cc_default(context, &ccache))) { snprintf(buf, sizeof buf, MSG_GSS_PRINTERROR_KRB5CCDEFAULTRETURNEDX_I, retval); gsslib_print_error(buf); return; } if ((retval = krb5_cc_initialize(context, ccache, me))) { snprintf(buf, sizeof buf, MSG_GSS_PRINTERROR_KRB5CCINITIALIZERETURNEDX_I, retval); gsslib_print_error(buf); return; } /* Copy GSS creds into ccache */ maj_stat = gss_krb5_copy_ccache(&min_stat, creds, ccache); if (maj_stat != GSS_S_COMPLETE) { gsslib_display_status(MSG_GSS_PRINTERROR_COPYINGDELEGATEDCREDSTOCC, maj_stat, min_stat); goto cleanup; } return; cleanup: krb5_cc_destroy(context, ccache); }
static gss_client_response *store_gss_creds(gss_server_state *state) { OM_uint32 maj_stat, min_stat; krb5_principal princ = NULL; krb5_ccache ccache = NULL; krb5_error_code problem; krb5_context context; gss_client_response *response = NULL; problem = krb5_init_context(&context); if (problem) { response = other_error("No auth_data value in request from client"); return response; } problem = krb5_parse_name(context, state->username, &princ); if (problem) { response = krb5_ctx_error(context, problem); goto end; } if ((response = create_krb5_ccache(state, context, princ, &ccache))) { goto end; } maj_stat = gss_krb5_copy_ccache(&min_stat, state->client_creds, ccache); if (GSS_ERROR(maj_stat)) { response = gss_error(__func__, "gss_krb5_copy_ccache", maj_stat, min_stat); response->return_code = AUTH_GSS_ERROR; goto end; } krb5_cc_close(context, ccache); ccache = NULL; response = calloc(1, sizeof(gss_client_response)); if(response == NULL) die1("Memory allocation failed"); // TODO: something other than AUTH_GSS_COMPLETE? response->return_code = AUTH_GSS_COMPLETE; end: if (princ) krb5_free_principal(context, princ); if (ccache) krb5_cc_destroy(context, ccache); krb5_free_context(context); return response; }
int cli_credentials_set_client_gss_creds(struct cli_credentials *cred, gss_cred_id_t gssapi_cred, enum credentials_obtained obtained) { int ret; OM_uint32 maj_stat, min_stat; struct ccache_container *ccc; struct gssapi_creds_container *gcc; if (cred->client_gss_creds_obtained > obtained) { return 0; } gcc = talloc(cred, struct gssapi_creds_container); if (!gcc) { return ENOMEM; } ret = cli_credentials_new_ccache(cred, &ccc); if (ret != 0) { return ret; } maj_stat = gss_krb5_copy_ccache(&min_stat, gssapi_cred, ccc->ccache); if (maj_stat) { if (min_stat) { ret = min_stat; } else { ret = EINVAL; } } if (ret == 0) { ret = cli_credentials_set_from_ccache(cred, obtained); } if (ret == 0) { gcc->creds = gssapi_cred; talloc_set_destructor(gcc, free_gssapi_creds); cred->client_gss_creds_obtained = obtained; cred->client_gss_creds = gcc; } return ret; }
static int mod_authn_gssapi_store_gss_creds(server *srv, connection *con, plugin_data *p, char *princ_name, gss_cred_id_t delegated_cred) { OM_uint32 maj_stat, min_stat; krb5_principal princ = NULL; krb5_ccache ccache = NULL; krb5_error_code problem; krb5_context context; problem = krb5_init_context(&context); if (problem) { mod_authn_gssapi_log_krb5_error(srv, __FILE__, __LINE__, "krb5_init_context", NULL, context, problem); return 0; } problem = krb5_parse_name(context, princ_name, &princ); if (problem) { mod_authn_gssapi_log_krb5_error(srv, __FILE__, __LINE__, "krb5_parse_name", NULL, context, problem); goto end; } if (mod_authn_gssapi_create_krb5_ccache(srv, con, p, context, princ, &ccache)) goto end; maj_stat = gss_krb5_copy_ccache(&min_stat, delegated_cred, ccache); if (GSS_ERROR(maj_stat)) { mod_authn_gssapi_log_gss_error(srv, __FILE__, __LINE__, "gss_krb5_copy_ccache", princ_name, maj_stat, min_stat); goto end; } krb5_cc_close(context, ccache); krb5_free_principal(context, princ); krb5_free_context(context); return 1; end: if (princ) krb5_free_principal(context, princ); if (ccache) krb5_cc_destroy(context, ccache); krb5_free_context(context); return 0; }
static void ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) { krb5_ccache ccache; krb5_error_code problem; krb5_principal princ; OM_uint32 maj_status, min_status; int len; if (client->creds == NULL) { debug("No credentials stored"); return; } if (ssh_gssapi_krb5_init() == 0) return; #ifdef HEIMDAL if ((problem = krb5_cc_gen_new(krb_context, &krb5_fcc_ops, &ccache))) { logit("krb5_cc_gen_new(): %.100s", krb5_get_err_text(krb_context, problem)); return; } #else { int tmpfd; char ccname[40]; snprintf(ccname, sizeof(ccname), "FILE:/tmp/krb5cc_%d_XXXXXX", geteuid()); if ((tmpfd = mkstemp(ccname + strlen("FILE:"))) == -1) { logit("mkstemp(): %.100s", strerror(errno)); problem = errno; return; } if (fchmod(tmpfd, S_IRUSR | S_IWUSR) == -1) { logit("fchmod(): %.100s", strerror(errno)); close(tmpfd); problem = errno; return; } close(tmpfd); if ((problem = krb5_cc_resolve(krb_context, ccname, &ccache))) { logit("krb5_cc_resolve(): %.100s", krb5_get_err_text(krb_context, problem)); return; } } #endif /* #ifdef HEIMDAL */ if ((problem = krb5_parse_name(krb_context, client->exportedname.value, &princ))) { logit("krb5_parse_name(): %.100s", krb5_get_err_text(krb_context, problem)); krb5_cc_destroy(krb_context, ccache); return; } if ((problem = krb5_cc_initialize(krb_context, ccache, princ))) { logit("krb5_cc_initialize(): %.100s", krb5_get_err_text(krb_context, problem)); krb5_free_principal(krb_context, princ); krb5_cc_destroy(krb_context, ccache); return; } krb5_free_principal(krb_context, princ); if ((maj_status = gss_krb5_copy_ccache(&min_status, client->creds, ccache))) { logit("gss_krb5_copy_ccache() failed"); krb5_cc_destroy(krb_context, ccache); return; } client->store.filename = xstrdup(krb5_cc_get_name(krb_context, ccache)); client->store.envvar = "KRB5CCNAME"; len = strlen(client->store.filename) + 6; client->store.envval = xmalloc(len); snprintf(client->store.envval, len, "FILE:%s", client->store.filename); #ifdef USE_PAM if (options.use_pam) do_pam_putenv(client->store.envvar, client->store.envval); #endif krb5_cc_close(krb_context, ccache); return; }
static void ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) { krb5_ccache ccache; krb5_error_code problem; krb5_principal princ; OM_uint32 maj_status, min_status; const char *errmsg; const char *new_ccname; if (client->creds == NULL) { debug("No credentials stored"); return; } if (ssh_gssapi_krb5_init() == 0) return; #ifdef HEIMDAL # ifdef HAVE_KRB5_CC_NEW_UNIQUE if ((problem = krb5_cc_new_unique(krb_context, krb5_fcc_ops.prefix, NULL, &ccache)) != 0) { errmsg = krb5_get_error_message(krb_context, problem); logit("krb5_cc_new_unique(): %.100s", errmsg); # else if ((problem = krb5_cc_gen_new(krb_context, &krb5_fcc_ops, &ccache))) { logit("krb5_cc_gen_new(): %.100s", krb5_get_err_text(krb_context, problem)); # endif krb5_free_error_message(krb_context, errmsg); return; } #else if ((problem = ssh_krb5_cc_gen(krb_context, &ccache))) { errmsg = krb5_get_error_message(krb_context, problem); logit("ssh_krb5_cc_gen(): %.100s", errmsg); krb5_free_error_message(krb_context, errmsg); return; } #endif /* #ifdef HEIMDAL */ if ((problem = krb5_parse_name(krb_context, client->exportedname.value, &princ))) { errmsg = krb5_get_error_message(krb_context, problem); logit("krb5_parse_name(): %.100s", errmsg); krb5_free_error_message(krb_context, errmsg); return; } if ((problem = krb5_cc_initialize(krb_context, ccache, princ))) { errmsg = krb5_get_error_message(krb_context, problem); logit("krb5_cc_initialize(): %.100s", errmsg); krb5_free_error_message(krb_context, errmsg); krb5_free_principal(krb_context, princ); krb5_cc_destroy(krb_context, ccache); return; } krb5_free_principal(krb_context, princ); if ((maj_status = gss_krb5_copy_ccache(&min_status, client->creds, ccache))) { logit("gss_krb5_copy_ccache() failed"); krb5_cc_destroy(krb_context, ccache); return; } new_ccname = krb5_cc_get_name(krb_context, ccache); client->store.envvar = "KRB5CCNAME"; #ifdef USE_CCAPI xasprintf(&client->store.envval, "API:%s", new_ccname); client->store.filename = NULL; #else xasprintf(&client->store.envval, "FILE:%s", new_ccname); client->store.filename = xstrdup(new_ccname); #endif #ifdef USE_PAM if (options.use_pam) do_pam_putenv(client->store.envvar, client->store.envval); #endif krb5_cc_close(krb_context, ccache); return; } int ssh_gssapi_krb5_updatecreds(ssh_gssapi_ccache *store, ssh_gssapi_client *client) { krb5_ccache ccache = NULL; krb5_principal principal = NULL; char *name = NULL; krb5_error_code problem; OM_uint32 maj_status, min_status; if ((problem = krb5_cc_resolve(krb_context, store->envval, &ccache))) { logit("krb5_cc_resolve(): %.100s", krb5_get_err_text(krb_context, problem)); return 0; } /* Find out who the principal in this cache is */ if ((problem = krb5_cc_get_principal(krb_context, ccache, &principal))) { logit("krb5_cc_get_principal(): %.100s", krb5_get_err_text(krb_context, problem)); krb5_cc_close(krb_context, ccache); return 0; } if ((problem = krb5_unparse_name(krb_context, principal, &name))) { logit("krb5_unparse_name(): %.100s", krb5_get_err_text(krb_context, problem)); krb5_free_principal(krb_context, principal); krb5_cc_close(krb_context, ccache); return 0; } if (strcmp(name,client->exportedname.value)!=0) { debug("Name in local credentials cache differs. Not storing"); krb5_free_principal(krb_context, principal); krb5_cc_close(krb_context, ccache); krb5_free_unparsed_name(krb_context, name); return 0; } krb5_free_unparsed_name(krb_context, name); /* Name matches, so lets get on with it! */ if ((problem = krb5_cc_initialize(krb_context, ccache, principal))) { logit("krb5_cc_initialize(): %.100s", krb5_get_err_text(krb_context, problem)); krb5_free_principal(krb_context, principal); krb5_cc_close(krb_context, ccache); return 0; } krb5_free_principal(krb_context, principal); if ((maj_status = gss_krb5_copy_ccache(&min_status, client->creds, ccache))) { logit("gss_krb5_copy_ccache() failed. Sorry!"); krb5_cc_close(krb_context, ccache); return 0; } return 1; }
static void copy_import(void) { gss_cred_id_t cred1, cred2; OM_uint32 maj_stat, min_stat; gss_name_t name1, name2; OM_uint32 lifetime1, lifetime2; gss_cred_usage_t usage1, usage2; gss_OID_set mechs1, mechs2; krb5_ccache id; krb5_error_code ret; krb5_context context; int equal; maj_stat = gss_acquire_cred(&min_stat, GSS_C_NO_NAME, GSS_C_INDEFINITE, GSS_C_NO_OID_SET, GSS_C_INITIATE, &cred1, NULL, NULL); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_acquire_cred"); maj_stat = gss_inquire_cred(&min_stat, cred1, &name1, &lifetime1, &usage1, &mechs1); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_inquire_cred"); ret = krb5_init_context(&context); if (ret) errx(1, "krb5_init_context"); ret = krb5_cc_new_unique(context, krb5_cc_type_memory, NULL, &id); if (ret) krb5_err(context, 1, ret, "krb5_cc_new_unique"); maj_stat = gss_krb5_copy_ccache(&min_stat, cred1, id); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_krb5_copy_ccache"); maj_stat = gss_krb5_import_cred(&min_stat, id, NULL, NULL, &cred2); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_krb5_import_cred"); maj_stat = gss_inquire_cred(&min_stat, cred2, &name2, &lifetime2, &usage2, &mechs2); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_inquire_cred 2"); maj_stat = gss_compare_name(&min_stat, name1, name2, &equal); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_compare_name"); if (!equal) errx(1, "names not equal"); if (lifetime1 != lifetime2) errx(1, "lifetime not equal %lu != %lu", (unsigned long)lifetime1, (unsigned long)lifetime2); if (usage1 != usage2) { /* as long any of them is both are everything it ok */ if (usage1 != GSS_C_BOTH && usage2 != GSS_C_BOTH) errx(1, "usages disjoined"); } gss_release_name(&min_stat, &name2); gss_release_oid_set(&min_stat, &mechs2); maj_stat = gss_inquire_cred(&min_stat, cred2, &name2, &lifetime2, &usage2, &mechs2); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_inquire_cred"); maj_stat = gss_compare_name(&min_stat, name1, name2, &equal); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_compare_name"); if (!equal) errx(1, "names not equal"); if (lifetime1 != lifetime2) errx(1, "lifetime not equal %lu != %lu", (unsigned long)lifetime1, (unsigned long)lifetime2); gss_release_cred(&min_stat, &cred1); gss_release_cred(&min_stat, &cred2); gss_release_name(&min_stat, &name1); gss_release_name(&min_stat, &name2); #if 0 compare(mechs1, mechs2); #endif gss_release_oid_set(&min_stat, &mechs1); gss_release_oid_set(&min_stat, &mechs2); krb5_cc_destroy(context, id); krb5_free_context(context); }
static int store_gss_creds(gss_store_state *state, char *princ_name, gss_cred_id_t delegated_cred) { OM_uint32 maj_stat, min_stat; krb5_error_code problem; const char * temp_ccname = "FILE:/tmp/krb5cc_pykerberos_XXXXXX"; int ret = 1; problem = krb5_init_context(&state->context); if (problem) { PyErr_SetObject(BasicAuthException_class, Py_BuildValue("((s:i))", "Cannot initialize Kerberos5 context", problem)); return 0; } int name_len = strlen(temp_ccname); state->ccache_name = (char *)malloc(name_len + 1); strcpy(state->ccache_name, temp_ccname); int fd = mkstemp(state->ccache_name + strlen("FILE:")); if (fd < 0) { PyErr_SetObject(BasicAuthException_class, Py_BuildValue("(s:s)", "Error in mkstemp", strerror(errno))); ret = 0; goto end; } close(fd); problem = krb5_cc_resolve(state->context, state->ccache_name, &state->ccache); if (problem) { set_basicauth_error(state->context, problem); ret = 0; goto end; } problem = krb5_parse_name(state->context, princ_name, &state->client); if (problem) { set_basicauth_error(state->context, problem); goto end; } problem = krb5_cc_initialize(state->context, state->ccache, state->client); if (problem) { set_basicauth_error(state->context, problem); ret = 0; goto end; } maj_stat = gss_krb5_copy_ccache(&min_stat, delegated_cred, state->ccache); if (GSS_ERROR(maj_stat)) { set_gss_error(maj_stat, min_stat); ret = 0; goto end; } ret = 1; return ret; end: if (state->client != NULL) krb5_free_principal(state->context, state->client); if (state->ccache != NULL) krb5_cc_destroy(state->context, state->ccache); krb5_free_context(state->context); return ret; }
static void ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) { krb5_ccache ccache; krb5_error_code problem; krb5_principal princ; OM_uint32 maj_status, min_status; int len; const char *new_ccname; if (client->creds == NULL) { debug("No credentials stored"); return; } if (ssh_gssapi_krb5_init() == 0) return; #ifdef HEIMDAL if ((problem = krb5_cc_gen_new(krb_context, &krb5_fcc_ops, &ccache))) { logit("krb5_cc_gen_new(): %.100s", krb5_get_err_text(krb_context, problem)); return; } #else if ((problem = ssh_krb5_cc_gen(krb_context, &ccache))) { logit("ssh_krb5_cc_gen(): %.100s", krb5_get_err_text(krb_context, problem)); return; } #endif /* #ifdef HEIMDAL */ if ((problem = krb5_parse_name(krb_context, client->exportedname.value, &princ))) { logit("krb5_parse_name(): %.100s", krb5_get_err_text(krb_context, problem)); krb5_cc_destroy(krb_context, ccache); return; } if ((problem = krb5_cc_initialize(krb_context, ccache, princ))) { logit("krb5_cc_initialize(): %.100s", krb5_get_err_text(krb_context, problem)); krb5_free_principal(krb_context, princ); krb5_cc_destroy(krb_context, ccache); return; } krb5_free_principal(krb_context, princ); if ((maj_status = gss_krb5_copy_ccache(&min_status, client->creds, ccache))) { logit("gss_krb5_copy_ccache() failed"); krb5_cc_destroy(krb_context, ccache); return; } new_ccname = krb5_cc_get_name(krb_context, ccache); client->store.envvar = "KRB5CCNAME"; #ifdef USE_CCAPI xasprintf(&client->store.envval, "API:%s", new_ccname); client->store.filename = NULL; #else xasprintf(&client->store.envval, "FILE:%s", new_ccname); client->store.filename = xstrdup(new_ccname); #endif #ifdef USE_PAM if (options.use_pam) do_pam_putenv(client->store.envvar, client->store.envval); #endif krb5_cc_close(krb_context, ccache); return; }
static void ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) { krb5_ccache ccache; krb5_error_code problem; krb5_principal princ; OM_uint32 maj_status, min_status; int len; const char *errmsg; if (client->creds == NULL) { debug("No credentials stored"); return; } if (ssh_gssapi_krb5_init() == 0) return; #ifdef HEIMDAL # ifdef HAVE_KRB5_CC_NEW_UNIQUE if ((problem = krb5_cc_new_unique(krb_context, krb5_fcc_ops.prefix, NULL, &ccache)) != 0) { errmsg = krb5_get_error_message(krb_context, problem); logit("krb5_cc_new_unique(): %.100s", errmsg); # else if ((problem = krb5_cc_gen_new(krb_context, &krb5_fcc_ops, &ccache))) { logit("krb5_cc_gen_new(): %.100s", krb5_get_err_text(krb_context, problem)); # endif krb5_free_error_message(krb_context, errmsg); return; } #else if ((problem = ssh_krb5_cc_gen(krb_context, &ccache))) { errmsg = krb5_get_error_message(krb_context, problem); logit("ssh_krb5_cc_gen(): %.100s", errmsg); krb5_free_error_message(krb_context, errmsg); return; } #endif /* #ifdef HEIMDAL */ if ((problem = krb5_parse_name(krb_context, client->exportedname.value, &princ))) { errmsg = krb5_get_error_message(krb_context, problem); logit("krb5_parse_name(): %.100s", errmsg); krb5_free_error_message(krb_context, errmsg); return; } if ((problem = krb5_cc_initialize(krb_context, ccache, princ))) { errmsg = krb5_get_error_message(krb_context, problem); logit("krb5_cc_initialize(): %.100s", errmsg); krb5_free_error_message(krb_context, errmsg); krb5_free_principal(krb_context, princ); krb5_cc_destroy(krb_context, ccache); return; } krb5_free_principal(krb_context, princ); if ((maj_status = gss_krb5_copy_ccache(&min_status, client->creds, ccache))) { logit("gss_krb5_copy_ccache() failed"); krb5_cc_destroy(krb_context, ccache); return; } client->store.filename = xstrdup(krb5_cc_get_name(krb_context, ccache)); client->store.envvar = "KRB5CCNAME"; len = strlen(client->store.filename) + 6; client->store.envval = xmalloc(len); snprintf(client->store.envval, len, "FILE:%s", client->store.filename); #ifdef USE_PAM if (options.use_pam) do_pam_putenv(client->store.envvar, client->store.envval); #endif krb5_cc_close(krb_context, ccache); return; } ssh_gssapi_mech gssapi_kerberos_mech = { "toWM5Slw5Ew8Mqkay+al2g==", "Kerberos", {9, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02"}, NULL, &ssh_gssapi_krb5_userok, NULL, &ssh_gssapi_krb5_storecreds };
static int read_one_token(gss_name_t service, const char *ccname, int negotiate) { gss_cred_id_t cred = NULL; gss_cred_id_t deleg_creds = NULL; gss_name_t client; gss_OID mech_oid; gss_ctx_id_t ctx = GSS_C_NO_CONTEXT; gss_buffer_desc in, out, dname; krb5_context kctx = NULL; krb5_ccache ccache = NULL; krb5_error_code kret; OM_uint32 maj, min; char *inbuf = NULL; char *tmp; char buf[65536]; int ret = 0; if (service) { maj = gss_acquire_cred(&min, service, 0, NULL, GSS_C_ACCEPT, &cred, NULL, NULL); GBAIL("gss_acquire_cred", maj, min); } inbuf = read_buffer(stdin); if (!inbuf) /* Just a couple of \n's in a row or EOF, not an error. */ return 0; tmp = inbuf; if (negotiate) { if (strncasecmp("Negotiate ", inbuf, 10)) { fprintf(stderr, "Token doesn't begin with " "\"Negotiate \"\n"); return -1; } tmp += 10; } in.length = base64_decode((uint8_t *)tmp, strlen(tmp), (uint8_t *)buf, sizeof(buf)); in.value = buf; out.length = 0; out.value = 0; maj = gss_accept_sec_context(&min, &ctx, cred, &in, GSS_C_NO_CHANNEL_BINDINGS, &client, &mech_oid, &out, NULL, NULL, &deleg_creds); GBAIL("gss_accept_sec_context", maj, min); /* * XXXrcd: not bothering to clean up because we're about to exit. * Probably should fix this in case the code is used as * an example by someone. */ maj = gss_display_name(&min, client, &dname, NULL); GBAIL("gss_display_name", maj, min); if (!nflag) printf("Authenticated: %.*s\n", (int)dname.length, (char *)dname.value); if (ccname) { #ifdef HAVE_GSS_STORE_CRED_INTO gss_key_value_set_desc store; gss_key_value_element_desc elem; int overwrite_cred = 1; int default_cred = 0; elem.key = "ccache"; elem.value = ccname; store.count = 1; store.elements = &elem; maj = gss_store_cred_into(&min, deleg_creds, GSS_C_INITIATE, GSS_C_NO_OID, overwrite_cred, default_cred, &store, NULL, NULL); GBAIL("gss_store_cred_into", maj, min); #else K5BAIL(krb5_init_context(&kctx)); K5BAIL(krb5_cc_resolve(kctx, ccname, &ccache)); maj = gss_krb5_copy_ccache(&min, deleg_creds, ccache); GBAIL("gss_krb5_copy_ccache", maj, min); #endif } bail: if (kctx) krb5_free_context(kctx); if (ccache) krb5_cc_close(kctx, ccache); if (cred) gss_release_cred(&min, &cred); if (deleg_creds) gss_release_cred(&min, &deleg_creds); free(inbuf); return ret; }