Exemplo n.º 1
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);
}
Exemplo n.º 2
0
static void
acquire_release_loop(gss_name_t name, int counter, gss_cred_usage_t usage)
{
    OM_uint32 maj_stat, min_stat;
    gss_cred_id_t cred;
    int i;

    for (i = 0; i < counter; i++) {
	maj_stat = gss_acquire_cred(&min_stat, name,
				    GSS_C_INDEFINITE,
				    GSS_C_NO_OID_SET,
				    usage,
				    &cred,
				    NULL,
				    NULL);
	if (maj_stat != GSS_S_COMPLETE)
	    gss_err(1, min_stat, "aquire %d %d != GSS_S_COMPLETE",
		    i, (int)maj_stat);
				
	maj_stat = gss_release_cred(&min_stat, &cred);
	if (maj_stat != GSS_S_COMPLETE)
	    gss_err(1, min_stat, "release %d %d != GSS_S_COMPLETE",
		    i, (int)maj_stat);
    }
}
Exemplo n.º 3
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);
}
Exemplo n.º 4
0
static void
copy_cred(void)
{
    OM_uint32 major_status, minor_status;
    gss_cred_id_t cred_handle;
    OM_uint32 time_rec;

    major_status = gss_acquire_cred(&minor_status,
				    GSS_C_NO_NAME,
				    0,
				    NULL,
				    GSS_C_INITIATE,
				    &cred_handle,
				    NULL,
				    &time_rec);
    if (GSS_ERROR(major_status))
	errx(1, "acquire_cred failed");

    print_time(time_rec);

    test_add(cred_handle);
    test_add(cred_handle);
    test_add(cred_handle);

    major_status = gss_release_cred(&minor_status,
				    &cred_handle);
    if (GSS_ERROR(major_status))
	errx(1, "release_cred failed");
}
Exemplo n.º 5
0
static int
server_acquire_creds(char *service_name, gss_cred_id_t *server_creds)
{
    gss_buffer_desc name_buf;
    gss_name_t server_name;
    OM_uint32 maj_stat, min_stat;

    name_buf.value = service_name;
    name_buf.length = strlen(name_buf.value) + 1;
    maj_stat = gss_import_name(&min_stat, &name_buf,
                               (gss_OID) gss_nt_service_name, &server_name);
    if (maj_stat != GSS_S_COMPLETE) {
        display_status("importing name", maj_stat, min_stat);
        return -1;
    }

    maj_stat = gss_acquire_cred(&min_stat, server_name, 0,
                                GSS_C_NO_OID_SET, GSS_C_ACCEPT,
                                server_creds, NULL, NULL);
    if (maj_stat != GSS_S_COMPLETE) {
        display_status("acquiring credentials", maj_stat, min_stat);
        return -1;
    }

    (void) gss_release_name(&min_stat, &server_name);

    return 0;
}
Exemplo n.º 6
0
int main()
{
    OM_uint32                           minor_status;
    OM_uint32                           major_status;
    gss_cred_id_t                       cred;
    char *                              error_str;
    int                                 rc = EXIT_SUCCESS;

    printf("1..1\n");

    globus_module_activate(GLOBUS_GSI_GSS_ASSIST_MODULE);
    globus_module_activate(GLOBUS_GSI_GSSAPI_MODULE);
    
    major_status = gss_acquire_cred(
        &minor_status,
        NULL,
        GSS_C_INDEFINITE,
        GSS_C_NO_OID_SET,
        GSS_C_BOTH,
        &cred,
        NULL,
        NULL);
    
    if(GSS_ERROR(major_status))
    {
        globus_gss_assist_display_status_str(&error_str,
                                             NULL,
                                             major_status,
                                             minor_status,
                                             0);
        fprintf(stderr, "\nLINE %d ERROR: %s\n", __LINE__, error_str);
        free(error_str);
        rc = EXIT_FAILURE;
        goto fail;
    }
    
    major_status = gss_release_cred(
        &minor_status,
        &cred);
    
    if(GSS_ERROR(major_status))
    {
        globus_gss_assist_display_status_str(&error_str,
                                             NULL,
                                             major_status,
                                             minor_status,
                                             0);
        fprintf(stderr, "\nLINE %d ERROR: %s\n", __LINE__, error_str);
        free(error_str);
        rc = EXIT_FAILURE;
        goto fail;
    }
    
fail:
    printf("%s gssapi_acquire_test\n",
            (rc == EXIT_SUCCESS) ? "ok" : "not ok");
    globus_module_deactivate_all();
    
    return rc;
}
Exemplo n.º 7
0
int
gsslib_acquire_client_credentials(gss_cred_id_t *client_creds)
{
   gss_name_t client_name = NULL;
   OM_uint32 maj_stat, min_stat;
   int cc=0;
   
   gsslib_reset_error();

   /*
    * get credentials for the service
    */

   maj_stat = gss_acquire_cred(&min_stat, client_name, 0,
                               GSS_C_NULL_OID_SET, GSS_C_INITIATE,
                               client_creds, NULL, NULL);

   if (maj_stat != GSS_S_COMPLETE) {
      gsslib_display_status(MSG_GSS_DISPLAYSTATUS_ACQUIRINGCREDENTIALS , maj_stat, min_stat);
      return -1;
   }

   if (client_name)
      (void) gss_release_name(&min_stat, &client_name);

   return cc;
}
Exemplo n.º 8
0
static bool mag_acquire_creds(request_rec *req,
                              struct mag_config *cfg,
                              gss_OID_set desired_mechs,
                              gss_cred_usage_t cred_usage,
                              gss_cred_id_t *creds,
                              gss_OID_set *actual_mechs)
{
    uint32_t maj, min;
#ifdef HAVE_CRED_STORE
    gss_const_key_value_set_t store = cfg->cred_store;

    maj = gss_acquire_cred_from(&min, GSS_C_NO_NAME, GSS_C_INDEFINITE,
                                desired_mechs, cred_usage, store, creds,
                                actual_mechs, NULL);
#else
    maj = gss_acquire_cred(&min, GSS_C_NO_NAME, GSS_C_INDEFINITE,
                           desired_mechs, cred_usage, creds,
                           actual_mechs, NULL);
#endif

    if (GSS_ERROR(maj)) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, req, "%s",
                      mag_error(req, "gss_acquire_cred[_from]() "
                                "failed to get server creds",
                                maj, min));
        return false;
    }

    return true;
}
Exemplo n.º 9
0
/*-------------*/
static int acquire_credentials (gss_name_t *server_name, gss_cred_id_t *server_creds)
{
    OM_uint32 major_status = 0, minor_status = 0;
    char *envp;

    if ((envp = getenv("KRB5_KTNAME")))
        LOG(log_debug, logtype_uams,
            "acquire credentials: acquiring credentials (uid = %d, keytab = %s)",
            (int)geteuid(), envp);
    else
        LOG(log_debug, logtype_uams,
            "acquire credentials: acquiring credentials (uid = %d) - $KRB5_KTNAME not found in env",
            (int)geteuid());
        
    /*
     * Acquire credentials usable for accepting context negotiations.
     * Credentials are for server_name, have an indefinite lifetime,
     * have no specific mechanisms, are to be used for accepting context
     * negotiations and are to be placed in server_creds.
     * We don't care about the mechanisms or about the time for which they are valid.
     */
    major_status = gss_acquire_cred( &minor_status, *server_name,
                                     GSS_C_INDEFINITE, GSS_C_NO_OID_SET, GSS_C_ACCEPT,
                                     server_creds, NULL, NULL );

    if (major_status != GSS_S_COMPLETE) {
        log_status( "acquire_cred", major_status, minor_status );
        return 1;
    }

    return 0;
}
Exemplo n.º 10
0
int zmq::gssapi_mechanism_base_t::acquire_credentials (char * service_name_, gss_cred_id_t * cred_)
{
    OM_uint32 maj_stat;
    OM_uint32 min_stat;
    gss_name_t server_name;

    gss_buffer_desc name_buf;
    name_buf.value = service_name_;
    name_buf.length = strlen ((char *) name_buf.value) + 1;

    maj_stat = gss_import_name (&min_stat, &name_buf,
                                GSS_C_NT_HOSTBASED_SERVICE, &server_name);

    if (maj_stat != GSS_S_COMPLETE)
        return -1;

    maj_stat = gss_acquire_cred (&min_stat, server_name, 0,
                                 GSS_C_NO_OID_SET, GSS_C_ACCEPT,
                                 cred_, NULL, NULL);

    if (maj_stat != GSS_S_COMPLETE)
        return -1;

    gss_release_name(&min_stat, &server_name);

    return 0;
}
Exemplo n.º 11
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;
}
Exemplo n.º 12
0
static void
acquire_add_release_add(gss_name_t name, gss_cred_usage_t usage)
{
    OM_uint32 maj_stat, min_stat;
    gss_cred_id_t cred, cred2, cred3;

    maj_stat = gss_acquire_cred(&min_stat, name,
				GSS_C_INDEFINITE,
				GSS_C_NO_OID_SET,
				usage,
				&cred,
				NULL,
				NULL);
    if (maj_stat != GSS_S_COMPLETE)
	gss_err(1, min_stat, "aquire %d != GSS_S_COMPLETE", (int)maj_stat);

    maj_stat = gss_add_cred(&min_stat,
			    cred,
			    GSS_C_NO_NAME,
			    GSS_KRB5_MECHANISM,
			    usage,
			    GSS_C_INDEFINITE,
			    GSS_C_INDEFINITE,
			    &cred2,
			    NULL,
			    NULL,
			    NULL);

    if (maj_stat != GSS_S_COMPLETE)
	gss_err(1, min_stat, "add_cred %d != GSS_S_COMPLETE", (int)maj_stat);

    maj_stat = gss_release_cred(&min_stat, &cred);
    if (maj_stat != GSS_S_COMPLETE)
	gss_err(1, min_stat, "release %d != GSS_S_COMPLETE", (int)maj_stat);

    maj_stat = gss_add_cred(&min_stat,
			    cred2,
			    GSS_C_NO_NAME,
			    GSS_KRB5_MECHANISM,
			    GSS_C_BOTH,
			    GSS_C_INDEFINITE,
			    GSS_C_INDEFINITE,
			    &cred3,
			    NULL,
			    NULL,
			    NULL);
    if (maj_stat != GSS_S_COMPLETE)
	gss_err(1, min_stat, "add_cred 2 %d != GSS_S_COMPLETE", (int)maj_stat);

    maj_stat = gss_release_cred(&min_stat, &cred2);
    if (maj_stat != GSS_S_COMPLETE)
	gss_err(1, min_stat, "release 2 %d != GSS_S_COMPLETE", (int)maj_stat);

    maj_stat = gss_release_cred(&min_stat, &cred3);
    if (maj_stat != GSS_S_COMPLETE)
	gss_err(1, min_stat, "release 3 %d != GSS_S_COMPLETE", (int)maj_stat);
}
Exemplo n.º 13
0
int authenticate_gss_server_init(const char *service, gss_server_state *state)
{
    OM_uint32 maj_stat;
    OM_uint32 min_stat;
    size_t service_len;
    gss_buffer_desc name_token = GSS_C_EMPTY_BUFFER;
    int ret = AUTH_GSS_COMPLETE;
    
    state->context = GSS_C_NO_CONTEXT;
    state->server_name = GSS_C_NO_NAME;
    state->client_name = GSS_C_NO_NAME;
    state->server_creds = GSS_C_NO_CREDENTIAL;
    state->client_creds = GSS_C_NO_CREDENTIAL;
    state->username = NULL;
    state->targetname = NULL;
    state->response = NULL;
    state->gss_flags = 0;
    
    // Server name may be empty which means we aren't going to create our own creds
    service_len = strlen(service);
    if (service_len != 0)
    {
        // Import server name first
        name_token.length = strlen(service);
        name_token.value = (char *)service;
        
        maj_stat = gss_import_name(&min_stat, &name_token, GSS_C_NT_HOSTBASED_SERVICE, &state->server_name);
        
        if (GSS_ERROR(maj_stat))
        {
            set_gss_error(maj_stat, min_stat);
            ret = AUTH_GSS_ERROR;
            goto end;
        }
        
        // Get credentials
        maj_stat = gss_acquire_cred(&min_stat, state->server_name, GSS_C_INDEFINITE,
                                    GSS_C_NO_OID_SET, GSS_C_ACCEPT, &state->server_creds, NULL, NULL);
        
        if (GSS_ERROR(maj_stat))
        {
            set_gss_error(maj_stat, min_stat);
            ret = AUTH_GSS_ERROR;
            goto end;
        }
    }
    
end:
    return ret;
}
Exemplo n.º 14
0
bool_t Svcauth_gss_acquire_cred(void)
{
  OM_uint32 maj_stat, min_stat;

  maj_stat = gss_acquire_cred(&min_stat, svcauth_gss_name, 0,
                              GSS_C_NULL_OID_SET, GSS_C_ACCEPT,
                              &svcauth_gss_creds, NULL, NULL);

  if(maj_stat != GSS_S_COMPLETE)
    {
      return (FALSE);
    }
  return (TRUE);
}
Exemplo n.º 15
0
static gss_cred_id_t
acquire_cred_service(const char *service,
		     gss_OID nametype,
		     gss_OID_set oidset,
		     int flags)
{
    OM_uint32 major_status, minor_status;
    gss_cred_id_t cred_handle;
    OM_uint32 time_rec;
    gss_buffer_desc name_buffer;
    gss_name_t name = GSS_C_NO_NAME;

    if (service) {
	name_buffer.value = rk_UNCONST(service);
	name_buffer.length = strlen(service);

	major_status = gss_import_name(&minor_status,
				       &name_buffer,
				       nametype,
				       &name);
	if (GSS_ERROR(major_status))
	    errx(1, "import_name failed");
    }

    major_status = gss_acquire_cred(&minor_status,
				    name,
				    0,
				    oidset,
				    flags,
				    &cred_handle,
				    NULL,
				    &time_rec);
    if (GSS_ERROR(major_status)) {
	warnx("acquire_cred failed: %s",
	     gssapi_err(major_status, minor_status, GSS_C_NO_OID));
    } else {
	print_time(time_rec);
	gss_release_cred(&minor_status, &cred_handle);
    }

    if (name != GSS_C_NO_NAME)
	gss_release_name(&minor_status, &name);

    if (GSS_ERROR(major_status))
	exit(1);

    return cred_handle;
}
static OM_uint32
acceptor_approved(void *userptr,
		  gss_name_t target_name, 
		  const gss_cred_id_t cred_handle,
		  gss_OID mech)
{
    OM_uint32 junk, ret;
    gss_OID_set oidset;

    if (cred_handle) {
	int present = 0;

	ret = gss_inquire_cred(&junk,
			       cred_handle,
			       NULL,
			       NULL,
			       NULL,
			       &oidset);
	if (ret != GSS_S_COMPLETE)
	    return ret;

	ret = gss_test_oid_set_member(&junk, mech, oidset, &present);
	gss_release_oid_set(&junk, &oidset);
	
	if (ret != GSS_S_COMPLETE || present == 0)
	    return GSS_S_FAILURE;

    } else {
	gss_cred_id_t cred = GSS_C_NO_CREDENTIAL;

	if (target_name == GSS_C_NO_NAME)
	    return GSS_S_COMPLETE;
	
	gss_create_empty_oid_set(&junk, &oidset);
	gss_add_oid_set_member(&junk, mech, &oidset);

	ret = gss_acquire_cred(&junk, target_name, GSS_C_INDEFINITE, oidset,
			       GSS_C_ACCEPT, &cred, NULL, NULL);
	gss_release_oid_set(&junk, &oidset);
	if (ret != GSS_S_COMPLETE)
	    return ret;
	gss_release_cred(&junk, &cred);
    }

    return GSS_S_COMPLETE;
}
Exemplo n.º 17
0
static bool_t
svcauth_gss_acquire_cred(void)
{
	OM_uint32	maj_stat, min_stat;

	log_debug("in svcauth_gss_acquire_cred()");

	maj_stat = gss_acquire_cred(&min_stat, _svcauth_gss_name, 0,
				    GSS_C_NULL_OID_SET, GSS_C_ACCEPT,
				    &_svcauth_gss_creds, NULL, NULL);

	if (maj_stat != GSS_S_COMPLETE) {
		log_status("gss_acquire_cred", maj_stat, min_stat);
		return (FALSE);
	}
	return (TRUE);
}
Exemplo n.º 18
0
int
gssd_acquire_cred(char *server_name, const gss_OID oid)
{
	gss_buffer_desc name;
	gss_name_t target_name;
	u_int32_t maj_stat, min_stat;
	u_int32_t ignore_maj_stat, ignore_min_stat;
	gss_buffer_desc pbuf;

	/* If server_name is NULL, get cred for GSS_C_NO_NAME */
	if (server_name == NULL) {
		target_name = GSS_C_NO_NAME;
	} else {
		name.value = (void *)server_name;
		name.length = strlen(server_name);

		maj_stat = gss_import_name(&min_stat, &name,
				oid,
				&target_name);

		if (maj_stat != GSS_S_COMPLETE) {
			pgsserr("gss_import_name", maj_stat, min_stat, g_mechOid);
			return (FALSE);
		}
	}

	maj_stat = gss_acquire_cred(&min_stat, target_name, GSS_C_INDEFINITE,
			GSS_C_NO_OID_SET, GSS_C_ACCEPT,
			&gssd_creds, NULL, NULL);

	if (maj_stat != GSS_S_COMPLETE) {
		pgsserr("gss_acquire_cred", maj_stat, min_stat, g_mechOid);
		ignore_maj_stat = gss_display_name(&ignore_min_stat,
				target_name, &pbuf, NULL);
		if (ignore_maj_stat == GSS_S_COMPLETE) {
			printerr(1, "Unable to obtain credentials for '%.*s'\n",
				 pbuf.length, pbuf.value);
			ignore_maj_stat = gss_release_buffer(&ignore_min_stat,
							     &pbuf);
		}
	}

	ignore_maj_stat = gss_release_name(&ignore_min_stat, &target_name);

	return (maj_stat == GSS_S_COMPLETE);
}
Exemplo n.º 19
0
bool
svcauth_gss_acquire_cred(void)
{
	OM_uint32 maj_stat, min_stat;
	int64_t now;
	OM_uint32 timerec;
	gss_cred_id_t old_creds, ancient_creds;

	now = get_time_fast();
	if (svcauth_gss_creds && (!svcauth_gss_creds_expires || svcauth_gss_creds_expires > now))
		return (true);

	mutex_lock(&svcauth_gss_creds_lock);
	if (svcauth_gss_creds && (!svcauth_gss_creds_expires || svcauth_gss_creds_expires > now)) {
		maj_stat = GSS_S_COMPLETE;
	} else {
		ancient_creds = svcauth_prev_gss_creds;
		old_creds = svcauth_gss_creds;
		timerec = 0;
		now = get_time_fast();
		maj_stat =
		    gss_acquire_cred(&min_stat, svcauth_gss_name, 0, GSS_C_NULL_OID_SET,
				     GSS_C_ACCEPT, &svcauth_gss_creds, NULL, &timerec);
		if (maj_stat == GSS_S_COMPLETE) {
			if (timerec == GSS_C_INDEFINITE)
				svcauth_gss_creds_expires = 0;
			else
				svcauth_gss_creds_expires = now + timerec;
			if (old_creds) {
				svcauth_prev_gss_creds = old_creds;
			}
			if (ancient_creds) {
				(void) gss_release_cred(&min_stat, &ancient_creds);
			}
		}
	}
	mutex_unlock(&svcauth_gss_creds_lock);
	if (maj_stat != GSS_S_COMPLETE)
		return (false);

	return (true);
}
Exemplo n.º 20
0
uint32_t
sapgss_acquire_cred(
    uint32_t *minor_status,
    gss_name_t desired_name,
    uint32_t time_req,
    sapgss_OID_set desired_mechs,
    gss_cred_usage_t cred_usage,
    gss_cred_id_t *output_cred_handle,
    sapgss_OID_set *actual_mechs,
    uint32_t *time_rec)
{
    gss_OID_set desired_mechs_loc;
    gss_OID_set actual_mechs_loc;
    uint32_t major_status, dummy;
    int ret;
    
    memset(&desired_mechs_loc, 0, sizeof(desired_mechs_loc));
    memset(&actual_mechs_loc, 0, sizeof(actual_mechs_loc));
    ret = gss_OID_set_sap_to_loc(desired_mechs, &desired_mechs_loc);
    if (ret != 0) {
	*minor_status = ret;
	return GSS_S_FAILURE;
    }
    major_status = gss_acquire_cred(minor_status, desired_name, time_req,
				    desired_mechs_loc, cred_usage,
				    output_cred_handle, &actual_mechs_loc,
				    time_rec);
    /* Meet the gss_OID_set_sap_to_loc contract and free desired_mechs_loc */
    gss_OID_set_loc_release(&desired_mechs_loc);
    /* Must inquire_cred to force resolution for the krb5 mech */
    if (major_status != 0)
	return major_status;
    (void)gss_inquire_cred(&dummy, *output_cred_handle,
				    NULL, NULL, NULL, &actual_mechs_loc);
    ret = gss_OID_set_loc_to_sap(actual_mechs_loc, actual_mechs);
    if (ret != 0) {
	*minor_status = ret;
	return GSS_S_FAILURE;
    }
    return major_status;
}
Exemplo n.º 21
0
static OM_uint32
acceptor_approved(gss_name_t target_name, gss_OID mech)
{
    gss_cred_id_t cred = GSS_C_NO_CREDENTIAL;
    gss_OID_set oidset;
    OM_uint32 junk, ret;

    if (target_name == GSS_C_NO_NAME)
	return GSS_S_COMPLETE;

    gss_create_empty_oid_set(&junk, &oidset);
    gss_add_oid_set_member(&junk, mech, &oidset);

    ret = gss_acquire_cred(&junk, target_name, GSS_C_INDEFINITE, oidset,
			   GSS_C_ACCEPT, &cred, NULL, NULL);
    gss_release_oid_set(&junk, &oidset);
    if (ret != GSS_S_COMPLETE)
	return ret;
    gss_release_cred(&junk, &cred);

    return GSS_S_COMPLETE;
}
Exemplo n.º 22
0
int
limit_krb5_enctypes(struct rpc_gss_sec *sec, uid_t uid)
{
	u_int maj_stat, min_stat;
	gss_cred_id_t credh;
	gss_OID_set_desc  desired_mechs;
	krb5_enctype enctypes[] = { ENCTYPE_DES_CBC_CRC,
				    ENCTYPE_DES_CBC_MD5,
				    ENCTYPE_DES_CBC_MD4 };
	int num_enctypes = sizeof(enctypes) / sizeof(enctypes[0]);

	/* We only care about getting a krb5 cred */
	desired_mechs.count = 1;
	desired_mechs.elements = &krb5oid;

	maj_stat = gss_acquire_cred(&min_stat, NULL, 0,
				    &desired_mechs, GSS_C_INITIATE,
				    &credh, NULL, NULL);

	if (maj_stat != GSS_S_COMPLETE) {
		if (get_verbosity() > 0)
			pgsserr("gss_acquire_cred",
				maj_stat, min_stat, &krb5oid);
		return -1;
	}

	maj_stat = gss_set_allowable_enctypes(&min_stat, credh, &krb5oid,
					     num_enctypes, &enctypes);
	if (maj_stat != GSS_S_COMPLETE) {
		pgsserr("gss_set_allowable_enctypes",
			maj_stat, min_stat, &krb5oid);
		gss_release_cred(&min_stat, &credh);
		return -1;
	}
	sec->cred = credh;

	return 0;
}
Exemplo n.º 23
0
/*
 * Given a service name, imports it and acquires credentials for it, storing
 * them in the second argument.  Returns true on success and false on failure,
 * logging an error message.
 *
 * Normally, you don't want to do this; instead, normally you want to allow
 * the underlying GSS-API library choose the appropriate credentials from a
 * keytab for each incoming connection.
 */
