Example #1
0
void auth_md5_hmac_digest(auth_mod_t *am, struct su_md5_t *imd5,
                          void *hmac, size_t size)
{
    uint8_t digest[SU_MD5_DIGEST_SIZE];
    su_md5_t omd5[1];

    /* inner sum */
    su_md5_digest(imd5, digest);

    *omd5 = am->am_hmac_opad;
    su_md5_update(omd5, digest, sizeof *digest);

    /* outer sum */
    if (size == sizeof digest) {
        su_md5_digest(omd5, hmac);
    }
    else {
        su_md5_digest(omd5, digest);

        if (size > sizeof digest) {
            memset((char *)hmac + (sizeof digest), 0, size - sizeof digest);
            size = sizeof digest;
        }

        memcpy(hmac, digest, size);
    }
}
Example #2
0
/** Create a new outbound object */
outbound_t *
outbound_new(outbound_owner_t *owner,
	     outbound_owner_vtable const *owner_methods,
	     su_root_t *root,
	     nta_agent_t *agent,
	     char const *instance)
{
  outbound_t *ob;

  if (!owner || !owner_methods || !root || !agent)
    return NULL;

  ob = su_home_clone((su_home_t *)owner, sizeof *ob);

  if (ob) {
    su_md5_t md5[1];
    uint8_t digest[SU_MD5_DIGEST_SIZE];
    su_guid_t guid[1];

    ob->ob_owner = owner;
    ob->ob_oo = owner_methods;
    ob->ob_root = root;
    ob->ob_nta = agent;

    if (instance)
      ob->ob_instance =
	su_sprintf(ob->ob_home, "+sip.instance=\"<%s>\"", instance);
    ob->ob_reg_id = 0;

    outbound_peer_info(ob, NULL);

    /* Generate a random cookie (used as Call-ID) for us */
    su_md5_init(md5);
    su_guid_generate(guid);
    if (instance)
      su_md5_update(md5, (void *)instance, strlen(instance));
    su_md5_update(md5, (void *)guid, sizeof guid);
    su_md5_digest(md5, digest);
    token64_e(ob->ob_cookie, sizeof ob->ob_cookie, digest, sizeof digest);

    if (instance && !ob->ob_instance)
      su_home_unref(ob->ob_home), ob = NULL;
  }

  return ob;
}
Example #3
0
int test_md5(void)
{
  BEGIN();

  su_md5_t md5[1], md5i[1];
  uint8_t digest[SU_MD5_DIGEST_SIZE];
  char hexdigest[2 * SU_MD5_DIGEST_SIZE + 1];

  struct { char *input; uint8_t digest[SU_MD5_DIGEST_SIZE]; } suite[] = {
    { (""),
	{ 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
	  0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e } },
    { ("a"), { 0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8,
	       0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61 } },
    { ("abc"), { 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0,
		 0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72 } },
    { ("message digest"),
      { 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d,
	0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0 } },
    { ("abcdefghijklmnopqrstuvwxyz"),
      { 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00,
	0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b } },
    { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
      { 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5,
	0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f } },

    { "1234567890123456789012345678901234567890"
      "1234567890123456789012345678901234567890",
      { 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55,
	0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a } }};

  su_md5_init(md5);
  su_md5_update(md5, suite[0].input, 0);
  su_md5_digest(md5, digest);
  TEST_M(digest, suite[0].digest, SU_MD5_DIGEST_SIZE);
  su_md5_deinit(md5);

  su_md5_init(md5);
  su_md5_strupdate(md5, suite[1].input);
  su_md5_digest(md5, digest);
  TEST_M(digest, suite[1].digest, SU_MD5_DIGEST_SIZE);
  su_md5_deinit(md5);

  su_md5_init(md5);
  su_md5_iupdate(md5, suite[2].input, 3);
  su_md5_digest(md5, digest);
  TEST_M(digest, suite[2].digest, SU_MD5_DIGEST_SIZE);
  su_md5_deinit(md5);

  su_md5_init(md5);
  su_md5_striupdate(md5, suite[3].input);
  su_md5_digest(md5, digest);
  TEST_M(digest, suite[3].digest, SU_MD5_DIGEST_SIZE);
  su_md5_deinit(md5);

  su_md5_init(md5);
  su_md5_iupdate(md5, suite[4].input, 13);
  su_md5_striupdate(md5, suite[4].input + 13);
  su_md5_digest(md5, digest);
  TEST_M(digest, suite[4].digest, SU_MD5_DIGEST_SIZE);
  su_md5_deinit(md5);

  su_md5_init(md5);
  su_md5_update(md5, suite[5].input, 13);
  su_md5_strupdate(md5, suite[5].input + 13);
  su_md5_digest(md5, digest);
  TEST_M(digest, suite[5].digest, SU_MD5_DIGEST_SIZE);
  su_md5_deinit(md5);

  su_md5_init(md5);
  su_md5_update(md5, suite[6].input, 13);
  su_md5_strupdate(md5, suite[6].input + 13);
  su_md5_digest(md5, digest);
  TEST_M(digest, suite[6].digest, SU_MD5_DIGEST_SIZE);
  su_md5_deinit(md5);

  su_md5_init(md5);
  su_md5_str0update(md5, NULL);
  su_md5_hexdigest(md5, hexdigest);
  TEST_S(hexdigest, "93b885adfe0da089cdf634904fd59f71");
  su_md5_deinit(md5);

  su_md5_init(md5);
  su_md5_stri0update(md5, NULL);
  su_md5_stri0update(md5, "ABBADABBADOO");
  su_md5_hexdigest(md5, hexdigest);
  TEST_S(hexdigest, "101e6dd7cfabdb5c74f44b4c545c05cc");

  su_md5_init(md5);
  su_md5_update(md5, "\0abbadabbadoo\0", 14);
  su_md5_hexdigest(md5, hexdigest);
  TEST_S(hexdigest, "101e6dd7cfabdb5c74f44b4c545c05cc");
  su_md5_deinit(md5);

  /* Calculate md5 sum of 512 MB of zero */
  if (getenv("EXPENSIVE_CHECKS")) {
    char zerokilo[1024] = { '\0' };
    int i;

    su_md5_init(md5);
    su_md5_iupdate(md5, zerokilo, 19);
    for (i = 1; i < 512 * 1024; i++)
      su_md5_update(md5, zerokilo, 1024);
    *md5i = *md5;

    su_md5_update(md5, zerokilo, 1024 - 19);
    su_md5_hexdigest(md5, hexdigest);
    TEST_S(hexdigest, "aa559b4e3523a6c931f08f4df52d58f2");
    su_md5_deinit(md5);

    su_md5_iupdate(md5i, zerokilo, 1024 - 19);
    su_md5_hexdigest(md5i, hexdigest);
    TEST_S(hexdigest, "aa559b4e3523a6c931f08f4df52d58f2");
  }
  END();
}
Example #4
0
/**Initialize an authentication module instance.
 *
 * The function auth_mod_init_default() initializes an authentication module
 * object used to authenticate the requests.
 *
 * @param am
 * @param base
 * @param root
 * @param tag,value,... tagged argument list
 *
 * @TAGS
 * AUTHTAG_REALM(), AUTHTAG_OPAQUE(), AUTHTAG_DB(), AUTHTAG_QOP(),
 * AUTHTAG_ALGORITHM(), AUTHTAG_EXPIRES(), AUTHTAG_NEXT_EXPIRES(),
 * AUTHTAG_BLACKLIST(), AUTHTAG_FORBIDDEN(), AUTHTAG_ANONYMOUS(),
 * AUTHTAG_FAKE(), AUTHTAG_ALLOW(), AUTHTAG_REMOTE(), and
 * AUTHTAG_MASTER_KEY().
 *
 * @return 0 if successful
 * @return -1 upon an error
 */
