Beispiel #1
0
void test_host(struct parsedfile *config, char *host) {
	struct serverent *path;
	char *hostname, *port;
	char separator;
	unsigned long portno = 0;
	int af;
	int flag;
	struct sockaddr_in addr4;
#ifdef ENABLE_IPV6
	struct sockaddr_in6 addr6;
#endif
	void *hostaddr;
	char buf[60];

	/* See if a port has been specified */
	hostname = strsplit(&separator, &host, ": \t\n");
	if (separator == ':') {
		port = strsplit(NULL, &host, " \t\n");
		if (port)
			portno = strtol(port, NULL, 0);
	}

	/* First resolve the host to an ip */
#ifdef ENABLE_IPV6
	if ((flag = resolve_ip(AF_INET6, hostname, 0, 1, (void *) &addr6)) == -1) {
#endif
		af = AF_INET;
		flag = resolve_ip(AF_INET, hostname, 0, 1, (void *) &addr4);
		hostaddr = (void *) &addr4.sin_addr;
#ifdef ENABLE_IPV6
	} else {
		af = AF_INET6;
		hostaddr = (void *) &addr6.sin6_addr;
	}
#endif
	if (flag == -1) {
		fprintf(stderr, "Error: Cannot resolve %s\n", host);
		return;
	} else {
		inet_ntop(af, hostaddr, buf, 60);
		printf("Finding path for %s...\n", buf);
		if (!(is_local(config, af, hostaddr))) {
			printf("Path is local\n");
		} else {
			pick_server(config, &path, af, hostaddr, portno);
			if (path == &(config->defaultserver)) {
				printf("Path is via default server:\n");
				show_server(config, path, 1);
			} else {
				printf("Host is reached via this path:\n");
				show_server(config, path, 0);
			}
		}
	}

	return;
}
Beispiel #2
0
Datei: ngs.c Projekt: Wingie/ngs
void print_exception(VM *vm, VALUE result) {
	// TODO: fprintf to stderr and teach dump_titled to optionally fprintf to stderr too
	printf("====== Exception of type '%s' ======\n", obj_to_cstring(NGS_TYPE_NAME(NORMAL_TYPE_INSTANCE_TYPE(result))));
	// TODO: maybe macro to iterate attributes
	VALUE fields = NGS_TYPE_FIELDS(NORMAL_TYPE_INSTANCE_TYPE(result));
	HASH_OBJECT_ENTRY *e;
	for(e=HASH_HEAD(fields); e; e=e->insertion_order_next) {
		if(obj_is_of_type(ARRAY_ITEMS(NORMAL_TYPE_INSTANCE_FIELDS(result))[GET_INT(e->val)], vm->Backtrace)) {
			printf("=== [ backtrace ] ===\n");
			// Backtrace.frames = [{"closure": ..., "ip": ...}, ...]
			VALUE backtrace = ARRAY_ITEMS(NORMAL_TYPE_INSTANCE_FIELDS(result))[GET_INT(e->val)];
			VALUE frames;
			assert(get_normal_type_instace_attribute(backtrace, make_string("frames"), &frames) == METHOD_OK);
			unsigned int i;
			for(i = 0; i < OBJ_LEN(frames); i++) {
				VALUE frame, resolved_ip, ip;
				frame = ARRAY_ITEMS(frames)[i];
				H(ip, frame, "ip");
				resolved_ip = resolve_ip(vm, (IP)(GET_INT(ip) - 1));
				if(IS_HASH(resolved_ip)) {
					VALUE file, first_line, first_column, last_line, last_column;
					HASH_OBJECT_ENTRY *closure_entry;
					char *closure_name = "<anonymous>";
					H(file, resolved_ip, "file");
					H(first_line, resolved_ip, "first_line");
					H(first_column, resolved_ip, "first_column");
					H(last_line, resolved_ip, "last_line");
					H(last_column, resolved_ip, "last_column");
					closure_entry = get_hash_key(frame, make_string("closure"));
					if(closure_entry && IS_CLOSURE(closure_entry->val) && (IS_HASH(CLOSURE_OBJ_ATTRS(closure_entry->val)))) {
						HASH_OBJECT_ENTRY *name_entry;
						name_entry = get_hash_key(CLOSURE_OBJ_ATTRS(closure_entry->val), make_string("name"));
						if(name_entry) {
							closure_name = obj_to_cstring(name_entry->val);
						}
					}
					// TODO: fix types
					printf("[Frame #%u] %s:%d:%d - %d:%d [in %s]\n", i, obj_to_cstring(file), (int) GET_INT(first_line), (int) GET_INT(first_column), (int) GET_INT(last_line), (int) GET_INT(last_column), closure_name);
				} else {
					printf("[Frame #%u] (no source location)\n", i);
				}
			}
			continue;
		}
		if(obj_is_of_type(ARRAY_ITEMS(NORMAL_TYPE_INSTANCE_FIELDS(result))[GET_INT(e->val)], vm->Exception)) {
			assert(IS_STRING(e->key));
			printf("---8<--- %s - start ---8<---\n", obj_to_cstring(e->key));
			print_exception(vm, ARRAY_ITEMS(NORMAL_TYPE_INSTANCE_FIELDS(result))[GET_INT(e->val)]);
			printf("---8<--- %s - end ---8<---\n", obj_to_cstring(e->key));
			continue;
		}
		if(IS_STRING(e->key)) {
			dump_titled(obj_to_cstring(e->key), ARRAY_ITEMS(NORMAL_TYPE_INSTANCE_FIELDS(result))[GET_INT(e->val)]);
		} else {
			// Should not happen
			dump_titled("attribute key", e->key);
			dump_titled("attribute value", ARRAY_ITEMS(NORMAL_TYPE_INSTANCE_FIELDS(result))[GET_INT(e->val)]);
		}
	}
}
Beispiel #3
0
SOCKET connect_socket(const char* host, ushort port)
{
	SOCKET		sock;
	SOCKADDR_IN	addr;

	if((sock=socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) == INVALID_SOCKET) {
		lprintf(LOG_ERR,"ERROR %u creating socket", ERROR_VALUE);
		return INVALID_SOCKET;
	}

	lprintf(LOG_DEBUG,"Setting TCP_NODELAY to %d",tcp_nodelay);
	setsockopt(sock,IPPROTO_TCP,TCP_NODELAY,(char*)&tcp_nodelay,sizeof(tcp_nodelay));

	ZERO_VAR(addr);
	addr.sin_addr.s_addr = resolve_ip(host);
	addr.sin_family = AF_INET;
	addr.sin_port   = htons(port);

	lprintf(LOG_INFO,"Connecting to %s port %u", host, port);
	if(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) {
		lprintf(LOG_INFO,"Connected from COM Port (handle %u) to %s TCP port %u using socket descriptor %u"
			,com_handle, host, port, sock);
		return sock;
	}

	lprintf(LOG_ERR,"SOCKET ERROR %u connecting to %s port %u", ERROR_VALUE, host, port);
	closesocket(sock);

	return INVALID_SOCKET;
}
Beispiel #4
0
static gboolean
initiate_resolving(gpointer data)
{
	PurpleDnsQueryData *query_data;
	PurpleProxyType proxy_type;

	query_data = data;
	query_data->timeout = 0;

	if (resolve_ip(query_data))
		/* resolve_ip calls purple_dnsquery_resolved */
		return FALSE;

	proxy_type = purple_proxy_info_get_type(
		purple_proxy_get_setup(query_data->account));
	if (proxy_type == PURPLE_PROXY_TOR) {
		purple_dnsquery_failed(query_data,
			_("Aborting DNS lookup in Tor Proxy mode."));
		return FALSE;
	}

	if (purple_dnsquery_ui_resolve(query_data))
		/* The UI is handling the resolve; we're done */
		return FALSE;

	resolve_host(query_data);

	return FALSE;
}
Beispiel #5
0
/* Main function */
int main (int argc, char **argv) {
        /* Check command line */
        if(argc != 4) {
                fprintf(stderr, "\nnhrp-dos (c) by Martin Kluge <*****@*****.**>, 2007\n");
                fprintf(stderr, "------------------------------------------------\n");
                fprintf(stderr, "Usage: ./nhrp-dos <device> <target> <GRE key>\n");
                fprintf(stderr, "(Set GRE key = 0 to disable GRE keys!)\n\n");
                exit(EXIT_FAILURE);
        }

        /* Check UID */
        if(getuid() != 0 && geteuid() != 0) {
                fprintf(stderr, "Error: Please run as root!\n");
                exit(EXIT_FAILURE);
        }

        /* Open a socket */
        sockfd = open_socket();

        /* Send DoS packet */
        send_dos(sockfd, get_int_ipv4(argv[1]), resolve_ip(argv[2]), atoi(argv[3]));

        /* Close the socket */
        close_socket(sockfd);
        
        exit(EXIT_SUCCESS);
}
Beispiel #6
0
static void
parse_request(rb_helper *helper)
{
	int len;
	static char *parv[MAXPARA + 1];
	int parc;
	while((len = rb_helper_read(helper, readBuf, sizeof(readBuf))) > 0)
	{
		parc = rb_string_to_array(readBuf, parv, MAXPARA);
		switch (*parv[0])
		{
		case 'I':
			if(parc != 4)
				abort();
			resolve_ip(parv);
			break;
		case 'H':
			if(parc != 4)
				abort();
			resolve_host(parv);
			break;
		case 'B':
			if(parc != 4)
				abort();
			set_bind(parv);
			break;
		case 'R':
			restart_resolver();
			report_nameservers();
			break;
		default:
			break;
		}
	}
}
Beispiel #7
0
/*
 * Do a reverse lookup on `my_ip_addr'. If successfull, replace
 * `hostname' and `def_domain' with returned result.
 */
