/[imapfilter]/imapfilter/response.c
ViewVC logotype

Contents of /imapfilter/response.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.9.2.1 - (show annotations)
Wed Oct 31 20:33:10 2001 UTC (22 years, 5 months ago) by lefcha
Branch: release-0_6_2-patches
Changes since 1.9: +1 -1 lines
File MIME type: text/plain
Searching response buffer overflow bug fix.

1 #include <stdio.h>
2 #include <unistd.h>
3 #include <stdlib.h>
4 #include <ctype.h>
5 #include <errno.h>
6 #include <string.h>
7 #include <fcntl.h>
8 #include <sys/time.h>
9 #include <sys/types.h>
10 #include <regex.h>
11
12
13 #include "config.h"
14 #include "imapfilter.h"
15
16
17 extern int sock;
18 extern unsigned int options;
19
20
21 /*
22 * Read data the server sent.
23 */
24 int receive_response(char *buf)
25 {
26 int flags;
27 fd_set fds;
28 struct timeval tv;
29
30 memset(buf, 0, RESPONSE_BUF);
31
32 tv.tv_sec = 20;
33 tv.tv_usec = 0;
34
35 flags = fcntl(sock, F_GETFL, 0);
36 fcntl(sock, F_SETFL, flags | O_NONBLOCK);
37
38 FD_ZERO(&fds);
39 FD_SET(sock, &fds);
40
41 if ((select(sock + 1, &fds, NULL, NULL, &tv) > 0)
42 && FD_ISSET(sock, &fds)) {
43 if (read(sock, buf, RESPONSE_BUF - 1) != -1) {
44 #ifdef DEBUG
45 printf("\n%s\n", buf);
46 #endif
47 fcntl(sock, F_SETFL, flags);
48
49 return analyze_response(buf);
50 }
51 }
52 fcntl(sock, F_SETFL, flags);
53
54 fatal(ERROR_NETWORK, "imapfilter: waiting input from socket; %s\n",
55 strerror(errno));
56
57 return ERROR_NETWORK;
58 }
59
60
61 /*
62 * Get server response to client's request.
63 */
64 int server_response(unsigned int tag)
65 {
66 int r;
67 char buf[RESPONSE_BUF];
68
69 do
70 r = receive_response(buf);
71 while (tag && !strcasestr(buf, ultostr(tag, 16)));
72
73 return r;
74 }
75
76
77 /*
78 * Process the greeting that server sends during connection.
79 */
80 int greeting_response(void)
81 {
82 char buf[RESPONSE_BUF];
83
84 receive_response(buf);
85
86 if (strcasestr(buf, "BYE"))
87 return RESPONSE_BYE;
88
89 return RESPONSE_OK;
90 }
91
92 /*
93 * Process the data that server sent due to IMAP CAPABILITY client request.
94 */
95 int capability_response(unsigned int tag)
96 {
97 int r;
98 char buf[RESPONSE_BUF];
99
100 do
101 r = receive_response(buf);
102 while (!strcasestr(buf, ultostr(tag, 16)));
103
104 if (!strcasestr(buf, "IMAP4rev1")) {
105 error("imapfilter: server does not support IMAP4rev1 protocol\n");
106 return -2;
107 }
108 return r;
109 }
110
111
112 /*
113 * Process the data that server sent due to IMAP STATUS client request.
114 */
115 int status_response(unsigned int tag)
116 {
117 int r;
118 char buf[RESPONSE_BUF];
119 unsigned int exist, recent, unseen;
120 char *c;
121
122 exist = recent = unseen = 0;
123
124 do
125 r = receive_response(buf);
126 while (!strcasestr(buf, ultostr(tag, 16)));
127
128 if ((c = strcasestr(buf, "MESSAGES"))) {
129 c += 9;
130 exist = strtoul(c, NULL, 10);
131 }
132 if ((c = strcasestr(buf, "RECENT"))) {
133 c += 7;
134 recent = strtoul(c, NULL, 10);
135 }
136 if ((c = strcasestr(buf, "UNSEEN"))) {
137 c += 7;
138 unseen = strtoul(c, NULL, 10);
139 }
140 if (!exist) {
141 info("No messages ");
142 return -2;
143 }
144 info("%d message%s, %d recent, %d unseen, ", exist, plural(exist),
145 recent, unseen);
146
147 return r;
148 }
149
150
151 /*
152 * Process the data that server sent due to IMAP SELECT client request.
153 */
154 int select_response(unsigned int tag)
155 {
156 int r;
157 char buf[RESPONSE_BUF];
158
159 do
160 r = receive_response(buf);
161 while (!strcasestr(buf, ultostr(tag, 16)));
162
163 if (strcasestr(buf, "[READ-ONLY]"))
164 return RESPONSE_READONLY;
165
166 return r;
167 }
168
169
170 /*
171 * Process the data that server sent due to IMAP SEARCH client request.
172 */
173 int search_response(unsigned int tag, char *mesgs)
174 {
175 int r;
176 char buf[RESPONSE_BUF];
177 char *c, *m = mesgs;
178
179 do
180 r = receive_response(buf);
181 while (!strcasestr(buf, ultostr(tag, 16)));
182
183 if ((c = strcasestr(buf, "SEARCH "))) {
184 c += 7;
185 while (m - mesgs < SEARCH_MESSAGES_BUF && (isdigit(*c) || *c == ' '))
186 *(m++) = *(c++);
187 *m = 0;
188 }
189
190 return r;
191 }
192
193
194 /*
195 * Process the data that server sent due to IMAP FETCH client request.
196 */
197 int fetch_response(unsigned int tag)
198 {
199 int r, s, i;
200 char buf[RESPONSE_BUF];
201 char *pos;
202 char headers[HEADERS_BUF];
203
204 headers[0] = 0;
205
206 do
207 r = receive_response(buf);
208 while (!strcasestr(buf, ultostr(tag, 16)));
209
210 pos = buf;
211
212 while ((pos = strchr(pos, '{'))) {
213 s = atoi(pos + 1);
214 pos = strchr(pos, '}');
215
216 for (i = 0; i < HEADERS_BUF - 1 && i < s - 2; i++)
217 headers[i] = *(pos + 3 + i);
218
219 headers[i] = 0;
220
221 if (*headers) {
222 if (options & OPTION_HEADERS)
223 info("%s\n", headers);
224 log_info(LOG_WRITE, headers);
225 } else
226 log_info(LOG_WRITE, NULL);
227 }
228
229 return r;
230 }
231
232
233 /*
234 * Process the data that server sent due to IMAP COPY client request.
235 */
236 int copy_response(unsigned int tag)
237 {
238 int r;
239 char buf[RESPONSE_BUF];
240
241 do
242 r = receive_response(buf);
243 while (!strcasestr(buf, ultostr(tag, 16)));
244
245 if (r == RESPONSE_NO && strcasestr(buf, "[TRYCREATE]"))
246 return RESPONSE_TRYCREATE;
247
248 return RESPONSE_OK;
249 }
250
251
252 /*
253 * Check if response of server to client's request was succesfully
254 * delivered or there was some kind of error.
255 */
256 int analyze_response(char *buf)
257 {
258 int r = RESPONSE_OK;
259 regex_t creg;
260 regmatch_t match[3];
261 const char *reg = "[[:xdigit:]]{6,6} ((OK|NO|BAD)[[:print:]]*)\r\n";
262 char result[RESULT_BUF];
263
264 result[0] = 0;
265
266 regcomp(&creg, reg, REG_EXTENDED | REG_ICASE);
267
268 if (!regexec(&creg, buf, 3, match, 0)) {
269 strncat(result, buf + match[1].rm_so,
270 min(match[1].rm_eo - match[1].rm_so, RESULT_BUF - 1));
271
272 if (!strncasecmp(buf + match[2].rm_so, "NO", 2))
273 r = RESPONSE_NO;
274 else if (!strncasecmp(buf + match[2].rm_so, "BAD", 3))
275 r = RESPONSE_BAD;
276
277 verbose("Server response: %s\n", result);
278 }
279 regfree(&creg);
280
281 return r;
282 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26