8000 refer out of dialog by cspiel1 · Pull Request #508 · baresip/re · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

refer out of dialog #508

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments. 8000
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions include/re_sip.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,13 +250,21 @@ struct sip_conncfg {
uint16_t srcport;
};

/** SIP UAS Authentication */
struct sip_uas_auth {
const char *realm;
char *nonce;
bool stale;
};

struct sip;
struct sip_lsnr;
struct sip_request;
struct sip_strans;
struct sip_auth;
struct sip_dialog;
struct sip_keepalive;
struct sip_uas_auth;
struct dnsc;

typedef bool(sip_msg_h)(const struct sip_msg *msg, void *arg);
Expand All @@ -276,6 +284,8 @@ typedef void(sip_keepalive_h)(int err, void *arg);
typedef void(sip_trace_h)(bool tx, enum sip_transp tp,
const struct sa *src, const struct sa *dst,
const uint8_t *pkt, size_t len, void *arg);
typedef int (sip_uas_auth_h)(uint8_t *ha1, const struct pl *user,
const char *realm, void *arg);


/* sip */
Expand Down Expand Up @@ -424,3 +434,12 @@ int sip_keepalive_start(struct sip_keepalive **kap, struct sip *sip,
/* sip_conncfg */
int sip_conncfg_set(struct sip *sip, const struct sa *paddr,
const struct sip_conncfg conncfg);


/* sip_uas_auth */
int sip_uas_auth_gen(struct sip_uas_auth **authp, const struct sip_msg *msg,
const char *realm);
int sip_uas_auth_print(struct re_printf *pf,
const struct sip_uas_auth *auth);
int sip_uas_auth_check(struct sip_uas_auth *auth, const struct sip_msg *msg,
sip_uas_auth_h *authh, void *arg);
148 changes: 148 additions & 0 deletions src/sip/auth.c
< 10000 tr class="js-expandable-line js-skip-tagsearch" data-position="8">
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*
* Copyright (C) 2010 Creytiv.com
*/
#include <time.h>
#include <string.h>
#include <re_types.h>
#include <re_mem.h>
Expand All @@ -19,6 +20,10 @@
#include <re_sip.h>
#include "sip.h"

enum {
NONCE_EXPIRES = 300,
NONCE_MIN_SIZE = 33,
};

struct sip_auth {
struct list realml;
Expand Down Expand Up @@ -324,3 +329,146 @@ void sip_auth_reset(struct sip_auth *auth)

list_flush(&auth->realml);
}


static int gen_nonce(char **noncep, time_t ts, const struct sa *src,
const char *realm)
{
uint8_t key[MD5_SIZE];
struct mbuf *mb;
int err;

mb = mbuf_alloc(40);
if (!mb)
return ENOMEM;

err = mbuf_printf(mb,"%lu%j%s", ts, src, realm);
if (err)
goto out;

md5(mb->buf, mb->end, key);
mbuf_rewind(mb);
err = mbuf_printf(mb,"%w%016lx", key, sizeof(key), ts);
if (err)
goto out;

mbuf_set_pos(mb, 0);
err = mbuf_strdup(mb, noncep, mbuf_get_left(mb));

out:
mem_deref(mb);
return err;
}


static int check_nonce(const struct pl *nonce, const struct sa *src,
const char *realm)
{
struct pl pl;
time_t ts;
char *comp = NULL;
bool eq;
int err;

if (!nonce || !nonce->p || nonce->l < NONCE_MIN_SIZE)
return EINVAL;

pl = *nonce;
pl.p = pl.p + (pl.l - 16);
pl.l = 16;
ts = (time_t) pl_x64(&pl);

if (time(NULL) - ts > NONCE_EXPIRES)
return ETIME;

err = gen_nonce(&comp, ts, src, realm);
if (err)
return err;

eq = !pl_strcmp(nonce, comp);
mem_deref(comp);
return eq ? 0 : EAUTH;
}


int sip_uas_auth_print(struct re_printf *pf,
const struct sip_uas_auth *auth)
{
return re_hprintf(pf, "WWW-Authenticate: "
"Digest realm=\"%s\", nonce=\"%s\", "
"algorithm=MD5, "
"qop=\"auth\"%s"
"\r\n",
auth->realm, auth->nonce,
auth->stale ? ", stale=true" : "");
}


static void sip_uas_destructor(void *arg)
{
struct sip_uas_auth *auth = arg;

mem_deref(auth->nonce);
}


int sip_uas_auth_gen(struct sip_uas_auth **authp, const struct sip_msg *msg,
const char *realm)
{
struct sip_uas_auth *auth;
int err;

if (!authp || !msg)
return EINVAL;

auth = mem_zalloc(sizeof(*auth), sip_uas_destructor);
auth->realm = realm;
err = gen_nonce(&auth->nonce, time(NULL), &msg->src, realm);

if (err)
mem_deref(auth);
else
*authp = auth;

return err;
}


int sip_uas_auth_check(struct sip_uas_auth *auth, const struct sip_msg *msg,
sip_uas_auth_h *authh, void *arg)
{
struct httpauth_digest_resp resp;
const struct sip_hdr *hdr;
uint8_t ha1[MD5_SIZE];
int err;

if (!msg || !auth || !authh)
return EINVAL;

hdr = sip_msg_hdr_apply(msg, true, SIP_HDR_AUTHORIZATION, NULL, NULL);
if (!hdr)
return EAUTH;

if (httpauth_digest_response_decode(&resp, &hdr->val))
return EINVAL;

if (pl_strcasecmp(&resp.realm, auth->realm))
return EINVAL;

err = check_nonce(&resp.nonce, &msg->src, auth->realm);
if (err == ETIME || err == EAUTH) {
auth->stale = true;
return EAUTH;
}
else if (err) {
return err;
}

if (authh(ha1, &resp.username, auth->realm, arg))
return EINVAL;

if (httpauth_digest_response_auth(&resp, &msg->met, ha1))
return EACCES;

return 0;
}
0