ratelimit fix: omit the limit parameter from the database lookup
[exim.git] / src / src / srs.c
CommitLineData
892a2814 1/* $Cambridge: exim/src/src/srs.c,v 1.7 2005/05/25 17:50:33 tom Exp $ */
8523533c
TK
2
3/*************************************************
4* Exim - an Internet mail transport agent *
5*************************************************/
6
7/* SRS - Sender rewriting scheme support
384152a6
TK
8 (C)2004 Miles Wilton <miles@mirtol.com>
9
10 SRS Support Version: 1.0a
11
8523533c
TK
12 License: GPL */
13
14#include "exim.h"
15#ifdef EXPERIMENTAL_SRS
16
17#include <srs_alt.h>
18#include "srs.h"
19
20srs_t *srs = NULL;
21uschar *srs_db_forward = NULL;
22uschar *srs_db_reverse = NULL;
23
24
25/* srs_init just initialises libsrs and creates (if necessary)
26 an srs object to use for all srs calls in this instance */
8e669ac1 27
8523533c
TK
28int eximsrs_init()
29{
8523533c 30 uschar *list = srs_config;
384152a6
TK
31 uschar secret_buf[SRS_MAX_SECRET_LENGTH];
32 uschar *secret;
33 uschar sbuf[4];
34 uschar *sbufp;
8523533c 35
130e9641 36 /* Check if this instance of Exim has not initialized SRS */
384152a6 37 if(srs == NULL)
8523533c 38 {
384152a6
TK
39 int co = 0;
40 int hashlen, maxage;
41 BOOL usetimestamp, usehash;
42
43 /* Copy config vars */
44 hashlen = srs_hashlength;
45 maxage = srs_maxage;
46 usetimestamp = srs_usetimestamp;
47 usehash = srs_usehash;
48
49 /* Pass srs_config var (overrides new config vars) */
50 co = 0;
51 if(srs_config != NULL)
8523533c 52 {
384152a6
TK
53 secret = string_nextinlist(&list, &co, secret_buf, SRS_MAX_SECRET_LENGTH);
54
55 if((sbufp = string_nextinlist(&list, &co, sbuf, sizeof(sbuf))) != NULL)
56 maxage = atoi(sbuf);
57
58 if((sbufp = string_nextinlist(&list, &co, sbuf, sizeof(sbuf))) != NULL)
59 hashlen = atoi(sbuf);
60
61 if((sbufp = string_nextinlist(&list, &co, sbuf, sizeof(sbuf))) != NULL)
62 usetimestamp = atoi(sbuf);
63
64 if((sbufp = string_nextinlist(&list, &co, sbuf, sizeof(sbuf))) != NULL)
65 usehash = atoi(sbuf);
8523533c 66 }
8e669ac1 67
384152a6
TK
68 if(srs_hashmin == -1)
69 srs_hashmin = hashlen;
70
71 /* First secret specified in secrets? */
8523533c 72 co = 0;
384152a6 73 list = srs_secrets;
892a2814 74 if(secret == NULL || *secret == NULL)
8523533c 75 {
384152a6
TK
76 if((secret = string_nextinlist(&list, &co, secret_buf, SRS_MAX_SECRET_LENGTH)) == NULL)
77 {
78 log_write(0, LOG_MAIN | LOG_PANIC,
79 "SRS Configuration Error: No secret specified");
80 return DEFER;
81 }
8523533c 82 }
8e669ac1 83
384152a6 84 /* Check config */
8523533c
TK
85 if(maxage < 0 || maxage > 365)
86 {
87 log_write(0, LOG_MAIN | LOG_PANIC,
88 "SRS Configuration Error: Invalid maximum timestamp age");
89 return DEFER;
90 }
384152a6 91 if(hashlen < 1 || hashlen > 20 || srs_hashmin < 1 || srs_hashmin > 20)
8523533c
TK
92 {
93 log_write(0, LOG_MAIN | LOG_PANIC,
94 "SRS Configuration Error: Invalid hash length");
95 return DEFER;
96 }
8e669ac1 97
384152a6 98 if((srs = srs_open(secret, Ustrlen(secret), maxage, hashlen, srs_hashmin)) == NULL)
8523533c
TK
99 {
100 log_write(0, LOG_MAIN | LOG_PANIC,
101 "Failed to allocate SRS memory");
102 return DEFER;
103 }
104
384152a6
TK
105 srs_set_option(srs, SRS_OPTION_USETIMESTAMP, usetimestamp);
106 srs_set_option(srs, SRS_OPTION_USEHASH, usehash);
8523533c 107
384152a6
TK
108 /* Extra secrets? */
109 while((secret = string_nextinlist(&list, &co, secret_buf, SRS_MAX_SECRET_LENGTH)) != NULL)
110 srs_add_secret(srs, secret, strnlen(secret, SRS_MAX_SECRET_LENGTH));
8523533c
TK
111
112 DEBUG(D_any)
113 debug_printf("SRS initialized\n");
114 }
115
116 return OK;
117}
118
119
120int eximsrs_done()
121{
384152a6 122 if(srs != NULL)
8523533c 123 srs_close(srs);
8e669ac1 124
8523533c
TK
125 srs = NULL;
126
127 return OK;
128}
129
130
131int eximsrs_forward(uschar **result, uschar *orig_sender, uschar *domain)
132{
133 char res[512];
134 int n;
135
136 if((n = srs_forward(srs, orig_sender, domain, res, sizeof(res))) & SRS_RESULT_FAIL)
137 {
138 DEBUG(D_any)
139 debug_printf("srs_forward failed (%s, %s): %s\n", orig_sender, domain, srs_geterrormsg(n));
140 return DEFER;
141 }
142
143 *result = string_copy(res);
144 return OK;
145}
146
147
148int eximsrs_reverse(uschar **result, uschar *address)
149{
150 char res[512];
151 int n;
152
153 if((n = srs_reverse(srs, address, res, sizeof(res))) & SRS_RESULT_FAIL)
154 {
155 DEBUG(D_any)
156 debug_printf("srs_reverse failed (%s): %s\n", address, srs_geterrormsg(n));
157 if(n == SRS_RESULT_NOTSRS || n == SRS_RESULT_BADSRS)
158 return DECLINE;
159 if(n == SRS_RESULT_BADHASH || n == SRS_RESULT_BADTIMESTAMP || n == SRS_RESULT_TIMESTAMPEXPIRED)
160 return FAIL;
161 return DEFER;
162 }
163
164 *result = string_copy(res);
165 return OK;
166}
167
168
169int eximsrs_db_set(BOOL reverse, uschar *srs_db)
170{
171 if(reverse)
384152a6 172 srs_db_reverse = (srs_db == NULL ? NULL : string_copy(srs_db));
8523533c 173 else
384152a6 174 srs_db_forward = (srs_db == NULL ? NULL : string_copy(srs_db));
8e669ac1 175
384152a6
TK
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)
8523533c 178 return DEFER;
8e669ac1 179
8523533c
TK
180 return OK;
181}
182
183
184srs_result eximsrs_db_insert(srs_t *srs, char *data, uint data_len, char *result, uint result_len)
185{
186 uschar *res;
384152a6
TK
187 uschar buf[64];
188
189 if(srs_db_forward == NULL)
190 return SRS_RESULT_DBERROR;
8523533c
TK
191
192 srs_db_address = string_copyn(data, data_len);
193 if(srs_generate_unique_id(srs, srs_db_address, buf, 64) & SRS_RESULT_FAIL)
384152a6 194 return SRS_RESULT_DBERROR;
8e669ac1 195
8523533c 196 srs_db_key = string_copyn(buf, 16);
8e669ac1 197
8523533c
TK
198 if((res = expand_string(srs_db_forward)) == NULL)
199 return SRS_RESULT_DBERROR;
8e669ac1 200
8523533c
TK
201 if(result_len < 17)
202 return SRS_RESULT_DBERROR;
8e669ac1 203
384152a6 204 Ustrncpy(result, srs_db_key, result_len);
8523533c
TK
205
206 return SRS_RESULT_OK;
207}
208
209
210srs_result eximsrs_db_lookup(srs_t *srs, char *data, uint data_len, char *result, uint result_len)
211{
212 uschar *res;
213
384152a6
TK
214 if(srs_db_reverse == NULL)
215 return SRS_RESULT_DBERROR;
216
8523533c
TK
217 srs_db_key = string_copyn(data, data_len);
218 if((res = expand_string(srs_db_reverse)) == NULL)
219 return SRS_RESULT_DBERROR;
8e669ac1 220
8523533c
TK
221 if(Ustrlen(res) >= result_len)
222 return SRS_RESULT_ADDRESSTOOLONG;
8e669ac1 223
8523533c
TK
224 strncpy(result, res, result_len);
225
226 return SRS_RESULT_OK;
227}
228
229
230#endif
231