Skip to content

Commit

Permalink
Merge branch 'main' into coverity
Browse files Browse the repository at this point in the history
  • Loading branch information
sreimers committed Apr 23, 2024
2 parents 6ed5272 + 0e13821 commit 1d69e1c
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 53 deletions.
1 change: 1 addition & 0 deletions include/re_sip.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ typedef int(sip_auth_h)(char **username, char **password, const char *realm,
typedef bool(sip_hdr_h)(const struct sip_hdr *hdr, const struct sip_msg *msg,
void *arg);
typedef void(sip_keepalive_h)(int err, void *arg);
typedef int(digest_printf_h)(uint8_t *md, const char *fmt, ...);

#define LIBRE_HAVE_SIPTRACE 1
typedef void(sip_trace_h)(bool tx, enum sip_transp tp,
Expand Down
106 changes: 78 additions & 28 deletions src/sip/auth.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,17 @@
#include <re_sa.h>
#include <re_sys.h>
#include <re_md5.h>
#include <re_sha.h>
#include <re_httpauth.h>
#include <re_udp.h>
#include <re_msg.h>
#include <re_sip.h>
#include "sip.h"

#define DEBUG_MODULE "sip_auth"
#define DEBUG_LEVEL 5
#include <re_dbg.h>

enum {
NONCE_EXPIRES = 300,
NONCE_MIN_SIZE = 33,
Expand All @@ -42,6 +47,7 @@ struct realm {
char *opaque;
char *user;
char *pass;
char *algorithm;
uint32_t nc;
enum sip_hdrid hdr;
};
Expand Down Expand Up @@ -69,6 +75,7 @@ static void realm_destructor(void *arg)
mem_deref(realm->opaque);
mem_deref(realm->user);
mem_deref(realm->pass);
mem_deref(realm->algorithm);
}


Expand All @@ -83,33 +90,66 @@ static void auth_destructor(void *arg)
}


static int mkdigest(uint8_t *digest, const struct realm *realm,
static int mkdigest(struct mbuf **digestp, const struct realm *realm,
const char *met, const char *uri, uint64_t cnonce)
{
uint8_t ha1[MD5_SIZE], ha2[MD5_SIZE];
struct mbuf *digest;
uint8_t *ha1 = NULL, *ha2 = NULL;
digest_printf_h *digest_printf;
int err;

err = md5_printf(ha1, "%s:%s:%s",
realm->user, realm->realm, realm->pass);
bool use_sha256 = str_casecmp(realm->algorithm, "sha-256") == 0;
size_t h_size = use_sha256 ? SHA256_DIGEST_SIZE : MD5_SIZE;

digest = mbuf_alloc(h_size);
if (!digest)
return ENOMEM;

mbuf_set_end(digest, h_size);

ha1 = mem_zalloc(h_size, NULL);
if (!ha1) {
err = ENOMEM;
goto out;
}

ha2 = mem_zalloc(h_size, NULL);
if (!ha2) {
err = ENOMEM;
goto out;
}

if (use_sha256)
digest_printf = &sha256_printf;
else
digest_printf = &md5_printf;

err = digest_printf(ha1, "%s:%s:%s", realm->user, realm->realm,
realm->pass);
if (err)
return err;
goto out;

err = md5_printf(ha2, "%s:%s", met, uri);
err = digest_printf(ha2, "%s:%s", met, uri);
if (err)
return err;
goto out;

if (realm->qop)
return md5_printf(digest, "%w:%s:%08x:%016llx:auth:%w",
ha1, sizeof(ha1),
realm->nonce,
realm->nc,
cnonce,
ha2, sizeof(ha2));
err = digest_printf(
mbuf_buf(digest), "%w:%s:%08x:%016llx:auth:%w", ha1,
h_size, realm->nonce, realm->nc, cnonce, ha2, h_size);
else
err = digest_printf(mbuf_buf(digest), "%w:%s:%w", ha1, h_size,
realm->nonce, ha2, h_size);
out:
mem_deref(ha1);
mem_deref(ha2);

if (err)
mem_deref(digest);
else
return md5_printf(digest, "%w:%s:%w",
ha1, sizeof(ha1),
realm->nonce,
ha2, sizeof(ha2));
*digestp = digest;

return err;
}


Expand All @@ -131,7 +171,7 @@ static bool auth_handler(const struct sip_hdr *hdr, const struct sip_msg *msg,
{
struct httpauth_digest_chall ch;
struct sip_auth *auth = arg;
struct realm *realm = NULL;
struct realm *realm = NULL;
int err;
(void)msg;

Expand All @@ -140,7 +180,11 @@ static bool auth_handler(const struct sip_hdr *hdr, const struct sip_msg *msg,
goto out;
}

if (pl_isset(&ch.algorithm) && pl_strcasecmp(&ch.algorithm, "md5")) {
if (!pl_isset(&ch.algorithm))
pl_set_str(&ch.algorithm, "MD5");

if (pl_strcasecmp(&ch.algorithm, "md5") &&
pl_strcasecmp(&ch.algorithm, "sha-256")) {
err = ENOSYS;
goto out;
}
Expand All @@ -160,6 +204,10 @@ static bool auth_handler(const struct sip_hdr *hdr, const struct sip_msg *msg,
if (err)
goto out;

err = pl_strdup(&realm->algorithm, &ch.algorithm);
if (err)
goto out;

err = auth->authh(&realm->user, &realm->pass,
realm->realm, auth->arg);
if (err)
Expand All @@ -171,9 +219,10 @@ static bool auth_handler(const struct sip_hdr *hdr, const struct sip_msg *msg,
goto out;
}

realm->nonce = mem_deref(realm->nonce);
realm->qop = mem_deref(realm->qop);
realm->opaque = mem_deref(realm->opaque);
realm->nonce = mem_deref(realm->nonce);
realm->qop = mem_deref(realm->qop);
realm->opaque = mem_deref(realm->opaque);
realm->algorithm = mem_deref(realm->algorithm);
}

realm->hdr = hdr->id;
Expand All @@ -187,7 +236,7 @@ static bool auth_handler(const struct sip_hdr *hdr, const struct sip_msg *msg,
if (pl_isset(&ch.opaque))
err |= pl_strdup(&realm->opaque, &ch.opaque);

out:
out:
if (err) {
mem_deref(realm);
auth->err = err;
Expand Down Expand Up @@ -236,9 +285,9 @@ int sip_auth_encode(struct mbuf *mb, struct sip_auth *auth, const char *met,

const uint64_t cnonce = rand_u64();
struct realm *realm = le->data;
uint8_t digest[MD5_SIZE];
struct mbuf *digest = NULL;

err = mkdigest(digest, realm, met, uri, cnonce);
err = mkdigest(&digest, realm, met, uri, cnonce);
if (err)
break;

Expand All @@ -260,8 +309,9 @@ int sip_auth_encode(struct mbuf *mb, struct sip_auth *auth, const char *met,
err |= mbuf_printf(mb, ", realm=\"%s\"", realm->realm);
err |= mbuf_printf(mb, ", nonce=\"%s\"", realm->nonce);
err |= mbuf_printf(mb, ", uri=\"%s\"", uri);
err |= mbuf_printf(mb, ", response=\"%w\"",
digest, sizeof(digest));
err |= mbuf_printf(mb, ", response=\"%w\"", digest->buf,
digest->end);
digest = mem_deref(digest);

if (realm->opaque)
err |= mbuf_printf(mb, ", opaque=\"%s\"",
Expand All @@ -275,7 +325,7 @@ int sip_auth_encode(struct mbuf *mb, struct sip_auth *auth, const char *met,

++realm->nc;

err |= mbuf_write_str(mb, ", algorithm=MD5");
err |= mbuf_printf(mb, ", algorithm=%s", realm->algorithm);
err |= mbuf_write_str(mb, "\r\n");
if (err)
break;
Expand Down
102 changes: 77 additions & 25 deletions test/sipauth.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,57 @@
#include <re_dbg.h>


static const char *testv[] = {
/* without algorithm - default MD5 */
"SIP/2.0 401 Unauthorized\r\n"
"Via: SIP/2.0/TLS "
"10.0.0.1:37589;branch=z9hG4bK5625ce6f310a0fc8;rport=13718;"
"received=10.0.0.2\r\n"
"WWW-Authenticate: Digest realm=\"example.net\", "
"nonce=\"YZlVk2GZVGegVBZVKaMHpnxmUA+QyoSl\"\r\n"
"Content-Length: 0\r\n\r\n",

/* explicit MD5 */
"SIP/2.0 401 Unauthorized\r\n"
"Via: SIP/2.0/TLS "
"10.0.0.1:37589;branch=z9hG4bK5625ce6f310a0fc8;rport=13718;"
"received=10.0.0.2\r\n"
"WWW-Authenticate: Digest realm=\"example.net\", "
"algorithm=\"MD5\", "
"nonce=\"YZlVk2GZVGegVBZVKaMHpnxmUA+QyoSl\"\r\n"
"Content-Length: 0\r\n\r\n",

/* explicit SHA-256 */
"SIP/2.0 401 Unauthorized\r\n"
"Via: SIP/2.0/TLS "
"10.0.0.1:37589;branch=z9hG4bK5625ce6f310a0fc8;rport=13718;"
"received=10.0.0.2\r\n"
"WWW-Authenticate: Digest realm=\"example.net\", "
"algorithm=\"SHA-256\", "
"nonce=\"YZlVk2GZVGegVBZVKaMHpnxmUA+QyoSl\"\r\n"
"Content-Length: 0\r\n\r\n",

/* explicit SHA-256 qop */
"SIP/2.0 401 Unauthorized\r\n"
"Via: SIP/2.0/TLS "
"10.0.0.1:37589;branch=z9hG4bK5625ce6f310a0fc8;rport=13718;"
"received=10.0.0.2\r\n"
"WWW-Authenticate: Digest realm=\"example.net\", "
"algorithm=\"SHA-256\", "
"qop=\"auth\", "
"nonce=\"YZlVk2GZVGegVBZVKaMHpnxmUA+QyoS\"\r\n"
"Content-Length: 0\r\n\r\n"
};


static const char *testr[] = {
"algorithm=MD5",
"algorithm=MD5",
"algorithm=SHA-256",
"algorithm=SHA-256"
};


static int auth_handler(char **user, char **pass, const char *rlm, void *arg)
{
(void)user;
Expand All @@ -30,14 +81,6 @@ static int test_sip_auth_encode(void)
struct sip_msg *msg = NULL;
const char met[] = "REGISTER";
const char uri[] = "<sip:user@host:5060;transport=udp>";
const char str_raw[] =
"SIP/2.0 401 Unauthorized\r\n"
"Via: SIP/2.0/TLS "
"10.0.0.1:37589;branch=z9hG4bK5625ce6f310a0fc8;rport=13718;"
"received=10.0.0.2\r\n"
"WWW-Authenticate: Digest realm=\"example.net\", "
"nonce=\"YZlVk2GZVGegVBZVKaMHpnxmUA+QyoSl\"\r\n"
"Content-Length: 0\r\n\r\n";

mb = mbuf_alloc(2048);
if (!mb)
Expand All @@ -49,36 +92,45 @@ static int test_sip_auth_encode(void)
return ENOMEM;
}

err = sip_auth_alloc(&auth, auth_handler, NULL, false);
TEST_ERR(err);
for (size_t i = 0; i < RE_ARRAY_SIZE(testv); i++) {
mbuf_rewind(mb);
mbuf_rewind(mb_enc);

err = mbuf_write_str(mb, str_raw);
TEST_ERR(err);
err = sip_auth_alloc(&auth, auth_handler, NULL, false);
TEST_ERR(err);

mbuf_set_pos(mb, 0);
err = mbuf_write_str(mb, testv[i]);
TEST_ERR(err);

err = sip_msg_decode(&msg, mb);
TEST_ERR(err);
mbuf_set_pos(mb, 0);

err = sip_auth_authenticate(auth, msg);
TEST_ERR(err);
err = sip_msg_decode(&msg, mb);
TEST_ERR(err);

err = sip_auth_encode(mb_enc, auth, met, uri);
TEST_ERR(err);
err = sip_auth_authenticate(auth, msg);
TEST_ERR(err);

mbuf_set_pos(mb_enc, 0);
mbuf_read_str(mb_enc, buf, mbuf_get_left(mb_enc));
err = sip_auth_encode(mb_enc, auth, met, uri);
TEST_ERR(err);

err = re_regex(buf, str_len(buf), "algorithm=MD5");
TEST_ERR(err);
mbuf_set_pos(mb_enc, 0);
mbuf_read_str(mb_enc, buf, mbuf_get_left(mb_enc));

err = re_regex(buf, str_len(buf), testr[i]);
TEST_ERR(err);

mem_deref(msg);
mem_deref(auth);
}

out:
mem_deref(mb);
mem_deref(mb_enc);
if (msg)
if (err) {
mem_deref(msg);
if (auth)
mem_deref(auth);
}

return err;
}

Expand Down

0 comments on commit 1d69e1c

Please sign in to comment.