Browse Source

Merge branch 'master' into ppa

ppa
Timo Röhling 12 years ago
parent
commit
39ab47243a
6 changed files with 74 additions and 29 deletions
  1. 3
    0
      .gitignore
  2. 4
    2
      README.md
  3. 56
    23
      postsrsd.c
  4. 7
    0
      postsrsd.default
  5. 2
    3
      postsrsd.init.in
  6. 2
    1
      postsrsd.upstart.in

+ 3
- 0
.gitignore View File

@@ -1 +1,4 @@
1 1
 build
2
+.project
3
+.cproject
4
+.settings

+ 4
- 2
README.md View File

@@ -33,10 +33,12 @@ files.
33 33
 
34 34
 Configuration
35 35
 =============
36
-The configuration is located in `/etc/default/postsrsd`. You must store 
37
-a secret key in `/etc/postsrsd.secret`. The installer tries to generate 
36
+The configuration is located in `/etc/default/postsrsd`. You must store
37
+at least one secret key in `/etc/postsrsd.secret`. The installer tries to generate
38 38
 one from `/dev/urandom`. Be careful that no one can guess your secret,
39 39
 because anyone who knows it can use your mail server as open relay!
40
+Each line of `/etc/postsrsd.secret` is used as secret. The first secret is
41
+used for signing and verification, the others for verification only.
40 42
 
41 43
 PostSRSd exposes its functionality via two TCP lookup tables. The
42 44
 recommended Postfix configuration is to add the following fragment to

+ 56
- 23
postsrsd.c View File

@@ -85,6 +85,7 @@ static char hex2num (char c)
85 85
   if (c >= '0' && c <= '9') return c - '0';
86 86
   if (c >= 'a' && c <= 'f') return c - 'a' + 10;
87 87
   if (c >= 'A' && c <= 'F') return c - 'A' + 10;
88
+  return 0;
88 89
 }
89 90
 
90 91
 static char num2hex (char c)
@@ -139,12 +140,24 @@ static char* url_encode (char* buf, size_t len, const char *input)
139 140
   return buf;
140 141
 }
141 142
 
