1 /* $Cambridge: exim/src/src/srs.c,v 1.3 2004/12/17 14:52:44 ph10 Exp $ */
3 /*************************************************
4 * Exim - an Internet mail transport agent *
5 *************************************************/
7 /* SRS - Sender rewriting scheme support
8 ©2004 Miles Wilton <miles@mirtol.com>
12 #ifdef EXPERIMENTAL_SRS
18 uschar *srs_db_forward = NULL;
19 uschar *srs_db_reverse = NULL;
22 /* srs_init just initialises libsrs and creates (if necessary)
23 an srs object to use for all srs calls in this instance */
28 uschar *list = srs_config;
29 char secret_buf[SRS_MAX_SECRET_LENGTH];
41 log_write(0, LOG_MAIN | LOG_PANIC,
42 "SRS Configuration Error");
48 if((secret = string_nextinlist(&list, &co, secret_buf,
49 SRS_MAX_SECRET_LENGTH)) == NULL)
51 log_write(0, LOG_MAIN | LOG_PANIC,
52 "SRS Configuration Error: No secret specified");
56 if((sbufp = string_nextinlist(&list, &co, sbuf, sizeof(sbuf))) == NULL)
60 if(maxage < 0 || maxage > 365)
62 log_write(0, LOG_MAIN | LOG_PANIC,
63 "SRS Configuration Error: Invalid maximum timestamp age");
67 if((sbufp = string_nextinlist(&list, &co, sbuf, sizeof(sbuf))) == NULL)
71 if(hashlen < 1 || hashlen > 20)
73 log_write(0, LOG_MAIN | LOG_PANIC,
74 "SRS Configuration Error: Invalid hash length");
79 if((srs = srs_open(secret, strnlen(secret, SRS_MAX_SECRET_LENGTH),
80 maxage, hashlen, hashlen)) == NULL)
82 log_write(0, LOG_MAIN | LOG_PANIC,
83 "Failed to allocate SRS memory");
88 if((sbufp = string_nextinlist(&list, &co, sbuf, sizeof(sbuf))) != NULL)
89 srs_set_option(srs, SRS_OPTION_USETIMESTAMP, atoi(sbuf));
91 if((sbufp = string_nextinlist(&list, &co, sbuf, sizeof(sbuf))) != NULL)
92 srs_set_option(srs, SRS_OPTION_USEHASH, atoi(sbuf));
95 debug_printf("SRS initialized\n");
113 int eximsrs_forward(uschar **result, uschar *orig_sender, uschar *domain)
118 if((n = srs_forward(srs, orig_sender, domain, res, sizeof(res))) & SRS_RESULT_FAIL)
121 debug_printf("srs_forward failed (%s, %s): %s\n", orig_sender, domain, srs_geterrormsg(n));
125 *result = string_copy(res);
130 int eximsrs_reverse(uschar **result, uschar *address)
135 if((n = srs_reverse(srs, address, res, sizeof(res))) & SRS_RESULT_FAIL)
138 debug_printf("srs_reverse failed (%s): %s\n", address, srs_geterrormsg(n));
139 if(n == SRS_RESULT_NOTSRS || n == SRS_RESULT_BADSRS)
141 if(n == SRS_RESULT_BADHASH || n == SRS_RESULT_BADTIMESTAMP || n == SRS_RESULT_TIMESTAMPEXPIRED)
146 *result = string_copy(res);
151 int eximsrs_db_set(BOOL reverse, uschar *srs_db)
154 srs_db_reverse = string_copy(srs_db);
156 srs_db_forward = string_copy(srs_db);
158 if(srs_set_db_functions(srs, eximsrs_db_insert, eximsrs_db_lookup) * SRS_RESULT_FAIL)
165 srs_result eximsrs_db_insert(srs_t *srs, char *data, uint data_len, char *result, uint result_len)
170 srs_db_address = string_copyn(data, data_len);
171 if(srs_generate_unique_id(srs, srs_db_address, buf, 64) & SRS_RESULT_FAIL)
174 srs_db_key = string_copyn(buf, 16);
176 if((res = expand_string(srs_db_forward)) == NULL)
177 return SRS_RESULT_DBERROR;
180 return SRS_RESULT_DBERROR;
182 strncpy(result, srs_db_key, result_len);
184 return SRS_RESULT_OK;
188 srs_result eximsrs_db_lookup(srs_t *srs, char *data, uint data_len, char *result, uint result_len)
192 srs_db_key = string_copyn(data, data_len);
193 if((res = expand_string(srs_db_reverse)) == NULL)
194 return SRS_RESULT_DBERROR;
196 if(Ustrlen(res) >= result_len)
197 return SRS_RESULT_ADDRESSTOOLONG;
199 strncpy(result, res, result_len);
201 return SRS_RESULT_OK;