ingress control
[exim.git] / src / src / srs.c
index a1e08c36e710a88a5be0f4af307e833089b6945c..0115c0b518adc31996d0c0688f1e35e886e6fc80 100644 (file)
@@ -1,11 +1,12 @@
-/* $Cambridge: exim/src/src/srs.c,v 1.2 2004/12/16 15:11:47 tom Exp $ */
-
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
 /* SRS - Sender rewriting scheme support
-  ©2004 Miles Wilton <miles@mirtol.com>
+  (C)2004 Miles Wilton <miles@mirtol.com>
+
+  SRS Support Version: 1.0a
+
   License: GPL */
 
 #include "exim.h"
@@ -21,75 +22,90 @@ uschar   *srs_db_reverse        = NULL;
 
 /* srs_init just initialises libsrs and creates (if necessary)
    an srs object to use for all srs calls in this instance */
-   
+
 int eximsrs_init()
 {
-  int co;
   uschar *list = srs_config;
-  char secret_buf[SRS_MAX_SECRET_LENGTH];
-  char *secret;
-  char sbuf[4];
-  char *sbufp;
-  int hashlen, maxage;
-
-  
-  if(!srs)
+  uschar secret_buf[SRS_MAX_SECRET_LENGTH];
+  uschar *secret = NULL;
+  uschar sbuf[4];
+  uschar *sbufp;
+
+  /* Check if this instance of Exim has not initialized SRS */
+  if(srs == NULL)
   {
-    // Check config
-    if(!srs_config)
+    int co = 0;
+    int hashlen, maxage;
+    BOOL usetimestamp, usehash;
+
+    /* Copy config vars */
+    hashlen = srs_hashlength;
+    maxage = srs_maxage;
+    usetimestamp = srs_usetimestamp;
+    usehash = srs_usehash;
+
+    /* Pass srs_config var (overrides new config vars) */
+    co = 0;
+    if(srs_config != NULL)
     {
-      log_write(0, LOG_MAIN | LOG_PANIC,
-          "SRS Configuration Error");
-      return DEFER;
+      secret = string_nextinlist(&list, &co, secret_buf, SRS_MAX_SECRET_LENGTH);
+
+      if((sbufp = string_nextinlist(&list, &co, sbuf, sizeof(sbuf))) != NULL)
+        maxage = atoi(sbuf);
+
+      if((sbufp = string_nextinlist(&list, &co, sbuf, sizeof(sbuf))) != NULL)
+        hashlen = atoi(sbuf);
+
+      if((sbufp = string_nextinlist(&list, &co, sbuf, sizeof(sbuf))) != NULL)
+        usetimestamp = atoi(sbuf);
+
+      if((sbufp = string_nextinlist(&list, &co, sbuf, sizeof(sbuf))) != NULL)
+        usehash = atoi(sbuf);
     }
-    
-    // Get config
+
+    if(srs_hashmin == -1)
+      srs_hashmin = hashlen;
+
+    /* First secret specified in secrets? */
     co = 0;
-    if((secret = string_nextinlist(&list, &co, secret_buf,
-                                   SRS_MAX_SECRET_LENGTH)) == NULL)
+    list = srs_secrets;
+    if(secret == NULL || *secret == '\0')
     {
-      log_write(0, LOG_MAIN | LOG_PANIC,
-          "SRS Configuration Error: No secret specified");
-      return DEFER;
+      if((secret = string_nextinlist(&list, &co, secret_buf, SRS_MAX_SECRET_LENGTH)) == NULL)
+      {
+        log_write(0, LOG_MAIN | LOG_PANIC,
+            "SRS Configuration Error: No secret specified");
+        return DEFER;
+      }
     }
-    
-    if((sbufp = string_nextinlist(&list, &co, sbuf, sizeof(sbuf))) == NULL)
-      maxage = 31;
-    else
-      maxage = atoi(sbuf);
+
+    /* Check config */
     if(maxage < 0 || maxage > 365)
     {
       log_write(0, LOG_MAIN | LOG_PANIC,
           "SRS Configuration Error: Invalid maximum timestamp age");
       return DEFER;
     }
-
-    if((sbufp = string_nextinlist(&list, &co, sbuf, sizeof(sbuf))) == NULL)
-      hashlen = 6;
-    else
-      hashlen = atoi(sbuf);
-    if(hashlen < 1 || hashlen > 20)
+    if(hashlen < 1 || hashlen > 20 || srs_hashmin < 1 || srs_hashmin > 20)
     {
       log_write(0, LOG_MAIN | LOG_PANIC,
           "SRS Configuration Error: Invalid hash length");
       return DEFER;
     }
-    
-    
-    if((srs = srs_open(secret, strnlen(secret, SRS_MAX_SECRET_LENGTH),
-                      maxage, hashlen, hashlen)) == NULL)
+
+    if((srs = srs_open(secret, Ustrlen(secret), maxage, hashlen, srs_hashmin)) == NULL)
     {
       log_write(0, LOG_MAIN | LOG_PANIC,
           "Failed to allocate SRS memory");
       return DEFER;
     }
 
+    srs_set_option(srs, SRS_OPTION_USETIMESTAMP, usetimestamp);
+    srs_set_option(srs, SRS_OPTION_USEHASH, usehash);
 
-    if((sbufp = string_nextinlist(&list, &co, sbuf, sizeof(sbuf))) != NULL)
-      srs_set_option(srs, SRS_OPTION_USETIMESTAMP, atoi(sbuf));
-    
-    if((sbufp = string_nextinlist(&list, &co, sbuf, sizeof(sbuf))) != NULL)
-      srs_set_option(srs, SRS_OPTION_USEHASH, atoi(sbuf));
+    /* Extra secrets? */
+    while((secret = string_nextinlist(&list, &co, secret_buf, SRS_MAX_SECRET_LENGTH)) != NULL)
+        srs_add_secret(srs, secret, (Ustrlen(secret) > SRS_MAX_SECRET_LENGTH) ? SRS_MAX_SECRET_LENGTH :  Ustrlen(secret));
 
     DEBUG(D_any)
       debug_printf("SRS initialized\n");
@@ -101,9 +117,9 @@ int eximsrs_init()
 
 int eximsrs_done()
 {
-  if(srs)
+  if(srs != NULL)
     srs_close(srs);
-  
+
   srs = NULL;
 
   return OK;
@@ -151,13 +167,14 @@ int eximsrs_reverse(uschar **result, uschar *address)
 int eximsrs_db_set(BOOL reverse, uschar *srs_db)
 {
   if(reverse)
-    srs_db_reverse = string_copy(srs_db);
+    srs_db_reverse = (srs_db == NULL ? NULL : string_copy(srs_db));
   else
-    srs_db_forward = string_copy(srs_db);
-    
-  if(srs_set_db_functions(srs, eximsrs_db_insert, eximsrs_db_lookup) * SRS_RESULT_FAIL)
+    srs_db_forward = (srs_db == NULL ? NULL : string_copy(srs_db));
+
+  if(srs_set_db_functions(srs, (srs_db_forward ? eximsrs_db_insert : NULL),
+                               (srs_db_reverse ? eximsrs_db_lookup : NULL)) & SRS_RESULT_FAIL)
     return DEFER;
-  
+
   return OK;
 }
 
@@ -165,21 +182,24 @@ int eximsrs_db_set(BOOL reverse, uschar *srs_db)
 srs_result eximsrs_db_insert(srs_t *srs, char *data, uint data_len, char *result, uint result_len)
 {
   uschar *res;
-  char buf[64];
+  uschar buf[64];
+
+  if(srs_db_forward == NULL)
+    return SRS_RESULT_DBERROR;
 
   srs_db_address = string_copyn(data, data_len);
   if(srs_generate_unique_id(srs, srs_db_address, buf, 64) & SRS_RESULT_FAIL)
-    return DEFER;
-  
+    return SRS_RESULT_DBERROR;
+
   srs_db_key = string_copyn(buf, 16);
-  
+
   if((res = expand_string(srs_db_forward)) == NULL)
     return SRS_RESULT_DBERROR;
-  
+
   if(result_len < 17)
     return SRS_RESULT_DBERROR;
-    
-  strncpy(result, srs_db_key, result_len);
+
+  Ustrncpy(result, srs_db_key, result_len);
 
   return SRS_RESULT_OK;
 }
@@ -189,13 +209,16 @@ srs_result eximsrs_db_lookup(srs_t *srs, char *data, uint data_len, char *result
 {
   uschar *res;
 
+  if(srs_db_reverse == NULL)
+    return SRS_RESULT_DBERROR;
+
   srs_db_key = string_copyn(data, data_len);
   if((res = expand_string(srs_db_reverse)) == NULL)
     return SRS_RESULT_DBERROR;
-  
+
   if(Ustrlen(res) >= result_len)
     return SRS_RESULT_ADDRESSTOOLONG;
-    
+
   strncpy(result, res, result_len);
 
   return SRS_RESULT_OK;