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
 build
1
 build
2
+.project
3
+.cproject
4
+.settings

+ 4
- 2
README.md View File

33
 
33
 
34
 Configuration
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
 one from `/dev/urandom`. Be careful that no one can guess your secret,
38
 one from `/dev/urandom`. Be careful that no one can guess your secret,
39
 because anyone who knows it can use your mail server as open relay!
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
 PostSRSd exposes its functionality via two TCP lookup tables. The
43
 PostSRSd exposes its functionality via two TCP lookup tables. The
42
 recommended Postfix configuration is to add the following fragment to
44
 recommended Postfix configuration is to add the following fragment to

+ 56
- 23
postsrsd.c View File

85
   if (c >= '0' && c <= '9') return c - '0';
85
   if (c >= '0' && c <= '9') return c - '0';
86
   if (c >= 'a' && c <= 'f') return c - 'a' + 10;
86
   if (c >= 'a' && c <= 'f') return c - 'a' + 10;
87
   if (c >= 'A' && c <= 'F') return c - 'A' + 10;
87
   if (c >= 'A' && c <= 'F') return c - 'A' + 10;
88
+  return 0;
88
 }
89
 }
89
 
90
 
90
 static char num2hex (char c)
91
 static char num2hex (char c)
139
   return buf;
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
   int result;
145
   int result;
146
+  size_t addrlen;
145
   char value[1024];
147
   char value[1024];
146
   char outputbuf[1024], *output;
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
   result = srs_forward(srs, value, sizeof(value), address, domain);
161
   result = srs_forward(srs, value, sizeof(value), address, domain);