142
-static void handle_forward (srs_t *srs, FILE *fp, const char *address, const char *domain)
143
+static void handle_forward (srs_t *srs, FILE *fp, const char *address, const char *domain, const char **excludes)
143 144
 {
144 145
   int result;
146
+  size_t addrlen;
145 147
   char value[1024];
146 148
   char outputbuf[1024], *output;
147 149
 
150
+  addrlen = strlen(address);
151
+  for(; *excludes; excludes++) {
152
+    size_t len;
153
+    len = strlen(*excludes);
154
+    if (len >= addrlen) continue;
155
+    if (strcasecmp(*excludes, &address[addrlen - len]) == 0 && (**excludes == '.' || address[addrlen - len - 1] == '@')) {
156
+      fputs ("500 Domain excluded from SRS\n", fp);
157
+      fflush (fp);
158
+      return;
159
+    }
160
+  }
148 161
   result = srs_forward(srs, value, sizeof(value), address, domain);
149 162
   if (result == SRS_SUCCESS) {
150 163
     output = url_encode(outputbuf, sizeof(outputbuf), value);
@@ -158,7 +171,7 @@ static void handle_forward (srs_t *srs, FILE *fp, const char *address, const cha
158 171
   fflush (fp);
159 172
 }
160 173
 
161
-static void handle_reverse (srs_t *srs, FILE *fp, const char *address, const char *domain)
174
+static void handle_reverse (srs_t *srs, FILE *fp, const char *address, const char *domain, const char **excludes)
162 175
 {
163 176
   int result;
164 177
   char value[1024];
@@ -188,7 +201,7 @@ static void show_help ()
188 201
     "\n"
189 202
     "Usage: %s -s<file> -d<domain> [other options]\n"
190 203
     "Options:\n"
191
-    "   -s<file>       read secret from file (required)\n"
204
+    "   -s<file>       read secrets from file (required)\n"
192 205
     "   -d<domain>     set domain name for rewrite (required)\n"
193 206
     "   -f<port>       set port for the forward SRS lookup (default: 10001)\n"
194 207
     "   -r<port>       set port for the reverse SRS lookup (default: 10002)\n"
@@ -196,6 +209,7 @@ static void show_help ()
196 209
     "   -c<dir>        chroot to <dir> (default: none)\n"
197 210
     "   -u<user>       switch user id after port bind (default: none)\n"
198 211
     "   -t<seconds>    timeout for idle client connections (default: 1800)\n"
212
+    "   -X<domain>     exclude additional domain from address rewriting\n"
199 213
     "   -D             fork into background\n"
200 214
     "   -4             force IPv4 socket (default: any)\n"
201 215
     "   -6             force IPv6 socket (default: any)\n"
@@ -206,7 +220,7 @@ static void show_help ()
206 220
   );
207 221
 }
208 222
 
209
-typedef void(*handle_t)(srs_t*, FILE*, const char*, const char*);
223
+typedef void(*handle_t)(srs_t*, FILE*, const char*, const char*, const char**);
210 224
 
211 225
 int main (int argc, char **argv)
212 226
 {
@@ -216,18 +230,21 @@ int main (int argc, char **argv)
216 230
        *user = NULL, *domain = NULL, *chroot_dir = NULL;
217 231
   int forward_sock, reverse_sock;
218 232
   char *secret_file = NULL, *pid_file = NULL;
219
-  FILE *pf = NULL;
233
+  FILE *pf = NULL, *sf = NULL;
220 234
   struct passwd *pwd = NULL;
221
-  char secret[1024];
235
+  char secretbuf[1024], *secret = NULL;
222 236
   char *tmp;
223 237
   srs_t *srs;
224 238
   struct pollfd fds[3];
239
+  const char **excludes;
240
+  size_t s1 = 0, s2 = 1;
225 241
   handle_t handler[2] = { handle_forward, handle_reverse };
226 242
 
243
+  excludes = (const char**)calloc(1, sizeof(char*));
227 244
   tmp = strrchr(argv[0], '/');
228 245
   if (tmp) self = strdup(tmp + 1); else self = strdup(argv[0]);
229 246
 
230
-  while ((opt = getopt(argc, argv, "46d:f:r:s:u:t:p:c:Dhv")) != -1) {
247
+  while ((opt = getopt(argc, argv, "46d:f:r:s:u:t:p:c:X::Dhv")) != -1) {
231 248
     switch (opt) {
232 249
       case '?':
233 250
         return EXIT_FAILURE;
@@ -259,17 +276,35 @@ int main (int argc, char **argv)
259 276
         user = strdup(optarg);
260 277
         break;
261 278
       case 'c':
262
-	chroot_dir = strdup(optarg);
263
-	break;
279
+        chroot_dir = strdup(optarg);
280
+        break;
264 281
       case 'D':
265 282
         daemonize = TRUE;
266 283
         break;
267 284
       case 'h':
268
-	show_help();
285
+        show_help();
269 286
         return EXIT_SUCCESS;
287
+      case 'X':
288
+        if (optarg != NULL) {
289
+          tmp = strtok(optarg, ",; \t\r\n");
290
+          while (tmp) {
291
+            if (s1 + 1 >= s2) {
292
+              s2 *= 2;
293
+              excludes = (const char **)realloc(excludes, s2 * sizeof(char*));
294
+              if (excludes == NULL) {
295
+                fprintf (stderr, "%s: Out of memory\n\n", self);
296
+                return EXIT_FAILURE;
297
+              }
298
+            }
299
+            excludes[s1++] = strdup(tmp);
300
+            tmp = strtok(NULL, ",; \t\r\n");
301
+          }
302
+          excludes[s1] = NULL;
303
+        }
304
+        break;
270 305
       case 'v':
271
-	fprintf (stdout, "%s\n", VERSION);
272
-	return EXIT_SUCCESS;
306
+        fprintf (stdout, "%s\n", VERSION);
307
+        return EXIT_SUCCESS;
273 308
     }
274 309
   }
275 310
   if (domain == NULL) {
@@ -291,18 +326,11 @@ int main (int argc, char **argv)
291 326
   /* Read secret. The default installation makes this root accessible only. */
292 327
   if (secret_file != NULL) {
293 328
     size_t len;
294
-    FILE *fp = fopen(secret_file, "rb");
295
-    if (fp == NULL) {
329
+    sf = fopen(secret_file, "rb");
330
+    if (sf == NULL) {
296 331
       fprintf (stderr, "%s: Cannot open file with secret: %s\n", self, secret_file);
297 332
       return EXIT_FAILURE;
298 333
     }
299
-    len = fread(secret, 1, sizeof(secret) - 1, fp);
300
-    if (len == 0 || len > sizeof(secret) - 1) {
301
-      fprintf (stderr, "%s: Cannot read secret from file: %s\n", self, secret_file);
302
-      return EXIT_FAILURE;
303
-    }
304
-    secret[len] = 0;
305
-    fclose (fp);
306 334
   } else {
307 335
     fprintf (stderr, "%s: You must set a secret (-s)\n", self);
308 336
     show_help();
@@ -370,7 +398,12 @@ int main (int argc, char **argv)
370 398
   }
371 399
 
372 400
   srs = srs_new();
373
-  srs_add_secret (srs, secret);
401
+  while ((secret = fgets(secretbuf, sizeof(secretbuf), sf))) {
402
+    secret = strtok(secret, "\r\n");
403
+    if (secret)
404
+      srs_add_secret (srs, secret);
405
+  }
406
+  fclose (sf);
374 407
   srs_set_separator (srs, '+');
375 408
 
376 409
   fds[0].fd = forward_sock;
@@ -416,7 +449,7 @@ int main (int argc, char **argv)
416 449
             }
417 450
             key = url_decode(keybuf, sizeof(keybuf), token);
418 451
             if (!key) break;
419
-            handler[i](srs, fp, key, domain);
452
+            handler[i](srs, fp, key, domain, excludes);
420 453
             if (poll(&fds[2], 1, timeout * 1000) <= 0) break;
421 454
             line = fgets(linebuf, sizeof(linebuf), fp);
422 455
           }

+ 7
- 0
postsrsd.default View File

@@ -6,6 +6,13 @@
6 6
 #
7 7
 #SRS_DOMAIN=example.com
8 8
 
9
+# Exclude additional domains.
10
+# You may list domains which shall not be subjected to address rewriting.
11
+# If a domain name starts with a dot, it matches all subdomains, but not
12
+# the domain itself. Separate multiple domains by space or comma.
13
+#
14
+#SRS_EXCLUDE_DOMAINS=.example.com,example.org
15
+
9 16
 # Secret key to sign rewritten addresses.
10 17
 # When postsrsd is installed for the first time, a random secret is generated
11 18
 # and stored in /etc/postsrsd.secret. For most installations, that's just fine.

+ 2
- 3
postsrsd.init.in View File

@@ -41,8 +41,6 @@ then
41 41
     . /etc/default/$NAME
42 42
 fi
43 43
 
44
-POSTSRS_OPTS="-4 -f$SRS_FORWARD_PORT -r$SRS_REVERSE_PORT -d$SRS_DOMAIN -s$SRS_SECRET -u$RUN_AS -p$PIDFILE -c$CHROOT -D"
45
-
46 44
 test -r "$SRS_SECRET" -a -n "$SRS_DOMAIN" || exit 0
47 45
 
48 46
 ret=0
@@ -52,7 +50,8 @@ case "$1" in
52 50
 	if start-stop-daemon --start --oknodo --quiet \
53 51
 		--pidfile $PIDFILE \
54 52
 		--name $NAME \
55
-		--startas $DAEMON -- $POSTSRS_OPTS
53
+		--startas $DAEMON \
54
+		-- -4 -f"$SRS_FORWARD_PORT" -r"$SRS_REVERSE_PORT" -d"$SRS_DOMAIN" -s"$SRS_SECRET" -u"$RUN_AS" -p"$PIDFILE" -c"$CHROOT" -X"$SRS_EXCLUDE_DOMAINS" -D
56 55
 	then
57 56
 	    log_end_msg 0
58 57
 	else

+ 2
- 1
postsrsd.upstart.in View File

@@ -12,11 +12,12 @@ script
12 12
 	SRS_FORWARD_PORT=10001
13 13
 	SRS_REVERSE_PORT=10002
14 14
 	SRS_SECRET=/etc/@PROJECT_NAME@.secret
15
+	SRS_EXCLUDE_DOMAINS=
15 16
 	RUN_AS=nobody
16 17
 	CHROOT=@CHROOT_DIR@
17 18
 	if [ -r "$DEFAULTFILE" ]; then
18 19
 		. "$DEFAULTFILE"
19 20
 	fi
20
-	exec @CMAKE_INSTALL_PREFIX@/sbin/@POSTSRSD@ -4 -f$SRS_FORWARD_PORT -r$SRS_REVERSE_PORT -d$SRS_DOMAIN -s$SRS_SECRET -u$RUN_AS -c$CHROOT
21
+	exec @CMAKE_INSTALL_PREFIX@/sbin/@POSTSRSD@ -4 -f"$SRS_FORWARD_PORT" -r"$SRS_REVERSE_PORT" -d"$SRS_DOMAIN" -s"$SRS_SECRET" -u"$RUN_AS" -c"$CHROOT" -X"$SRS_EXCLUDE_DOMAINS"
21 22
 end script
22 23
 

Loading…
Cancel
Save