"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