Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/dma/conf.c
39475 views
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 <[email protected]>, 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
36
#include <err.h>
37
#include <errno.h>
38
#include <stdio.h>
39
#include <stdlib.h>
40
#include <string.h>
41
#include <syslog.h>
42
#include <stdarg.h>
43
44
#include "dma.h"
45
46
#define DP ": \t"
47
#define EQS " \t"
48
49
50
/*
51
* Remove trailing \n's
52
*/
53
void
54
trim_line(char *line)
55
{
56
size_t linelen;
57
char *p;
58
59
if ((p = strchr(line, '\n')))
60
*p = (char)0;
61
62
/* Escape leading dot in every case */
63
linelen = strlen(line);
64
if (line[0] == '.') {
65
if ((linelen + 2) > 1000) {
66
syslog(LOG_CRIT, "Cannot escape leading dot. Buffer overflow");
67
exit(EX_DATAERR);
68
}
69
memmove((line + 1), line, (linelen + 1));
70
line[0] = '.';
71
}
72
}
73
74
static void
75
chomp(char *str)
76
{
77
size_t len = strlen(str);
78
79
if (len == 0)
80
return;
81
if (str[len - 1] == '\n')
82
str[len - 1] = 0;
83
}
84
85
/*
86
* Read the SMTP authentication config file
87
*
88
* file format is:
89
* user|host:password
90
*
91
* A line starting with # is treated as comment and ignored.
92
*/
93
void
94
parse_authfile(const char *path)
95
{
96
char line[2048];
97
struct authuser *au;
98
FILE *a;
99
char *data;
100
int lineno = 0;
101
102
a = fopen(path, "r");
103
if (a == NULL) {
104
errlog(EX_NOINPUT, "can not open auth file `%s'", path);
105
/* NOTREACHED */
106
}
107
108
while (!feof(a)) {
109
if (fgets(line, sizeof(line), a) == NULL)
110
break;
111
lineno++;
112
113
chomp(line);
114
115
/* We hit a comment */
116
if (*line == '#')
117
continue;
118
/* Ignore empty lines */
119
if (*line == 0)
120
continue;
121
122
au = calloc(1, sizeof(*au));
123
if (au == NULL)
124
errlog(EX_OSERR, "calloc()");
125
126
data = strdup(line);
127
au->login = strsep(&data, "|");
128
au->host = strsep(&data, DP);
129
au->password = data;
130
131
if (au->login == NULL ||
132
au->host == NULL ||
133
au->password == NULL) {
134
errlogx(EX_CONFIG, "syntax error in authfile %s:%d", path, lineno);
135
/* NOTREACHED */
136
}
137
138
SLIST_INSERT_HEAD(&authusers, au, next);
139
}
140
141
fclose(a);
142
}
143
144
/*
145
* XXX TODO
146
* Check for bad things[TM]
147
*/
148
void
149
parse_conf(const char *config_path)
150
{
151
char *word;
152
char *data;
153
FILE *conf;
154
char line[2048];
155
int lineno = 0;
156
157
conf = fopen(config_path, "r");
158
if (conf == NULL) {
159
/* Don't treat a non-existing config file as error */
160
if (errno == ENOENT)
161
return;
162
errlog(EX_NOINPUT, "can not open config `%s'", config_path);
163
/* NOTREACHED */
164
}
165
166
while (!feof(conf)) {
167
if (fgets(line, sizeof(line), conf) == NULL)
168
break;
169
lineno++;
170
171
chomp(line);
172
173
/* We hit a comment */
174
if (strchr(line, '#'))
175
*strchr(line, '#') = 0;
176
177
data = line;
178
word = strsep(&data, EQS);
179
180
/* Ignore empty lines */
181
if (word == NULL || *word == 0)
182
continue;
183
184
if (data != NULL && *data != 0)
185
data = strdup(data);
186
else
187
data = NULL;
188
189
if (strcmp(word, "SMARTHOST") == 0 && data != NULL)
190
config.smarthost = data;
191
else if (strcmp(word, "PORT") == 0 && data != NULL)
192
config.port = atoi(data);
193
else if (strcmp(word, "ALIASES") == 0 && data != NULL)
194
config.aliases = data;
195
else if (strcmp(word, "SPOOLDIR") == 0 && data != NULL)
196
config.spooldir = data;
197
else if (strcmp(word, "AUTHPATH") == 0 && data != NULL)
198
config.authpath= data;
199
else if (strcmp(word, "CERTFILE") == 0 && data != NULL)
200
config.certfile = data;
201
else if (strcmp(word, "MAILNAME") == 0 && data != NULL)
202
config.mailname = data;
203
else if (strcmp(word, "MASQUERADE") == 0 && data != NULL) {
204
char *user = NULL, *host = NULL;
205
if (strrchr(data, '@')) {
206
host = strrchr(data, '@');
207
*host = 0;
208
host++;
209
user = data;
210
} else {
211
host = data;
212
}
213
if (host && *host == 0)
214
host = NULL;
215
if (user && *user == 0)
216
user = NULL;
217
config.masquerade_host = host;
218
config.masquerade_user = user;
219
} else if (strcmp(word, "STARTTLS") == 0 && data == NULL)
220
config.features |= STARTTLS;
221
else if (strcmp(word, "FINGERPRINT") == 0) {
222
if (strlen(data) != SHA256_DIGEST_LENGTH * 2) {
223
errlogx(EX_CONFIG, "invalid sha256 fingerprint length");
224
}
225
unsigned char *fingerprint = malloc(SHA256_DIGEST_LENGTH);
226
if (fingerprint == NULL) {
227
errlogx(EX_CONFIG, "fingerprint allocation failed");
228
}
229
unsigned int i;
230
for (i = 0; i < SHA256_DIGEST_LENGTH; i++) {
231
if(sscanf(data + 2 * i, "%02hhx", &fingerprint[i]) != 1) {
232
errlogx(EX_CONFIG, "failed to read fingerprint");
233
}
234
}
235
free(data);
236
config.fingerprint = fingerprint;
237
} else if (strcmp(word, "OPPORTUNISTIC_TLS") == 0 && data == NULL)
238
config.features |= TLS_OPP;
239
else if (strcmp(word, "SECURETRANSFER") == 0 && data == NULL)
240
config.features |= SECURETRANSFER;
241
else if (strcmp(word, "DEFER") == 0 && data == NULL)
242
config.features |= DEFER;
243
else if (strcmp(word, "INSECURE") == 0 && data == NULL)
244
config.features |= INSECURE;
245
else if (strcmp(word, "FULLBOUNCE") == 0 && data == NULL)
246
config.features |= FULLBOUNCE;
247
else if (strcmp(word, "NULLCLIENT") == 0 && data == NULL)
248
config.features |= NULLCLIENT;
249
else {
250
errlogx(EX_CONFIG, "syntax error in %s:%d", config_path, lineno);
251
/* NOTREACHED */
252
}
253
}
254
255
if ((config.features & NULLCLIENT) && config.smarthost == NULL) {
256
errlogx(EX_CONFIG, "%s: NULLCLIENT requires SMARTHOST", config_path);
257
/* NOTREACHED */
258
}
259
260
fclose(conf);
261
}
262
263