static bool
acquire_creds(char *service, gss_cred_id_t *creds)
{
    gss_buffer_desc buffer;
    gss_name_t name;
    OM_uint32 major, minor;

    buffer.value = service;
    buffer.length = strlen(buffer.value) + 1;
    major = gss_import_name(&minor, &buffer, GSS_C_NT_USER_NAME, &name);
    if (major != GSS_S_COMPLETE) {
        warn_gssapi("while importing name", major, minor);
        return false;
    }
    major = gss_acquire_cred(&minor, name, 0, GSS_C_NULL_OID_SET,
                             GSS_C_ACCEPT, creds, NULL, NULL);
    if (major != GSS_S_COMPLETE) {
        warn_gssapi("while acquiring credentials", major, minor);
        return false;
    }
    gss_release_name(&minor, &name);
    return true;
}
Exemplo n.º 24
0
isc_result_t
dst_gssapi_acquirecred(dns_name_t *name, isc_boolean_t initiate,
		       gss_cred_id_t *cred)
{
#ifdef GSSAPI
	isc_buffer_t namebuf;
	gss_name_t gname;
	gss_buffer_desc gnamebuf;
	unsigned char array[DNS_NAME_MAXTEXT + 1];
	OM_uint32 gret, minor;
	gss_OID_set mechs;
	OM_uint32 lifetime;
	gss_cred_usage_t usage;
	char buf[1024];

	REQUIRE(cred != NULL && *cred == NULL);

	/*
	 * XXXSRA In theory we could use GSS_C_NT_HOSTBASED_SERVICE
	 * here when we're in the acceptor role, which would let us
	 * default the hostname and use a compiled in default service
	 * name of "DNS", giving one less thing to configure in
	 * named.conf.	Unfortunately, this creates a circular
	 * dependency due to DNS-based realm lookup in at least one
	 * GSSAPI implementation (Heimdal).  Oh well.
	 */
	if (name != NULL) {
		isc_buffer_init(&namebuf, array, sizeof(array));
		name_to_gbuffer(name, &namebuf, &gnamebuf);
		gret = gss_import_name(&minor, &gnamebuf,
				       GSS_C_NO_OID, &gname);
		if (gret != GSS_S_COMPLETE) {
			check_config((char *)array);

			gss_log(3, "failed gss_import_name: %s",
				gss_error_tostring(gret, minor, buf,
						   sizeof(buf)));
			return (ISC_R_FAILURE);
		}
	} else
		gname = NULL;

	/* Get the credentials. */
	if (gname != NULL)
		gss_log(3, "acquiring credentials for %s",
			(char *)gnamebuf.value);
	else {
		/* XXXDCL does this even make any sense? */
		gss_log(3, "acquiring credentials for ?");
	}

	if (initiate)
		usage = GSS_C_INITIATE;
	else
		usage = GSS_C_ACCEPT;

	gret = gss_acquire_cred(&minor, gname, GSS_C_INDEFINITE,
				&mech_oid_set,
				usage, cred, &mechs, &lifetime);

	if (gret != GSS_S_COMPLETE) {
		gss_log(3, "failed to acquire %s credentials for %s: %s",
			initiate ? "initiate" : "accept",
			(char *)gnamebuf.value,
			gss_error_tostring(gret, minor, buf, sizeof(buf)));
		check_config((char *)array);
		return (ISC_R_FAILURE);
	}

	gss_log(4, "acquired %s credentials for %s",
		initiate ? "initiate" : "accept",
		(char *)gnamebuf.value);

	log_cred(*cred);

	return (ISC_R_SUCCESS);
#else
	UNUSED(name);
	UNUSED(initiate);
	UNUSED(cred);

	return (ISC_R_NOTIMPLEMENTED);
#endif
}
Exemplo n.º 25
0
int
main(int argc, char **argv)
{
    int i, s, done, print_body, gssapi_done, gssapi_started, optidx = 0;
    const char *host, *page;
    struct http_req req;
    char *headers[99]; /* XXX */
    int num_headers;
    krb5_storage *sp;

    gss_cred_id_t client_cred = GSS_C_NO_CREDENTIAL;
    gss_ctx_id_t context_hdl = GSS_C_NO_CONTEXT;
    gss_name_t server = GSS_C_NO_NAME;
    gss_OID mech_oid, cred_mech_oid;
    OM_uint32 flags;
    OM_uint32 maj_stat, min_stat;

    setprogname(argv[0]);

    if(getarg(http_args, num_http_args, argc, argv, &optidx))
	usage(1);

    if (help_flag)
	usage (0);

    if(version_flag) {
	print_version(NULL);
	exit(0);
    }

    argc -= optidx;
    argv += optidx;

    mech_oid = select_mech(mech);

    if (cred_mech_str)
	cred_mech_oid = select_mech(cred_mech_str);
    else
	cred_mech_oid = mech_oid;

    if (argc != 1 && argc != 2)
	errx(1, "usage: %s host [page]", getprogname());
    host = argv[0];
    if (argc == 2)
	page = argv[1];
    else
	page = "/";

    flags = 0;
    if (delegate_flag)
	flags |= GSS_C_DELEG_FLAG;
    if (policy_flag)
	flags |= GSS_C_DELEG_POLICY_FLAG;
    if (mutual_flag)
	flags |= GSS_C_MUTUAL_FLAG;

    done = 0;
    num_headers = 0;
    gssapi_done = 0;
    gssapi_started = 0;

    if (client_str) {
	gss_buffer_desc name_buffer;
	gss_name_t name;
	gss_OID_set mechset = GSS_C_NO_OID_SET;

	name_buffer.value = client_str;
	name_buffer.length = strlen(client_str);

	maj_stat = gss_import_name(&min_stat, &name_buffer, GSS_C_NT_USER_NAME, &name);
	if (maj_stat)
	    errx(1, "failed to import name");

	if (cred_mech_oid) {
	    gss_create_empty_oid_set(&min_stat, &mechset);
	    gss_add_oid_set_member(&min_stat, cred_mech_oid, &mechset);
	}
	
	maj_stat = gss_acquire_cred(&min_stat, name, GSS_C_INDEFINITE,
				    mechset, GSS_C_INITIATE,
				    &client_cred, NULL, NULL);
	gss_release_name(&min_stat, &name);
	gss_release_oid_set(&min_stat, &mechset);
	if (maj_stat)
	    errx(1, "failed to find cred of name %s", client_str);
    }

    {
	gss_buffer_desc name_token;
	char *name;
	asprintf(&name, "%s@%s", gss_service, host);
	name_token.length = strlen(name);
	name_token.value = name;
	
	maj_stat = gss_import_name(&min_stat,
				   &name_token,
				   GSS_C_NT_HOSTBASED_SERVICE,
				   &server);
	if (GSS_ERROR(maj_stat))
	    gss_err (1, min_stat, "gss_inport_name: %s", name);
	free(name);
    }

    s = do_connect(host, port_str);
    if (s < 0)
	errx(1, "connection failed");

    sp = krb5_storage_from_fd(s);
    if (sp == NULL)
	errx(1, "krb5_storage_from_fd");

    do {
	print_body = 0;

	http_query(sp, host, page, headers, num_headers, &req);
	for (i = 0 ; i < num_headers; i++)
	    free(headers[i]);
	num_headers = 0;

	if (strstr(req.response, " 200 ") != NULL) {
	    print_body = 1;
	    done = 1;
	} else if (strstr(req.response, " 401 ") != NULL) {
	    if (http_find_header(&req, "WWW-Authenticate:") == NULL)
		errx(1, "Got %s but missed `WWW-Authenticate'", req.response);
	}

	if (!gssapi_done) {
	    const char *h = http_find_header(&req, "WWW-Authenticate:");
	    if (h == NULL)
		errx(1, "Got %s but missed `WWW-Authenticate'", req.response);

	    if (strncasecmp(h, "Negotiate", 9) == 0) {
		gss_buffer_desc input_token, output_token;

		if (verbose_flag)
		    printf("Negotiate found\n");

		i = 9;
		while(h[i] && isspace((unsigned char)h[i]))
		    i++;
		if (h[i] != '\0') {
		    size_t len = strlen(&h[i]);
		    int slen;
		    if (len == 0)
			errx(1, "invalid Negotiate token");
		    input_token.value = emalloc(len);
		    slen = base64_decode(&h[i], input_token.value);
		    if (slen < 0)
			errx(1, "invalid base64 Negotiate token %s", &h[i]);
		    input_token.length = slen;
		} else {
		    if (gssapi_started)
			errx(1, "Negotiate already started");
		    gssapi_started = 1;

		    input_token.length = 0;
		    input_token.value = NULL;
		}

		if (strstr(req.response, " 200 ") != NULL)
		    sleep(1);

		maj_stat =
		    gss_init_sec_context(&min_stat,
					 client_cred,
					 &context_hdl,
					 server,
					 mech_oid,
					 flags,
					 0,
					 GSS_C_NO_CHANNEL_BINDINGS,
					 &input_token,
					 NULL,
					 &output_token,
					 NULL,
					 NULL);
		if (maj_stat == GSS_S_CONTINUE_NEEDED) {

		} else if (maj_stat == GSS_S_COMPLETE) {
		    gss_name_t targ_name, src_name;
		    gss_buffer_desc name_buffer;
		    gss_OID mech_type;

		    gssapi_done = 1;

		    maj_stat = gss_inquire_context(&min_stat,
						   context_hdl,
						   &src_name,
						   &targ_name,
						   NULL,
						   &mech_type,
						   NULL,
						   NULL,
						   NULL);
		    if (GSS_ERROR(maj_stat))
			gss_err (1, min_stat, "gss_inquire_context");

		    printf("Negotiate done: %s\n", mech);

		    maj_stat = gss_display_name(&min_stat,
						src_name,
						&name_buffer,
						NULL);
		    if (GSS_ERROR(maj_stat))
			gss_print_errors(min_stat);
		    else
			printf("Source: %.*s\n",
			       (int)name_buffer.length,
			       (char *)name_buffer.value);

		    gss_release_buffer(&min_stat, &name_buffer);

		    maj_stat = gss_display_name(&min_stat,
						targ_name,
						&name_buffer,
						NULL);
		    if (GSS_ERROR(maj_stat))
			gss_print_errors(min_stat);
		    else
			printf("Target: %.*s\n",
			       (int)name_buffer.length,
			       (char *)name_buffer.value);

		    gss_release_name(&min_stat, &targ_name);
		    gss_release_buffer(&min_stat, &name_buffer);
		} else {
		    gss_err (1, min_stat, "gss_init_sec_context");
		}


		if (output_token.length) {
		    char *neg_token;

		    base64_encode(output_token.value,
				  (int)output_token.length,
				  &neg_token);

		    asprintf(&headers[0], "Authorization: Negotiate %s",
			     neg_token);

		    num_headers = 1;
		    free(neg_token);
		    gss_release_buffer(&min_stat, &output_token);
		}
		if (input_token.length)
		    free(input_token.value);

	    } else
		done = 1;
	} else
	    done = 1;

	if (print_body || verbose_flag)
	    printf("%.*s\n", (int)req.body_size, (char *)req.body);

	http_req_free(&req);
    } while (!done);

    if (gssapi_done == 0)
	errx(1, "gssapi not done but http dance done");

    krb5_storage_free(sp);
    close(s);

    return 0;
}
Exemplo n.º 26
0
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;
}
Exemplo n.º 27
0
/*
 * Negotiate a krb5 gss context from the server end.
 */
