]> git.ipfire.org Git - people/ms/dma.git/blobdiff - conf.c
Merge pull request #34 from mtremer/better-authentication
[people/ms/dma.git] / conf.c
diff --git a/conf.c b/conf.c
index 02a7ca9f92d86a0d21bd8246183d8ff72d4e9971..3e3c7d3d8bd2af783d196ee850451bcb2f5f09df 100644 (file)
--- a/conf.c
+++ b/conf.c
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- *
- * $DragonFly: src/libexec/dma/conf.c,v 1.1 2008/02/02 18:20:51 matthias Exp $
  */
 
 #include <err.h>
+#include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
 #include "dma.h"
 
-#define DP     ": \t\n"
-#define EQS    " \t\n"
+#define DP     ": \t"
+#define EQS    " \t"
 
-extern struct virtusers virtusers;
-extern struct authusers authusers;
 
 /*
  * Remove trailing \n's
@@ -59,8 +56,6 @@ trim_line(char *line)
        size_t linelen;
        char *p;
 
-       p = line;
-
        if ((p = strchr(line, '\n')))
                *p = (char)0;
 
@@ -69,182 +64,182 @@ trim_line(char *line)
        if (line[0] == '.') {
                if ((linelen + 2) > 1000) {
                        syslog(LOG_CRIT, "Cannot escape leading dot.  Buffer overflow");
-                       exit(1);
+                       exit(EX_DATAERR);
                }
                memmove((line + 1), line, (linelen + 1));
                line[0] = '.';
        }
 }
 
-/*
- * Add a virtual user entry to the list of virtual users
- */
 static void
-add_virtuser(char *login, char *address)
+chomp(char *str)
 {
-       struct virtuser *v;
-
-       v = malloc(sizeof(struct virtuser));
-       v->login = strdup(login);
-       v->address = strdup(address);
-       SLIST_INSERT_HEAD(&virtusers, v, next);
-}
-
-/*
- * Read the virtual user table
- */
-int
-parse_virtuser(const char *path)
-{
-       FILE *v;
-       char *word;
-       char *data;
-       char line[2048];
-
-       v = fopen(path, "r");
-       if (v == NULL)
-               return (-1);
-
-       while (!feof(v)) {
-               fgets(line, sizeof(line), v);
-               /* We hit a comment */
-               if (strchr(line, '#'))
-                       *strchr(line, '#') = 0;
-               if ((word = strtok(line, DP)) != NULL) {
-                       data = strtok(NULL, DP);
-                       if (data != NULL) {
-                               add_virtuser(word, data);
-                       }
-               }
-       }
+       size_t len = strlen(str);
 
-       fclose(v);
-       return (0);
-}
-
-/*
- * Add entry to the SMTP auth user list
- */
-static void
-add_smtp_auth_user(char *userstring, char *password)
-{
-       struct authuser *a;
-       char *temp;
-
-       a = malloc(sizeof(struct virtuser));
-       a->password= strdup(password);
-
-       temp = strrchr(userstring, '|');
-       if (temp == NULL)
-               errx(1, "auth.conf file in wrong format");
-
-       a->host = strdup(temp+1);
-       a->login = strdup(strtok(userstring, "|"));
-       if (a->login == NULL)
-               errx(1, "auth.conf file in wrong format");
-
-       SLIST_INSERT_HEAD(&authusers, a, next);
+       if (len == 0)
+               return;
+       if (str[len - 1] == '\n')
+               str[len - 1] = 0;
 }
 
 /*
  * Read the SMTP authentication config file
+ *
+ * file format is:
+ * user|host:password
+ *
+ * A line starting with # is treated as comment and ignored.
  */
