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
;