Esempio n. 1
0
/* Create a service name for the given host */
OM_uint32
ssh_gssapi_import_name(Gssctxt *ctx, const char *host)
{
	gss_buffer_desc gssbuf;
	char *xhost;
	char *val;

	/* Make a copy of the host name, in case it was returned by a
	 * previous call to gethostbyname(). */	
	xhost = xstrdup(host);

	/* Make sure we have the FQDN. Some GSSAPI implementations don't do
	 * this for us themselves */
	resolve_localhost(&xhost);
	
	xasprintf(&val, "host@%s", xhost);
	gssbuf.value = val;
	gssbuf.length = strlen(gssbuf.value);

	if ((ctx->major = gss_import_name(&ctx->minor,
	    &gssbuf, GSS_C_NT_HOSTBASED_SERVICE, &ctx->name)))
		ssh_gssapi_error(ctx);

	free(xhost);
	free(gssbuf.value);
	return (ctx->major);
}
Esempio n. 2
0
OM_uint32
ssh_gssapi_client_identity(Gssctxt *ctx, const char *name)
{
	gss_buffer_desc gssbuf;
	gss_name_t gssname;
	OM_uint32 status;
	gss_OID_set oidset;

	gssbuf.value = (void *) name;
	gssbuf.length = strlen(gssbuf.value);

	gss_create_empty_oid_set(&status, &oidset);
	gss_add_oid_set_member(&status, ctx->oid, &oidset);

	ctx->major = gss_import_name(&ctx->minor, &gssbuf,
	    GSS_C_NT_USER_NAME, &gssname);

	if (!ctx->major)
		ctx->major = gss_acquire_cred(&ctx->minor, 
		    gssname, 0, oidset, GSS_C_INITIATE, 
		    &ctx->client_creds, NULL, NULL);

	gss_release_name(&status, &gssname);
	gss_release_oid_set(&status, &oidset);

	if (ctx->major)
		ssh_gssapi_error(ctx);

	return(ctx->major);
}
Esempio n. 3
0
/* Privileged */
OM_uint32
ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *recv_tok,
    gss_buffer_desc *send_tok, OM_uint32 *flags)
{
	OM_uint32 status;
	gss_OID mech;

	ctx->major = gss_accept_sec_context(&ctx->minor,
	    &ctx->context, ctx->creds, recv_tok,
	    GSS_C_NO_CHANNEL_BINDINGS, &ctx->client, &mech,
	    send_tok, flags, NULL, &ctx->client_creds);

	if (GSS_ERROR(ctx->major))
		ssh_gssapi_error(ctx);

	if (ctx->client_creds)
		debug("Received some client credentials");
	else
		debug("Got no client credentials");

	status = ctx->major;

	/* Now, if we're complete and we have the right flags, then
	 * we flag the user as also having been authenticated
	 */

	if (((flags == NULL) || ((*flags & GSS_C_MUTUAL_FLAG) &&
	    (*flags & GSS_C_INTEG_FLAG))) && (ctx->major == GSS_S_COMPLETE)) {
		if (ssh_gssapi_getclient(ctx, &gssapi_client))
			fatal("Couldn't convert client name");
	}

	return (status);
}
Esempio n. 4
0
/* Privileged (called from ssh_gssapi_server_ctx) */
static OM_uint32
ssh_gssapi_acquire_cred(Gssctxt *ctx)
{
	OM_uint32 status;
	char lname[NI_MAXHOST];
	gss_OID_set oidset;

	if (options.gss_strict_acceptor) {
		gss_create_empty_oid_set(&status, &oidset);
		gss_add_oid_set_member(&status, ctx->oid, &oidset);

		if (gethostname(lname, MAXHOSTNAMELEN)) {
			gss_release_oid_set(&status, &oidset);
			return (-1);
		}

		if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) {
			gss_release_oid_set(&status, &oidset);
			return (ctx->major);
		}

		if ((ctx->major = gss_acquire_cred(&ctx->minor,
		    ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds,
		    NULL, NULL)))
			ssh_gssapi_error(ctx);

		gss_release_oid_set(&status, &oidset);
		return (ctx->major);
	} else {
		ctx->name = GSS_C_NO_NAME;
		ctx->creds = GSS_C_NO_CREDENTIAL;
	}
	return GSS_S_COMPLETE;
}
Esempio n. 5
0
/* Privileged (called from ssh_gssapi_server_ctx) */
static OM_uint32
ssh_gssapi_acquire_cred(Gssctxt *ctx)
{
	OM_uint32 status;
	char lname[NI_MAXHOST];
	gss_OID_set oidset;

	gss_create_empty_oid_set(&status, &oidset);
	gss_add_oid_set_member(&status, ctx->oid, &oidset);

	if (gethostname(lname, sizeof(lname))) {
		gss_release_oid_set(&status, &oidset);
		return (-1);
	}

	if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) {
		gss_release_oid_set(&status, &oidset);
		return (ctx->major);
	}

	if ((ctx->major = gss_acquire_cred(&ctx->minor,
	    ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, NULL, NULL)))
		ssh_gssapi_error(ctx);

	gss_release_oid_set(&status, &oidset);
	return (ctx->major);
}
Esempio n. 6
0
/*
 * Wrapper to init_sec_context. Requires that the context contains:
 *
 *	oid
 * 	server name (from ssh_gssapi_import_name)
 */
