/*
 * 
 * proxy_check
 *
 * This plugin was written by Renaud Deraison and is released
 * under the GPL
 *
 */
#include <includes.h>
#define NAME "Proxy CONNECT check"
#define DESC "Some misconfigured proxy accepts the CONNECT\n\
requests of their clients, which is a very bad thing since\n\
it can allow anyone to bypass a firewall and to use the proxy\n\
as a launch pad for attacking another site\n\
Risk factor : very high"
#define COPYRIGHT "Renaud Deraison <deraison@worldnet.fr>"
#define SUMM "checks for badly configured proxies"




PlugExport int plugin_init(struct arglist *desc);
PlugExport int plugin_init(struct arglist *desc)
{
	plug_set_name(desc, NAME);
	plug_set_description(desc, DESC);
	plug_set_summary(desc, SUMM);
	plug_set_copyright(desc, COPYRIGHT);
	plug_set_category(desc, ACT_ATTACK);
	plug_set_family(desc, "Firewalls");
	return(0);
}


PlugExport int plugin_run(struct arglist * env);
PlugExport int plugin_run(struct arglist * env)
{
 int port = -1;
 int access = 0;
 int ports = 0;
 if(host_get_port_state(env, 3128)>0)port = 3128;
 else if(host_get_port_state(env, 8080)>0)port = 8080;
 else if(host_get_port_state(env, 80)>0)port = 80;
 
 
 if(port>0)
 {
  int soc = open_sock_tcp(env, port);
  char * our_host = emalloc(255);
  struct in_addr our_ip;
  struct hostent * he;
  
  if((soc < 0)&&(port == 3128)){
   port = 8080;
   soc = open_sock_tcp(env,port);
   if(soc < 0){
     port=80;
     soc = open_sock_tcp(env, port);
     }
  }
  if(soc < 0)return(0);
  gethostname(our_host, 254);
  our_ip = nn_resolve(our_host);
  he = gethostbyaddr((char *)&our_ip, sizeof(long), AF_INET);
  efree(&our_host);
  if(he){
   our_host = emalloc(strlen(he->h_name)+1);
   strncpy(our_host, he->h_name, strlen(he->h_name));
   }
  else
  {
   our_host = emalloc(255);
   strncpy(our_host, "localhost", strlen("localhost"));
   }
 if(check_proxy_connect(env, soc, our_host))
 {
  char * report = emalloc(1024);
sprintf(report,"The remote proxy accepted the request : \n\
CONNECT %s:25 HTTP/1.1\n\
This means that anyone can use it to connect\n\
anonymously anywhere and to bypass your firewalls\n\
Solution: deny all the ability to perform any CONNECT\n\
request", our_host);

  post_hole(env, port, report);
  efree(&report);
 }
  efree(&our_host);
  }
  return(0);
}





int check_proxy_connect(env, soc, our_host)
 struct arglist * env;
 int soc;
 char * our_host;
{
 char * buffer = emalloc(255);
 int err;
 char * c[2];
 int result = 0;

 sprintf(buffer, "CONNECT %s:25 HTTP/1.0\n\n", our_host);
 send(soc, buffer, strlen(buffer), 0);
 bzero(buffer, strlen(buffer));
 
 recv_line(soc, buffer, 255);
 c[0] = emalloc(strlen(buffer)+1);
 c[1] = emalloc(strlen(buffer)+1);
 sscanf(buffer, "%s %d %s", c[0], &err, c[1]);
 
 efree(&c[0]);
 efree(&c[1]);
 
 if((err == 200)||(err == 500))result = 1;
 efree(&buffer);
 return(result);
}
