From 1549ea3b295d116c7aee9a9f8c5bf96aa5ff38a7 Mon Sep 17 00:00:00 2001 From: Philip Hazel Date: Mon, 20 Jun 2005 10:04:55 +0000 Subject: [PATCH] Fix bug in my conversion of Tom's snprintf to string_vformat. Also make local functions static. --- src/src/expand.c | 206 ++++++++++++++++++++++---------------------- src/src/functions.h | 4 +- src/src/string.c | 5 +- 3 files changed, 109 insertions(+), 106 deletions(-) diff --git a/src/src/expand.c b/src/src/expand.c index 961882397..6811c2940 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/expand.c,v 1.29 2005/06/17 13:52:15 ph10 Exp $ */ +/* $Cambridge: exim/src/src/expand.c,v 1.30 2005/06/20 10:04:55 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -2425,8 +2425,6 @@ return rc; - - /************************************************* * Handle MD5 or SHA-1 computation for HMAC * *************************************************/ @@ -2472,6 +2470,110 @@ else +/******************************************************** +* prvs: Get last three digits of days since Jan 1, 1970 * +********************************************************/ + +/* This is needed to implement the "prvs" BATV reverse + path signing scheme + +Argument: integer "days" offset to add or substract to + or from the current number of days. + +Returns: pointer to string containing the last three + digits of the number of days since Jan 1, 1970, + modified by the offset argument, NULL if there + was an error in the conversion. + +*/ + +static uschar * +prvs_daystamp(int day_offset) +{ +uschar *days = store_get(16); +(void)string_format(days, 16, TIME_T_FMT, + (time(NULL) + day_offset*86400)/86400); +return (Ustrlen(days) >= 3) ? &days[Ustrlen(days)-3] : NULL; +} + + + +/******************************************************** +* prvs: perform HMAC-SHA1 computation of prvs bits * +********************************************************/ + +/* This is needed to implement the "prvs" BATV reverse + path signing scheme + +Arguments: + address RFC2821 Address to use + key The key to use (must be less than 64 characters + in size) + key_num Single-digit key number to use. Defaults to + '0' when NULL. + +Returns: pointer to string containing the first three + bytes of the final hash in hex format, NULL if + there was an error in the process. +*/ + +static uschar * +prvs_hmac_sha1(uschar *address, uschar *key, uschar *key_num, uschar *daystamp) +{ +uschar *hash_source, *p; +int size = 0,offset = 0,i; +sha1 sha1_base; +void *use_base = &sha1_base; +uschar innerhash[20]; +uschar finalhash[20]; +uschar innerkey[64]; +uschar outerkey[64]; +uschar *finalhash_hex = store_get(40); + +if (key_num == NULL) + key_num = US"0"; + +if (Ustrlen(key) > 64) + return NULL; + +hash_source = string_cat(NULL,&size,&offset,key_num,1); +string_cat(hash_source,&size,&offset,daystamp,3); +string_cat(hash_source,&size,&offset,address,Ustrlen(address)); +hash_source[offset] = '\0'; + +DEBUG(D_expand) debug_printf("prvs: hash source is '%s'\n", hash_source); + +memset(innerkey, 0x36, 64); +memset(outerkey, 0x5c, 64); + +for (i = 0; i < Ustrlen(key); i++) + { + innerkey[i] ^= key[i]; + outerkey[i] ^= key[i]; + } + +chash_start(HMAC_SHA1, use_base); +chash_mid(HMAC_SHA1, use_base, innerkey); +chash_end(HMAC_SHA1, use_base, hash_source, offset, innerhash); + +chash_start(HMAC_SHA1, use_base); +chash_mid(HMAC_SHA1, use_base, outerkey); +chash_end(HMAC_SHA1, use_base, innerhash, 20, finalhash); + +p = finalhash_hex; +for (i = 0; i < 3; i++) + { + *p++ = hex_digits[(finalhash[i] & 0xf0) >> 4]; + *p++ = hex_digits[finalhash[i] & 0x0f]; + } +*p = '\0'; + +return finalhash_hex; +} + + + + /************************************************* * Join a file onto the output string * *************************************************/ @@ -4941,104 +5043,6 @@ expand_string_message = string_sprintf(CS msg, s); return -2; } -/******************************************************** -* prvs: Get last three digits of days since Jan 1, 1970 * -********************************************************/ - -/* This is needed to implement the "prvs" BATV reverse - path signing scheme - -Argument: integer "days" offset to add or substract to - or from the current number of days. - -Returns: pointer to string containing the last three - digits of the number of days since Jan 1, 1970, - modified by the offset argument, NULL if there - was an error in the conversion. - -*/ - -uschar * -prvs_daystamp(int day_offset) -{ -uschar *days = store_get(10); -(void)string_format(days, 10, TIME_T_FMT, - (((LONGLONG_T)time(NULL))+(day_offset*86400))/86400); -return (Ustrlen(days) >= 3) ? &days[Ustrlen(days)-3] : NULL; -} - -/******************************************************** -* prvs: perform HMAC-SHA1 computation of prvs bits * -********************************************************/ - -/* This is needed to implement the "prvs" BATV reverse - path signing scheme - -Arguments: - address RFC2821 Address to use - key The key to use (must be less than 64 characters - in size) - key_num Single-digit key number to use. Defaults to - '0' when NULL. - -Returns: pointer to string containing the first three - bytes of the final hash in hex format, NULL if - there was an error in the process. -*/ - -uschar * -prvs_hmac_sha1(uschar *address, uschar *key, uschar *key_num, uschar *daystamp) -{ -uschar *hash_source, *p; -int size = 0,offset = 0,i; -sha1 sha1_base; -void *use_base = &sha1_base; -uschar innerhash[20]; -uschar finalhash[20]; -uschar innerkey[64]; -uschar outerkey[64]; -uschar *finalhash_hex = store_get(40); - -if (key_num == NULL) - key_num = US"0"; - -if (Ustrlen(key) > 64) - return NULL; - -hash_source = string_cat(NULL,&size,&offset,key_num,1); -string_cat(hash_source,&size,&offset,daystamp,3); -string_cat(hash_source,&size,&offset,address,Ustrlen(address)); -hash_source[offset] = '\0'; - -DEBUG(D_expand) debug_printf("prvs: hash source is '%s'\n", hash_source); - -memset(innerkey, 0x36, 64); -memset(outerkey, 0x5c, 64); - -for (i = 0; i < Ustrlen(key); i++) - { - innerkey[i] ^= key[i]; - outerkey[i] ^= key[i]; - } - -chash_start(HMAC_SHA1, use_base); -chash_mid(HMAC_SHA1, use_base, innerkey); -chash_end(HMAC_SHA1, use_base, hash_source, offset, innerhash); - -chash_start(HMAC_SHA1, use_base); -chash_mid(HMAC_SHA1, use_base, outerkey); -chash_end(HMAC_SHA1, use_base, innerhash, 20, finalhash); - -p = finalhash_hex; -for (i = 0; i < 3; i++) - { - *p++ = hex_digits[(finalhash[i] & 0xf0) >> 4]; - *p++ = hex_digits[finalhash[i] & 0x0f]; - } -*p = '\0'; - -return finalhash_hex; -} /************************************************* ************************************************** diff --git a/src/src/functions.h b/src/src/functions.h index 24eb84c6d..2c8c4321d 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/functions.h,v 1.15 2005/06/16 20:01:29 tom Exp $ */ +/* $Cambridge: exim/src/src/functions.h,v 1.16 2005/06/20 10:04:55 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -173,8 +173,6 @@ extern uschar *parse_find_address_end(uschar *, BOOL); extern uschar *parse_find_at(uschar *); extern uschar *parse_fix_phrase(uschar *, int, uschar *, int); extern uschar *parse_quote_2047(uschar *, int, uschar *, uschar *, int); -extern uschar *prvs_daystamp(int); -extern uschar *prvs_hmac_sha1(uschar *, uschar *, uschar *, uschar *); extern BOOL queue_action(uschar *, int, uschar **, int, int); extern void queue_check_only(void); diff --git a/src/src/string.c b/src/src/string.c index 1679e8850..f64641dd6 100644 --- a/src/src/string.c +++ b/src/src/string.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/string.c,v 1.6 2005/06/17 13:52:15 ph10 Exp $ */ +/* $Cambridge: exim/src/src/string.c,v 1.7 2005/06/20 10:04:55 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -1075,7 +1075,8 @@ while (*fp != 0) case 'u': case 'x': case 'X': - if (p >= last - 24) { yield = FALSE; goto END_FORMAT; } + if (p >= last - ((length > L_LONG)? 24 : 12)) + { yield = FALSE; goto END_FORMAT; } strncpy(newformat, item_start, fp - item_start); newformat[fp - item_start] = 0; -- 2.25.1