static int
gss_server(
    struct tcp_conn *rc)
{
    OM_uint32 maj_stat, min_stat, ret_flags;
    gss_buffer_desc send_tok, recv_tok, AA;
    gss_OID doid;
    gss_name_t gss_name;
    gss_cred_id_t gss_creds;
    char *p, *realm, *msg;
    int rval = -1;
    int rvalue;
    char errbuf[256];
    char *errmsg = NULL;

    auth_debug(1, "gss_server\n");

    assert(rc != NULL);

    /*
     * We need to be root while in gss_acquire_cred() to read the host key
     * out of the default keytab.  We also need to be root in
     * gss_accept_context() thanks to the replay cache code.
     */
    if (!set_root_privs(0)) {
	g_snprintf(errbuf, SIZEOF(errbuf),
	    _("can't take root privileges to read krb5 host key: %s"), strerror(errno));
	goto out;
    }

    rc->gss_context = GSS_C_NO_CONTEXT;
    send_tok.value = vstralloc("host/", myhostname, NULL);
    send_tok.length = strlen(send_tok.value) + 1;
    for (p = send_tok.value; *p != '\0'; p++) {
	if (isupper((int)*p))
	    *p = tolower(*p);
    }
    maj_stat = gss_import_name(&min_stat, &send_tok, GSS_C_NULL_OID,
	&gss_name);
    if (maj_stat != (OM_uint32)GSS_S_COMPLETE) {
	set_root_privs(0);
	g_snprintf(errbuf, SIZEOF(errbuf),
	    _("can't import name %s: %s"), (char *)send_tok.value,
	    gss_error(maj_stat, min_stat));
	amfree(send_tok.value);
	goto out;
    }
    amfree(send_tok.value);