int auth_init_default(auth_mod_t *am,
                      auth_scheme_t *base,
                      su_root_t *root,
                      tag_type_t tag, tag_value_t value, ...)
{
    int retval = 0;

    ta_list ta;

    char const *realm = NULL, *opaque = NULL, *db = NULL, *allows = NULL;
    char const *qop = NULL, *algorithm = NULL;
    unsigned expires = 60 * 60, next_expires = 5 * 60;
    unsigned max_ncount = 0;
    unsigned blacklist = 5;
    int forbidden = 0;
    int anonymous = 0;
    int fake = 0;
    url_string_t const *remote = NULL;
    char const *master_key = "fish";
    char *s;

    ta_start(ta, tag, value);

    /* Authentication stuff */
    tl_gets(ta_args(ta),
            AUTHTAG_REALM_REF(realm),
            AUTHTAG_OPAQUE_REF(opaque),
            AUTHTAG_DB_REF(db),
            AUTHTAG_QOP_REF(qop),
            AUTHTAG_ALGORITHM_REF(algorithm),
            AUTHTAG_EXPIRES_REF(expires),
            AUTHTAG_NEXT_EXPIRES_REF(next_expires),
            AUTHTAG_MAX_NCOUNT_REF(max_ncount),
            AUTHTAG_BLACKLIST_REF(blacklist),
            AUTHTAG_FORBIDDEN_REF(forbidden),
            AUTHTAG_ANONYMOUS_REF(anonymous),
            AUTHTAG_FAKE_REF(fake),
            AUTHTAG_ALLOW_REF(allows),
            AUTHTAG_REMOTE_REF(remote),
            AUTHTAG_MASTER_KEY_REF(master_key),
            TAG_NULL());

    if (!realm) realm = "*";
    if (!allows) allows = "ACK, BYE, CANCEL";

    am->am_realm = su_strdup(am->am_home, realm);
    am->am_opaque = su_strdup(am->am_home, opaque);
    am->am_db = su_strdup(am->am_home, db);
    s = su_strdup(am->am_home, allows);
    if (s)
        msg_commalist_d(am->am_home, &s, &am->am_allow, NULL);
    am->am_expires = expires;
    am->am_next_exp = next_expires;
    am->am_max_ncount = max_ncount;
    am->am_blacklist = blacklist;
    am->am_forbidden = forbidden;
    am->am_anonymous = anonymous;
    am->am_fake = fake;
    am->am_remote = url_hdup(am->am_home, (url_t *)remote);
    am->am_algorithm = algorithm ? su_strdup(am->am_home, algorithm) : "MD5";
    am->am_nextnonce = !algorithm || su_casematch(algorithm, "MD5");
    if (next_expires == 0)
        am->am_nextnonce = 0;
    am->am_qop = su_strdup(am->am_home, qop);

    if (master_key) {
        su_md5_t md5[1];

        su_md5_init(md5);
        su_md5_strupdate(md5, master_key);
        su_md5_strupdate(md5, "70P 53KR37");
        su_md5_digest(md5, am->am_master_key);
    }

    auth_md5_hmac_key(am);

    /* Make sure that we have something
       that can be used to identify credentials */
    if (am->am_opaque && strcmp(am->am_opaque, "*") == 0) {
#ifndef HOST_NAME_MAX
#define HOST_NAME_MAX 255
#endif
        char hostname[HOST_NAME_MAX + 1];
        su_md5_t md5[1];
        uint8_t hmac[6];

        gethostname(hostname, sizeof hostname);

        auth_md5_hmac_init(am, md5);

        su_md5_strupdate(md5, hostname);
        su_md5_update(md5, ":", 1);
        if (am->am_remote)
            url_update(md5, am->am_remote);

        auth_md5_hmac_digest(am, md5, hmac, sizeof hmac);

        base64_e(hostname, sizeof hostname, hmac, sizeof hmac);

        am->am_opaque = su_strdup(am->am_home, hostname);

        if (!am->am_opaque) {
            retval = -1;
            SU_DEBUG_1(("%s: cannot create unique identifier\n", __func__));
        }
    }

    if (retval < 0)
        ;
    else if (db) {
        retval = auth_readdb(am);
        if (retval == -1) {
            int err = errno;
            SU_DEBUG_1(("auth-module: %s: %s\n", am->am_db, strerror(err)));
            errno = err;
        }
    }
    else {
        retval = auth_htable_resize(am->am_home, am->am_users, 0);
    }

    ta_end(ta);

    return retval;
}
Example #5
0
static int nua_notify_client_init_etag(nua_client_request_t *cr,
				       msg_t *msg, sip_t *sip,
				       tagi_t const *tags)
{
#if SU_HAVE_EXPERIMENTAL
  nua_handle_t *nh = cr->cr_owner;
  struct notifier_usage *nu = nua_dialog_usage_private(cr->cr_usage);
  nua_server_request_t *sr;

  if (nu->nu_tag)
    su_free(nh->nh_home, nu->nu_tag), nu->nu_tag = NULL;
    nu->nu_no_body = 0;

  if (sip->sip_etag) {
    nu->nu_appl_etags = 1;
    nu->nu_tag = su_strdup(nh->nh_home, sip->sip_etag->g_string);
  }
  else if (!nu->nu_appl_etags && nu->nu_etags) {
    su_md5_t md5[1];
    unsigned char digest[SU_MD5_DIGEST_SIZE];
    sip_payload_t pl[1] = { SIP_PAYLOAD_INIT() };
    char token[2 * 16];

    su_md5_init(md5);

    if (sip->sip_payload) *pl = *sip->sip_payload;

    if (pl->pl_len)
      su_md5_update(md5, pl->pl_data, pl->pl_len);
    su_md5_update(md5, &pl->pl_len, sizeof(pl->pl_len));

    if (sip->sip_content_type)
      su_md5_striupdate(md5, sip->sip_content_type->c_type);

    su_md5_digest(md5, digest);
    token64_e(token, sizeof token, digest, sizeof digest);
    token[(sizeof token) - 1] = '\0';
    nu->nu_tag = su_strdup(nh->nh_home, token);
  }

  if (!nu->nu_requested || !nu->nu_tag)
    return 0;

  /* Check if SUBSCRIBE had matching suppression */
  for (sr = nh->nh_ds->ds_sr; sr; sr = sr->sr_next)
    if (sr->sr_usage == cr->cr_usage && sr->sr_method == sip_method_subscribe)
      break;

  if (sr) {
    sip_t const *sip = sr->sr_request.sip;

    sip_suppress_body_if_match_t *sbim;
    sip_suppress_notify_if_match_t *snim;

    if (cr->cr_usage->du_ready) {
      snim = sip_suppress_notify_if_match(sip);

      if (snim && su_casematch(snim->snim_tag, nu->nu_tag)) {
	if (nu->nu_requested > nu->nu_expires)
	  nu->nu_expires = nu->nu_requested;
	nu->nu_requested = 0;
	return nua_client_return(cr, 202, "NOTIFY Suppressed", msg);
      }
    }

    sbim = sip_suppress_body_if_match(sip);
    if (sbim && su_casematch(sbim->sbim_tag, nu->nu_tag))
      nu->nu_no_body = 1;
  }
#endif

  return 0;
}