Mercurial > notdcc
comparison dcclib/parse_srvr_nm.c @ 0:c7f6b056b673
First import of vendor version
author | Peter Gervai <grin@grin.hu> |
---|---|
date | Tue, 10 Mar 2009 13:49:58 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:c7f6b056b673 |
---|---|
1 /* Distributed Checksum Clearinghouse | |
2 * | |
3 * Copyright (c) 2008 by Rhyolite Software, LLC | |
4 * | |
5 * This agreement is not applicable to any entity which sells anti-spam | |
6 * solutions to others or provides an anti-spam solution as part of a | |
7 * security solution sold to other entities, or to a private network | |
8 * which employs the DCC or uses data provided by operation of the DCC | |
9 * but does not provide corresponding data to other users. | |
10 * | |
11 * Permission to use, copy, modify, and distribute this software without | |
12 * changes for any purpose with or without fee is hereby granted, provided | |
13 * that the above copyright notice and this permission notice appear in all | |
14 * copies and any distributed versions or copies are either unchanged | |
15 * or not called anything similar to "DCC" or "Distributed Checksum | |
16 * Clearinghouse". | |
17 * | |
18 * Parties not eligible to receive a license under this agreement can | |
19 * obtain a commercial license to use DCC by contacting Rhyolite Software | |
20 * at sales@rhyolite.com. | |
21 * | |
22 * A commercial license would be for Distributed Checksum and Reputation | |
23 * Clearinghouse software. That software includes additional features. This | |
24 * free license for Distributed ChecksumClearinghouse Software does not in any | |
25 * way grant permision to use Distributed Checksum and Reputation Clearinghouse | |
26 * software | |
27 * | |
28 * THE SOFTWARE IS PROVIDED "AS IS" AND RHYOLITE SOFTWARE, LLC DISCLAIMS ALL | |
29 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES | |
30 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL RHYOLITE SOFTWARE, LLC | |
31 * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES | |
32 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | |
33 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |
34 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | |
35 * SOFTWARE. | |
36 * | |
37 * Rhyolite Software DCC 1.3.103-1.47 $Revision$ | |
38 */ | |
39 | |
40 #include "dcc_clnt.h" | |
41 | |
42 | |
43 /* open a file of server names, ports, and so forth */ | |
44 FILE * | |
45 dcc_open_srvr_nm(DCC_EMSG emsg, const char *nm) | |
46 { | |
47 FILE *f; | |
48 DCC_PATH path; | |
49 | |
50 f = fopen(nm, "r"); | |
51 if (!f) { | |
52 dcc_pemsg(EX_NOINPUT, emsg, | |
53 "fopen(%s): %s", fnm2abs_err(path, nm), ERROR_STR()); | |
54 return 0; | |
55 } | |
56 | |
57 /* the file contains passwords, | |
58 * so refuse to use it if everyone can read it */ | |
59 if (!dcc_ck_private(emsg, 0, nm, fileno(f))) { | |
60 fclose(f); | |
61 return 0; | |
62 } | |
63 return f; | |
64 } | |
65 | |
66 | |
67 | |
68 /* get "hostname,port" string from the start of a line */ | |
69 const char * /* 0=bad, rest of line if ok */ | |
70 dcc_parse_nm_port(DCC_EMSG emsg, | |
71 const char *line0, | |
72 u_int def_port, /* default or DCC_GET_PORT_INVALID */ | |
73 char *hostname, /* put host name here */ | |
74 u_int hostname_len, | |
75 u_int16_t *portp, /* put port # in network byte order */ | |
76 char *portname, /* put port name here */ | |
77 u_int portname_len, | |
78 const char *fnm, int lno) /* configuration file source */ | |
79 { | |
80 DCC_FNM_LNO_BUF fnm_buf; | |
81 char buf[DCC_MAXDOMAINLEN+1+MAXPORTNAMELEN+1]; /* "name,#\0" */ | |
82 const char *line; | |
83 const char *pstr; | |
84 u_int port; | |
85 u_int hlen; | |
86 | |
87 | |
88 /* get both parameters */ | |
89 line = dcc_parse_word(emsg, buf, sizeof(buf), line0, | |
90 "hostname,port", fnm, lno); | |
91 if (!line) | |
92 return 0; | |
93 | |
94 /* get the hostname and separate the port number */ | |
95 pstr = strchr(buf, ','); | |
96 if (!pstr) { | |
97 if (def_port == DCC_GET_PORT_INVALID) { | |
98 dcc_pemsg(EX_USAGE, emsg, "missing port in \"%s\"%s", | |
99 buf, fnm_lno(&fnm_buf, fnm, lno)); | |
100 return 0; | |
101 } | |
102 hlen = strlen(buf); | |
103 pstr = "-"; | |
104 } else { | |
105 hlen = pstr++ - buf; | |
106 } | |
107 | |
108 if (hostname_len) { | |
109 memset(hostname, 0, hostname_len); | |
110 if (hlen >= hostname_len) { | |
111 dcc_pemsg(EX_NOHOST, emsg, | |
112 "hostname \"%.16s...\" too long%s", | |
113 buf, fnm_lno(&fnm_buf, fnm, lno)); | |
114 return 0; | |
115 } | |
116 if (hlen) | |
117 memcpy(hostname, buf, hlen); | |
118 } | |
119 if (portname_len) { | |
120 memset(portname, 0, portname_len); | |
121 hlen = strlen(pstr); | |
122 if (hlen >= portname_len) | |
123 hlen = portname_len-1; | |
124 if (hlen) | |
125 memcpy(portname, pstr, hlen); | |
126 } | |
127 | |
128 /* get the port number */ | |
129 port = dcc_get_port(emsg, pstr, def_port, fnm, lno); | |
130 if (port == DCC_GET_PORT_INVALID) | |
131 return 0; | |
132 | |
133 if (portp) | |
134 *portp = port; | |
135 return line; | |
136 } | |
137 | |
138 | |
139 | |
140 /* parse a line of the following form | |
141 * hostname[,port-#] [RTT+adj] [Greylist] [client-ID [password]] | |
142 * The port-# can be "-" to specifiy the default DCC server port. | |
143 * If both the client-ID and the password are absent, then the anonymous | |
144 * client-ID is used. | |
145 * A null string is assumed if the password is missing. | |
146 */ | |
147 int /* 1=parsed, 0=bad, -1=unknown name */ | |
148 dcc_parse_srvr_nm(DCC_EMSG emsg, | |
149 DCC_SRVR_NM *nmp, /* build this entry */ | |
150 u_char *pgrey, /* 1=for greylisting */ | |
151 const char *line, /* from this string */ | |
152 const char *fnm, int lno) /* that came from here */ | |
153 { | |
154 DCC_FNM_LNO_BUF fnm_buf; | |
155 char id_buf[12]; | |
156 char port_buf[3]; | |
157 char *p; | |
158 long l; | |
159 | |
160 memset(nmp, 0, sizeof(DCC_SRVR_NM)); | |
161 | |
162 line = dcc_parse_nm_port(emsg, line, DCC_GREY2PORT(pgrey && *pgrey), | |
163 nmp->hostname, sizeof(nmp->hostname), | |
164 &nmp->port, port_buf, sizeof(port_buf), | |
165 fnm, lno); | |
166 if (!line) | |
167 return 0; | |
168 | |
169 for (;;) { | |
170 /* look for greylist flag */ | |
171 if (!CLITCMP(line, "greylist") | |
172 && (line[LITZ("greylist")] == '\0' | |
173 || line[LITZ("greylist")] == ' ' | |
174 || line[LITZ("greylist")] == '\t')) { | |
175 line += LITZ("greylist")+strspn(line+LITZ("greylist"), | |
176 DCC_WHITESPACE); | |
177 if (pgrey) | |
178 *pgrey = 1; | |
179 if (port_buf[0] == '\0' || !strcmp(port_buf, "-")) | |
180 nmp->port = htons(DCC_GREY_PORT); | |
181 continue; | |
182 } | |
183 | |
184 /* look for optional RTT adjustment */ | |
185 if (CLITCMP(line, "rtt")) | |
186 break; | |
187 line += LITZ("rtt")+strspn(line+LITZ("rtt"), DCC_WHITESPACE); | |
188 l = strtol(line, &p, 10); | |
189 if (p != line) { | |
190 int wsp = strspn(p, DCC_WHITESPACE); | |
191 if (!CLITCMP(p+wsp, "ms")) | |
192 p += wsp+LITZ("ms"); | |
193 } | |
194 if (p == line | |
195 || (*p != '\0' && *p != ' ' && *p != '\t')) { | |
196 dcc_pemsg(EX_DATAERR, emsg, | |
197 "invalid RTT adjustment%s", | |
198 fnm_lno(&fnm_buf, fnm, lno)); | |
199 return 0; | |
200 } | |
201 if (l < -DCC_RTT_ADJ_MAX/1000) { | |
202 l = -DCC_RTT_ADJ_MAX/1000; | |
203 } else if (l > DCC_RTT_ADJ_MAX/1000) { | |
204 l = DCC_RTT_ADJ_MAX/1000; | |
205 } | |
206 nmp->rtt_adj = l*1000; | |
207 line = p+strspn(p, DCC_WHITESPACE); | |
208 } | |
209 | |
210 /* get the client-ID */ | |
211 line = dcc_parse_word(emsg, id_buf, sizeof(id_buf), | |
212 line, "client-ID", fnm, lno); | |
213 if (!line) | |
214 return 0; | |
215 if (id_buf[0] == '\0') { | |
216 nmp->clnt_id = DCC_ID_ANON; | |
217 } else { | |
218 nmp->clnt_id = dcc_get_id(emsg, id_buf, fnm, lno); | |
219 if (nmp->clnt_id == DCC_ID_INVALID) | |
220 return 0; | |
221 if (nmp->clnt_id < DCC_CLNT_ID_MIN | |
222 && nmp->clnt_id != DCC_ID_ANON) { | |
223 dcc_pemsg(EX_DATAERR, emsg, | |
224 "server-ID %d is not a client-ID", | |
225 nmp->clnt_id); | |
226 return 0; | |
227 } | |
228 } | |
229 | |
230 /* allow null password only for anonymous clients | |
231 * clients of greylist servers cannot be anonymous */ | |
232 if (nmp->clnt_id == DCC_ID_ANON) { | |
233 if (*line != '\0') { | |
234 dcc_pemsg(EX_DATAERR, emsg, | |
235 "password invalid for %s" | |
236 " with anonymous client-ID%s", | |
237 nmp->hostname, | |
238 fnm_lno(&fnm_buf, fnm, lno)); | |
239 return 0; | |
240 } | |
241 return 1; | |
242 } | |
243 | |
244 if (*line == '\0') { | |
245 dcc_pemsg(EX_DATAERR, emsg, | |
246 "invalid null password for client-ID %d for %s%s", | |
247 nmp->clnt_id, nmp->hostname, | |
248 fnm_lno(&fnm_buf, fnm, lno)); | |
249 return 0; | |
250 } | |
251 | |
252 line = parse_passwd(emsg, nmp->passwd, line, "passwd", fnm, lno); | |
253 if (!line) | |
254 return 0; | |
255 if (nmp->passwd[0] == '\0' || *line != '\0') { | |
256 dcc_pemsg(EX_DATAERR, emsg, | |
257 "invalid password server %s, client-ID %d%s", | |
258 nmp->hostname, nmp->clnt_id, | |
259 fnm_lno(&fnm_buf, fnm, lno)); | |
260 return 0; | |
261 } | |
262 | |
263 return 1; | |
264 } |