-int
+void
 parse_authfile(const char *path)
 {
+       char line[2048];
+       struct authuser *au;
        FILE *a;
-       char *word;
        char *data;
-       char line[2048];
+       int lineno = 0;
 
        a = fopen(path, "r");
-       if (a == NULL)
-               return (1);
+       if (a == NULL) {
+               errlog(EX_NOINPUT, "can not open auth file `%s'", path);
+               /* NOTREACHED */
+       }
 
        while (!feof(a)) {
-               fgets(line, sizeof(line), a);
+               if (fgets(line, sizeof(line), a) == NULL)
+                       break;
+               lineno++;
+
+               chomp(line);
+
                /* We hit a comment */
-               if (strchr(line, '#'))
-                       *strchr(line, '#') = 0;
-               if ((word = strtok(line, DP)) != NULL) {
-                       data = strtok(NULL, DP);
-                       if (data != NULL) {
-                               add_smtp_auth_user(word, data);
-                       }
+               if (*line == '#')
+                       continue;
+               /* Ignore empty lines */
+               if (*line == 0)
+                       continue;
+
+               au = calloc(1, sizeof(*au));
+               if (au == NULL)
+                       errlog(EX_OSERR, NULL);
+
+               data = strdup(line);
+               au->login = strsep(&data, "|");
+               au->host = strsep(&data, DP);
+               au->password = data;
+
+               if (au->login == NULL ||
+                   au->host == NULL ||
+                   au->password == NULL) {
+                       errlogx(EX_CONFIG, "syntax error in authfile %s:%d", path, lineno);
+                       /* NOTREACHED */
                }
+
+               SLIST_INSERT_HEAD(&authusers, au, next);
        }
 
        fclose(a);
-       return (0);
 }
 
 /*
  * XXX TODO
- * Check if the user supplied a value.  If not, fill in default
  * Check for bad things[TM]
  */
-int
-parse_conf(const char *config_path, struct config *config)
+void
+parse_conf(const char *config_path)
 {
        char *word;
        char *data;
        FILE *conf;
        char line[2048];
+       int lineno = 0;
 
        conf = fopen(config_path, "r");
-       if (conf == NULL)
-               return (-1);
-
-       /* Reset features */
-       config->features = 0;
+       if (conf == NULL) {
+               /* Don't treat a non-existing config file as error */
+               if (errno == ENOENT)
+                       return;
+               errlog(EX_NOINPUT, "can not open config `%s'", config_path);
+               /* NOTREACHED */
+       }
 
        while (!feof(conf)) {
-               fgets(line, sizeof(line), conf);
+               if (fgets(line, sizeof(line), conf) == NULL)
+                       break;
+               lineno++;
+
+               chomp(line);
+
                /* We hit a comment */
                if (strchr(line, '#'))
                        *strchr(line, '#') = 0;
-               if ((word = strtok(line, EQS)) != NULL) {
-                       data = strtok(NULL, EQS);
-                       if (strcmp(word, "SMARTHOST") == 0) {
-                               if (data != NULL)
-                                       config->smarthost = strdup(data);
-                       }
-                       else if (strcmp(word, "PORT") == 0) {
-                               if (data != NULL)
-                                       config->port = atoi(strdup(data));
-                       }
-                       else if (strcmp(word, "ALIASES") == 0) {
-                               if (data != NULL)
-                                       config->aliases = strdup(data);
-                       }
-                       else if (strcmp(word, "SPOOLDIR") == 0) {
-                               if (data != NULL)
-                                       config->spooldir = strdup(data);
-                       }
-                       else if (strcmp(word, "VIRTPATH") == 0) {
-                               if (data != NULL)
-                                       config->virtualpath = strdup(data);
-                       }
-                       else if (strcmp(word, "AUTHPATH") == 0) {
-                               if (data != NULL)
-                                       config->authpath= strdup(data);
-                       }
-                       else if (strcmp(word, "CERTFILE") == 0) {
-                               if (data != NULL)
-                                       config->certfile = strdup(data);
+
+               data = line;
+               word = strsep(&data, EQS);
+
+               /* Ignore empty lines */
+               if (word == NULL || *word == 0)
+                       continue;
+
+               if (data != NULL && *data != 0)
+                       data = strdup(data);
+               else
+                       data = NULL;
+
+               if (strcmp(word, "SMARTHOST") == 0 && data != NULL)
+                       config.smarthost = data;
+               else if (strcmp(word, "PORT") == 0 && data != NULL)
+                       config.port = atoi(data);
+               else if (strcmp(word, "ALIASES") == 0 && data != NULL)
+                       config.aliases = data;
+               else if (strcmp(word, "SPOOLDIR") == 0 && data != NULL)
+                       config.spooldir = data;
+               else if (strcmp(word, "AUTHPATH") == 0 && data != NULL)
+                       config.authpath= data;
+               else if (strcmp(word, "CERTFILE") == 0 && data != NULL)
+                       config.certfile = data;
+               else if (strcmp(word, "MAILNAME") == 0 && data != NULL)
+                       config.mailname = data;
+               else if (strcmp(word, "MASQUERADE") == 0 && data != NULL) {
+                       char *user = NULL, *host = NULL;
+                       if (strrchr(data, '@')) {
+                               host = strrchr(data, '@');
+                               *host = 0;
+                               host++;
+                               user = data;
+                       } else {
+                               host = data;
                        }
-                       else if (strcmp(word, "VIRTUAL") == 0)
-                               config->features |= VIRTUAL;
-                       else if (strcmp(word, "STARTTLS") == 0)
-                               config->features |= STARTTLS;
-                       else if (strcmp(word, "SECURETRANSFER") == 0)
-                               config->features |= SECURETRANS;
-                       else if (strcmp(word, "DEFER") == 0)
-                               config->features |= DEFER;
+                       if (host && *host == 0)
+                               host = NULL;
+                        if (user && *user == 0)
+                                user = NULL;
+                       config.masquerade_host = host;
+                       config.masquerade_user = user;
+               } else if (strcmp(word, "STARTTLS") == 0 && data == NULL)
+                       config.features |= STARTTLS;
+               else if (strcmp(word, "OPPORTUNISTIC_TLS") == 0 && data == NULL)
+                       config.features |= TLS_OPP;
+               else if (strcmp(word, "SECURETRANSFER") == 0 && data == NULL)
+                       config.features |= SECURETRANS;
+               else if (strcmp(word, "DEFER") == 0 && data == NULL)
+                       config.features |= DEFER;
+               else if (strcmp(word, "INSECURE") == 0 && data == NULL)
+                       config.features |= INSECURE;
+               else if (strcmp(word, "FULLBOUNCE") == 0 && data == NULL)
+                       config.features |= FULLBOUNCE;
+               else if (strcmp(word, "NULLCLIENT") == 0 && data == NULL)
+                       config.features |= NULLCLIENT;
+               else {
+                       errlogx(EX_CONFIG, "syntax error in %s:%d", config_path, lineno);
+                       /* NOTREACHED */
                }
        }
 
+       if ((config.features & NULLCLIENT) && config.smarthost == NULL) {
+               errlogx(EX_CONFIG, "%s: NULLCLIENT requires SMARTHOST", config_path);
+               /* NOTREACHED */
+       }
+
        fclose(conf);
-       return (0);
 }
-