1 /* $Cambridge: exim/src/src/srs.c,v 1.8 2005/06/27 18:10:30 tom Exp $ */
3 /*************************************************
4 * Exim - an Internet mail transport agent *
5 *************************************************/
7 /* SRS - Sender rewriting scheme support
8 (C)2004 Miles Wilton <miles@mirtol.com>
10 SRS Support Version: 1.0a
15 #ifdef EXPERIMENTAL_SRS
21 uschar *srs_db_forward = NULL;
22 uschar *srs_db_reverse = NULL;
25 /* srs_init just initialises libsrs and creates (if necessary)
26 an srs object to use for all srs calls in this instance */
30 uschar *list = srs_config;
31 uschar secret_buf[SRS_MAX_SECRET_LENGTH];
32 uschar *secret = NULL;
36 /* Check if this instance of Exim has not initialized SRS */
41 BOOL usetimestamp, usehash;
43 /* Copy config vars */
44 hashlen = srs_hashlength;
46 usetimestamp = srs_usetimestamp;
47 usehash = srs_usehash;
49 /* Pass srs_config var (overrides new config vars) */
51 if(srs_config != NULL)
53 secret = string_nextinlist(&list, &co, secret_buf, SRS_MAX_SECRET_LENGTH);
55 if((sbufp = string_nextinlist(&list, &co, sbuf, sizeof(sbuf))) != NULL)
58 if((sbufp = string_nextinlist(&list, &co, sbuf, sizeof(sbuf))) != NULL)
61 if((sbufp = string_nextinlist(&list, &co, sbuf, sizeof(sbuf))) != NULL)
62 usetimestamp = atoi(sbuf);
64 if((sbufp = string_nextinlist(&list, &co, sbuf, sizeof(sbuf))) != NULL)
69 srs_hashmin = hashlen;
71 /* First secret specified in secrets? */
74 if(secret == NULL || *secret == '\0')
76 if((secret = string_nextinlist(&list, &co, secret_buf, SRS_MAX_SECRET_LENGTH)) == NULL)
78 log_write(0, LOG_MAIN | LOG_PANIC,
79 "SRS Configuration Error: No secret specified");
85 if(maxage < 0 || maxage > 365)
87 log_write(0, LOG_MAIN | LOG_PANIC,
88 "SRS Configuration Error: Invalid maximum timestamp age");
91 if(hashlen < 1 || hashlen > 20 || srs_hashmin < 1 || srs_hashmin > 20)
93 log_write(0, LOG_MAIN | LOG_PANIC,
94 "SRS Configuration Error: Invalid hash length");
98 if((srs = srs_open(secret, Ustrlen(secret), maxage, hashlen, srs_hashmin)) == NULL)
100 log_write(0, LOG_MAIN | LOG_PANIC,
101 "Failed to allocate SRS memory");
105 srs_set_option(srs, SRS_OPTION_USETIMESTAMP, usetimestamp);
106 srs_set_option(srs, SRS_OPTION_USEHASH, usehash);
109 while((secret = string_nextinlist(&list, &co, secret_buf, SRS_MAX_SECRET_LENGTH)) != NULL)
110 srs_add_secret(srs, secret, (Ustrlen(secret) > SRS_MAX_SECRET_LENGTH) ? SRS_MAX_SECRET_LENGTH : Ustrlen(secret));
113 debug_printf("SRS initialized\n");
131 int eximsrs_forward(uschar **result, uschar *orig_sender, uschar *domain)
136 if((n = srs_forward(srs, orig_sender, domain, res, sizeof(res))) & SRS_RESULT_FAIL)
139 debug_printf("srs_forward failed (%s, %s): %s\n", orig_sender, domain, srs_geterrormsg(n));
143 *result = string_copy(res);
148 int eximsrs_reverse(uschar **result, uschar *address)
153 if((n = srs_reverse(srs, address, res, sizeof(res))) & SRS_RESULT_FAIL)
156 debug_printf("srs_reverse failed (%s): %s\n", address, srs_geterrormsg(n));
157 if(n == SRS_RESULT_NOTSRS || n == SRS_RESULT_BADSRS)
159 if(n == SRS_RESULT_BADHASH || n == SRS_RESULT_BADTIMESTAMP || n == SRS_RESULT_TIMESTAMPEXPIRED)
164 *result = string_copy(res);
169 int eximsrs_db_set(BOOL reverse, uschar *srs_db)
172 srs_db_reverse = (srs_db == NULL ? NULL : string_copy(srs_db));
174 srs_db_forward = (srs_db == NULL ? NULL : string_copy(srs_db));
176 if(srs_set_db_functions(srs, (srs_db_forward ? eximsrs_db_insert : NULL),
177 (srs_db_reverse ? eximsrs_db_lookup : NULL)) & SRS_RESULT_FAIL)
184 srs_result eximsrs_db_insert(srs_t *srs, char *data, uint data_len, char *result, uint result_len)
189 if(srs_db_forward == NULL)
190 return SRS_RESULT_DBERROR;
192 srs_db_address = string_copyn(data, data_len);
193 if(srs_generate_unique_id(srs, srs_db_address, buf, 64) & SRS_RESULT_FAIL)
194 return SRS_RESULT_DBERROR;
196 srs_db_key = string_copyn(buf, 16);
198 if((res = expand_string(srs_db_forward)) == NULL)
199 return SRS_RESULT_DBERROR;
202 return SRS_RESULT_DBERROR;
204 Ustrncpy(result, srs_db_key, result_len);
206 return SRS_RESULT_OK;
210 srs_result eximsrs_db_lookup(srs_t *srs, char *data, uint data_len, char *result, uint result_len)
214 if(srs_db_reverse == NULL)
215 return SRS_RESULT_DBERROR;
217 srs_db_key = string_copyn(data, data_len);
218 if((res = expand_string(srs_db_reverse)) == NULL)
219 return SRS_RESULT_DBERROR;
221 if(Ustrlen(res) >= result_len)
222 return SRS_RESULT_ADDRESSTOOLONG;
224 strncpy(result, res, result_len);
226 return SRS_RESULT_OK;