Example #1
0
/** Authenticate a request with @b Basic authentication scheme.
 *
 */
void auth_method_basic(auth_mod_t *am,
		       auth_status_t *as,
		       msg_auth_t *au,
		       auth_challenger_t const *ach)
{
  char *userpass, buffer[128];
  size_t n, upsize;
  char *pass;
  auth_passwd_t *apw;

  if (!as->as_realm)
    return;

  userpass = buffer, upsize = sizeof buffer;

  for (au = auth_mod_credentials(au, "Basic", NULL);
       au;
       au = auth_mod_credentials(au->au_next, "Basic", NULL)) {
    if (!au->au_params)
      continue;
    n = base64_d(userpass, upsize - 1, au->au_params[0]);
    if (n >= INT_MAX)
      continue;
    if (n >= upsize) {
      void *b = realloc(userpass == buffer ? NULL : userpass, upsize = n + 1);
      if (b == NULL)
	break;
      base64_d(userpass = b, upsize - 1, au->au_params[0]);
    }
    userpass[n] = 0;
    if (!(pass = strchr(userpass, ':')))
      continue;
    *pass++ = '\0';
    SU_DEBUG_5(("auth_method_basic: %s => %s:%s\n",
		au->au_params[0], userpass, pass));

    if (!(apw = auth_mod_getpass(am, userpass, as->as_realm)))
      continue;
    if (strcmp(apw->apw_pass, pass))
      continue;

    as->as_user = apw->apw_user;
    as->as_anonymous = apw == am->am_anon_user;
    as->as_ident = apw->apw_ident;
    as->as_match = (msg_header_t *)au;
    as->as_status = 0;	/* Successful authentication! */

    break;
  }

  if (userpass != buffer)
    free(userpass);

  if (au)
    return;

  if (auth_allow_check(am, as))
    auth_challenge_basic(am, as, ach);
}
Example #2
0
/** Verify digest authentication */
void auth_check_digest(auth_mod_t *am,
                       auth_status_t *as,
                       auth_response_t *ar,
                       auth_challenger_t const *ach)
{
    char const *a1;
    auth_hexmd5_t a1buf, response;
    auth_passwd_t *apw;
    char const *phrase;
    msg_time_t now = msg_now();

    if (am == NULL || as == NULL || ar == NULL || ach == NULL) {
        if (as) {
            as->as_status = 500, as->as_phrase = "Internal Server Error";
            as->as_response = NULL;
        }
        return;
    }

    phrase = "Bad authorization";

#define PA "Authorization missing "

    if ((!ar->ar_username && (phrase = PA "username")) ||
            (!ar->ar_nonce && (phrase = PA "nonce")) ||
            (!ar->ar_uri && (phrase = PA "URI")) ||
            (!ar->ar_response && (phrase = PA "response")) ||
            /* (!ar->ar_opaque && (phrase = PA "opaque")) || */
            /* Check for qop */
            (ar->ar_qop &&
             ((ar->ar_auth &&
               !su_casematch(ar->ar_qop, "auth") &&
               !su_casematch(ar->ar_qop, "\"auth\"")) ||
              (ar->ar_auth_int &&
               !su_casematch(ar->ar_qop, "auth-int") &&
               !su_casematch(ar->ar_qop, "\"auth-int\"")))
             && (phrase = PA "has invalid qop"))) {
        assert(phrase);
        SU_DEBUG_5(("auth_method_digest: 400 %s\n", phrase));
        as->as_status = 400, as->as_phrase = phrase;
        as->as_response = NULL;
        return;
    }

    if (as->as_nonce_issued == 0 /* Already validated nonce */ &&
            auth_validate_digest_nonce(am, as, ar, now) < 0) {
        as->as_blacklist = am->am_blacklist;
        auth_challenge_digest(am, as, ach);
        return;
    }

    if (as->as_stale) {
        auth_challenge_digest(am, as, ach);
        return;
    }

    apw = auth_mod_getpass(am, ar->ar_username, ar->ar_realm);

    if (apw && apw->apw_hash)
        a1 = apw->apw_hash;
    else if (apw && apw->apw_pass)
        auth_digest_a1(ar, a1buf, apw->apw_pass), a1 = a1buf;
    else
        auth_digest_a1(ar, a1buf, "xyzzy"), a1 = a1buf, apw = NULL;

    if (ar->ar_md5sess)
        auth_digest_a1sess(ar, a1buf, a1), a1 = a1buf;

    auth_digest_response(ar, response, a1,
                         as->as_method, as->as_body, as->as_bodylen);

    if (!apw || strcmp(response, ar->ar_response)) {

        if (am->am_forbidden) {
            as->as_status = 403, as->as_phrase = "Forbidden";
            as->as_response = NULL;
            as->as_blacklist = am->am_blacklist;
        }
        else {
            auth_challenge_digest(am, as, ach);
            as->as_blacklist = am->am_blacklist;
        }
        SU_DEBUG_5(("auth_method_digest: response did not match\n"));

        return;
    }

    assert(apw);

    as->as_user = apw->apw_user;
    as->as_anonymous = apw == am->am_anon_user;
    as->as_ident = apw->apw_ident;

    if (am->am_nextnonce || am->am_mutual)
        auth_info_digest(am, as, ach);

    if (am->am_challenge)
        auth_challenge_digest(am, as, ach);

    SU_DEBUG_7(("auth_method_digest: successful authentication\n"));

    as->as_status = 0;	/* Successful authentication! */
    as->as_phrase = "";
}