1 /* 2 * Copyright (c) 2008 The DragonFly Project. All rights reserved. 3 * 4 * This code is derived from software contributed to The DragonFly Project 5 * by Matthias Schmidt <matthias@dragonflybsd.org>, University of Marburg, 6 * Germany. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in 16 * the documentation and/or other materials provided with the 17 * distribution. 18 * 3. Neither the name of The DragonFly Project nor the names of its 19 * contributors may be used to endorse or promote products derived 20 * from this software without specific, prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 26 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 27 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 30 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 32 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * 35 * $DragonFly: src/libexec/dma/conf.c,v 1.2 2008/02/04 10:11:41 matthias Exp $ 36 */ 37 38 #include <err.h> 39 #include <stdio.h> 40 #include <stdlib.h> 41 #include <string.h> 42 #include <syslog.h> 43 #include <stdarg.h> 44 45 #include "dma.h" 46 47 #define DP ": \t\n" 48 #define EQS " \t\n" 49 50 extern struct virtusers virtusers; 51 extern struct authusers authusers; 52 53 /* 54 * Remove trailing \n's 55 */ 56 void 57 trim_line(char *line) 58 { 59 size_t linelen; 60 char *p; 61 62 p = line; 63 64 if ((p = strchr(line, '\n'))) 65 *p = (char)0; 66 67 /* Escape leading dot in every case */ 68 linelen = strlen(line); 69 if (line[0] == '.') { 70 if ((linelen + 2) > 1000) { 71 syslog(LOG_CRIT, "Cannot escape leading dot. Buffer overflow"); 72 exit(1); 73 } 74 memmove((line + 1), line, (linelen + 1)); 75 line[0] = '.'; 76 } 77 } 78 79 /* 80 * Add a virtual user entry to the list of virtual users 81 */ 82 static void 83 add_virtuser(char *login, char *address) 84 { 85 struct virtuser *v; 86 87 v = malloc(sizeof(struct virtuser)); 88 v->login = strdup(login); 89 v->address = strdup(address); 90 SLIST_INSERT_HEAD(&virtusers, v, next); 91 } 92 93 /* 94 * Read the virtual user table 95 */ 96 int 97 parse_virtuser(const char *path) 98 { 99 FILE *v; 100 char *word; 101 char *data; 102 char line[2048]; 103 104 v = fopen(path, "r"); 105 if (v == NULL) 106 return (-1); 107 108 while (!feof(v)) { 109 fgets(line, sizeof(line), v); 110 /* We hit a comment */ 111 if (strchr(line, '#')) 112 *strchr(line, '#') = 0; 113 if ((word = strtok(line, DP)) != NULL) { 114 data = strtok(NULL, DP); 115 if (data != NULL) { 116 add_virtuser(word, data); 117 } 118 } 119 } 120 121 fclose(v); 122 return (0); 123 } 124 125 /* 126 * Add entry to the SMTP auth user list 127 */ 128 static void 129 add_smtp_auth_user(char *userstring, char *password) 130 { 131 struct authuser *a; 132 char *temp; 133 134 a = malloc(sizeof(struct virtuser)); 135 a->password= strdup(password); 136 137 temp = strrchr(userstring, '|'); 138 if (temp == NULL) 139 errx(1, "auth.conf file in wrong format"); 140 141 a->host = strdup(temp+1); 142 a->login = strdup(strtok(userstring, "|")); 143 if (a->login == NULL) 144 errx(1, "auth.conf file in wrong format"); 145 146 SLIST_INSERT_HEAD(&authusers, a, next); 147 } 148 149 /* 150 * Read the SMTP authentication config file 151 */ 152 int 153 parse_authfile(const char *path) 154 { 155 FILE *a; 156 char *word; 157 char *data; 158 char line[2048]; 159 160 a = fopen(path, "r"); 161 if (a == NULL) 162 return (1); 163 164 while (!feof(a)) { 165 fgets(line, sizeof(line), a); 166 /* We hit a comment */ 167 if (strchr(line, '#')) 168 *strchr(line, '#') = 0; 169 if ((word = strtok(line, DP)) != NULL) { 170 data = strtok(NULL, DP); 171 if (data != NULL) { 172 add_smtp_auth_user(word, data); 173 } 174 } 175 } 176 177 fclose(a); 178 return (0); 179 } 180 181 /* 182 * XXX TODO 183 * Check if the user supplied a value. If not, fill in default 184 * Check for bad things[TM] 185 */ 186 int 187 parse_conf(const char *config_path, struct config *config) 188 { 189 char *word; 190 char *data; 191 FILE *conf; 192 char line[2048]; 193 194 conf = fopen(config_path, "r"); 195 if (conf == NULL) 196 return (-1); 197 198 /* Reset features */ 199 config->features = 0; 200 201 while (!feof(conf)) { 202 fgets(line, sizeof(line), conf); 203 /* We hit a comment */ 204 if (strchr(line, '#')) 205 *strchr(line, '#') = 0; 206 if ((word = strtok(line, EQS)) != NULL) { 207 data = strtok(NULL, EQS); 208 if (strcmp(word, "SMARTHOST") == 0) { 209 if (data != NULL) 210 config->smarthost = strdup(data); 211 } 212 else if (strcmp(word, "PORT") == 0) { 213 if (data != NULL) 214 config->port = atoi(strdup(data)); 215 } 216 else if (strcmp(word, "ALIASES") == 0) { 217 if (data != NULL) 218 config->aliases = strdup(data); 219 } 220 else if (strcmp(word, "SPOOLDIR") == 0) { 221 if (data != NULL) 222 config->spooldir = strdup(data); 223 } 224 else if (strcmp(word, "VIRTPATH") == 0) { 225 if (data != NULL) 226 config->virtualpath = strdup(data); 227 } 228 else if (strcmp(word, "AUTHPATH") == 0) { 229 if (data != NULL) 230 config->authpath= strdup(data); 231 } 232 else if (strcmp(word, "CERTFILE") == 0) { 233 if (data != NULL) 234 config->certfile = strdup(data); 235 } 236 else if (strcmp(word, "VIRTUAL") == 0) 237 config->features |= VIRTUAL; 238 else if (strcmp(word, "STARTTLS") == 0) 239 config->features |= STARTTLS; 240 else if (strcmp(word, "SECURETRANSFER") == 0) 241 config->features |= SECURETRANS; 242 else if (strcmp(word, "DEFER") == 0) 243 config->features |= DEFER; 244 else if (strcmp(word, "INSECURE") == 0) 245 config->features |= INSECURE; 246 } 247 } 248 249 fclose(conf); 250 return (0); 251 } 252 253