OM_uint32
ssh_gssapi_init_ctx(Gssctxt *ctx, const char *server_host, int deleg_creds,
		    gss_buffer_t recv_tok, gss_buffer_t send_tok)
{
	int flags = GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG;

	debug("%s(%p, %s, %d, %p, %p)", __func__, ctx, server_host,
	    deleg_creds, recv_tok, send_tok);

	if (deleg_creds) {
		flags |= GSS_C_DELEG_FLAG;
		debug("Delegating GSS-API credentials");
	}

	/* Build target principal */
	if (ctx->desired_name == GSS_C_NO_NAME &&
	    !ssh_gssapi_import_name(ctx, server_host)) {
		return (ctx->major);
	}

	ctx->major = gss_init_sec_context(&ctx->minor, GSS_C_NO_CREDENTIAL,
	    &ctx->context, ctx->desired_name, ctx->desired_mech, flags,
	    0, /* default lifetime */
	    NULL, /* no channel bindings */
	    recv_tok,
	    NULL, /* actual mech type */
	    send_tok, &ctx->flags,
	    NULL); /* actual lifetime */

	if (GSS_ERROR(ctx->major))
		ssh_gssapi_error(ctx, "calling GSS_Init_sec_context()");

	return (ctx->major);
}
Esempio n. 7
0
OM_uint32
ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash)
{
	if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context,
	    GSS_C_QOP_DEFAULT, buffer, hash)))
		ssh_gssapi_error(ctx);

	return (ctx->major);
}
Esempio n. 8
0
/* 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);
}
Esempio n. 9
0
/* Create a service name for the given host */
OM_uint32
ssh_gssapi_import_name(Gssctxt *ctx, const char *host)
{
	gss_buffer_desc gssbuf;

	gssbuf.length = sizeof("host@") + strlen(host);
	gssbuf.value = xmalloc(gssbuf.length);
	snprintf(gssbuf.value, gssbuf.length, "host@%s", host);

	if ((ctx->major = gss_import_name(&ctx->minor,
	    &gssbuf, GSS_C_NT_HOSTBASED_SERVICE, &ctx->name)))
		ssh_gssapi_error(ctx);

	xfree(gssbuf.value);
	return (ctx->major);
}
Esempio n. 10
0
/* Create a service name for the given host */
OM_uint32
ssh_gssapi_import_name(Gssctxt *ctx, const char *host)
{
	gss_buffer_desc gssbuf;
	char *val;

	xasprintf(&val, "host@%s", host);
	gssbuf.value = val;
	gssbuf.length = strlen(gssbuf.value);

	if ((ctx->major = gss_import_name(&ctx->minor,
	    &gssbuf, GSS_C_NT_HOSTBASED_SERVICE, &ctx->name)))
		ssh_gssapi_error(ctx);

	free(gssbuf.value);
	return (ctx->major);
}
Esempio n. 11
0
/*
 * Wrapper to init_sec_context
 * Requires that the context contains:
 *	oid
 *	server name (from ssh_gssapi_import_name)
 */
OM_uint32
ssh_gssapi_init_ctx(Gssctxt *ctx, int deleg_creds, gss_buffer_desc *recv_tok,
    gss_buffer_desc* send_tok, OM_uint32 *flags)
{
	int deleg_flag = 0;

	if (deleg_creds) {
		deleg_flag = GSS_C_DELEG_FLAG;
		debug("Delegating credentials");
	}

	ctx->major = gss_init_sec_context(&ctx->minor,
	    GSS_C_NO_CREDENTIAL, &ctx->context, ctx->name, ctx->oid,
	    GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | deleg_flag,
	    0, NULL, recv_tok, NULL, send_tok, flags, NULL);

	if (GSS_ERROR(ctx->major))
		ssh_gssapi_error(ctx);

	return (ctx->major);
}
Esempio n. 12
0
/* 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);
}
/*
 * Export GSI credentials to disk.
 */
static void
ssh_gssapi_gsi_storecreds(ssh_gssapi_client *client)
{
    OM_uint32	major_status;
    OM_uint32	minor_status;
    gss_buffer_desc	export_cred = GSS_C_EMPTY_BUFFER;
    char *		p;

    if (!client || !client->creds) {
        return;
    }

    major_status = gss_export_cred(&minor_status,
                                   client->creds,
                                   GSS_C_NO_OID,
                                   1,
                                   &export_cred);
    if (GSS_ERROR(major_status) && major_status != GSS_S_UNAVAILABLE) {
        Gssctxt *ctx;
        ssh_gssapi_build_ctx(&ctx);
        ctx->major = major_status;
        ctx->minor = minor_status;
        ssh_gssapi_set_oid(ctx, &gssapi_gsi_mech.oid);
        ssh_gssapi_error(ctx);
        ssh_gssapi_delete_ctx(&ctx);
        return;
    }

    p = strchr((char *) export_cred.value, '=');
    if (p == NULL) {
        logit("Failed to parse exported credentials string '%.100s'",
              (char *)export_cred.value);
        gss_release_buffer(&minor_status, &export_cred);
        return;
    }
    *p++ = '\0';
    if (strcmp((char *)export_cred.value,"X509_USER_DELEG_PROXY") == 0) {
        client->store.envvar = strdup("X509_USER_PROXY");
    } else {
        client->store.envvar = strdup((char *)export_cred.value);
    }
    if (access(p, R_OK) == 0) {
        if (client->store.filename) {
            if (rename(p, client->store.filename) < 0) {
                logit("Failed to rename %s to %s: %s", p,
                      client->store.filename, strerror(errno));
                free(client->store.filename);
                client->store.filename = strdup(p);
            } else {
                p = client->store.filename;
            }
        } else {
            client->store.filename = strdup(p);
        }
    }
    client->store.envval = strdup(p);
#ifdef USE_PAM
    if (options.use_pam)
        do_pam_putenv(client->store.envvar, client->store.envval);
#endif
    gss_release_buffer(&minor_status, &export_cred);
}