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 }