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
/** Validate nonce parameter.
 *
 * @param am   pointer to authentication module object
 * @param as   authentication status structure [OUT]
 * @param ar   decoded authentication response from client [IN]
 * @param now  current time [IN]
 */
int auth_validate_digest_nonce(auth_mod_t *am,
                               auth_status_t *as,
                               auth_response_t *ar,
                               msg_time_t now)
{
    struct nonce nonce[1] = {{ 0 }};
    su_md5_t md5[1];
    uint8_t hmac[sizeof nonce->digest];
    unsigned expires;

    /* Check nonce */
    if (!ar->ar_nonce) {
        SU_DEBUG_5(("auth_method_digest: no nonce\n"));
        return -1;
    }
    if (base64_d((void*)nonce, (sizeof nonce), ar->ar_nonce) != (sizeof nonce)) {
        SU_DEBUG_5(("auth_method_digest: too short nonce\n"));
        return -1;
    }

    /* Calculate HMAC over decoded nonce data */
    auth_md5_hmac_init(am, md5);
    su_md5_update(md5, nonce, offsetof(struct nonce, digest));
    auth_md5_hmac_digest(am, md5, hmac, sizeof hmac);

    if (memcmp(nonce->digest, hmac, sizeof nonce->digest)) {
        SU_DEBUG_5(("auth_method_digest: bad nonce\n"));
        return -1;
    }

    as->as_nonce_issued = nonce->issued;
    as->as_nextnonce = nonce->nextnonce != 0;

    expires = nonce->nextnonce ? am->am_next_exp : am->am_expires;

    if (nonce->issued > now ||
            (expires && nonce->issued + expires < now)) {
        SU_DEBUG_5(("auth_method_digest: nonce expired %lu seconds ago "
                    "(lifetime %u)\n",
                    now - (nonce->issued + expires), expires));
        as->as_stale = 1;
    }

    if (am->am_max_ncount && ar->ar_nc) {
        unsigned long nc = strtoul(ar->ar_nc, NULL, 10);

        if (nc == 0 || nc > am->am_max_ncount) {
            SU_DEBUG_5(("auth_method_digest: nonce used %s times, max %u\n",
                        ar->ar_nc, am->am_max_ncount));
            as->as_stale = 1;
        }
    }

    /* We should also check cnonce, nc... */

    return 0;
}