    maj_stat = gss_display_name(&min_stat, gss_name, &AA, &doid);
    dbprintf(_("gss_name %s\n"), (char *)AA.value);
    maj_stat = gss_acquire_cred(&min_stat, gss_name, 0,
	GSS_C_NULL_OID_SET, GSS_C_ACCEPT, &gss_creds, NULL, NULL);
    if (maj_stat != (OM_uint32)GSS_S_COMPLETE) {
	g_snprintf(errbuf, SIZEOF(errbuf),
	    _("can't acquire creds for host key host/%s: %s"), myhostname,
	    gss_error(maj_stat, min_stat));
	gss_release_name(&min_stat, &gss_name);
	set_root_privs(0);
	goto out;
    }
    gss_release_name(&min_stat, &gss_name);

    for (recv_tok.length = 0;;) {
	recv_tok.value = NULL;
        rvalue = tcpm_recv_token(rc, rc->read, &rc->handle, &rc->errmsg,
				 /* (void *) is to avoid type-punning warning */
				 (char **)(void *)&recv_tok.value,
				 (ssize_t *)&recv_tok.length, 60);
	if (rvalue <= 0) {
	    if (rvalue < 0) {
		g_snprintf(errbuf, SIZEOF(errbuf),
		    _("recv error in gss loop: %s"), rc->errmsg);
		amfree(rc->errmsg);
	    } else
		g_snprintf(errbuf, SIZEOF(errbuf), _("EOF in gss loop"));
	    goto out;
	}

	maj_stat = gss_accept_sec_context(&min_stat, &rc->gss_context,
	    gss_creds, &recv_tok, GSS_C_NO_CHANNEL_BINDINGS,
	    &gss_name, &doid, &send_tok, &ret_flags, NULL, NULL);

	if (maj_stat != (OM_uint32)GSS_S_COMPLETE &&
	    maj_stat != (OM_uint32)GSS_S_CONTINUE_NEEDED) {
	    g_snprintf(errbuf, SIZEOF(errbuf),
		_("error accepting context: %s"), gss_error(maj_stat, min_stat));
	    amfree(recv_tok.value);
	    goto out;
	}
	amfree(recv_tok.value);

	if (send_tok.length != 0 && tcpm_send_token(rc, rc->write, 0, &errmsg, send_tok.value, send_tok.length) < 0) {
	    strncpy(errbuf, rc->errmsg, SIZEOF(errbuf) - 1);
	    errbuf[SIZEOF(errbuf) - 1] = '\0';
	    amfree(rc->errmsg);
	    gss_release_buffer(&min_stat, &send_tok);
	    goto out;
	}
	gss_release_buffer(&min_stat, &send_tok);


	/*
	 * If we need to get more from the client, then register for
	 * more packets.
	 */
	if (maj_stat != (OM_uint32)GSS_S_CONTINUE_NEEDED)
	    break;
    }

