diff --git a/apps/Makefile b/apps/Makefile index a8a4e3b627..7b527d343b 100755 --- a/apps/Makefile +++ b/apps/Makefile @@ -30,7 +30,8 @@ APPS=app_dial.so app_playback.so app_voicemail.so app_directory.so app_mp3.so\ app_groupcount.so app_txtcidname.so app_controlplayback.so \ app_talkdetect.so app_alarmreceiver.so app_userevent.so app_verbose.so \ app_test.so app_forkcdr.so app_math.so app_realtime.so \ - app_dumpchan.so app_waitforsilence.so app_while.so app_setrdnis.so + app_dumpchan.so app_waitforsilence.so app_while.so app_setrdnis.so \ + app_md5.so ifneq (${OSARCH},Darwin) ifneq (${OSARCH},SunOS) diff --git a/apps/app_md5.c b/apps/app_md5.c new file mode 100755 index 0000000000..1be840aed2 --- /dev/null +++ b/apps/app_md5.c @@ -0,0 +1,86 @@ +/* + * Asterisk -- A telephony toolkit for Linux. + * + * MD5 checksum application + * + * Copyright (C) 2005, Olle E. Johansson, Edvina.net + * + * This program is free software, distributed under the terms of + * the GNU General Public License + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static char *tdesc = "MD5 checksum application"; +static char *app_md5 = "md5"; +static char *synopsis = +" md5(=): Calculates a MD5 checksum on .\n" +"Returns hash value in a channel variable. Always return 0\n"; + +STANDARD_LOCAL_USER; + +LOCAL_USER_DECL; + +static int md5_exec(struct ast_channel *chan, void *data) +{ + int res=0; + struct localuser *u; + char *varname= NULL; /* Variable to set */ + char *string = NULL; /* String to calculate on */ + char retvar[50]; /* Return value */ + + if (!data) { + ast_log(LOG_WARNING, "Syntax: md5(=) - missing argument!\n"); + return -1; + } + LOCAL_USER_ADD(u); + memset(retvar,0, sizeof(retvar)); + string = ast_strdupa(data); + varname = strsep(&string,"="); + if (ast_strlen_zero(varname)) { + ast_log(LOG_WARNING, "Syntax: md5(=) - missing argument!\n"); + LOCAL_USER_REMOVE(u); + return -1; + } + ast_md5_hash(retvar, string); + pbx_builtin_setvar_helper(chan, varname, retvar); + LOCAL_USER_REMOVE(u); + return res; +} + +int unload_module(void) +{ + STANDARD_HANGUP_LOCALUSERS; + return ast_unregister_application(app_md5); +} + +int load_module(void) +{ + return ast_register_application(app_md5, md5_exec, synopsis, tdesc); +} + +char *description(void) +{ + return tdesc; +} + +int usecount(void) +{ + int res; + STANDARD_USECOUNT(res); + return res; +} + +char *key() +{ + return ASTERISK_GPL_KEY; +} diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 5e21641e61..9a8ad83c99 100755 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -4966,21 +4965,6 @@ static void build_route(struct sip_pvt *p, struct sip_request *req, int backward list_route(p->route); } -/*--- md5_hash: Produce MD5 hash of value. Used for authentication ---*/ -static void md5_hash(char *output, char *input) -{ - struct MD5Context md5; - unsigned char digest[16]; - char *ptr; - int x; - MD5Init(&md5); - MD5Update(&md5, input, strlen(input)); - MD5Final(digest, &md5); - ptr = output; - for (x=0;x<16;x++) - ptr += sprintf(ptr, "%2.2x", digest[x]); -} - /*--- check_auth: Check user authorization from peer definition ---*/ /* Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set) */ @@ -5114,10 +5098,10 @@ static int check_auth(struct sip_pvt *p, struct sip_request *req, char *randdata if (!ast_strlen_zero(md5secret)) snprintf(a1_hash, sizeof(a1_hash), "%s", md5secret); else - md5_hash(a1_hash, a1); - md5_hash(a2_hash, a2); + ast_md5_hash(a1_hash, a1); + ast_md5_hash(a2_hash, a2); snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, randdata, a2_hash); - md5_hash(resp_hash, resp); + ast_md5_hash(resp_hash, resp); /* resp_hash now has the expected response, compare the two */ @@ -7107,15 +7091,15 @@ static int build_reply_digest(struct sip_pvt *p, char* orig_header, char* digest if (!ast_strlen_zero(p->peermd5secret)) strncpy(a1_hash, p->peermd5secret, sizeof(a1_hash) - 1); else - md5_hash(a1_hash,a1); - md5_hash(a2_hash,a2); + ast_md5_hash(a1_hash,a1); + ast_md5_hash(a2_hash,a2); /* XXX We hard code the nonce-number to 1... What are the odds? Are we seriously going to keep track of every nonce we've seen? Also we hard code to "auth"... XXX */ if (!ast_strlen_zero(p->qop)) snprintf(resp,sizeof(resp),"%s:%s:%s:%s:%s:%s",a1_hash,p->nonce, "00000001", cnonce, "auth", a2_hash); else snprintf(resp,sizeof(resp),"%s:%s:%s",a1_hash,p->nonce,a2_hash); - md5_hash(resp_hash,resp); + ast_md5_hash(resp_hash,resp); /* XXX We hard code our qop to "auth" for now. XXX */ if (!ast_strlen_zero(p->qop)) snprintf(digest,digest_len,"Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\", opaque=\"%s\", qop=\"%s\", cnonce=\"%s\", nc=%s",p->authname,p->realm,uri,p->nonce,resp_hash, p->opaque, "auth", cnonce, "00000001"); diff --git a/include/asterisk/utils.h b/include/asterisk/utils.h index c9b9717353..6e3a7d5db9 100755 --- a/include/asterisk/utils.h +++ b/include/asterisk/utils.h @@ -127,10 +127,13 @@ struct ast_hostent { extern char *ast_strip(char *buf); extern struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp); +/* ast_md5_hash: Produces MD5 hash based on input string */ +extern void ast_md5_hash(char *output, char *input); extern int ast_base64encode(char *dst, unsigned char *src, int srclen, int max); extern int ast_base64decode(unsigned char *dst, char *src, int max); extern int test_for_thread_safety(void); + extern const char *ast_inet_ntoa(char *buf, int bufsiz, struct in_addr ia); extern int ast_utils_init(void); diff --git a/utils.c b/utils.c index 685a66aa10..0d7a8781c3 100755 --- a/utils.c +++ b/utils.c @@ -25,6 +25,7 @@ #include #include #include +#include static char base64[64]; static char b2a[256]; @@ -245,6 +246,21 @@ int test_for_thread_safety(void) return(test_errors); /* return 0 on success. */ } +/*--- ast_md5_hash: Produce 16 char MD5 hash of value. ---*/ +void ast_md5_hash(char *output, char *input) +{ + struct MD5Context md5; + unsigned char digest[16]; + char *ptr; + int x; + MD5Init(&md5); + MD5Update(&md5, input, strlen(input)); + MD5Final(digest, &md5); + ptr = output; + for (x=0;x<16;x++) + ptr += sprintf(ptr, "%2.2x", digest[x]); +} + int ast_base64decode(unsigned char *dst, char *src, int max) { int cnt = 0;