Mercurial > notdcc
comparison dcclib/xhdr.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 * build and parse headers | |
4 * | |
5 * Copyright (c) 2008 by Rhyolite Software, LLC | |
6 * | |
7 * This agreement is not applicable to any entity which sells anti-spam | |
8 * solutions to others or provides an anti-spam solution as part of a | |
9 * security solution sold to other entities, or to a private network | |
10 * which employs the DCC or uses data provided by operation of the DCC | |
11 * but does not provide corresponding data to other users. | |
12 * | |
13 * Permission to use, copy, modify, and distribute this software without | |
14 * changes for any purpose with or without fee is hereby granted, provided | |
15 * that the above copyright notice and this permission notice appear in all | |
16 * copies and any distributed versions or copies are either unchanged | |
17 * or not called anything similar to "DCC" or "Distributed Checksum | |
18 * Clearinghouse". | |
19 * | |
20 * Parties not eligible to receive a license under this agreement can | |
21 * obtain a commercial license to use DCC by contacting Rhyolite Software | |
22 * at sales@rhyolite.com. | |
23 * | |
24 * A commercial license would be for Distributed Checksum and Reputation | |
25 * Clearinghouse software. That software includes additional features. This | |
26 * free license for Distributed ChecksumClearinghouse Software does not in any | |
27 * way grant permision to use Distributed Checksum and Reputation Clearinghouse | |
28 * software | |
29 * | |
30 * THE SOFTWARE IS PROVIDED "AS IS" AND RHYOLITE SOFTWARE, LLC DISCLAIMS ALL | |
31 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES | |
32 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL RHYOLITE SOFTWARE, LLC | |
33 * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES | |
34 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | |
35 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |
36 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | |
37 * SOFTWARE. | |
38 * | |
39 * Rhyolite Software DCC 1.3.103-1.37 $Revision$ | |
40 */ | |
41 | |
42 #include "dcc_clnt.h" | |
43 #include "dcc_xhdr.h" | |
44 | |
45 | |
46 /* add text to the growing X-DCC header line */ | |
47 void | |
48 xhdr_add_str(DCC_HEADER_BUF *hdr, const char *p, ...) | |
49 { | |
50 char *hp; | |
51 u_int lim, n; | |
52 va_list args; | |
53 | |
54 lim = sizeof(hdr->buf) - hdr->used; | |
55 if (lim <= 0) | |
56 return; | |
57 hp = &hdr->buf[hdr->used]; | |
58 if (*(hp-1) == '\n') { | |
59 *(hp-1) = ' '; | |
60 ++hdr->col; | |
61 } | |
62 va_start(args, p); | |
63 n = vsnprintf(hp, lim, p, args); | |
64 va_end(args); | |
65 if (n >= lim-3) { | |
66 dcc_error_msg("header buffer too small"); | |
67 hdr->buf[lim-1] = '\n'; | |
68 hdr->used = sizeof(hdr->buf); | |
69 return; | |
70 } | |
71 hdr->col += n; | |
72 hp[n++] = '\n'; | |
73 hp[n] = '\0'; | |
74 hdr->used += n; | |
75 | |
76 /* follow RFC 2822 and limit lines to 78 */ | |
77 if (hdr->col > DCC_MAX_HDR_LINE /* if pushed past line end, */ | |
78 && *(hp-1) == ' ' /* & not the first cksum report, */ | |
79 && hdr->used < sizeof(hdr->buf)-2) { /* & have space */ | |
80 memmove(hp+1, hp, n+1); /* then break the line */ | |
81 *(hp-1) = '\n'; | |
82 *hp = '\t'; | |
83 hdr->col = n+8; | |
84 ++hdr->used; | |
85 } | |
86 } | |
87 | |
88 | |
89 | |
90 /* generate X-DCC field name */ | |
91 int /* bytes put into buffer */ | |
92 get_xhdr_fname(char *xhdr, int xhdr_len, const DCC_CLNT_INFO *info) | |
93 { | |
94 SRVR_INX srvr_inx; | |
95 const char *brand; | |
96 int i; | |
97 | |
98 if (!info | |
99 || !GOOD_SRVR(&info->dcc, srvr_inx = info->dcc.srvr_inx)) { | |
100 brand = ""; | |
101 i = 0; | |
102 } else { | |
103 brand = info->dcc.addrs[srvr_inx].brand; | |
104 i = xhdr_len-sizeof(DCC_XHDR_START); | |
105 if (i < 0) | |
106 i = 0; | |
107 if (i > ISZ(DCC_BRAND)) | |
108 i = ISZ(DCC_BRAND); | |
109 } | |
110 | |
111 i = snprintf(xhdr, xhdr_len, DCC_XHDR_PAT, i, brand); | |
112 if (i >= xhdr_len) | |
113 i = xhdr_len-1; | |
114 return i; | |
115 } | |
116 | |
117 | |
118 | |
119 /* get ready to generate an X-DCC header including generating the | |
120 * field name */ | |
121 void | |
122 xhdr_init(DCC_HEADER_BUF *hdr, DCC_SRVR_ID srvr_id) | |
123 { | |
124 if (srvr_id < DCC_SRVR_ID_MIN || srvr_id > DCC_SRVR_ID_MAX) { | |
125 hdr->used = get_xhdr_fname(hdr->buf, sizeof(hdr->buf)-8, | |
126 0); | |
127 } else { | |
128 hdr->used = get_xhdr_fname(hdr->buf, sizeof(hdr->buf)-8, | |
129 dcc_clnt_info); | |
130 } | |
131 hdr->col = hdr->used; | |
132 hdr->start_len = hdr->used; | |
133 | |
134 xhdr_add_str(hdr, ": %s %d;", dcc_clnt_hostname, srvr_id); | |
135 } | |
136 | |
137 | |
138 | |
139 /* add a checksum and its counts to a growing X-DCC-Warning header line */ | |
140 void | |
141 xhdr_add_ck(DCC_HEADER_BUF *hdr, | |
142 DCC_CK_TYPES type, /* which kind of checksum */ | |
143 DCC_TGTS tgts) | |
144 { | |
145 char tbuf[30], ckcnt[10]; | |
146 | |
147 xhdr_add_str(hdr, "%s=%s", | |
148 dcc_type2str(tbuf, sizeof(tbuf), type, 0, 0, 0), | |
149 dcc_tgts2str(ckcnt, sizeof(ckcnt), tgts, 0)); | |
150 } | |
151 | |
152 | |
153 | |
154 /* write header with lines ending with either "\n" or "\r\n" | |
155 * the buffer must already contain '\n' as needed */ | |
156 void | |
157 xhdr_write(LOG_WRITE_FNC fnc, void *wctxt, | |
158 const char *hdr, int hdr_len, | |
159 u_char crlf) /* 1=use "\r\n" instead of "\n" */ | |
160 { | |
161 char c; | |
162 int i; | |
163 | |
164 if (hdr_len == 0) | |
165 return; | |
166 | |
167 i = 0; | |
168 for (;;) { | |
169 c = hdr[i]; | |
170 if (c == '\n' && crlf) { | |
171 if (i != 0) | |
172 fnc(wctxt, hdr, i); | |
173 fnc(wctxt, "\r\n", 2); | |
174 ++i; | |
175 hdr += i; | |
176 hdr_len -= i; | |
177 if (hdr_len <= 0) | |
178 return; | |
179 i = 0; | |
180 continue; | |
181 } | |
182 if (++i >= hdr_len) { | |
183 fnc(wctxt, hdr, i); | |
184 return; | |
185 } | |
186 } | |
187 } | |
188 | |
189 | |
190 | |
191 /* create a special X-DCC header for a whitelist mail message | |
192 * it lacks a DCC server-ID because there is none and to let | |
193 * DCC clients distinguish it from real X-DCC headers */ | |
194 void | |
195 xhdr_whitelist(DCC_HEADER_BUF *hdr) | |
196 { | |
197 hdr->col = 0; | |
198 hdr->start_len = 0; | |
199 hdr->used = 0; | |
200 xhdr_add_str(hdr, DCC_XHDR_START DCC_XHDR_END": %s; "DCC_XHDR_WHITELIST, | |
201 dcc_clnt_hostname); | |
202 } | |
203 | |
204 | |
205 | |
206 /* see if an X-DCC header looks like one of our own and so should | |
207 * be deleted */ | |
208 u_char /* 1=is an X-DCC-...-metrics header */ | |
209 is_xhdr(const char *buf, /* complete header */ | |
210 int buf_len) | |
211 { | |
212 const char *e; | |
213 | |
214 if (buf[0] != 'X' && buf[0] != 'x') | |
215 return 0; | |
216 if (buf_len <= LITZ(DCC_XHDR_START DCC_XHDR_END":") | |
217 || CLITCMP(buf, DCC_XHDR_START)) | |
218 return 0; | |
219 | |
220 buf += LITZ(DCC_XHDR_START); | |
221 buf_len -= LITZ(DCC_XHDR_START); | |
222 | |
223 /* look for the end of header field name */ | |
224 e = memchr(buf, ':', buf_len); | |
225 if (e) { | |
226 buf_len = e - buf; | |
227 if (buf_len < LITZ(DCC_XHDR_END)) | |
228 return 0; | |
229 } | |
230 | |
231 buf_len -= LITZ(DCC_XHDR_END); | |
232 buf += buf_len; | |
233 if (!CLITCMP(buf, DCC_XHDR_END)) | |
234 return 1; | |
235 | |
236 return 0; | |
237 } |