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

Annotation of /imapfilter/response.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.11 - (hide 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 lefcha 1.1 #include <stdio.h>
2     #include <unistd.h>
3     #include <stdlib.h>
4 lefcha 1.9 #include <ctype.h>
5 lefcha 1.4 #include <errno.h>
6 lefcha 1.1 #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 lefcha 1.3 * Read data the server sent.
20 lefcha 1.1 */
21     int receive_response(char *buf)
22     {
23 lefcha 1.10 socket_read(buf);
24 lefcha 1.1
25     #ifdef DEBUG
26 lefcha 1.11 printf("\n%s\n", buf);
27 lefcha 1.1 #endif
28 lefcha 1.11
29 lefcha 1.10 return analyze_response(buf);
30 lefcha 1.1 }
31    
32    
33     /*
34     * Get server response to client's request.
35     */
36 lefcha 1.9 int server_response(unsigned int tag)
37 lefcha 1.1 {
38 lefcha 1.4 int r;
39 lefcha 1.1 char buf[RESPONSE_BUF];
40 lefcha 1.6
41 lefcha 1.4 do
42     r = receive_response(buf);
43 lefcha 1.9 while (tag && !strcasestr(buf, ultostr(tag, 16)));
44 lefcha 1.6
45 lefcha 1.4 return r;
46 lefcha 1.1 }
47    
48    
49     /*
50 lefcha 1.9 * 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 lefcha 1.3 * Process the data that server sent due to IMAP STATUS client request.
86 lefcha 1.1 */
87 lefcha 1.9 int status_response(unsigned int tag)
88 lefcha 1.1 {
89     int r;
90     char buf[RESPONSE_BUF];
91     unsigned int exist, recent, unseen;
92 lefcha 1.9 char *c;
93 lefcha 1.1
94     exist = recent = unseen = 0;
95    
96     do
97     r = receive_response(buf);
98 lefcha 1.9 while (!strcasestr(buf, ultostr(tag, 16)));
99 lefcha 1.1
100 lefcha 1.9 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 lefcha 1.8 if (!exist) {
113     info("No messages ");
114     return -2;
115     }
116 lefcha 1.9 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 lefcha 1.1
138     return r;
139     }
140    
141    
142     /*
143 lefcha 1.3 * Process the data that server sent due to IMAP SEARCH client request.
144 lefcha 1.1 */
145 lefcha 1.9 int search_response(unsigned int tag, char *mesgs)
146 lefcha 1.1 {
147     int r;
148     char buf[RESPONSE_BUF];
149 lefcha 1.9 char *c, *m = mesgs;
150 lefcha 1.1
151     do
152     r = receive_response(buf);
153 lefcha 1.9 while (!strcasestr(buf, ultostr(tag, 16)));
154 lefcha 1.1
155 lefcha 1.9 if ((c = strcasestr(buf, "SEARCH "))) {
156     c += 7;
157 lefcha 1.11 while (m - mesgs < SEARCH_MESSAGES_BUF && (isdigit(*c) || *c == ' '))
158 lefcha 1.9 *(m++) = *(c++);
159     *m = 0;
160     }
161 lefcha 1.1 return r;
162     }
163    
164    
165     /*
166 lefcha 1.3 * Process the data that server sent due to IMAP FETCH client request.
167 lefcha 1.1 */
168 lefcha 1.9 int fetch_response(unsigned int tag)
169 lefcha 1.1 {
170     int r, s, i;
171     char buf[RESPONSE_BUF];
172     char *pos;
173 lefcha 1.4 char headers[HEADERS_BUF];
174 lefcha 1.6
175 lefcha 1.4 headers[0] = 0;
176 lefcha 1.6
177 lefcha 1.1 do
178     r = receive_response(buf);
179 lefcha 1.9 while (!strcasestr(buf, ultostr(tag, 16)));
180 lefcha 1.6
181 lefcha 1.4 pos = buf;
182 lefcha 1.1
183 lefcha 1.6 while ((pos = strchr(pos, '{'))) {
184 lefcha 1.4 s = atoi(pos + 1);
185     pos = strchr(pos, '}');
186 lefcha 1.8
187 lefcha 1.4 for (i = 0; i < HEADERS_BUF - 1 && i < s - 2; i++)
188     headers[i] = *(pos + 3 + i);
189 lefcha 1.6
190 lefcha 1.4 headers[i] = 0;
191 lefcha 1.10 pos += i;
192 lefcha 1.6
193 lefcha 1.7 if (*headers) {
194     if (options & OPTION_HEADERS)
195     info("%s\n", headers);
196 lefcha 1.6 log_info(LOG_WRITE, headers);
197 lefcha 1.7 } else
198 lefcha 1.6 log_info(LOG_WRITE, NULL);
199 lefcha 1.4 }
200 lefcha 1.6
201 lefcha 1.1 return r;
202     }
203    
204    
205     /*
206 lefcha 1.3 * Process the data that server sent due to IMAP COPY client request.
207 lefcha 1.1 */
208 lefcha 1.9 int copy_response(unsigned int tag)
209 lefcha 1.1 {
210     int r;
211     char buf[RESPONSE_BUF];
212    
213     do
214     r = receive_response(buf);
215 lefcha 1.9 while (!strcasestr(buf, ultostr(tag, 16)));
216 lefcha 1.1
217 lefcha 1.9 if (r == RESPONSE_NO && strcasestr(buf, "[TRYCREATE]"))
218     return RESPONSE_TRYCREATE;
219 lefcha 1.1
220 lefcha 1.9 return RESPONSE_OK;
221 lefcha 1.1 }
222    
223    
224     /*
225 lefcha 1.3 * Check if response of server to client's request was succesfully
226 lefcha 1.1 * delivered or there was some kind of error.
227     */
228     int analyze_response(char *buf)
229     {
230 lefcha 1.9 int r = RESPONSE_OK;
231 lefcha 1.1 regex_t creg;
232     regmatch_t match[3];
233 lefcha 1.9 const char *reg = "[[:xdigit:]]{6,6} ((OK|NO|BAD)[[:print:]]*)\r\n";
234 lefcha 1.1 char result[RESULT_BUF];
235    
236 lefcha 1.4 result[0] = 0;
237    
238 lefcha 1.9 regcomp(&creg, reg, REG_EXTENDED | REG_ICASE);
239 lefcha 1.6
240 lefcha 1.1 if (!regexec(&creg, buf, 3, match, 0)) {
241 lefcha 1.4 strncat(result, buf + match[1].rm_so,
242     min(match[1].rm_eo - match[1].rm_so, RESULT_BUF - 1));
243 lefcha 1.1
244 lefcha 1.9 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 lefcha 1.6
249 lefcha 1.1 verbose("Server response: %s\n", result);
250     }
251 lefcha 1.6 regfree(&creg);
252 lefcha 1.1
253     return r;
254     }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26