int reverse_lookup_myip (void)
{
  char myname [MAX_HOSTLEN];

  if (!resolve_ip(htonl(my_ip_addr),myname))
     return (0);

  if (debug_on >= 1)
  {
    outs (_LANG("My FQDN: "));
    outsnl (myname);
  }
  if (sethostname(myname,sizeof(myname)) < 0)
     return (0);
  return (1);
}
Beispiel #8
0
bool OSCQueryDevice::reconnect()
{
  const auto& cur_settings = settings();
  const auto& stgs
      = cur_settings.deviceSpecificSettings.value<OSCQuerySpecificSettings>();

  if (m_dev && m_mirror && m_oldSettings == cur_settings)
  {
    // TODO update settings
    try
    {
      m_mirror->reconnect();
      m_connected = true;
    }
    catch (std::exception& e)
    {
      qDebug() << "Could not connect: " << e.what();
      m_connected = false;
    }
    catch (...)
    {
      // TODO save the reason of the non-connection.
      m_connected = false;
    }

    connectionChanged(m_connected);
    return connected();
  }

  disconnect();

  std::thread resolver([this, host = stgs.host.toStdString()] {
    bool ok = resolve_ip(host);
    if (ok)
    {
      sig_createDevice();
    }

    m_connected = false;
    connectionChanged(m_connected);
  });

  resolver.detach();

  return connected();
}
Beispiel #9
0
static gboolean resolve_host(PurpleDnsQueryData *query_data, PurpleDnsQueryResolvedCallback resolved_cb, PurpleDnsQueryFailedCallback failed_cb) {
	ResolverData *data = new ResolverData;
	data->query_data = query_data;
	data->resolved_cb = resolved_cb;
	data->failed_cb = failed_cb;
	data->error_message = NULL;
	data->hosts = NULL;
	data->destroyed = false;
	data->mutex = g_mutex_new();

	if (!resolve_ip(data)) {
		if (g_hash_table_size(query_data_cache) == 5) {
			Log("DNSResolver", "Resolving " << purple_dnsquery_get_host(query_data) << ": query_data queued.");
			queue = g_list_append(queue, data);
		}
		else {
			return start_resolver_thread(data);
		}
	}

	return TRUE;
}
void test_host(struct parsedfile *config, char *host) { 
	struct in_addr hostaddr;
	struct serverent *path;
   char *hostname, *port;
   char separator;
   unsigned long portno = 0;

   /* See if a port has been specified */
   hostname = strsplit(&separator, &host, ": \t\n");
   if (separator == ':') {
      port = strsplit(NULL, &host, " \t\n");
      if (port) 
         portno = strtol(port, NULL, 0);
   }

	/* First resolve the host to an ip */
	if ((hostaddr.s_addr = resolve_ip(hostname, 0, 1)) == 0) {
		fprintf(stderr, "Error: Cannot resolve %s\n", host);
		return;
	} else {
		printf("Finding path for %s...\n", inet_ntoa(hostaddr));
      if (!(is_local(config, &(hostaddr)))) {
         printf("Path is local\n");
      } else {
         pick_server(config, &path, &hostaddr, portno);
         if (path == &(config->defaultserver)) {
            printf("Path is via default server:\n");
            show_server(config, path, 1);
         } else {
            printf("Host is reached via this path:\n");
            show_server(config, path, 0);
         }
      }
	}

	return;
}
Beispiel #11
0
struct hostent *gethostbyaddr (const char *adr_name, int len, int type)
{
  struct _hostent *h, ret;
  struct  hostent *h2;
  DWORD   addr;
  char    name [MAX_HOSTLEN];

  h_errno = HOST_NOT_FOUND;

  if (type != AF_INET || len != sizeof(addr))
     return (NULL);

  addr = *(DWORD*) adr_name;

  ret.h_address = addr;
  h = (_hostent*) tree_find (host_root, (void*)&ret, (CmpFunc)host_cmp_addr);
  if (h)
     return FillHostEnt (h);

  if ((ret.h_name = strdup(name)) == NULL)
  {
    h_errno = NETDB_INTERNAL;
    errno = ENOMEM;
    return (NULL);
  }

