From 9c6c6317eacd9af245a8e0e403cbe71bc94eed82 Mon Sep 17 00:00:00 2001 From: nils-ohlmeier Date: Wed, 22 Mar 2006 00:27:05 +0000 Subject: [PATCH] added option -J to take ha1 instead of password git-svn-id: http://svn.berlios.de/svnroot/repos/sipsak/trunk@402 75b5f7c7-cfd4-0310-b54c-e118b2c5249a (cherry picked from commit 98a908b18b003e0a0a1e231be709421961f531aa) (cherry picked from commit 63aa353b37d960cf2dd09251106f937ddc659763) --- auth.c | 42 ++++++++++++++++++++++++++---------------- shoot.c | 4 ++-- sipsak.1 | 14 ++++++++++++++ sipsak.c | 20 +++++++++++++++----- sipsak.h | 2 +- 5 files changed, 58 insertions(+), 24 deletions(-) diff --git a/auth.c b/auth.c index bd5b24c..c1c2cd0 100644 --- a/auth.c +++ b/auth.c @@ -264,14 +264,19 @@ void insert_auth(char *message, char *authreq) password = EMPTY_STR; if (algo == SIPSAK_ALGO_MD5) { - MD5Init(&Md5Ctx); - MD5Update(&Md5Ctx, usern, (unsigned int)strlen(usern)); - MD5Update(&Md5Ctx, ":", 1); - MD5Update(&Md5Ctx, realm, (unsigned int)strlen(realm)); - MD5Update(&Md5Ctx, ":", 1); - MD5Update(&Md5Ctx, password, (unsigned int)strlen(password)); - MD5Final(&ha1[0], &Md5Ctx); - cvt_hex(&ha1[0], &ha1_hex[0], SIPSAK_HASHLEN_MD5); + if (authhash) { + strncpy(ha1_hex, authhash, SIPSAK_HASHHEXLEN_MD5); + } + else { + MD5Init(&Md5Ctx); + MD5Update(&Md5Ctx, usern, (unsigned int)strlen(usern)); + MD5Update(&Md5Ctx, ":", 1); + MD5Update(&Md5Ctx, realm, (unsigned int)strlen(realm)); + MD5Update(&Md5Ctx, ":", 1); + MD5Update(&Md5Ctx, password, (unsigned int)strlen(password)); + MD5Final(&ha1[0], &Md5Ctx); + cvt_hex(&ha1[0], &ha1_hex[0], SIPSAK_HASHLEN_MD5); + } MD5Init(&Md5Ctx); MD5Update(&Md5Ctx, method, (unsigned int)strlen(method)); @@ -294,14 +299,19 @@ void insert_auth(char *message, char *authreq) } #ifdef HAVE_OPENSSL_SHA1 else if (algo == SIPSAK_ALGO_SHA1) { - SHA1_Init(&Sha1Ctx); - SHA1_Update(&Sha1Ctx, usern, (unsigned int)strlen(usern)); - SHA1_Update(&Sha1Ctx, ":", 1); - SHA1_Update(&Sha1Ctx, realm, (unsigned int)strlen(realm)); - SHA1_Update(&Sha1Ctx, ":", 1); - SHA1_Update(&Sha1Ctx, password, (unsigned int)strlen(password)); - SHA1_Final(&ha1[0], &Sha1Ctx); - cvt_hex(&ha1[0], &ha1_hex[0], SIPSAK_HASHLEN_SHA1); + if (authhash) { + strncopy(ha1_hex, authhash, SIPSAK_HASHHEXLEN_SHA1); + } + else { + SHA1_Init(&Sha1Ctx); + SHA1_Update(&Sha1Ctx, usern, (unsigned int)strlen(usern)); + SHA1_Update(&Sha1Ctx, ":", 1); + SHA1_Update(&Sha1Ctx, realm, (unsigned int)strlen(realm)); + SHA1_Update(&Sha1Ctx, ":", 1); + SHA1_Update(&Sha1Ctx, password, (unsigned int)strlen(password)); + SHA1_Final(&ha1[0], &Sha1Ctx); + cvt_hex(&ha1[0], &ha1_hex[0], SIPSAK_HASHLEN_SHA1); + } SHA1_Init(&Sha1Ctx); SHA1_Update(&Sha1Ctx, method, (unsigned int)strlen(method)); diff --git a/shoot.c b/shoot.c index 055121c..a6a207a 100644 --- a/shoot.c +++ b/shoot.c @@ -993,7 +993,7 @@ void shoot(char *buf, int buff_size) continue; } else if (regexec(&(regexps.authexp), rec, 0, 0, 0) == REG_NOERROR) { - if (!username) { + if (!username && !auth_username) { if (timing > 0) { timing--; if (timing == 0) { @@ -1006,7 +1006,7 @@ void shoot(char *buf, int buff_size) continue; } fprintf(stderr, "%s\nerror: received 40[17] but cannot " - "authentication without a username\n", rec); + "authentication without a username or auth username\n", rec); exit_code(2); } /* prevents a strange error */ diff --git a/sipsak.1 b/sipsak.1 index 3f007fc..5368319 100644 --- a/sipsak.1 +++ b/sipsak.1 @@ -25,6 +25,10 @@ sipsak \- a utility for various tests on sip servers and user agents .I STRING .B ] [-H .I HOSTNAME +.B ] [-j +.I STRING +.B ] [-J +.I STRING .B ] [-l .I PORT .B ] [-m @@ -297,6 +301,16 @@ will be added as one or more additional headers to the request. The string "\\n" (note: two characters) will be replaced with CRLF and thus result in two separate headers. That way more then one header can be added. +.IP "-J, --autohash STRING" +The +.BR string +will be used as the H(A1) input to the digest authentication response +calculation. Thus no password from the +.BR -a +option is required if this option is provided. The given +.BR string +is expected to be a hex string with the length of the used hash function. + .IP "-l, --local-port PORT" The receiving UDP socket will use the local network .I port. diff --git a/sipsak.c b/sipsak.c index dbb9fcd..6707245 100644 --- a/sipsak.c +++ b/sipsak.c @@ -149,6 +149,7 @@ void print_long_help() { " and reliable transports (default: 64)\n" " --transport=STRING specify transport to be used\n" " --headers=STRING adds additional headers to the request\n" + " --authhash=STRING ha1 hash for authentication instead of password\n" ); exit_code(0); } @@ -215,6 +216,7 @@ void print_help() { " and reliable transports (default: 64)\n" " -E STRING specify transport to be used\n" " -j STRING adds additional headers to the request\n" + " -J STRING ha1 hash for authentication instead of password\n" ); exit_code(0); } @@ -277,6 +279,7 @@ int main(int argc, char *argv[]) {"timeout-factor", 1, 0, 'D'}, {"transport", 1, 0, 'E'}, {"headers", 1, 0, 'j'}, + {"authhash", 1, 0, 'J'}, {0, 0, 0, 0} }; #endif @@ -287,7 +290,7 @@ int main(int argc, char *argv[]) namebeg=nameend=maxforw= -1; numeric=via_ins=redirects=fix_crlf=processes = 1; username=password=replace_str=hostname=contact_uri=mes_body = NULL; - con_dis=auth_username=from_uri=headers = NULL; + con_dis=auth_username=from_uri=headers=authhash = NULL; scheme = user = host = backup = req = rep = rec = NULL; re = NULL; address= 0; @@ -304,9 +307,9 @@ int main(int argc, char *argv[]) /* lots of command line switches to handle*/ #ifdef HAVE_GETOPT_LONG - while ((c=getopt_long(argc, argv, "a:A:b:B:c:C:dD:e:E:f:Fg:GhH:iIj:l:Lm:MnNo:O:p:P:q:r:Rs:St:Tu:UvVwW:x:Xz:", l_opts, &option_index)) != EOF){ + while ((c=getopt_long(argc, argv, "a:A:b:B:c:C:dD:e:E:f:Fg:GhH:iIj:J:l:Lm:MnNo:O:p:P:q:r:Rs:St:Tu:UvVwW:x:Xz:", l_opts, &option_index)) != EOF){ #else - while ((c=getopt(argc, argv, "a:A:b:B:c:C:dD:e:E:f:Fg:GhH:iIj:l:Lm:MnNo:O:p:P:q:r:Rs:St:Tu:UvVwW:x:z:")) != EOF){ + while ((c=getopt(argc, argv, "a:A:b:B:c:C:dD:e:E:f:Fg:GhH:iIj:J:l:Lm:MnNo:O:p:P:q:r:Rs:St:Tu:UvVwW:x:z:")) != EOF){ #endif switch(c){ case 'a': @@ -372,10 +375,10 @@ int main(int argc, char *argv[]) "sip:, sips:, *, or is not empty\n"); exit_code(2); } - else if (user == NULL) { + /*else if (user == NULL) { fprintf(stderr, "error: missing username in Contact uri\n"); exit_code(2); - } + }*/ else if (host == NULL) { fprintf(stderr, "error: missing host in Contact uri\n"); exit_code(2); @@ -469,6 +472,13 @@ int main(int argc, char *argv[]) case 'j': headers=optarg; break; + case 'J': + if (strlen(optarg) < SIPSAK_HASHHEXLEN_MD5) { + fprintf(stderr, "error: authhash string is too short\n"); + exit_code(2); + } + authhash=optarg; + break; case 'l': lport=str_to_int(optarg); break; diff --git a/sipsak.h b/sipsak.h index 8f5d283..e685715 100644 --- a/sipsak.h +++ b/sipsak.h @@ -303,7 +303,7 @@ int maxforw, lport, rport, randtrash, trashchar, numeric, symmetric; int file_b, uri_b, trace, via_ins, usrloc, redirects, rand_rem, replace_b; int empty_contact, nagios_warn, fix_crlf, timing, outbound_proxy, inv_final; char *username, *domainname, *password, *replace_str, *hostname, *contact_uri; -char *mes_body, *con_dis, *auth_username, *from_uri, *headers; +char *mes_body, *con_dis, *auth_username, *from_uri, *headers, *authhash; char fqdn[FQDN_SIZE]; char target_dot[INET_ADDRSTRLEN], source_dot[INET_ADDRSTRLEN]; char *req, *rep, *rec, *transport_str;