    maj_stat = gss_display_name(&min_stat, gss_name, &send_tok, &doid);
    if (maj_stat != (OM_uint32)GSS_S_COMPLETE) {
	g_snprintf(errbuf, SIZEOF(errbuf),
	    _("can't display gss name: %s"), gss_error(maj_stat, min_stat));
	gss_release_name(&min_stat, &gss_name);
	goto out;
    }
    gss_release_name(&min_stat, &gss_name);

    /* get rid of the realm */
    if ((p = strchr(send_tok.value, '@')) == NULL) {
	g_snprintf(errbuf, SIZEOF(errbuf),
	    _("malformed gss name: %s"), (char *)send_tok.value);
	amfree(send_tok.value);
	goto out;
    }
    *p = '\0';
    realm = ++p;

    /* 
     * If the principal doesn't match, complain
     */
    if ((msg = krb5_checkuser(rc->hostname, send_tok.value, realm)) != NULL) {
	g_snprintf(errbuf, SIZEOF(errbuf),
	    _("access not allowed from %s: %s"), (char *)send_tok.value, msg);
	amfree(send_tok.value);
	goto out;
    }
    amfree(send_tok.value);

    rval = 0;
out:
    set_root_privs(0);
    if (rval != 0) {
	rc->errmsg = stralloc(errbuf);
    } else {
	rc->auth = 1;
    }
    auth_debug(1, _("gss_server returning %d\n"), rval);
    return (rval);
}
Exemplo n.º 28
0
static int tunnel(struct gt_service *svc, int fd, struct sockaddr *cliaddr)
{
    AUTOCLEAN(char *tmbuf, autofreestr) = NULL;
    AUTOCLEAN(struct addrinfo *addr, autofreeaddrinfo) = NULL;
    AUTOCLEAN(int sd, autofreesocket) = -1;
    AUTOCLEAN(int efd, autofreesocket) = -1;
    AUTOCLEAN(gss_name_t name, autofreegssname) = GSS_C_NO_NAME;
    AUTOCLEAN(gss_name_t srcname, autofreegssname) = GSS_C_NO_NAME;
    AUTOCLEAN(gss_cred_id_t cred, autofreegsscred) = GSS_C_NO_CREDENTIAL;
    AUTOCLEAN(gss_ctx_id_t ctx, autofreegssctx) = GSS_C_NO_CONTEXT;
    AUTOCLEAN(gss_buffer_desc output, autofreegssbuf) = GSS_C_EMPTY_BUFFER;
    gss_buffer_desc input = GSS_C_EMPTY_BUFFER;
    gss_buffer_desc  namebuf;
    OM_uint32 maj, min;
    OM_uint32 ignore;
    struct epoll_event events[MAX_EVENTS];
    size_t tmlen;
    int pfd; /* plain text fd */
    int cfd; /* cipher text fd */
    int ret;

    /* We allocate a 1 MiB buffer for messages, that's also the maximum msg
     * size */
    tmbuf = malloc(MAX_MSG_SIZE);
    if (!tmbuf) return ENOMEM;

    if (svc->exec) {
        fprintf(stderr, "[%s] EXEC option not supported yet, sorry!\n",
                        svc->name);
        return ENOTSUP;
    }

    ret = string_to_addrinfo(svc->connect, &addr);
    if (ret) return ret;

    errno = 0;
    sd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
    if (sd == -1) return errno;

    ret = connect(sd, addr->ai_addr, addr->ai_addrlen);
    if (ret != 0) {
        ret = errno;
        fprintf(stderr, "[%s] Failed to connect to server '%s': %s\n",
                        svc->name, svc->connect, strerror(ret));
        return ret;
    }

    if (svc->target_name) {
        namebuf.length = strlen(svc->target_name);
        namebuf.value = svc->target_name;
        maj = gss_import_name(&min, &namebuf,
                              GSS_C_NT_HOSTBASED_SERVICE, &name);
        if (maj != GSS_S_COMPLETE) {
            fprintf(stderr, "[%s] Failed to import name: '%s' (%d/%d)\n",
                            svc->name, svc->target_name,
                            (int)maj, (int)min);
            return EINVAL;
        }
    }

    if (svc->client) {
        pfd = fd;
        cfd = sd;

        do {
            maj = gss_init_sec_context(&min, cred, &ctx, name, GSS_C_NO_OID,
                                       GSS_C_MUTUAL_FLAG
                                        | GSS_C_REPLAY_FLAG
                                        | GSS_C_SEQUENCE_FLAG
                                        | GSS_C_CONF_FLAG
                                        | GSS_C_INTEG_FLAG, 0,
                                       GSS_C_NO_CHANNEL_BINDINGS,
                                       &input, NULL, &output, NULL, NULL);

            if (maj != GSS_S_COMPLETE && maj != GSS_S_CONTINUE_NEEDED) {
                gt_gss_error(svc->name, GSS_C_NO_OID, maj, min);
                return EBADE;
            }

            if (output.length > MAX_MSG_SIZE) return ENOSPC;
            if (output.length > 0) {
                memcpy(tmbuf, output.value, output.length);
                tmlen = output.length;
                (void)gss_release_buffer(&ignore, &output);

                ret = send_msg(cfd, tmbuf, tmlen, true);
                if (ret) return ret;
            }

            if (maj == GSS_S_CONTINUE_NEEDED) {
                tmlen = MAX_MSG_SIZE;
                ret = recv_msg(cfd, tmbuf, &tmlen, true);
                if (ret) return ret;

                input.value = tmbuf;
                input.length = tmlen;
            }

        } while (maj == GSS_S_CONTINUE_NEEDED);

    } else {
        pfd = sd;
        cfd = fd;

        if (name != GSS_C_NO_NAME) {
            maj = gss_acquire_cred(&min, name, GSS_C_INDEFINITE,
                                   GSS_C_NO_OID_SET, GSS_C_ACCEPT,
                                   &cred, NULL, NULL);
            if (maj != GSS_S_COMPLETE) {
                fprintf(stderr,
                        "[%s] Failed to acquire creds for '%s' (%d/%d)\n",
                        svc->name, svc->target_name?svc->target_name:"",
                        (int)maj, (int)min);
                return EIO;
            }
        }

        do {
            tmlen = MAX_MSG_SIZE;
            ret = recv_msg(cfd, tmbuf, &tmlen, true);
            if (ret) return ret;

            input.value = tmbuf;
            input.length = tmlen;

            maj = gss_accept_sec_context(&min, &ctx, cred, &input,
                                         GSS_C_NO_CHANNEL_BINDINGS, &srcname,
                                         NULL, &output, NULL, NULL, NULL);

            if (maj != GSS_S_COMPLETE && maj != GSS_S_CONTINUE_NEEDED) {
                gt_gss_error(svc->name, GSS_C_NO_OID, maj, min);
                return EBADE;
            }

            if (output.length > MAX_MSG_SIZE) return ENOSPC;
            if (output.length > 0) {
                memcpy(tmbuf, output.value, output.length);
                tmlen = output.length;
                (void)gss_release_buffer(&ignore, &output);

                ret = send_msg(cfd, tmbuf, tmlen, true);
                if (ret) return ret;
            }

        } while (maj == GSS_S_CONTINUE_NEEDED);
    }

    /* negotiation completed, now handle traffic */

    ret = init_epoll(cfd, pfd, &efd);
    if (ret) return ret;

    while (efd != -1) {
        struct epoll_event *ev;
        int n;
        n = epoll_wait(efd, events, MAX_EVENTS, -1);
        if (n == -1) {
            ret = errno;
            if (ret == EINTR) continue;
            return ret;
        }
        for (int i = 0; i < n; i++) {
            ev = &events[i];
            if (ev->events & (EPOLLERR|EPOLLHUP)) {
                /* one of the peers gave up */
                return ENOLINK;
            }

            /* RECEIVE */

            tmlen = MAX_MSG_SIZE;
            ret = recv_msg(ev->data.fd, tmbuf, &tmlen, (ev->data.fd == cfd));
            if (ret) return ret;

            if (ev->data.fd == cfd) {
                /* sender encrypts */
                input.value = tmbuf;
                input.length = tmlen;
                maj = gss_unwrap(&min, ctx, &input, &output, NULL, NULL);
                if (maj != GSS_S_COMPLETE) {
                    gt_gss_error(svc->name, GSS_C_NO_OID, maj, min);
                    return EIO;
                }
                if (output.length > MAX_MSG_SIZE) return ENOSPC;
                memcpy(tmbuf, output.value, output.length);
                tmlen = output.length;
                (void)gss_release_buffer(&ignore, &output);
            }

            /* RESEND */
            if (ev->data.fd == pfd) {
                /* receiver encrypts */
                input.value = tmbuf;
                input.length = tmlen;
                maj = gss_wrap(&min, ctx, 1, 0, &input, NULL, &output);
                if (maj != GSS_S_COMPLETE) {
                    gt_gss_error(svc->name, GSS_C_NO_OID, maj, min);
                    return EIO;
                }
                if (output.length > MAX_MSG_SIZE) return ENOSPC;
                memcpy(tmbuf, output.value, output.length);
                tmlen = output.length;
                (void)gss_release_buffer(&ignore, &output);
            }

            /* send to the other fd, add header only if we encrypted */
            ret = send_msg((ev->data.fd == pfd)?cfd:pfd,
                           tmbuf, tmlen, (ev->data.fd == pfd));
            if (ret) return ret;
        }
    }

    return 0;
}
int main()
{
    OM_uint32                           init_maj_stat;
    OM_uint32                           accept_maj_stat;
    OM_uint32                           maj_stat;
    OM_uint32                           min_stat;
    OM_uint32                           ret_flags;
    OM_uint32                           req_flags = 0;
    OM_uint32                           time_rec;
    gss_buffer_desc                     send_tok;
    gss_buffer_desc                     recv_tok;
    gss_buffer_desc *                   token_ptr;
    gss_OID                             mech_type;
    gss_name_t                          target_name;
    gss_ctx_id_t                        init_context;
    gss_ctx_id_t                        accept_context;
    gss_ctx_id_t                        del_init_context;
    gss_ctx_id_t                        del_accept_context;
    gss_cred_id_t                       delegated_cred;
    gss_cred_id_t                       imported_cred;
    gss_cred_id_t                       cred_handle;
    char *                              error_str;
    globus_result_t                     result;
    globus_gsi_cert_utils_cert_type_t   cert_type;
    int                                 rc = EXIT_SUCCESS;

    printf("1..1\n");
    /* Activate Modules */
    globus_module_activate(GLOBUS_GSI_GSSAPI_MODULE);

    /* Initialize variables */
    
    token_ptr = GSS_C_NO_BUFFER;
    init_context = GSS_C_NO_CONTEXT;
    accept_context = GSS_C_NO_CONTEXT;
    del_init_context = GSS_C_NO_CONTEXT;
    del_accept_context = GSS_C_NO_CONTEXT;
    delegated_cred = GSS_C_NO_CREDENTIAL;
    accept_maj_stat = GSS_S_CONTINUE_NEEDED;
    ret_flags = 0;
    req_flags |= GSS_C_GLOBUS_LIMITED_DELEG_PROXY_FLAG;


    /* acquire the credential */

    maj_stat = gss_acquire_cred(&min_stat,
                                NULL,
                                GSS_C_INDEFINITE,
                                GSS_C_NO_OID_SET,
                                GSS_C_BOTH,
                                &cred_handle,
                                NULL,
                                NULL);

    if(maj_stat != GSS_S_COMPLETE)
    {
        globus_gsi_gssapi_test_print_error(stderr, maj_stat, min_stat);
        rc = EXIT_FAILURE;
        goto fail;
    }

    
    /* get the subject name */
    
    maj_stat = gss_inquire_cred(&min_stat, 
                                cred_handle,
                                &target_name,
                                NULL,
                                NULL,
                                NULL);

    if(maj_stat != GSS_S_COMPLETE)
    {
        globus_gsi_gssapi_test_print_error(stderr, maj_stat, min_stat);
        rc = EXIT_FAILURE;
        goto fail;
    }


    /* set up the first security context */
    
    init_maj_stat = gss_init_sec_context(&min_stat,
                                         cred_handle,
                                         &init_context,
                                         target_name,
                                         GSS_C_NULL_OID,
                                         0,
                                         0,
                                         GSS_C_NO_CHANNEL_BINDINGS,
                                         token_ptr,
                                         NULL,
                                         &send_tok,
                                         NULL,
                                         NULL);


    if(init_maj_stat != GSS_S_CONTINUE_NEEDED)
    {
        globus_gsi_gssapi_test_print_error(stderr, init_maj_stat, min_stat);
        rc = EXIT_FAILURE;
        goto fail;
    }

    while(1)
    {
        
        accept_maj_stat=gss_accept_sec_context(&min_stat,
                                               &accept_context,
                                               GSS_C_NO_CREDENTIAL,
                                               &send_tok, 
                                               GSS_C_NO_CHANNEL_BINDINGS,
                                               NULL,
                                               &mech_type,
                                               &recv_tok,
                                               &ret_flags,
                                               /* ignore time_rec */
                                               NULL, 
                                               NULL);

        if(accept_maj_stat != GSS_S_COMPLETE &&
           accept_maj_stat != GSS_S_CONTINUE_NEEDED)
        {
            globus_gsi_gssapi_test_print_error(stderr, accept_maj_stat, min_stat);
            rc = EXIT_FAILURE;
            goto fail;
        }
        else if(accept_maj_stat == GSS_S_COMPLETE)
        {
            break;
        }

        init_maj_stat = gss_init_sec_context(&min_stat,
                                             GSS_C_NO_CREDENTIAL,
                                             &init_context,
                                             target_name,
                                             GSS_C_NULL_OID,
                                             0,
                                             0,
                                             GSS_C_NO_CHANNEL_BINDINGS,
                                             &recv_tok,
                                             NULL,
                                             &send_tok,
                                             NULL,
                                             NULL);
        
        
        if(init_maj_stat != GSS_S_COMPLETE &&
           init_maj_stat != GSS_S_CONTINUE_NEEDED)
        {
            globus_gsi_gssapi_test_print_error(stderr, init_maj_stat, min_stat);
            rc = EXIT_FAILURE;
            goto fail;
        }
    }

    printf("# %s:%d: Successfully established initial security context\n",
           __FILE__,
           __LINE__);


    /* delegate our credential over the initial security context and
     * insert a restriction extension into the delegated credential.
     * This is a post GT 2.0 feature.
     */


    init_maj_stat = gss_init_delegation(&min_stat,
                                        init_context,
                                        cred_handle,
                                        GSS_C_NO_OID,
                                        GSS_C_NO_OID_SET,
                                        GSS_C_NO_BUFFER_SET,
                                        token_ptr,
                                        req_flags,
                                        0,
                                        &send_tok);
    

    if(init_maj_stat != GSS_S_COMPLETE &&
       init_maj_stat != GSS_S_CONTINUE_NEEDED)
    {
        globus_gsi_gssapi_test_print_error(stderr, init_maj_stat, min_stat);
        rc = EXIT_FAILURE;
        goto fail;
    }

    while(1)
    {
        accept_maj_stat=gss_accept_delegation(&min_stat,
                                              accept_context,
                                              GSS_C_NO_OID_SET,
                                              GSS_C_NO_BUFFER_SET,
                                              &send_tok,
                                              req_flags,
                                              0,
                                              &time_rec,
                                              &delegated_cred,
                                              &mech_type,
                                              &recv_tok);
        
        if(accept_maj_stat != GSS_S_COMPLETE &&
           accept_maj_stat != GSS_S_CONTINUE_NEEDED)
        {
            globus_gsi_gssapi_test_print_error(stderr, accept_maj_stat, min_stat);
            rc = EXIT_FAILURE;
            goto fail;
        }
        else if(accept_maj_stat == GSS_S_COMPLETE)
        {
            break;
        }

        init_maj_stat = gss_init_delegation(&min_stat,
                                            init_context,
                                            cred_handle,
                                            GSS_C_NO_OID,
                                            GSS_C_NO_OID_SET,
                                            GSS_C_NO_BUFFER_SET,
                                            &recv_tok,
                                            req_flags,
                                            0,
                                            &send_tok);


        if(init_maj_stat != GSS_S_COMPLETE &&
           init_maj_stat != GSS_S_CONTINUE_NEEDED)
        {
            globus_gsi_gssapi_test_print_error(stderr, init_maj_stat, min_stat);
            rc = EXIT_FAILURE;
            goto fail;
        }
    }
    
    printf("# %s:%d: Successfully delegated credential\n",
           __FILE__,
           __LINE__);

    /* export and import the delegated credential */
    /* this can be done both to a buffer and to a file */
    /* New in GT 2.0 */

    maj_stat = gss_export_cred(&min_stat,
                               delegated_cred,
                               GSS_C_NO_OID,
                               0,
                               &send_tok);

    if(maj_stat != GSS_S_COMPLETE)
    {
        globus_gsi_gssapi_test_print_error(stderr, maj_stat, min_stat);
        rc = EXIT_FAILURE;
        goto fail;
    }

    
    maj_stat = gss_import_cred(&min_stat,
                               &imported_cred,
                               GSS_C_NO_OID,
                               0,
                               &send_tok,
                               0,
                               &time_rec);


    if(maj_stat != GSS_S_COMPLETE)
    {
        globus_gsi_gssapi_test_print_error(stderr, maj_stat, min_stat);
        rc = EXIT_FAILURE;
        goto fail;
    }

    printf("# %s:%d: Successfully exported/imported the delegated credential\n",
           __FILE__,
           __LINE__);

    /* set up another security context using the delegated credential */
    
    init_maj_stat = gss_init_sec_context(&min_stat,
                                         imported_cred,
                                         &del_init_context,
                                         target_name,
                                         GSS_C_NULL_OID,
                                         0,
                                         0,
                                         GSS_C_NO_CHANNEL_BINDINGS,
                                         token_ptr,
                                         NULL,
                                         &send_tok,
                                         NULL,
                                         NULL);


    if(init_maj_stat != GSS_S_COMPLETE &&
       init_maj_stat != GSS_S_CONTINUE_NEEDED)
    {
        globus_gsi_gssapi_test_print_error(stderr, init_maj_stat, min_stat);
        rc = EXIT_FAILURE;
        goto fail;
    }


    
    while(1)
    {
        accept_maj_stat=gss_accept_sec_context(&min_stat,
                                               &del_accept_context,
                                               imported_cred,
                                               &send_tok, 
                                               GSS_C_NO_CHANNEL_BINDINGS,
                                               NULL,
                                               &mech_type,
                                               &recv_tok,
                                               &ret_flags,
                                               /* ignore time_rec */
                                               NULL, 
                                               NULL);

        if(accept_maj_stat != GSS_S_COMPLETE &&
           accept_maj_stat != GSS_S_CONTINUE_NEEDED)
        {
            globus_gsi_gssapi_test_print_error(stderr, accept_maj_stat, min_stat);
            rc = EXIT_FAILURE;
            goto fail;
        }
        else if(accept_maj_stat == GSS_S_COMPLETE)
        {
            break;
        }
        
        init_maj_stat = gss_init_sec_context(&min_stat,
                                             imported_cred,
                                             &del_init_context,
                                             target_name,
                                             GSS_C_NULL_OID,
                                             0,
                                             0,
                                             GSS_C_NO_CHANNEL_BINDINGS,
                                             &recv_tok,
                                             NULL,
                                             &send_tok,
                                             NULL,
                                             NULL);
        
        
        if(init_maj_stat != GSS_S_COMPLETE &&
           init_maj_stat != GSS_S_CONTINUE_NEEDED)
        {
            globus_gsi_gssapi_test_print_error(stderr, init_maj_stat, min_stat);
            rc = EXIT_FAILURE;
            goto fail;
        }
    }

    /* got sec context based on delegated cred now */
    printf("# %s:%d: Successfully established security context with delegated credential\n",
           __FILE__,
           __LINE__);

    /* Verify that the delegated credential is a limited proxy */
    result = globus_gsi_cred_get_cert_type(
        ((gss_cred_id_desc *)imported_cred)->cred_handle,
        &cert_type);
    if(result != GLOBUS_SUCCESS)
    {
        char *                          error_str;
        globus_object_t *               error_obj;

        error_obj = globus_error_get(result);
        error_str = globus_error_print_chain(error_obj);
        fprintf(stderr, "%s", error_str);
        globus_libc_free(error_str);
        globus_object_free(error_obj);
        rc = EXIT_FAILURE;
        goto fail;
    }

    if (! GLOBUS_GSI_CERT_UTILS_IS_LIMITED_PROXY(cert_type))
    {
        fprintf(stderr,
                "Invalid certificate type. Expected a limited proxy, got %d\n",
                (int) cert_type);
        rc = EXIT_FAILURE;
        goto fail;
    }

fail:
    printf("%s gssapi_limited_delegation_test\n",
            (rc==EXIT_SUCCESS) ? "ok" : "not ok");
    globus_module_deactivate_all();
    
    exit(rc);    
}
Exemplo n.º 30
0
/* Acquire GSSAPI credentials and set up RPC auth flavor. */
static kadm5_ret_t
setup_gss(kadm5_server_handle_t handle, kadm5_config_params *params_in,
          krb5_principal client, krb5_principal server)
{
    OM_uint32 gssstat, minor_stat;
    gss_buffer_desc buf;
    gss_name_t gss_client;
    gss_name_t gss_target;
    gss_cred_id_t gss_client_creds;
    const char *c_ccname_orig;
    char *ccname_orig;

    gss_client_creds = GSS_C_NO_CREDENTIAL;
    ccname_orig = NULL;
    gss_client = gss_target = GSS_C_NO_NAME;

    /* Temporarily use the kadm5 cache. */
    gssstat = gss_krb5_ccache_name(&minor_stat, handle->cache_name,
                                   &c_ccname_orig);
    if (gssstat != GSS_S_COMPLETE)
        goto error;
    if (c_ccname_orig)
        ccname_orig = strdup(c_ccname_orig);
    else
        ccname_orig = 0;

    buf.value = &server;
    buf.length = sizeof(server);
    gssstat = gss_import_name(&minor_stat, &buf,
                              (gss_OID)gss_nt_krb5_principal, &gss_target);
    if (gssstat != GSS_S_COMPLETE)
        goto error;

    if (client != NULL) {
        buf.value = &client;
        buf.length = sizeof(client);
        gssstat = gss_import_name(&minor_stat, &buf,
                                  (gss_OID)gss_nt_krb5_principal, &gss_client);
    } else gss_client = GSS_C_NO_NAME;

    if (gssstat != GSS_S_COMPLETE)
        goto error;

    gssstat = gss_acquire_cred(&minor_stat, gss_client, 0,
                               GSS_C_NULL_OID_SET, GSS_C_INITIATE,
                               &gss_client_creds, NULL, NULL);
    if (gssstat != GSS_S_COMPLETE) {
#if 0 /* for debugging only */
        {
            OM_uint32 maj_status, min_status, message_context = 0;
            gss_buffer_desc status_string;
            do {
                maj_status = gss_display_status(&min_status,
                                                gssstat,
                                                GSS_C_GSS_CODE,
                                                GSS_C_NO_OID,
                                                &message_context,
                                                &status_string);
                if (maj_status == GSS_S_COMPLETE) {
                    fprintf(stderr, "MAJ: %.*s\n",
                            (int) status_string.length,
                            (char *)status_string.value);
                    gss_release_buffer(&min_status, &status_string);
                } else {
                    fprintf(stderr,
                            "MAJ? gss_display_status returns 0x%lx?!\n",
                            (unsigned long) maj_status);
                    message_context = 0;
                }
            } while (message_context != 0);
            do {
                maj_status = gss_display_status(&min_status,
                                                minor_stat,
                                                GSS_C_MECH_CODE,
                                                GSS_C_NO_OID,
                                                &message_context,
                                                &status_string);
                if (maj_status == GSS_S_COMPLETE) {
                    fprintf(stderr, "MIN: %.*s\n",
                            (int) status_string.length,
                            (char *)status_string.value);
                    gss_release_buffer(&min_status, &status_string);
                } else {
                    fprintf(stderr,
                            "MIN? gss_display_status returns 0x%lx?!\n",
                            (unsigned long) maj_status);
                    message_context = 0;
                }
            } while (message_context != 0);
        }
#endif
        goto error;
    }

    /*
     * Do actual creation of RPC auth handle.  Implements auth flavor
     * fallback.
     */
    rpc_auth(handle, params_in, gss_client_creds, gss_target);

error:
    if (gss_client_creds != GSS_C_NO_CREDENTIAL)
        (void) gss_release_cred(&minor_stat, &gss_client_creds);

    if (gss_client)
        gss_release_name(&minor_stat, &gss_client);
    if (gss_target)
        gss_release_name(&minor_stat, &gss_target);

    /* Revert to prior gss_krb5 ccache. */
    if (ccname_orig) {
        gssstat = gss_krb5_ccache_name(&minor_stat, ccname_orig, NULL);
        if (gssstat) {
            return KADM5_GSS_ERROR;
        }
        free(ccname_orig);
    } else {
        gssstat = gss_krb5_ccache_name(&minor_stat, NULL, NULL);
        if (gssstat) {
            return KADM5_GSS_ERROR;
        }
    }

    if (handle->clnt->cl_auth == NULL) {
        return KADM5_GSS_ERROR;
    }
    return 0;
}