"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