149
   if (result == SRS_SUCCESS) {
162
   if (result == SRS_SUCCESS) {
150
     output = url_encode(outputbuf, sizeof(outputbuf), value);
163
     output = url_encode(outputbuf, sizeof(outputbuf), value);
158
   fflush (fp);
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
   int result;
176
   int result;
164
   char value[1024];
177
   char value[1024];
188
     "\n"
201
     "\n"
189
     "Usage: %s -s<file> -d<domain> [other options]\n"
202
     "Usage: %s -s<file> -d<domain> [other options]\n"
190
     "Options:\n"
203
     "Options:\n"
191
-    "   -s<file>       read secret from file (required)\n"
204
+    "   -s<file>       read secrets from file (required)\n"
192
     "   -d<domain>     set domain name for rewrite (required)\n"
205
     "   -d<domain>     set domain name for rewrite (required)\n"
193
     "   -f<port>       set port for the forward SRS lookup (default: 10001)\n"
206
     "   -f<port>       set port for the forward SRS lookup (default: 10001)\n"
194
     "   -r<port>       set port for the reverse SRS lookup (default: 10002)\n"
207
     "   -r<port>       set port for the reverse SRS lookup (default: 10002)\n"
196
     "   -c<dir>        chroot to <dir> (default: none)\n"
209
     "   -c<dir>        chroot to <dir> (default: none)\n"
197
     "   -u<user>       switch user id after port bind (default: none)\n"
210
     "   -u<user>       switch user id after port bind (default: none)\n"
198
     "   -t<seconds>    timeout for idle client connections (default: 1800)\n"
211
     "   -t<seconds>    timeout for idle client connections (default: 1800)\n"
212
+    "   -X<domain>     exclude additional domain from address rewriting\n"
199
     "   -D             fork into background\n"
213
     "   -D             fork into background\n"
200
     "   -4             force IPv4 socket (default: any)\n"
214
     "   -4             force IPv4 socket (default: any)\n"
201
     "   -6             force IPv6 socket (default: any)\n"
215
     "   -6             force IPv6 socket (default: any)\n"
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
 int main (int argc, char **argv)
225
 int main (int argc, char **argv)
212
 {
226
 {
216
        *user = NULL, *domain = NULL, *chroot_dir = NULL;
230
        *user = NULL, *domain = NULL, *chroot_dir = NULL;
217
   int forward_sock, reverse_sock;
231
   int forward_sock, reverse_sock;
218
   char *secret_file = NULL, *pid_file = NULL;
232
   char *secret_file = NULL, *pid_file = NULL;
219
-  FILE *pf = NULL;
233
+  FILE *pf = NULL, *sf = NULL;
220
   struct passwd *pwd = NULL;
234
   struct passwd *pwd = NULL;
221
-  char secret[1024];
235
+  char secretbuf[1024], *secret = NULL;
222
   char *tmp;
236
   char *tmp;
223
   srs_t *srs;
237
   srs_t *srs;
224
   struct pollfd fds[3];
238
   struct pollfd fds[3];
239
+  const char **excludes;
240
+  size_t s1 = 0, s2 = 1;
225
   handle_t handler[2] = { handle_forward, handle_reverse };
241
   handle_t handler[2] = { handle_forward, handle_reverse };
226
 
242
 
243
+  excludes = (const char**)calloc(1, sizeof(char*));
227
   tmp = strrchr(argv[0], '/');
244
   tmp = strrchr(argv[0], '/');
228
   if (tmp) self = strdup(tmp + 1); else self = strdup(argv[0]);
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
     switch (opt) {
248
     switch (opt) {
232
       case '?':
249
       case '?':
233
         return EXIT_FAILURE;
250
         return EXIT_FAILURE;
259
         user = strdup(optarg);
276
         user = strdup(optarg);
260
         break;
277
         break;
261
       case 'c':
278
       case 'c':
262
-	chroot_dir = strdup(optarg);
263
-	break;
279
+        chroot_dir = strdup(optarg);
280
+        break;
264
       case 'D':
281
       case 'D':
265
         daemonize = TRUE;
282
         daemonize = TRUE;
266
         break;
283
         break;
267
       case 'h':
284
       case 'h':
268
-	show_help();
285
+        show_help();
269
         return EXIT_SUCCESS;
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
       case 'v':
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
   if (domain == NULL) {
310
   if (domain == NULL) {
291
   /* Read secret. The default installation makes this root accessible only. */
326
   /* Read secret. The default installation makes this root accessible only. */
292
   if (secret_file != NULL) {
327
   if (secret_file != NULL) {
293
     size_t len;
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
       fprintf (stderr, "%s: Cannot open file with secret: %s\n", self, secret_file);
331
       fprintf (stderr, "%s: Cannot open file with secret: %s\n", self, secret_file);
297
       return EXIT_FAILURE;
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
   } else {
334
   } else {
307
     fprintf (stderr, "%s: You must set a secret (-s)\n", self);
335
     fprintf (stderr, "%s: You must set a secret (-s)\n", self);
308
     show_help();
336
     show_help();
370
   }
398
   }
371
 
399
 
372
   srs = srs_new();
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
   srs_set_separator (srs, '+');
407
   srs_set_separator (srs, '+');
375
 
408
 
376
   fds[0].fd = forward_sock;
409
   fds[0].fd = forward_sock;
416
             }
449
             }
417
             key = url_decode(keybuf, sizeof(keybuf), token);
450
             key = url_decode(keybuf, sizeof(keybuf), token);
418
             if (!key) break;
451
             if (!key) break;
419
-            handler[i](srs, fp, key, domain);
452
+            handler[i](srs, fp, key, domain, excludes);
420
             if (poll(&fds[2], 1, timeout * 1000) <= 0) break;
453
             if (poll(&fds[2], 1, timeout * 1000) <= 0) break;
421
             line = fgets(linebuf, sizeof(linebuf), fp);
454
             line = fgets(linebuf, sizeof(linebuf), fp);
422
           }
455
           }

+ 7
- 0
postsrsd.default View File

6
 #
6
 #
7
 #SRS_DOMAIN=example.com
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
 # Secret key to sign rewritten addresses.
16
 # Secret key to sign rewritten addresses.
10
 # When postsrsd is installed for the first time, a random secret is generated
17
 # When postsrsd is installed for the first time, a random secret is generated
11
 # and stored in /etc/postsrsd.secret. For most installations, that's just fine.
18
 # and stored in /etc/postsrsd.secret. For most installations, that's just fine.

+ 2
- 3
postsrsd.init.in View File

41
     . /etc/default/$NAME
41
     . /etc/default/$NAME
42
 fi
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
 test -r "$SRS_SECRET" -a -n "$SRS_DOMAIN" || exit 0
44
 test -r "$SRS_SECRET" -a -n "$SRS_DOMAIN" || exit 0
47
 
45
 
48
 ret=0
46
 ret=0
52
 	if start-stop-daemon --start --oknodo --quiet \
50
 	if start-stop-daemon --start --oknodo --quiet \
53
 		--pidfile $PIDFILE \
51
 		--pidfile $PIDFILE \
54
 		--name $NAME \
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
 	then
55
 	then
57
 	    log_end_msg 0
56
 	    log_end_msg 0
58
 	else
57
 	else

+ 2
- 1
postsrsd.upstart.in View File

12
 	SRS_FORWARD_PORT=10001
12
 	SRS_FORWARD_PORT=10001
13
 	SRS_REVERSE_PORT=10002
13
 	SRS_REVERSE_PORT=10002
14
 	SRS_SECRET=/etc/@PROJECT_NAME@.secret
14
 	SRS_SECRET=/etc/@PROJECT_NAME@.secret
15
+	SRS_EXCLUDE_DOMAINS=
15
 	RUN_AS=nobody
16
 	RUN_AS=nobody
16
 	CHROOT=@CHROOT_DIR@
17
 	CHROOT=@CHROOT_DIR@
17
 	if [ -r "$DEFAULTFILE" ]; then
18
 	if [ -r "$DEFAULTFILE" ]; then
18
 		. "$DEFAULTFILE"
19
 		. "$DEFAULTFILE"
19
 	fi
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
 end script
22
 end script
22
 
23
 

Loading…
Cancel
Save