summaryrefslogtreecommitdiff
path: root/channels
diff options
context:
space:
mode:
authorKevin P. Fleming <kpfleming@digium.com>2005-06-17 13:29:04 +0000
committerKevin P. Fleming <kpfleming@digium.com>2005-06-17 13:29:04 +0000
commit81d1a11ed63751550b085f204b37ca8516339680 (patch)
treedc42d86fb4f1ece6e1e2fed22be7cda4bf333434 /channels
parent9a80a7bc2ce5c68997feca8101a421a596d1cc18 (diff)
clean up and optimize reply_digest (bug #4447)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@5925 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels')
-rwxr-xr-xchannels/chan_sip.c113
1 files changed, 38 insertions, 75 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 6e024a267..b47ec0981 100755
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -7740,95 +7740,58 @@ static int do_proxy_auth(struct sip_pvt *p, struct sip_request *req, char *heade
/*--- reply_digest: reply to authentication for outbound registrations ---*/
/* This is used for register= servers in sip.conf, SIP proxies we register
with for receiving calls from. */
-static int reply_digest(struct sip_pvt *p, struct sip_request *req, char *header, int sipmethod, char *digest, int digest_len) {
-
+static int reply_digest(struct sip_pvt *p, struct sip_request *req,
+ char *header, int sipmethod, char *digest, int digest_len)
+{
char tmp[512] = "";
- char *realm = "";
- char *nonce = "";
- char *domain = "";
- char *opaque = "";
- char *qop = "";
char *c;
-
- ast_copy_string(tmp, get_header(req, header),sizeof(tmp));
+ /* table of recognised keywords, and places where they should be copied */
+ const struct x {
+ const char *key;
+ char *dst;
+ int dstlen;
+ } *i, keys[] = {
+ { "realm=", p->realm, sizeof(p->realm) },
+ { "nonce=", p->nonce, sizeof(p->nonce) },
+ { "opaque=", p->opaque, sizeof(p->opaque) },
+ { "qop=", p->qop, sizeof(p->qop) },
+ { "domain=", p->domain, sizeof(p->domain) },
+ { NULL, NULL, 0 },
+ };
+
+ ast_copy_string(tmp, get_header(req, header), sizeof(tmp));
if (ast_strlen_zero(tmp))
return -1;
- c = tmp;
- c+=strlen("Digest ");
- while (c) {
- while (*c && (*c < 33)) c++;
- if (!*c)
- break;
- if (!strncasecmp(c,"realm=", strlen("realm="))) {
- c+=strlen("realm=");
- if ((*c == '\"')) {
- realm=++c;
- if ((c = strchr(c,'\"')))
- *c = '\0';
- } else {
- realm = c;
- if ((c = strchr(c,',')))
- *c = '\0';
- }
- } else if (!strncasecmp(c, "nonce=", strlen("nonce="))) {
- c+=strlen("nonce=");
- if ((*c == '\"')) {
- nonce=++c;
- if ((c = strchr(c,'\"')))
- *c = '\0';
- } else {
- nonce = c;
- if ((c = strchr(c,',')))
- *c = '\0';
- }
- } else if (!strncasecmp(c, "opaque=", strlen("opaque="))) {
- c+=strlen("opaque=");
- if ((*c == '\"')) {
- opaque=++c;
- if ((c = strchr(c,'\"')))
- *c = '\0';
- } else {
- opaque = c;
- if ((c = strchr(c,',')))
- *c = '\0';
- }
- } else if (!strncasecmp(c, "qop=", strlen("qop="))) {
- c+=strlen("qop=");
- if ((*c == '\"')) {
- qop=++c;
- if ((c = strchr(c,'\"')))
- *c = '\0';
- } else {
- qop = c;
- if ((c = strchr(c,',')))
- *c = '\0';
- }
- } else if (!strncasecmp(c, "domain=", strlen("domain="))) {
- c+=strlen("domain=");
+ if (strstr(tmp, "Digest ") != tmp) {
+ ast_log(LOG_WARNING, "missing Digest.\n");
+ return -1;
+ }
+ c = tmp + strlen("Digest ");
+ for (i = keys; i->key != NULL; i++)
+ i->dst[0] = '\0'; /* init all to empty strings */
+ for (; c && *(c = ast_skip_blanks(c)) ; c++) { /* lookup for keys */
+ for (i = keys; i->key != NULL; i++) {
+ char *src;
+ if (strncasecmp(c, i->key, strlen(i->key)) != 0)
+ continue;
+ /* Found. Skip keyword, take text in quotes or up to the separator. */
+ c += strlen(i->key);
if ((*c == '\"')) {
- domain=++c;
+ src = ++c;
if ((c = strchr(c,'\"')))
*c = '\0';
} else {
- domain = c;
+ src = c;
if ((c = strchr(c,',')))
*c = '\0';
}
- } else
+ ast_copy_string(i->dst, src, i->dstlen);
+ break;
+ }
+ if (i->key == NULL)
c = strchr(c,',');
- if (c)
- c++;
}
- if (strlen(tmp) >= sizeof(tmp))
- ast_log(LOG_WARNING, "Buffer overflow detected! Please file a bug.\n");
-
- /* copy realm and nonce for later authorization of CANCELs and BYEs */
- ast_copy_string(p->realm, realm, sizeof(p->realm));
- ast_copy_string(p->nonce, nonce, sizeof(p->nonce));
- ast_copy_string(p->domain, domain, sizeof(p->domain));
- ast_copy_string(p->opaque, opaque, sizeof(p->opaque));
- ast_copy_string(p->qop, qop, sizeof(p->qop));
/* Save auth data for following registrations */
if (p->registry) {