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