"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.
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