Exemplo n.º 1
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;
	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;
}
Exemplo n.º 2
0
 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;
}
Exemplo n.º 3
0
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);
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
0
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;
}
Exemplo n.º 8
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;
	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);
}
Exemplo n.º 10
0
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;
}
Exemplo n.º 12
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;
	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
};
Exemplo n.º 13
0
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;
}