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

Contents of /imapfilter/response.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.11 - (show annotations)
Thu Nov 1 16:36:00 2001 UTC (22 years, 5 months ago) by lefcha
Branch: MAIN
Changes since 1.10: +3 -4 lines
File MIME type: text/plain
Fixed buffer overflow bug concerning SEARCH request buffer.

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

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26