"Fossies" - the Fresh Open Source Software Archive 
Member "scanssh-2.1/http.c" (5 Nov 2004, 7485 Bytes) of package /linux/privat/old/scanssh-2.1.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "http.c" see the
Fossies "Dox" file reference documentation.
1 /*
2 * Copyright 2000-2004 (c) Niels Provos <provos@citi.umich.edu>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #include <sys/types.h>
29
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33
34 #include <sys/tree.h>
35 #include <sys/queue.h>
36 #include <sys/socket.h>
37 #include <sys/time.h>
38 #include <netinet/in.h>
39
40 #include <stdlib.h>
41 #include <stdio.h>
42 #include <errno.h>
43 #include <string.h>
44 #include <signal.h>
45
46 #include <event.h>
47 #include <dnet.h>
48
49 #include "scanssh.h"
50 #include "socks.h"
51
52 #ifdef DEBUG
53 extern int debug;
54 #define DFPRINTF(x) if (debug) fprintf x
55 #else
56 #define DFPRINTF(x)
57 #endif
58
59 extern rand_t *ss_rand;
60
61 void http_init(struct bufferevent *bev, struct argument *arg);
62 void http_finalize(struct bufferevent *bev, struct argument *arg);
63 void http_readcb(struct bufferevent *bev, void *parameter);
64 void http_writecb(struct bufferevent *bev, void *parameter);
65 void http_errorcb(struct bufferevent *bev, short what, void *parameter);
66
67 #define HTTP_WAITING_RESPONSE 0x0001
68 #define HTTP_WAITING_CONNECT 0x0002
69 #define HTTP_READING_CONNECT 0x0004
70 #define HTTP_WRITING_COMMAND 0x0008
71 #define HTTP_GOT_HEADERS 0x0100
72 #define HTTP_GOT_OK 0x0200
73
74 #define HTTP10_OK "HTTP/1.0 200 "
75 #define HTTP11_OK "HTTP/1.1 200 "
76
77 int
78 http_response(char *line)
79 {
80 if (strncasecmp(line, HTTP10_OK, strlen(HTTP10_OK)) &&
81 strncasecmp(line, HTTP11_OK, strlen(HTTP11_OK)))
82 return (-1);
83 return (0);
84 }
85
86
87 int
88 http_getheaders(struct bufferevent *bev, struct argument *arg)
89 {
90 struct evbuffer *input = EVBUFFER_INPUT(bev);
91 size_t off;
92 char *p;
93
94 while ((p = evbuffer_find(input, "\n", 1)) != NULL) {
95 off = (size_t)p - (size_t)EVBUFFER_DATA(input) + 1;
96 if (off > 1 && *(p-1) == '\r')
97 *(p-1) = '\0';
98 *p = '\0';
99
100 if (strlen(EVBUFFER_DATA(input)) == 0) {
101 arg->a_flags |= HTTP_GOT_HEADERS;
102 evbuffer_drain(input, off);
103 break;
104 } else {
105 DFPRINTF((stderr, "Header: %s\n",
106 EVBUFFER_DATA(input)));
107 }
108
109 /* Check that we got an okay */
110 if (!(arg->a_flags & HTTP_GOT_OK)) {
111 if (http_response(EVBUFFER_DATA(input)) == -1) {
112 return (-1);
113 }
114 arg->a_flags |= HTTP_GOT_OK;
115 }
116 evbuffer_drain(input, off);
117 }
118
119 if ((arg->a_flags & HTTP_GOT_HEADERS) &&
120 !(arg->a_flags & HTTP_GOT_OK))
121 return (-1);
122
123 return (0);
124 }
125
126 int
127 http_bufferanalyse(struct bufferevent *bev, struct argument *arg)
128 {
129 struct evbuffer *input = EVBUFFER_INPUT(bev);
130
131 if (!(arg->a_flags & HTTP_GOT_HEADERS)) {
132 if (http_getheaders(bev, arg) == -1) {
133 postres(arg, "<error: response code>");
134 scanhost_return(bev, arg, 0);
135 return (-1);
136 }
137 }
138
139 if (arg->a_flags & HTTP_GOT_HEADERS) {
140 if (evbuffer_find(input, "\r\n", 2) == NULL)
141 return (0);
142
143 return (1);
144 }
145
146 return (0);
147 }
148
149 void
150 http_makerequest(struct bufferevent *bev, struct argument *arg,
151 const char *word, int fqdn)
152 {
153 extern struct addr *socks_dst_addr;
154 ip_addr_t address;
155
156 socks_resolveaddress("www.google.com", &address);
157 evbuffer_add_printf(EVBUFFER_OUTPUT(bev),
158 "GET %s%s/search?hl=en&ie=UTF-8&oe=UTF-8&q=%s&btnG=Google+Search HTTP/1.0\r\n"
159 "Host: www.google.com\r\n"
160 "User-Agent: %s\r\n"
161 "\r\n",
162 fqdn ? "http://" : "",
163 fqdn ? addr_ntoa(socks_dst_addr) : "",
164 word, SSHUSERAGENT);
165 bufferevent_enable(bev, EV_WRITE);
166 }
167
168 void
169 http_makeconnect(struct bufferevent *bev, struct argument *arg)
170 {
171 extern struct addr *socks_dst_addr;
172 ip_addr_t address;
173
174 socks_resolveaddress("www.google.com", &address);
175
176 evbuffer_add_printf(EVBUFFER_OUTPUT(bev),
177 "CONNECT %s:80 HTTP/1.0\r\n"
178 "\r\n", addr_ntoa(socks_dst_addr), SSHUSERAGENT);
179 bufferevent_enable(bev, EV_WRITE);
180 }
181
182 /* Scanner related functions */
183
184 void
185 http_init(struct bufferevent *bev, struct argument *arg)
186 {
187 arg->a_flags = 0;
188 }
189
190 void
191 http_finalize(struct bufferevent *bev, struct argument *arg)
192 {
193 arg->a_flags = 0;
194 }
195
196 void
197 http_readcb(struct bufferevent *bev, void *parameter)
198 {
199 struct argument *arg = parameter;
200
201 DFPRINTF((stderr, "%s: called\n", __func__));
202
203 if (arg->a_flags & HTTP_WAITING_RESPONSE) {
204 int res = http_bufferanalyse(bev, arg);
205 if (res == -1)
206 return;
207 if (res == 1) {
208 postres(arg, "http proxy");
209 scanhost_return(bev, arg, 1);
210 }
211 }
212
213 return;
214
215 scanhost_return(bev, arg, 0);
216 }
217
218 void
219 http_writecb(struct bufferevent *bev, void *parameter)
220 {
221 struct argument *arg = parameter;
222
223 DFPRINTF((stderr, "%s: called\n", __func__));
224
225 switch (arg->a_flags) {
226 case 0:
227 arg->a_flags = HTTP_WAITING_RESPONSE;
228 http_makerequest(bev, arg, socks_getword(), 1);
229 break;
230 }
231 }
232
233 void
234 http_errorcb(struct bufferevent *bev, short what, void *parameter)
235 {
236 struct argument *arg = parameter;
237
238 DFPRINTF((stderr, "%s: called\n", __func__));
239
240 postres(arg, "<http proxy error>");
241 scanhost_return(bev, arg, 0);
242 }
243
244 /* HTTP Connect method */
245
246 void
247 http_connect_readcb(struct bufferevent *bev, void *parameter)
248 {
249 struct argument *arg = parameter;
250
251 DFPRINTF((stderr, "%s: called\n", __func__));
252
253 if (arg->a_flags & HTTP_READING_CONNECT) {
254 if (!(arg->a_flags & HTTP_GOT_HEADERS)) {
255 if (http_getheaders(bev, arg) == -1) {
256 postres(arg, "<error: response code>");
257 scanhost_return(bev, arg, 0);
258 return;
259 }
260 }
261
262 if (arg->a_flags & HTTP_GOT_HEADERS) {
263 arg->a_flags = HTTP_WRITING_COMMAND;
264 http_makerequest(bev, arg, socks_getword(), 0);
265 bufferevent_disable(bev, EV_READ);
266 return;
267 }
268 } else if (arg->a_flags & HTTP_WAITING_RESPONSE) {
269 int res = http_bufferanalyse(bev, arg);
270 if (res == -1)
271 return;
272 if (res == -1) {
273 postres(arg, "http connect proxy");
274 scanhost_return(bev, arg, 1);
275 }
276 }
277
278 return;
279
280 scanhost_return(bev, arg, 0);
281 }
282
283 void
284 http_connect_writecb(struct bufferevent *bev, void *parameter)
285 {
286 struct argument *arg = parameter;
287
288 DFPRINTF((stderr, "%s: called\n", __func__));
289
290 if (arg->a_flags == 0) {
291 arg->a_flags = HTTP_WAITING_CONNECT;
292 http_makeconnect(bev, arg);
293 bufferevent_disable(bev, EV_READ);
294 } else if (arg->a_flags & HTTP_WAITING_CONNECT) {
295 bufferevent_enable(bev, EV_READ);
296 arg->a_flags = HTTP_READING_CONNECT;
297 } else if (arg->a_flags & HTTP_WRITING_COMMAND) {
298 bufferevent_enable(bev, EV_READ);
299 arg->a_flags = HTTP_WAITING_RESPONSE;
300 }
301 }
302