OM_uint32 GSSAPI_LIB_FUNCTION
gss_acquire_cred_ex(const gss_name_t desired_name,
		    OM_uint32 flags,
		    OM_uint32 time_req,
		    gss_const_OID desired_mech,
		    gss_cred_usage_t cred_usage,
		    gss_auth_identity_t identity,
		    gss_acquire_cred_complete complete)
{
    OM_uint32 ret;

    complete = (gss_acquire_cred_complete)Block_copy(complete);

    ret = gss_acquire_cred_ex_f(NULL,
				desired_name,
				flags,
				time_req,
				desired_mech,
				cred_usage,
				identity,
				complete,
				complete_block);
    if (ret != GSS_S_COMPLETE)
	Block_release(complete);
    return ret;
}
Example #2
0
File: gss.c Project: B1NG0/cifs
static int
smb_acquire_cred(const char *user, const char *domain, const char *password, 
				 gss_OID mech, void **gssCreds)
{
	gss_auth_identity_desc identity;
	struct smb_gss_cred_ctx aq_cred_ctx;
	uint32_t maj = !GSS_S_COMPLETE;

	if (password == NULL || user == NULL || *user == '\0') 
		return 0;
		
	identity.type = GSS_AUTH_IDENTITY_TYPE_1;
	identity.flags = 0;
	identity.username = strdup(user);
	identity.realm = strdup(domain ? domain : "");
	identity.password = strdup(password);
	identity.credentialsRef = NULL;
	
	if (identity.username == NULL ||
	    identity.realm == NULL || 
	    identity.password == NULL)
	    goto out;
	
	aq_cred_ctx.sem = dispatch_semaphore_create(0);
	if (aq_cred_ctx.sem == NULL)
		goto out;

	maj = gss_acquire_cred_ex_f(NULL,
				    GSS_C_NO_NAME,
				    0,
				    GSS_C_INDEFINITE,
				    mech,
				    GSS_C_INITIATE,
				    &identity,
				    &aq_cred_ctx,
				    acquire_cred_complete);
	
	if (maj == GSS_S_COMPLETE) {
		dispatch_semaphore_wait(aq_cred_ctx.sem, DISPATCH_TIME_FOREVER);
		maj = aq_cred_ctx.maj;
		*gssCreds = aq_cred_ctx.creds;
	}
	
	if (maj != GSS_S_COMPLETE)
		smb_log_info("Acquiring NTLM creds for %s\%s failed. GSS returned %d",
			ASL_LEVEL_INFO, domain, user, maj);

	dispatch_release(aq_cred_ctx.sem);
out:
	free(identity.username);
	free(identity.realm);
	free(identity.password);
	
	return (maj == GSS_S_COMPLETE);
}
Example #3
0
int					/* O - 0 on success, -1 on error */
_cupsSetNegotiateAuthString(
    http_t     *http,			/* I - Connection to server */
    const char *method,			/* I - Request method ("GET", "POST", "PUT") */
    const char *resource)		/* I - Resource path */
{
  OM_uint32	minor_status,		/* Minor status code */
		major_status;		/* Major status code */
  gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
					/* Output token */


  (void)method;
  (void)resource;

#  ifdef __APPLE__
 /*
  * If the weak-linked GSSAPI/Kerberos library is not present, don't try
  * to use it...
  */

  if (&gss_init_sec_context == NULL)
  {
    DEBUG_puts("1_cupsSetNegotiateAuthString: Weak-linked GSSAPI/Kerberos "
               "framework is not present");
    return (-1);
  }
#  endif /* __APPLE__ */

  if (http->gssname == GSS_C_NO_NAME)
  {
    http->gssname = cups_gss_getname(http, _cupsGSSServiceName());
  }

  if (http->gssctx != GSS_C_NO_CONTEXT)
  {
    gss_delete_sec_context(&minor_status, &http->gssctx, GSS_C_NO_BUFFER);
    http->gssctx = GSS_C_NO_CONTEXT;
  }

  major_status = gss_init_sec_context(&minor_status, GSS_C_NO_CREDENTIAL,
				      &http->gssctx,
				      http->gssname, http->gssmech,
				      GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG,
				      GSS_C_INDEFINITE,
				      GSS_C_NO_CHANNEL_BINDINGS,
				      GSS_C_NO_BUFFER, &http->gssmech,
				      &output_token, NULL, NULL);

#ifdef HAVE_GSS_ACQUIRE_CRED_EX_F
  if (major_status == GSS_S_NO_CRED)
  {
   /*
    * Ask the user for credentials...
    */

    char		prompt[1024],	/* Prompt for user */
			userbuf[256];	/* Kerberos username */
    const char		*username,	/* Username string */
			*password;	/* Password string */
    _cups_gss_acquire_t	data;		/* Callback data */
    gss_auth_identity_desc identity;	/* Kerberos user identity */
    _cups_globals_t	*cg = _cupsGlobals();
					/* Per-thread global data */

    if (!cg->lang_default)
      cg->lang_default = cupsLangDefault();

    snprintf(prompt, sizeof(prompt),
             _cupsLangString(cg->lang_default, _("Password for %s on %s? ")),
	     cupsUser(), http->gsshost);

    if ((password = cupsGetPassword2(prompt, http, method, resource)) == NULL)
      return (-1);

   /*
    * Try to acquire credentials...
    */

    username = cupsUser();
    if (!strchr(username, '@'))
    {
      snprintf(userbuf, sizeof(userbuf), "%s@%s", username, http->gsshost);
      username = userbuf;
    }

    identity.type           = GSS_AUTH_IDENTITY_TYPE_1;
    identity.flags          = 0;
    identity.username       = (char *)username;
    identity.realm          = (char *)"";
    identity.password       = (char *)password;
    identity.credentialsRef = NULL;

    data.sem   = dispatch_semaphore_create(0);
    data.major = 0;
    data.creds = NULL;

    if (data.sem)
    {
      major_status = gss_acquire_cred_ex_f(NULL, GSS_C_NO_NAME, 0,
				           GSS_C_INDEFINITE, GSS_KRB5_MECHANISM,
					   GSS_C_INITIATE, &identity, &data,
					   cups_gss_acquire);

      if (major_status == GSS_S_COMPLETE)
      {
	dispatch_semaphore_wait(data.sem, DISPATCH_TIME_FOREVER);
	major_status = data.major;
      }

      dispatch_release(data.sem);

      if (major_status == GSS_S_COMPLETE)
      {
        OM_uint32	release_minor;	/* Minor status from releasing creds */

	major_status = gss_init_sec_context(&minor_status, data.creds,
					    &http->gssctx,
					    http->gssname, http->gssmech,
					    GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG,
					    GSS_C_INDEFINITE,
					    GSS_C_NO_CHANNEL_BINDINGS,
					    GSS_C_NO_BUFFER, &http->gssmech,
					    &output_token, NULL, NULL);
        gss_release_cred(&release_minor, &data.creds);
      }
    }
  }
#endif /* HAVE_GSS_ACQUIRED_CRED_EX_F */

  if (GSS_ERROR(major_status))
  {
    cups_gss_printf(major_status, minor_status,
		    "_cupsSetNegotiateAuthString: Unable to initialize "
		    "security context");
    return (-1);
  }

#ifdef DEBUG
  else if (major_status == GSS_S_CONTINUE_NEEDED)
    cups_gss_printf(major_status, minor_status,
		    "_cupsSetNegotiateAuthString: Continuation needed!");
#endif /* DEBUG */

  if (output_token.length > 0 && output_token.length <= 65536)
  {
   /*
    * Allocate the authorization string since Windows KDCs can have
    * arbitrarily large credentials...
    */

    int authsize = 10 +			/* "Negotiate " */
		   (int)output_token.length * 4 / 3 + 1 + 1;
		   			/* Base64 + nul */

    httpSetAuthString(http, NULL, NULL);

    if ((http->authstring = malloc((size_t)authsize)) == NULL)
    {
      http->authstring = http->_authstring;
      authsize         = sizeof(http->_authstring);
    }

    strlcpy(http->authstring, "Negotiate ", (size_t)authsize);
    httpEncode64_2(http->authstring + 10, authsize - 10, output_token.value,
		   (int)output_token.length);

    gss_release_buffer(&minor_status, &output_token);
  }
  else
  {
    DEBUG_printf(("1_cupsSetNegotiateAuthString: Kerberos credentials too "
                  "large - %d bytes!", (int)output_token.length));
    gss_release_buffer(&minor_status, &output_token);

    return (-1);
  }

  return (0);
}
static int
test_scram(const char *test_name, const char *user, const char *password)
{
    gss_name_t cname, target = GSS_C_NO_NAME;
    OM_uint32 maj_stat, min_stat;
    gss_ctx_id_t ctx = GSS_C_NO_CONTEXT;
    gss_buffer_desc cn, input, output, output2;
    int ret;
    heim_scram *scram = NULL;
    heim_scram_data in, out;
    gss_auth_identity_desc identity;


    memset(&identity, 0, sizeof(identity));

    identity.username = rk_UNCONST(user);
    identity.realm = "";
    identity.password = rk_UNCONST(password);

    cn.value = rk_UNCONST(user);
    cn.length = strlen(user);

    maj_stat = gss_import_name(&min_stat, &cn, GSS_C_NT_USER_NAME, &cname);
    if (maj_stat)
	errx(1, "gss_import_name: %d", (int)maj_stat);

    maj_stat = gss_acquire_cred_ex_f(NULL,
				     cname,
				     0,
				     GSS_C_INDEFINITE,
				     GSS_SCRAM_MECHANISM,
				     GSS_C_INITIATE,
				     &identity,
				     NULL,
				     ac_complete);
    if (maj_stat)
	errx(1, "gss_acquire_cred_ex_f: %d", (int)maj_stat);

    if (client_cred == GSS_C_NO_CREDENTIAL)
	errx(1, "gss_acquire_cred_ex_f");

    cn.value = rk_UNCONST("host@localhost");
    cn.length = strlen((char *)cn.value);

    maj_stat = gss_import_name(&min_stat, &cn,
			       GSS_C_NT_HOSTBASED_SERVICE, &target);
    if (maj_stat)
	errx(1, "gss_import_name: %d", (int)maj_stat);

    maj_stat = gss_init_sec_context(&min_stat, client_cred, &ctx, 
				    target, GSS_SCRAM_MECHANISM, 
				    0, 0, NULL,
				    GSS_C_NO_BUFFER, NULL, 
				    &output, NULL, NULL); 
    if (maj_stat != GSS_S_CONTINUE_NEEDED)
	errx(1, "accept_sec_context %s %s", test_name,
	      gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));

    if (output.length == 0)
	errx(1, "output.length == 0");

    maj_stat = gss_decapsulate_token(&output, GSS_SCRAM_MECHANISM, &output2);
    if (maj_stat)
	errx(1, "decapsulate token");

    in.length = output2.length;
    in.data = output2.value;

    ret = heim_scram_server1(&in, NULL, HEIM_SCRAM_DIGEST_SHA1, &server_proc, NULL, &scram, &out);
    if (ret)
	errx(1, "heim_scram_server1");

    gss_release_buffer(&min_stat, &output);

    input.length = out.length;
    input.value = out.data;

    maj_stat = gss_init_sec_context(&min_stat, client_cred, &ctx,
				    target, GSS_SCRAM_MECHANISM,
				    0, 0, NULL,
				    &input, NULL,
				    &output, NULL, NULL);
    if (maj_stat != GSS_S_CONTINUE_NEEDED) {
	warnx("accept_sec_context v1 2 %s",
	     gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
	return 1;
    }

    in.length = output.length;
    in.data = output.value;

    ret = heim_scram_server2(&in, scram, &out);
    if (ret)
	errx(1, "heim_scram_server2");

    gss_release_buffer(&min_stat, &output);

    input.length = out.length;
    input.value = out.data;

    maj_stat = gss_init_sec_context(&min_stat, client_cred, &ctx, 
				    target, GSS_SCRAM_MECHANISM, 
				    0, 0, NULL,
				    &input, NULL, 
				    &output, NULL, NULL); 
    if (maj_stat != GSS_S_COMPLETE) {
	warnx("accept_sec_context v1 2 %s",
	     gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
	return 1;
    }

    heim_scram_free(scram);

    //gss_destroy_cred(NULL, &client_cred);

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

    return 0;
}