  if (resolve_ip(addr,name))   /* do a reverse ip lookup */
     h2 = FillHostEnt (&ret);
  else
  {
    ret.h_name = "";
    h2 = NULL;
  }
  tree_insert (&host_root, (void*)&ret, sizeof(ret), (CmpFunc)host_cmp_name);
  return (h2);
}
Beispiel #12
0
int connect(CONNECT_SIGNATURE) {
	struct sockaddr_in *connaddr;
	struct sockaddr_in peer_address;
	struct sockaddr_in server_address;
   int gotvalidserver = 0, rc, namelen = sizeof(peer_address);
	int sock_type = -1;
	int sock_type_len = sizeof(sock_type);
	unsigned int res = -1;
	struct serverent *path;
   struct connreq *newconn;

   get_environment();

	/* If the real connect doesn't exist, we're stuffed */
	if (realconnect == NULL) {
		show_msg(MSGERR, "Unresolved symbol: connect\n");
		return(-1);
	}

   show_msg(MSGDEBUG, "Got connection request\n");

	connaddr = (struct sockaddr_in *) __addr;

	/* Get the type of the socket */
	getsockopt(__fd, SOL_SOCKET, SO_TYPE, 
		   (void *) &sock_type, &sock_type_len);

	/* If this isn't an INET socket for a TCP stream we can't  */
	/* handle it, just call the real connect now               */
   if ((connaddr->sin_family != AF_INET) ||
       (sock_type != SOCK_STREAM)) {
      show_msg(MSGDEBUG, "Connection isn't a TCP stream ignoring\n");
		return(realconnect(__fd, __addr, __len));
   }

   /* If we haven't initialized yet, do it now */
   get_config();

   /* Are we already handling this connect? */
   if ((newconn = find_socks_request(__fd, 1))) {
      if (memcmp(&newconn->connaddr, connaddr, sizeof(*connaddr))) {
         /* Ok, they're calling connect on a socket that is in our
          * queue but this connect() isn't to the same destination, 
          * they're obviously not trying to check the status of 
          * they're non blocking connect, they must have close()d 
          * the other socket and created a new one which happens
          * to have the same fd as a request we haven't had the chance
          * to delete yet, so we delete it here. */
         show_msg(MSGDEBUG, "Call to connect received on old "
                            "tsocks request for socket %d but to "
                            "new destination, deleting old request\n",
                  newconn->sockid);
         kill_socks_request(newconn);
      } else {
         /* Ok, this call to connect() is to check the status of 
          * a current non blocking connect(). */
         if (newconn->state == FAILED) {
            show_msg(MSGDEBUG, "Call to connect received on failed "
                               "request %d, returning %d\n",
                     newconn->sockid, newconn->err);
            errno = newconn->err;
            rc = -1;
         } else if (newconn->state == DONE) {
            show_msg(MSGERR, "Call to connect received on completed "
                             "request %d\n",
                     newconn->sockid, newconn->err);
            rc = 0;
         } else {
            show_msg(MSGDEBUG, "Call to connect received on current request %d\n",
                     newconn->sockid);
            rc = handle_request(newconn);
            errno = rc;
         }
         if ((newconn->state == FAILED) || (newconn->state == DONE))
            kill_socks_request(newconn);
         return((rc ? -1 : 0));
      }
   }

   /* If the socket is already connected, just call connect  */
   /* and get its standard reply                             */
   if (!getpeername(__fd, (struct sockaddr *) &peer_address, &namelen)) {
      show_msg(MSGDEBUG, "Socket is already connected, defering to "
                         "real connect\n");
		return(realconnect(__fd, __addr, __len));
   }
      
   show_msg(MSGDEBUG, "Got connection request for socket %d to "
                      "%s\n", __fd, inet_ntoa(connaddr->sin_addr));

   /* If the address is local call realconnect */
   if (!(is_local(config, &(connaddr->sin_addr)))) {
      show_msg(MSGDEBUG, "Connection for socket %d is local\n", __fd);
      return(realconnect(__fd, __addr, __len));
   }

   /* Ok, so its not local, we need a path to the net */
   pick_server(config, &path, &(connaddr->sin_addr), ntohs(connaddr->sin_port));

   show_msg(MSGDEBUG, "Picked server %s for connection\n",
            (path->address ? path->address : "(Not Provided)"));
   if (path->address == NULL) {
      if (path == &(config->defaultserver)) 
         show_msg(MSGERR, "Connection needs to be made "
                          "via default server but "
                          "the default server has not "
                          "been specified\n");
      else 
         show_msg(MSGERR, "Connection needs to be made "
                          "via path specified at line "
                          "%d in configuration file but "
                          "the server has not been "
                          "specified for this path\n",
                  path->lineno);
   } else if ((res = resolve_ip(path->address, 0, HOSTNAMES)) == -1) {
      show_msg(MSGERR, "The SOCKS server (%s) listed in the configuration "
                       "file which needs to be used for this connection "
                       "is invalid\n", path->address);
   } else {	
      /* Construct the addr for the socks server */
      server_address.sin_family = AF_INET; /* host byte order */
      server_address.sin_addr.s_addr = res;
      server_address.sin_port = htons(path->port);
      bzero(&(server_address.sin_zero), 8);

      /* Complain if this server isn't on a localnet */
      if (is_local(config, &server_address.sin_addr)) {
         show_msg(MSGERR, "SOCKS server %s (%s) is not on a local subnet!\n", 
                  path->address, inet_ntoa(server_address.sin_addr));
      } else 
         gotvalidserver = 1;
   }

   /* If we haven't found a valid server we return connection refused */
   if (!gotvalidserver || 
       !(newconn = new_socks_request(__fd, connaddr, &server_address, path))) {
      errno = ECONNREFUSED;
      return(-1);
   } else {
      /* Now we call the main function to handle the connect. */
      rc = handle_request(newconn);
      /* If the request completed immediately it mustn't have been
       * a non blocking socket, in this case we don't need to know
       * about this socket anymore. */
      if ((newconn->state == FAILED) || (newconn->state == DONE))
         kill_socks_request(newconn);
      errno = rc;
      return((rc ? -1 : 0));
   }
}
Beispiel #13
0
/* TODO: IPv6 */
int sbbs_t::exec_net(csi_t* csi)
{
	char	str[512],rsp[512],buf[1025],ch,*p,**pp,**pp1,**pp2;
	ushort	w;
	uint 	i;
	BOOL	rd;
	int32_t	*lp,*lp1,*lp2;
	time_t	start;

	switch(*(csi->ip++)) {	/* sub-op-code stored as next byte */
		case CS_SOCKET_OPEN:
			lp=getintvar(csi,*(int32_t *)csi->ip);
			csi->ip+=4;
			csi->logic=LOGIC_FALSE;
			csi->socket_error=0;
			if(csi->sockets>=MAX_SOCKETS)
				return(0);
			if(lp!=NULL) {

				SOCKET sock=open_socket(SOCK_STREAM, NULL);
				if(sock!=INVALID_SOCKET) {

					SOCKADDR_IN	addr;

					memset(&addr,0,sizeof(addr));
					addr.sin_addr.s_addr = htonl(startup->outgoing4.s_addr);
					addr.sin_family = AF_INET;

					if((i=bind(sock, (struct sockaddr *) &addr, sizeof (addr)))!=0) {
						csi->socket_error=ERROR_VALUE;
						close_socket(sock);
						return(0);
					}

					*lp=sock;

					for(i=0;i<csi->sockets;i++)
						if(!csi->socket[i])
							break;
					csi->socket[i]=*lp;
					if(i==csi->sockets)
						csi->sockets++;
					csi->logic=LOGIC_TRUE; 
				} 
			}
			return(0);
		case CS_SOCKET_CLOSE:
			lp=getintvar(csi,*(int32_t *)csi->ip);
			csi->ip+=4;
			csi->logic=LOGIC_FALSE;
			csi->socket_error=0;
			if(lp && *lp) {
				csi->logic=close_socket((SOCKET)*lp);
				csi->socket_error=ERROR_VALUE;
				for(i=0;i<csi->sockets;i++)
					if(csi->socket[i]==(SOCKET)*lp)
						csi->socket[i]=0; 
				*lp=0;
			}
			return(0);
		case CS_SOCKET_CHECK:
			lp=getintvar(csi,*(int32_t *)csi->ip);
			csi->ip+=4;
			csi->logic=LOGIC_FALSE;
			csi->socket_error=0;

			if(lp==NULL || *lp==INVALID_SOCKET) 
				return(0);

			if(socket_check(*lp,NULL,NULL,0)==TRUE)
				csi->logic=LOGIC_TRUE;
			else
				csi->socket_error=ERROR_VALUE;
				
			return(0);
		case CS_SOCKET_CONNECT:
			lp=getintvar(csi,*(int32_t *)csi->ip);		/* socket */
			csi->ip+=4;

			pp=getstrvar(csi,*(int32_t *)csi->ip);		/* address */
			csi->ip+=4;

			w=*(ushort *)csi->ip;					/* port */
			csi->ip+=2;

			csi->logic=LOGIC_FALSE;
			csi->socket_error=0;

			if(!lp || !*lp || !pp || !*pp || !w)
				return(0);

			ulong ip_addr;

			if((ip_addr=resolve_ip(*pp))==INADDR_NONE)
				return(0);

			SOCKADDR_IN	addr;

			memset(&addr,0,sizeof(addr));
			addr.sin_addr.s_addr = ip_addr;
			addr.sin_family = AF_INET;
			addr.sin_port   = htons(w);

			if((i=connect(*lp, (struct sockaddr *)&addr, sizeof(addr)))!=0) {
				csi->socket_error=ERROR_VALUE;
				return(0);
			}
			csi->logic=LOGIC_TRUE;
			return(0);
		case CS_SOCKET_ACCEPT:
			lp1=getintvar(csi,*(int32_t *)csi->ip);		/* socket */
			csi->ip+=4;
			csi->socket_error=0;
			/* TODO */
			return(0);
		case CS_SOCKET_NREAD:
			lp1=getintvar(csi,*(int32_t *)csi->ip);		/* socket */
			csi->ip+=4;
			lp2=getintvar(csi,*(int32_t *)csi->ip);		/* var */
			csi->ip+=4;

			csi->logic=LOGIC_FALSE;
			csi->socket_error=0;

			if(!lp1 || !lp2)
				return(0);

			if(ioctlsocket(*lp1, FIONREAD, (ulong*)lp2)==0) 
				csi->logic=LOGIC_TRUE;
			else
				csi->socket_error=ERROR_VALUE;
			return(0);
		case CS_SOCKET_PEEK:
		case CS_SOCKET_READ:
			lp=getintvar(csi,*(int32_t *)csi->ip);			/* socket */
			csi->ip+=4;
			pp=getstrvar(csi,*(int32_t *)csi->ip);			/* buffer */
			csi->ip+=4;
			w=*(ushort *)csi->ip;						/* length */
			csi->ip+=2;					

			csi->logic=LOGIC_FALSE;
			csi->socket_error=0;

			if(!lp || !pp)
				return(0);

			if(w<1 || w>sizeof(buf)-1)
				w=sizeof(buf)-1;

			if((i=recv(*lp,buf,w
				,*(csi->ip-13)==CS_SOCKET_PEEK ? MSG_PEEK : 0))>0) {
				csi->logic=LOGIC_TRUE;
				buf[i]=0;
				if(csi->etx) {
					p=strchr(buf,csi->etx);
					if(p) *p=0; 
				}
				*pp=copystrvar(csi,*pp,buf); 
			} else
				csi->socket_error=ERROR_VALUE;
			return(0);
		case CS_SOCKET_READLINE:
			lp=getintvar(csi,*(int32_t *)csi->ip);			/* socket */
			csi->ip+=4;
			pp=getstrvar(csi,*(int32_t *)csi->ip);			/* buffer */
			csi->ip+=4;
			w=*(ushort *)csi->ip;						/* length */
			csi->ip+=2;					

			csi->logic=LOGIC_FALSE;
			csi->socket_error=0;

			if(!lp || !pp)
				return(0);

			if(w<1 || w>sizeof(buf)-1)
				w=sizeof(buf)-1;

			start=time(NULL);
			for(i=0;i<w;) {

				if(!online)
					return(1);

				if(!socket_check(*lp,&rd,NULL,1000))
					return(0);

				if(!rd) {
					if(time(NULL)-start>TIMEOUT_SOCK_READLINE) {
						lprintf(LOG_WARNING,"!socket_readline: timeout (%d) exceeded"
							,TIMEOUT_SOCK_READLINE);
						return(0);
					}
					continue;
				}

				if(recv(*lp, &ch, 1, 0)!=1) {
					csi->socket_error=ERROR_VALUE;
					return(0);
				}

				if(ch=='\n' && i>=1) 
					break;

				buf[i++]=ch;
			}
			if(i>0 && buf[i-1]=='\r')
				buf[i-1]=0;
			else
				buf[i]=0;

			if(csi->etx) {
				p=strchr(buf,csi->etx);
				if(p) *p=0; 
			}
			*pp=copystrvar(csi,*pp,buf); 
			csi->logic=LOGIC_TRUE;
			return(0);
		case CS_SOCKET_WRITE:	
			lp=getintvar(csi,*(int32_t *)csi->ip);			/* socket */
			csi->ip+=4;
			pp=getstrvar(csi,*(int32_t *)csi->ip);			/* buffer */
			csi->ip+=4;

			csi->logic=LOGIC_FALSE;
			csi->socket_error=0;

			if(!lp || !pp || !(*pp))
				return(0);

			if(sendsocket(*lp,*pp,strlen(*pp))>0)
				csi->logic=LOGIC_TRUE;
			else
				csi->socket_error=ERROR_VALUE;
			return(0);

		/* FTP Functions */
		case CS_FTP_LOGIN:
			lp=getintvar(csi,*(int32_t *)csi->ip);			/* socket */
			csi->ip+=4;
			pp1=getstrvar(csi,*(int32_t *)csi->ip);		/* username */
			csi->ip+=4;
			pp2=getstrvar(csi,*(int32_t *)csi->ip);		/* password */
			csi->ip+=4;

			csi->logic=LOGIC_FALSE;
			csi->socket_error=0;

			if(!lp || !pp1 || !pp2)
				return(0);

			if(!ftp_cmd(csi,*lp,NULL,rsp))
				return(0);

			if(atoi(rsp)!=220)
				return(0);

			sprintf(str,"USER %s",*pp1);

			if(!ftp_cmd(csi,*lp,str,rsp))
				return(0);
			
			if(atoi(rsp)==331) { /* Password needed */
				sprintf(str,"PASS %s",*pp2);
				if(!ftp_cmd(csi,*lp,str,rsp))
					return(0);
			}

			if(atoi(rsp)==230)	/* Login successful */
				csi->logic=LOGIC_TRUE;
			return(0);

		case CS_FTP_LOGOUT:
			lp=getintvar(csi,*(int32_t *)csi->ip);			/* socket */
			csi->ip+=4;
			csi->logic=LOGIC_FALSE;
			csi->socket_error=0;

			if(!lp)
				return(0);

			if(!ftp_cmd(csi,*lp,"QUIT",rsp))
				return(0);

			if(atoi(rsp)==221)	/* Logout successful */
				csi->logic=LOGIC_TRUE;
			return(0);

		case CS_FTP_PWD:
			lp=getintvar(csi,*(int32_t *)csi->ip);			/* socket */
			csi->ip+=4;
			csi->logic=LOGIC_FALSE;
			csi->socket_error=0;
			if(!lp)
				return(0);

			if(!ftp_cmd(csi,*lp,"PWD",rsp))
				return(0);

			if(atoi(rsp)==257)	/* pathname */
				csi->logic=LOGIC_TRUE;
			return(0);

		case CS_FTP_CWD:
			lp=getintvar(csi,*(int32_t *)csi->ip);			/* socket */
			csi->ip+=4;
			pp=getstrvar(csi,*(int32_t *)csi->ip);			/* path */
			csi->ip+=4;

			csi->logic=LOGIC_FALSE;
			csi->socket_error=0;
			if(!lp || !pp)
				return(0);
			
			sprintf(str,"CWD %s",*pp);
			if(!ftp_cmd(csi,*lp,str,rsp))
				return(0);

			if(atoi(rsp)==250)
				csi->logic=LOGIC_TRUE;

			return(0);

		case CS_FTP_DIR:
			lp=getintvar(csi,*(int32_t *)csi->ip);			/* socket */
			csi->ip+=4;
			pp=getstrvar(csi,*(int32_t *)csi->ip);			/* path */
			csi->ip+=4;

			csi->logic=LOGIC_FALSE;
			csi->socket_error=0;

			if(!lp || !pp)
				return(0);

			if(ftp_get(csi,*lp,*pp,NULL /* unused */, true /* DIR */)==true)
				csi->logic=LOGIC_TRUE;

			return(0);

		case CS_FTP_DELETE:
			lp=getintvar(csi,*(int32_t *)csi->ip);			/* socket */
			csi->ip+=4;
			pp=getstrvar(csi,*(int32_t *)csi->ip);			/* path */
			csi->ip+=4;

			csi->logic=LOGIC_FALSE;
			csi->socket_error=0;
			if(!lp || !pp)
				return(0);
			
			sprintf(str,"DELE %s",*pp);
			if(!ftp_cmd(csi,*lp,str,rsp))
				return(0);

			if(atoi(rsp)==250)
				csi->logic=LOGIC_TRUE;

			return(0);


		case CS_FTP_GET:
			lp=getintvar(csi,*(int32_t *)csi->ip);			/* socket */
			csi->ip+=4;
			pp1=getstrvar(csi,*(int32_t *)csi->ip);		/* src path */
			csi->ip+=4;
			pp2=getstrvar(csi,*(int32_t *)csi->ip);		/* dest path */
			csi->ip+=4;

			csi->logic=LOGIC_FALSE;
			csi->socket_error=0;

			if(!lp || !pp1 || !pp2)
				return(0);

			if(ftp_get(csi,*lp,*pp1,*pp2)==true)
				csi->logic=LOGIC_TRUE;
			
			return(0);

		case CS_FTP_PUT:
			lp=getintvar(csi,*(int32_t *)csi->ip);			/* socket */
			csi->ip+=4;
			pp1=getstrvar(csi,*(int32_t *)csi->ip);		/* src path */
			csi->ip+=4;
			pp2=getstrvar(csi,*(int32_t *)csi->ip);		/* dest path */
			csi->ip+=4;

			csi->logic=LOGIC_FALSE;
			csi->socket_error=0;

			if(!lp || !pp1 || !pp2)
				return(0);

			if(ftp_put(csi,*lp,*pp1,*pp2)==true)
				csi->logic=LOGIC_TRUE;
			
			return(0);


		default:
			errormsg(WHERE,ERR_CHK,"net sub-instruction",*(csi->ip-1));
			return(0); 
	}
}
int main(int argc, char *argv[]) {
	const char *usage = "Usage: <socks server name/ip> [portno]";
	char req[9];
	char resp[100];
	unsigned short int portno = defaultport;
	int ver = 0;
	int read_bytes;
	struct sockaddr_in server;

	if ((argc < 2) || (argc > 3)) {
		show_msg(MSGERR, "Invalid number of arguments\n");
		show_msg(MSGERR, "%s\n", usage);
		exit(1);
	}

	switch (argc) {
		case 3:
			portno = (unsigned short int)
				 strtol(argv[2], (char **) 0, 10);
			if ((portno == 0) || (errno == EINVAL)) {
				show_msg(MSGERR, "%s\n", usage);
				exit(1);
			}
		case 2:
			if ((server.sin_addr.s_addr = resolve_ip(argv[1], 1,HOSTNAMES))
                            ==  0) {
				show_msg(MSGERR, "Invalid IP/host specified (%s)\n", argv[1]);
				show_msg(MSGERR, "%s\n", usage);
				exit(1);
			}
	}

	server.sin_family = AF_INET; /* host byte order */
	server.sin_port = htons(portno);     /* short, network byte order */
	bzero(&(server.sin_zero), 8);/* zero the rest of the struct */

	/* Now, we send a SOCKS V5 request which happens to be */
	/* the same size as the smallest possible SOCKS V4     */
	/* request. In this packet we specify we have 7 auth   */
	/* methods but specify them all as NO AUTH.            */
	bzero(req, sizeof(req));
	req[0] = '\x05';
	req[1] = '\x07';
	read_bytes = send_request(&server, req, 
				  sizeof(req), resp, sizeof(resp));
	if (read_bytes > 0) {
		if ((int) resp[0] == 0) {
			ver = 4;
		} else if ((int) resp[0] == 5) {
			ver = 5;
		} 
		if (ver != 0) {
			printf("Reply indicates server is a version "
			       "%d socks server\n", ver);
		} else {
			show_msg(MSGERR, "Invalid SOCKS version reply (%d), "
			       	   "probably not a socks server\n",
				   ver);
		}
		exit(0);
	}	

	/* Hmmm.... disconnected so try a V4 request */
	printf("Server disconnected V5 request, trying V4\n");
	req[0] = '\x04';
	req[1] = '\x01';
	read_bytes = send_request(&server, req, 
				  sizeof(req), resp, sizeof(resp));	
	if (read_bytes > 0) {
		if ((int) resp[0] == 0) {
			ver = 4;
		} 
		if (ver == 4) {
			printf("Reply indicates server is a version "
			       "4 socks server\n");
		} else {
			show_msg(MSGERR, "Invalid SOCKS version reply (%d), "
			       	   "probably not a socks server\n",
				   (int) resp[0]);
		}
		exit(0);
	} else {
		show_msg(MSGERR, "Server disconnected, probably not a "
			   "socks server\n");
	}

	return(0);  
}
Beispiel #15
0
void show_server(struct parsedfile *config, struct serverent *server, int def) {
	struct sockaddr_in res4;
#ifdef ENABLE_IPV6
	struct sockaddr_in6 res6;
#endif
	void *res;
	struct netent *net;
	int af;
	int flag;
	char buf[60];

	/* Show address */
	if (server->address != NULL) {
#ifdef ENABLE_IPV6
		if ((flag = resolve_ip(AF_INET6, server->address, 0, HOSTNAMES, (void *) &res6)) == -1) {
#endif
			af = AF_INET;
			flag = resolve_ip(AF_INET, server->address, 0, HOSTNAMES, (void *) &res4);
			res = (void *) &res4.sin_addr;
#ifdef ENABLE_IPV6
		} else {
			af = AF_INET6;
			res = (void *) &res6.sin6_addr;
		}
#endif
		if (flag == -1)
			strcpy(buf, "Invalid!");
		else
			inet_ntop(af, res, buf, 60);
		printf("Server:       %s (%s)\n", server->address, buf);

		/* Check the server is on a local net */
		if ((flag != -1) && (is_local(config, af, res)))
			fprintf(stderr, "Error: Server is not on a network "
					"specified as local\n");
	} else
		printf("Server:       ERROR! None specified\n");

	/* Show port */
	printf("Port:         %d\n", server->port);

	/* Show SOCKS type */
	printf("SOCKS type:   %d\n", server->type);

	/* Show default username and password info */
	if (server->type == 5) {
		/* Show the default user info */
		printf("Default user: %s\n",
				 (server->defuser == NULL) ?
				 "Not Specified" : server->defuser);
		printf("Default pass: %s\n",
				 (server->defpass == NULL) ?
				 "Not Specified" : "******** (Hidden)");
		if ((server->defuser == NULL) &&
			 (server->defpass != NULL))
			fprintf(stderr, "Error: Default user must be specified "
					"if default pass is specified\n");
	} else {
		if (server->defuser) printf("Default user: %s\n",
						 server->defuser);
		if (server->defpass) printf("Default pass: %s\n",
						 server->defpass);
		if ((server->defuser != NULL) || (server->defpass != NULL))
			fprintf(stderr, "Error: Default user and password "
					"may only be specified for version 5 "
					"servers\n");
	}

	/* If this is the default servers and it has reachnets, thats stupid */
	if (def) {
		if (server->reachnets != NULL) {
			fprintf(stderr, "Error: The default server has "
					 "specified networks it can reach (reach statements), "
					 "these statements are ignored since the "
					 "default server will be tried for any network "
					 "which is not specified in a reach statement "
					 "for other servers\n");
		}
	} else if (server->reachnets == NULL) {
		fprintf(stderr, "Error: No reach statements specified for "
				 "server, this server will never be used\n");
	} else {
		printf("This server can be used to reach:\n");
		net = server->reachnets;
		while (net != NULL) {
			inet_ntop(net->af, net->localip, buf, 60);
			printf("Network: %40s   ", buf);
			printf("Prefixlen: %5d ", net->localnet);
			if (net->startport)
				printf("Ports: %5lu - %5lu",
						 net->startport, net->endport);
			printf("\n");
			net = net->next;
		}
	}
}
Beispiel #16
0
int connect(CONNECT_SIGNATURE) {
	struct sockaddr_in *connaddr;
	struct sockaddr_in peer_address;
	struct sockaddr_in server_address;
   int gotvalidserver = 0, rc, namelen = sizeof(peer_address);
	int sock_type = -1;
	int sock_type_len = sizeof(sock_type);
	unsigned int res = -1;
	struct serverent *path;
   struct connreq *newconn;

   get_environment();

	/* If the real connect doesn't exist, we're stuffed */
	if (realconnect == NULL) {
		show_msg(MSGERR, "Unresolved symbol: connect\n");
		return(-1);
	}

   show_msg(MSGDEBUG, "Got connection request\n");

	connaddr = (struct sockaddr_in *) __addr;

	/* Get the type of the socket */
	getsockopt(__fd, SOL_SOCKET, SO_TYPE, 
		   (void *) &sock_type, &sock_type_len);

	/* If this isn't an INET socket for a TCP stream we can't  */
	/* handle it, just call the real connect now               */
   if ((connaddr->sin_family != AF_INET) ||
       (sock_type != SOCK_STREAM)) {
      show_msg(MSGDEBUG, "Connection isn't a TCP stream ignoring\n");
		return(realconnect(__fd, __addr, __len));
   }

   /* If we haven't initialized yet, do it now */
   get_config();

   /* Are we already handling this connect? */
   if ((newconn = find_socks_request(__fd, 1))) {
      if (memcmp(&newconn->connaddr, connaddr, sizeof(*connaddr))) {
         /* Ok, they're calling connect on a socket that is in our
          * queue but this connect() isn't to the same destination, 
          * they're obviously not trying to check the status of 
          * they're non blocking connect, they must have close()d 
          * the other socket and created a new one which happens
          * to have the same fd as a request we haven't had the chance
          * to delete yet, so we delete it here. */
         show_msg(MSGDEBUG, "Call to connect received on old "
                            "tsocks request for socket %d but to "
                            "new destination, deleting old request\n",
                  newconn->sockid);
         kill_socks_request(newconn);
      } else {
         /* Ok, this call to connect() is to check the status of 
          * a current non blocking connect(). */
         if (newconn->state == FAILED) {
            show_msg(MSGDEBUG, "Call to connect received on failed "
                               "request %d, returning %d\n",
                     newconn->sockid, newconn->err);
            errno = newconn->err;
            rc = -1;
         } else if (newconn->state == DONE) {
            show_msg(MSGERR, "Call to connect received on completed "
                             "request %d\n",
                     newconn->sockid, newconn->err);
            rc = 0;
         } else {
            show_msg(MSGDEBUG, "Call to connect received on current request %d\n",
                     newconn->sockid);
            rc = handle_request(newconn);
            errno = rc;
         }
         if ((newconn->state == FAILED) || (newconn->state == DONE))
            kill_socks_request(newconn);
         return((rc ? -1 : 0));
      }
   }

   /* If the socket is already connected, just call connect  */
   /* and get its standard reply                             */
   if (!getpeername(__fd, (struct sockaddr *) &peer_address, &namelen)) {
      show_msg(MSGDEBUG, "Socket is already connected, defering to "
                         "real connect\n");
		return(realconnect(__fd, __addr, __len));
   }
     
   show_msg(MSGDEBUG, "Got connection request for socket %d to "
                      "%s\n", __fd, inet_ntoa(connaddr->sin_addr));

   /* If the address is local call realconnect */
#ifdef USE_TOR_DNS
   if (!(is_local(config, &(connaddr->sin_addr))) && 
       !is_dead_address(pool, connaddr->sin_addr.s_addr)) {
#else 
   if (!(is_local(config, &(connaddr->sin_addr)))) {
#endif
      show_msg(MSGDEBUG, "Connection for socket %d is local\n", __fd);
      return(realconnect(__fd, __addr, __len));
   }

   /* Ok, so its not local, we need a path to the net */
   pick_server(config, &path, &(connaddr->sin_addr), ntohs(connaddr->sin_port));

   show_msg(MSGDEBUG, "Picked server %s for connection\n",
            (path->address ? path->address : "(Not Provided)"));
   if (path->address == NULL) {
      if (path == &(config->defaultserver)) 
         show_msg(MSGERR, "Connection needs to be made "
                          "via default server but "
                          "the default server has not "
                          "been specified\n");
      else 
         show_msg(MSGERR, "Connection needs to be made "
                          "via path specified at line "
                          "%d in configuration file but "
                          "the server has not been "
                          "specified for this path\n",
                  path->lineno);
   } else if ((res = resolve_ip(path->address, 0, HOSTNAMES)) == -1) {
      show_msg(MSGERR, "The SOCKS server (%s) listed in the configuration "
                       "file which needs to be used for this connection "
                       "is invalid\n", path->address);
   } else {	
      /* Construct the addr for the socks server */
      server_address.sin_family = AF_INET; /* host byte order */
      server_address.sin_addr.s_addr = res;
      server_address.sin_port = htons(path->port);
      bzero(&(server_address.sin_zero), 8);

      /* Complain if this server isn't on a localnet */
      if (is_local(config, &server_address.sin_addr)) {
         show_msg(MSGERR, "SOCKS server %s (%s) is not on a local subnet!\n", 
                  path->address, inet_ntoa(server_address.sin_addr));
      } else 
         gotvalidserver = 1;
   }

   /* If we haven't found a valid server we return connection refused */
   if (!gotvalidserver || 
       !(newconn = new_socks_request(__fd, connaddr, &server_address, path))) {
      errno = ECONNREFUSED;
      return(-1);
   } else {
      /* Now we call the main function to handle the connect. */
      rc = handle_request(newconn);
      /* If the request completed immediately it mustn't have been
       * a non blocking socket, in this case we don't need to know
       * about this socket anymore. */
      if ((newconn->state == FAILED) || (newconn->state == DONE))
         kill_socks_request(newconn);
      errno = rc;
      return((rc ? -1 : 0));
   }
}

int select(SELECT_SIGNATURE) {
   int nevents = 0;
   int rc = 0;
   int setevents = 0;
   int monitoring = 0;
   struct connreq *conn, *nextconn;
   fd_set mywritefds, myreadfds, myexceptfds;

   /* If we're not currently managing any requests we can just 
    * leave here */
   if (!requests) {
      show_msg(MSGDEBUG, "No requests waiting, calling real select\n");
      return(realselect(n, readfds, writefds, exceptfds, timeout));
   }

   get_environment();

   show_msg(MSGDEBUG, "Intercepted call to select with %d fds, "
            "0x%08x 0x%08x 0x%08x, timeout %08x\n", n, 
            readfds, writefds, exceptfds, timeout);

   for (conn = requests; conn != NULL; conn = conn->next) {
      if ((conn->state == FAILED) || (conn->state == DONE))
         continue;
      conn->selectevents = 0;
      show_msg(MSGDEBUG, "Checking requests for socks enabled socket %d\n",
               conn->sockid);
      conn->selectevents |= (writefds ? (FD_ISSET(conn->sockid, writefds) ? WRITE : 0) : 0);
      conn->selectevents |= (readfds ? (FD_ISSET(conn->sockid, readfds) ? READ : 0) : 0);
      conn->selectevents |= (exceptfds ? (FD_ISSET(conn->sockid, exceptfds) ? EXCEPT : 0) : 0);
      if (conn->selectevents) {
         show_msg(MSGDEBUG, "Socket %d was set for events\n", conn->sockid);
         monitoring = 1;
      }
   }

   if (!monitoring)
      return(realselect(n, readfds, writefds, exceptfds, timeout));

   /* This is our select loop. In it we repeatedly call select(). We 
    * pass select the same fdsets as provided by the caller except we
    * modify the fdsets for the sockets we're managing to get events
    * we're interested in (while negotiating with the socks server). When
    * events we're interested in happen we go off and process the result
    * ourselves, without returning the events to the caller. The loop
    * ends when an event which isn't one we need to handle occurs or 
    * the select times out */
   do {
      /* Copy the clients fd events, we'll change them as we wish */
      if (readfds)
         memcpy(&myreadfds, readfds, sizeof(myreadfds));
      else
         FD_ZERO(&myreadfds);
      if (writefds)
         memcpy(&mywritefds, writefds, sizeof(mywritefds));
      else
         FD_ZERO(&mywritefds);
      if (exceptfds)
         memcpy(&myexceptfds, exceptfds, sizeof(myexceptfds));
      else
         FD_ZERO(&myexceptfds);

      /* Now enable our sockets for the events WE want to hear about */
      for (conn = requests; conn != NULL; conn = conn->next) {
         if ((conn->state == FAILED) || (conn->state == DONE) ||
             (conn->selectevents == 0))
            continue;
         /* We always want to know about socket exceptions */
         FD_SET(conn->sockid, &myexceptfds);
         /* If we're waiting for a connect or to be able to send
          * on a socket we want to get write events */
         if ((conn->state == SENDING) || (conn->state == CONNECTING))
            FD_SET(conn->sockid,&mywritefds);
         else
            FD_CLR(conn->sockid,&mywritefds);
         /* If we're waiting to receive data we want to get 
          * read events */
         if (conn->state == RECEIVING)
            FD_SET(conn->sockid,&myreadfds);
         else
            FD_CLR(conn->sockid,&myreadfds);
      }

      nevents = realselect(n, &myreadfds, &mywritefds, &myexceptfds, timeout);
      /* If there were no events we must have timed out or had an error */
      if (nevents <= 0)
         break;

      /* Loop through all the sockets we're monitoring and see if 
       * any of them have had events */
      for (conn = requests; conn != NULL; conn = nextconn) {
         nextconn = conn->next;
         if ((conn->state == FAILED) || (conn->state == DONE))
            continue;
         show_msg(MSGDEBUG, "Checking socket %d for events\n", conn->sockid);
         /* Clear all the events on the socket (if any), we'll reset
          * any that are necessary later. */
         setevents = 0;
         if (FD_ISSET(conn->sockid, &mywritefds))  {
            nevents--;
            setevents |= WRITE;
            show_msg(MSGDEBUG, "Socket had write event\n");
            FD_CLR(conn->sockid, &mywritefds);
         }
         if (FD_ISSET(conn->sockid, &myreadfds))  {
            nevents--;
            setevents |= READ;
            show_msg(MSGDEBUG, "Socket had write event\n");
            FD_CLR(conn->sockid, &myreadfds);
         }
         if (FD_ISSET(conn->sockid, &myexceptfds))  {
            nevents--;
            setevents |= EXCEPT;
            show_msg(MSGDEBUG, "Socket had except event\n");
            FD_CLR(conn->sockid, &myexceptfds);
         }

         if (!setevents) {
            show_msg(MSGDEBUG, "No events on socket %d\n", conn->sockid);
            continue;
         }

         if (setevents & EXCEPT) {
            conn->state = FAILED;
         } else {
            rc = handle_request(conn);
         }
         /* If the connection hasn't failed or completed there is nothing
          * to report to the client */
         if ((conn->state != FAILED) && 
             (conn->state != DONE))  
            continue;

         /* Ok, the connection is completed, for good or for bad. We now
          * hand back the relevant events to the caller. We don't delete the
          * connection though since the caller should call connect() to 
          * check the status, we delete it then */

         if (conn->state == FAILED) {
            /* Damn, the connection failed. Whatever the events the socket
             * was selected for we flag */
            if (conn->selectevents & EXCEPT) {
               FD_SET(conn->sockid, &myexceptfds);
               nevents++;
            }
            if (conn->selectevents & READ) {
               FD_SET(conn->sockid, &myreadfds);
               nevents++;
            }
            if (conn->selectevents & WRITE) {
               FD_SET(conn->sockid, &mywritefds);
               nevents++;
            }
            /* We should use setsockopt to set the SO_ERROR errno for this 
             * socket, but this isn't allowed for some silly reason which 
             * leaves us a bit hamstrung.
             * We don't delete the request so that hopefully we can 
             * return the error on the socket if they call connect() on it */
         } else {
            /* The connection is done,  if the client selected for 
             * writing we can go ahead and signal that now (since the socket must
             * be ready for writing), otherwise we'll just let the select loop
             * come around again (since we can't flag it for read, we don't know
             * if there is any data to be read and can't be bothered checking) */
            if (conn->selectevents & WRITE) {
               FD_SET(conn->sockid, &mywritefds);
               nevents++;
            }
         }
      }
   } while (nevents == 0);

   show_msg(MSGDEBUG, "Finished intercepting select(), %d events\n", nevents);

   /* Now copy our event blocks back to the client blocks */
   if (readfds)
      memcpy(readfds, &myreadfds, sizeof(myreadfds));
   if (writefds)
      memcpy(writefds, &mywritefds, sizeof(mywritefds));
   if (exceptfds)
      memcpy(exceptfds, &myexceptfds, sizeof(myexceptfds));

   return(nevents);
}
Beispiel #17
0
void sbbs_t::telnet_gate(char* destaddr, ulong mode, char* client_user_name, char* server_user_name, char* term_type)
{
	char*	p;
	uchar	buf[512];
	int		i;
	int		rd;
	uint	attempts;
	ulong	l;
	bool	gotline;
	ushort	port;
	ulong	ip_addr;
	ulong	save_console;
	SOCKET	remote_socket;
	SOCKADDR_IN	addr;

	if(mode&TG_RLOGIN)
		port=513;
	else
		port=IPPORT_TELNET;

	p=strchr(destaddr,':');
	if(p!=NULL) {
		*p=0;
		port=atoi(p+1);
	}

	ip_addr=resolve_ip(destaddr);
	if(ip_addr==INADDR_NONE) {
		lprintf(LOG_NOTICE,"!TELGATE Failed to resolve address: %s",destaddr);
		bprintf("!Failed to resolve address: %s\r\n",destaddr);
		return;
	}

    if((remote_socket = open_socket(SOCK_STREAM, client.protocol)) == INVALID_SOCKET) {
		errormsg(WHERE,ERR_OPEN,"socket",0);
		return;
	}

	memset(&addr,0,sizeof(addr));
	addr.sin_addr.s_addr = htonl(startup->telnet_interface);
	addr.sin_family = AF_INET;

	if((i=bind(remote_socket, (struct sockaddr *) &addr, sizeof (addr)))!=0) {
		lprintf(LOG_NOTICE,"!TELGATE ERROR %d (%d) binding to socket %d",i, ERROR_VALUE, remote_socket);
		bprintf("!ERROR %d (%d) binding to socket\r\n",i, ERROR_VALUE);
		close_socket(remote_socket);
		return;
	}

	memset(&addr,0,sizeof(addr));
	addr.sin_addr.s_addr = ip_addr;
	addr.sin_family = AF_INET;
	addr.sin_port   = htons(port);

	if((i=connect(remote_socket, (struct sockaddr *)&addr, sizeof(addr)))!=0) {
		lprintf(LOG_NOTICE,"!TELGATE ERROR %d (%d) connecting to server: %s"
			,i,ERROR_VALUE, destaddr);
		bprintf("!ERROR %d (%d) connecting to server: %s\r\n"
			,i,ERROR_VALUE, destaddr);
		close_socket(remote_socket);
		return;
	}

	l=1;

	if((i = ioctlsocket(remote_socket, FIONBIO, &l))!=0) {
		lprintf(LOG_NOTICE,"!TELGATE ERROR %d (%d) disabling socket blocking"
			,i, ERROR_VALUE);
		close_socket(remote_socket);
		return;
	}

	lprintf(LOG_INFO,"Node %d %s gate to %s port %u on socket %d"
		,cfg.node_num
		,mode&TG_RLOGIN ? "RLogin" : "Telnet"
		,destaddr,port,remote_socket);

	if(!(mode&TG_CTRLKEYS))
		console|=CON_RAW_IN;

	if(mode&TG_RLOGIN) {
		p=(char*)buf;
		*(p++)=0;
		p+=sprintf(p,"%s",client_user_name==NULL ? useron.alias : client_user_name);
		p++;	// Add NULL
		p+=sprintf(p,"%s",server_user_name==NULL ? useron.name : server_user_name);
		p++;	// Add NULL
		if(term_type!=NULL)
			p+=sprintf(p,"%s",term_type);
		else
			p+=sprintf(p,"%s/%u",terminal, cur_rate);
		p++;	// Add NULL
		l=p-(char*)buf;
		sendsocket(remote_socket,(char*)buf,l);
		mode|=TG_NOLF;	/* Send LF (to remote host) when Telnet client sends CRLF (when not in binary mode) */
	}

	/* This is required for gating to Unix telnetd */
	if(mode&TG_NOTERMTYPE)
		request_telnet_opt(TELNET_DONT,TELNET_TERM_TYPE, 3000);	// Re-negotiation of terminal type

	/* Text/NVT mode by default */
	request_telnet_opt(TELNET_DONT,TELNET_BINARY_TX, 3000);

	if(!(telnet_mode&TELNET_MODE_OFF) && (mode&TG_PASSTHRU))
		telnet_mode|=TELNET_MODE_GATE;	// Pass-through telnet commands

	while(online) {
		if(!(mode&TG_NOCHKTIME))
			gettimeleft();
		rd=RingBufRead(&inbuf,buf,sizeof(buf));
		if(rd) {
#if 0
			if(memchr(buf,TELNET_IAC,rd)) {
				char dump[2048];
				dump[0];
				p=dump;
				for(int i=0;i<rd;i++)
					p+=sprintf(p,"%u ",buf[i]);
				lprintf(LOG_DEBUG,"Node %d Telnet cmd from client: %s", cfg.node_num, dump);
			}
#endif
			if(telnet_remote_option[TELNET_BINARY_TX]!=TELNET_WILL) {
				if(*buf==0x1d) { // ^]
					save_console=console;
					console&=~CON_RAW_IN;	// Allow Ctrl-U/Ctrl-P
					CRLF;
					while(online) {
						SYNC;
						mnemonics("\1n\r\n\1h\1bTelnet Gate: \1y~D\1wisconnect, "
							"\1y~E\1wcho toggle, \1y~L\1wist Users, \1y~P\1wrivate message, "
							"\1y~Q\1wuit: ");
						switch(getkeys("DELPQ",0)) {
							case 'D':
								closesocket(remote_socket);
								break;
							case 'E':
								mode^=TG_ECHO;
								bprintf(text[EchoIsNow]
									,mode&TG_ECHO
									? text[ON]:text[OFF]);
								continue;
							case 'L':
								whos_online(true);
								continue;
							case 'P':
								nodemsg();
								continue;
						}
						break;
					}
					attr(LIGHTGRAY);
					console=save_console;
				}
				else if(*buf<' ' && (mode&TG_CTRLKEYS))
					handle_ctrlkey(*buf, K_NONE);
				gotline=false;
				if((mode&TG_LINEMODE) && buf[0]!='\r') {
					ungetkey(buf[0]);
					l=K_CHAT;
					if(!(mode&TG_ECHO))
						l|=K_NOECHO;
					rd=getstr((char*)buf,sizeof(buf)-1,l);
					if(!rd)
						continue;
					strcat((char*)buf,crlf);
					rd+=2;
					gotline=true;
				}
				if((mode&TG_CRLF) && buf[rd-1]=='\r')
					buf[rd++]='\n';
				else if((mode&TG_NOLF) && buf[rd-1]=='\n')
					rd--;
				if(!gotline && (mode&TG_ECHO) && rd) {
					RingBufWrite(&outbuf,buf,rd);
				}
			} /* Not Telnet Binary mode */
			if(rd > 0) {
				for(attempts=0;attempts<60 && online; attempts++) /* added retry loop here, Jan-20-2003 */
				{
					if((i=sendsocket(remote_socket,(char*)buf,rd))>=0)
						break;
					if(ERROR_VALUE!=EWOULDBLOCK)
						break;
					mswait(500);
				} 
				if(i<0) {
					lprintf(LOG_NOTICE,"!TELGATE ERROR %d sending on socket %d",ERROR_VALUE,remote_socket);
					break;
				}
			}
		}
		rd=recv(remote_socket,(char*)buf,sizeof(buf),0);
		if(rd<0) {
			if(ERROR_VALUE==EWOULDBLOCK) {
				if(mode&TG_NODESYNC) {
					SYNC;
				} else {
					// Check if the node has been interrupted
					getnodedat(cfg.node_num,&thisnode,0);
					if(thisnode.misc&NODE_INTR)
						break;
				}
				YIELD();
				continue;
			}
			lprintf(LOG_NOTICE,"!TELGATE ERROR %d receiving on socket %d",ERROR_VALUE,remote_socket);
			break;
		}
		if(!rd) {
			lprintf(LOG_INFO,"Node %d Telnet gate disconnected",cfg.node_num);
			break;
		}
#if 0
		if(memchr(buf,TELNET_IAC,rd)) {
			char dump[2048];
			dump[0];
			p=dump;
			for(int i=0;i<rd;i++)
				p+=sprintf(p,"%u ",buf[i]);
			lprintf(LOG_DEBUG,"Node %d Telnet cmd from server: %s", cfg.node_num, dump);
		}
#endif
		RingBufWrite(&outbuf,buf,rd);
	}
	console&=~CON_RAW_IN;
	telnet_mode&=~TELNET_MODE_GATE;

	/* Disable Telnet Terminal Echo */
	request_telnet_opt(TELNET_WILL,TELNET_ECHO);

	close_socket(remote_socket);

	lprintf(LOG_INFO,"Node %d Telnet gate to %s finished",cfg.node_num,destaddr);
}
Beispiel #18
0
int main (int argc, char **argv) {
  if (argc != 3) {
    log_error("Usage: geoip_server geoipdb port\n");
    return 1;
  }

  GeoIP* gi = init_geoip(argv[1]);
  if (gi == NULL) {
    log_error("Could not open geoip database %s\n", argv[1]);
    return 1;
  }
  void *context = zmq_init(1);
  if (context == NULL) {
    log_error("Could not initialize ZMQ\n");
    return 1;
  }

  //  Socket to talk to clients
  void *responder = zmq_socket(context, ZMQ_REP);
  if (responder == NULL) {
    log_error("Could not initialize ZMQ responder\n");
    return 1;
  }

  // Check port
  char port[25];
  if (strlen(argv[2]) > 6 || atoi(argv[2]) == 0) {
    log_error("Invalid port %s", argv[2]);
    return 1;
  }
  
  int rc;
  sprintf(port, "tcp://*:%s", argv[2]);
  rc = zmq_bind (responder, port);
  assert(rc == 0);

  while (1) {
    char input[MAX_BUFFER];
    //  Wait for next request from client
    zmq_msg_t request;
    rc = zmq_msg_init(&request);    
    assert(rc == 0);
    rc = zmq_recv(responder, &request, 0);
    assert(rc == 0);

    int size = zmq_msg_size(&request);
    if (size + 1 >= MAX_BUFFER ) {
      // treat this as an error, this message is too large to be a valid geoip request.
      goto bad_message;
    }

    // Copy and null terminate incoming message
    char* req_data = (char*) zmq_msg_data(&request);
    strncpy(input, req_data, size);
    input[size] = 0;
    zmq_msg_close(&request);

    // Process GeoIP request or fail.
    if (strncmp(input, "geoip ", 6) == 0) {
      char output[MAX_BUFFER];
      int bytes = resolve_ip(gi, input + 6, output, MAX_BUFFER);
      
      zmq_msg_t reply;
      rc = zmq_msg_init_size(&reply, bytes);
      assert(rc == 0);
      memcpy((void*)zmq_msg_data(&reply), output, bytes);
      rc = zmq_send(responder, &reply, 0);
      assert(rc == 0);
      zmq_msg_close(&reply);

    }
    else {
      goto bad_message;
    }
    continue;


  bad_message:
    // Bail, invalid input.
    rc = zmq_msg_close (&request);
    assert(rc == 0);
    zmq_msg_t reply;
    rc = zmq_msg_init_size(&reply, 6);
    assert(rc == 0);
    memcpy((void *) zmq_msg_data (&reply), "ERROR", 5);
    rc = zmq_send(responder, &reply, 0);
    assert(rc == 0);
    rc = zmq_msg_close (&reply);      
    assert(rc == 0);
  }
  zmq_term (context);
  return 0;
}
void show_server(struct parsedfile *config, struct serverent *server, int def) {
	struct in_addr res;
	struct netent *net;

	/* Show address */
	if (server->address != NULL) 
		printf("Server:       %s (%s)\n", server->address, 
	       		((res.s_addr = resolve_ip(server->address, 0, 
						  HOSTNAMES)) == 0 
			 ? "Invalid!" : inet_ntoa(res)));
	else
		printf("Server:       ERROR! None specified\n");

	/* Check the server is on a local net */
	if ((server->address != NULL) && (res.s_addr != 0) && 
	    (is_local(config, &res))) 
		fprintf(stderr, "Error: Server is not on a network "
				"specified as local\n");

	/* Show port */
	printf("Port:         %d\n", server->port);

	/* Show SOCKS type */
	printf("SOCKS type:   %d\n", server->type);

	/* Show default username and password info */
	if (server->type == 5) {
		/* Show the default user info */
		printf("Default user: %s\n", 
		       (server->defuser == NULL) ? 
		       "Not Specified" : server->defuser);
		printf("Default pass: %s\n", 
		       (server->defpass == NULL) ? 
		       "Not Specified" : "******** (Hidden)");
		if ((server->defuser == NULL) && 
		    (server->defpass != NULL)) 
			fprintf(stderr, "Error: Default user must be specified "
				   "if default pass is specified\n");
	} else {
		if (server->defuser) printf("Default user: %s\n", 
					    server->defuser);
		if (server->defpass) printf("Default pass: %s\n", 
					    server->defpass);
		if ((server->defuser != NULL) || (server->defpass != NULL))
			fprintf(stderr, "Error: Default user and password "
				   "may only be specified for version 5 "
				   "servers\n");
	}

	/* If this is the default servers and it has reachnets, thats stupid */
	if (def) {
		if (server->reachnets != NULL) { 
			fprintf(stderr, "Error: The default server has "
			       "specified networks it can reach (reach statements), "
			       "these statements are ignored since the "
			       "default server will be tried for any network "
			       "which is not specified in a reach statement "
			       "for other servers\n");
		}
	} else if (server->reachnets == NULL) {
		fprintf(stderr, "Error: No reach statements specified for "
		       "server, this server will never be used\n");
	} else {
		printf("This server can be used to reach:\n");
		net = server->reachnets;
		while (net != NULL) {
			printf("Network: %15s ",
			       inet_ntoa(net->localip));
			printf("NetMask: %15s ", 
			       inet_ntoa(net->localnet));
         if (net->startport)
            printf("Ports: %5lu - %5lu",
                   net->startport, net->endport);
         printf("\n");
			net = net->next;
		}
	}
}
Beispiel #20
0
/* Must be at least 128 bytes long                         */
int http_get_fd(char *URL, size_t *len, char *error)
{
    char 	host[MAX_HOST_LEN+1];
    ulong	ip_addr;
    int		s=-1;
    int		port=80;
    char	*p;
    char	*path;
    struct sockaddr_in addr;
    char	header[MAX_HEADER+1];

    if(len != NULL)
        *len=0;
    if(error != NULL)
        *error=0;
    if(strncasecmp(URL, "http://", 7))  {
        if(error!=NULL)
            strcpy(error, "URL is not http");
        return(-1);
    }
    strncpy(host, URL+7, MAX_HOST_LEN);
    host[MAX_HOST_LEN+1]=0;
    if((p=strchr(host,'/'))==NULL)  {
        if(error!=NULL)
            strcpy(error, "Host too long or no path info found");
        return(-1);
    }
    *p=0;
    if((p=strchr(host,':'))!=NULL)  {
        *p=0;
        port=atoi(p+1);
    }
    if((ip_addr=resolve_ip(host))==INADDR_NONE)  {
        if(error!=NULL)
            strcpy(error, "Unable to resolve host");
        return(-1);
    }
    if((path=strchr(URL+7, '/'))==NULL)  {
        if(error!=NULL)
            strcpy(error, "Path info not found");
        return(-1);
    }
    if ((s = socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) < 0)  {
        if(error!=NULL)
            strcpy(error, "Unable to create socket");
        return(-1);
    }
    memset(&addr,0,sizeof(addr));
    addr.sin_addr.s_addr = ip_addr;
    addr.sin_family = AF_INET;
    addr.sin_port   = htons(port);
    if (connect(s, (struct sockaddr*)&addr, sizeof (addr)) < 0) {
        close(s);
        if(error!=NULL)
            strcpy(error, "Unable to connect");
        return(-1);
    }
    if(error!=NULL)
        strcpy(error,"Unable to send request");
    if(write(s, "GET ", 4)!=4)  {
        close(s);
        return(-1);
    }
    if(write(s, path, strlen(path))!=strlen(path))  {
        close(s);
        return(-1);
    }
    if(write(s, " HTTP/1.0\r\nHost: ", 17)!=17)  {
        close(s);
        return(-1);
    }
    if(write(s, host, strlen(host))!=strlen(host))  {
        close(s);
        return(-1);
    }
    if(write(s, "\r\nConnection: close\r\n\r\n",23)!=23)  {
        close(s);
        return(-1);
    }
    if(error!=NULL)
        *error=0;
    if(sockreadline(s, header, sizeof(header), error) < 0)  {
        close(s);
        return(-1);
    }
    if(atoi(header+9)!=200)  {
        if(error != NULL)  {
            strncpy(error, header, 128);
            error[127]=0;
        }
        close(s);
        return(-1);
    }
    while(header[0])  {
        if(sockreadline(s, header, sizeof(header), error) < 0)  {
            close(s);
            return(-1);
        }
        if(len != NULL && strncasecmp(header,"content-length:",15)==0)  {
            *len=atol(header+15);
        }
    }
    return(s);
}