NoPaste Service
DOWNLOAD
Language: C
Author: Matrix86
Description: Simple Socks v5 Proxy
Date: 19/04/09 14:26
  1. /**************************************************************************
  2.                                                         Socks V5 Server
  3.                                                        
  4.     This program is free software; you can redistribute it and/or modify
  5.     it under the terms of the GNU General Public License as published by
  6.     the Free Software Foundation; either version 3 of the License, or
  7.     (at your option) any later version.
  8.  
  9.     This program is distributed in the hope that it will be useful,
  10.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.     GNU General Public License for more details.
  13.  
  14.     You should have received a copy of the GNU General Public License
  15.     along with this program.  If not, see <http://www.gnu.org/licenses/>.
  16.  
  17.    Coded By Matrix86 ----> matrix86 {AT} tuxmealux {DOT} net
  18.  
  19. ****************************************************************************/
  20.  
  21. #include <arpa/inet.h>
  22. #include <sys/types.h>
  23. #include <sys/time.h>
  24. #include <sys/socket.h>
  25. #include <netinet/in.h>
  26. #include <netdb.h>
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <errno.h>
  30. #include <signal.h>
  31. #include <string.h>
  32. #include <unistd.h>
  33. #include <sys/ioctl.h>
  34. #include <fcntl.h>
  35. #include <stdarg.h>
  36. #include <sys/wait.h>
  37. #include <pthread.h>
  38. #include <time.h>
  39.  
  40. #ifndef SIGFUNC_DEFINED
  41. typedef void            (*sigfunc_t)();
  42. #endif
  43.  
  44. #define BUFFERSIZE 65536
  45.  
  46. #define PORT            9050
  47. #define VERSION         "0.1_alpha"
  48. #define AUTHOR          "Matrix86"
  49. #define SITE            "http://www.tuxmealux.net"
  50.  
  51.  
  52. #define SOCKS5          05
  53. #define SOCKS4          04
  54.  
  55. #define IPV4            1
  56. #define IPV6            4
  57. #define DOMAIN          3
  58.  
  59. #define TCPCONN         01
  60. #define TCPBIND         02
  61. #define UDPCONN         03
  62.  
  63. #define REQ_OK      00
  64. #define REQ_FAIL    01
  65. #define NO_ALLOW    02
  66. #define NET_UNREAC  03
  67. #define HOST_UNREAC 04
  68. #define CON_REFUSED 05
  69. #define TTL_EXPIRED 06
  70. #define ERR_CMD     07
  71. #define ERR_ADDR    08
  72.  
  73. #define NOAUTH          00
  74.  
  75. #define FASE1           1
  76. #define FASE2           2
  77. #define FASE3           3
  78. #define FASE4           4
  79.  
  80. #define TIMEOUT         30
  81.  
  82. int dm = 0;
  83.  
  84. typedef struct context {
  85.         int socket_client;
  86.         int socket_server;
  87.         int handshake;
  88.         struct sockaddr_in addrclient;
  89.         unsigned int version;
  90.         unsigned int type;
  91.         unsigned int DstPort;
  92.         unsigned char DstAddr[1024];
  93.         unsigned char * last_request;
  94. } ss_context;
  95.  
  96.  
  97. int ss_fprintf( FILE *stream, const char *fmt, ... ) {
  98.         int c = 0;
  99.         va_list args;
  100.         va_start( args, fmt );
  101.  
  102.         // If daemon mode is off print text
  103.         if( !dm )
  104.                 c = vfprintf( stream, fmt, args );
  105.        
  106.         va_end(args);
  107.        
  108.         return c;
  109. }
  110.  
  111. void die( char *text ) {
  112.         ss_fprintf( stdout, "[ERROR] %s\n", text );
  113.         exit(1);
  114. }
  115.  
  116. void ss_banner(){
  117.         printf("*****************************************\n");
  118.         printf("*          SIMPLE SOCKS PROXY           *\n");
  119.         printf("*                                       *\n");
  120.         printf("* VERSION: %s                    *\n",VERSION);
  121.         printf("* Author:  %s                     *\n",AUTHOR);
  122.         printf("* Site:    %s     *\n",SITE);
  123.         printf("*                                       *\n");
  124.         printf("*****************************************\n\n");
  125. }
  126.  
  127. void ss_usage( char * ex ) {
  128.         printf( "Usage : %s <options>\n", ex );
  129.         printf( "\tOptions : \n" );
  130.         printf( "\t\t-p <num>  : set listen port.\n" );
  131.         printf( "\t\t-d        : daemon mode.\n" );
  132.         printf( "\t\t-h        : show this help.\n\n" );
  133. }
  134.  
  135. void set_timeout( int sd ){
  136.         struct timeval tv;
  137.         tv.tv_sec       = TIMEOUT;
  138.         tv.tv_usec      = 0;
  139.        
  140.         setsockopt( sd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(struct timeval) );
  141.         setsockopt( sd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(struct timeval) );
  142. }
  143.  
  144. void set_signal( int sig, sigfunc_t handler ) {
  145.         struct sigaction n, o;
  146.  
  147.         memset(&n, 0, sizeof n);
  148.         n.sa_handler = handler;
  149.  
  150.         if (sig != SIGALRM) {
  151.                 n.sa_flags = SA_RESTART;
  152.         }
  153.  
  154.         if (sigaction(sig, &n, &o) < 0)
  155.                 return SIG_ERR;
  156.         return o.sa_handler;
  157. }
  158.  
  159. int ss_send( ss_context * ctx, unsigned char * buffer, int lenght ) {
  160.         if( send( ctx->socket_client, buffer, lenght, 0 ) < 0 ) {
  161.                 return 1;
  162.         }
  163.        
  164.         return 0;
  165. }
  166.  
  167. int ss_connection( ss_context * ctx ) {
  168.         struct sockaddr_in server;
  169.         struct hostent * data;
  170.         char ip[INET6_ADDRSTRLEN];
  171.        
  172.         memset( (void *) ip, 0, sizeof(ip) );
  173.  
  174.         if ( ( ctx->socket_server = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 )
  175.         {
  176.         ss_fprintf( stderr, "[WARNING] Failed to create socket.\n" );
  177.         return -1;
  178.         }
  179.  
  180.         memset( (void *) &server, 0, sizeof(struct sockaddr_in) );
  181.         server.sin_family = AF_INET;
  182.         server.sin_port = htons( ctx->DstPort );
  183.        
  184.         // If a domain, get his IP address
  185.         if( ctx->type == DOMAIN ) {
  186.                 if ( ( data = gethostbyname( (const char *) ctx->DstAddr ) ) == NULL ) {
  187.                 ss_fprintf( stderr, "[WARNING] gethostbyname %s.\n", strerror(errno) );
  188.                         return -1;
  189.         }
  190.         inet_ntop(data->h_addrtype, data->h_addr, ip, sizeof(ip));
  191.         ss_fprintf( stdout, "- Destination IP: %s\n", ip );
  192.         }
  193.         else if( ctx->type == IPV4 )
  194.                 strcpy( ip, (const char *) ctx->DstAddr );
  195.        
  196.         server.sin_addr.s_addr = inet_addr( ip );
  197.        
  198.         if( connect ( ctx->socket_server, (struct sockaddr *) &server, sizeof( struct sockaddr ) ) < 0 )
  199.         {
  200.                 ss_fprintf( stderr, "[WARNING] connect %s.\n", strerror(errno) );
  201.                 return -1;
  202.         }
  203.         //printf("Connected to %s\n", ip);
  204.         set_timeout( ctx->socket_server );
  205.        
  206.         return 0;
  207. }
  208.  
  209. int ss_pkt_parse( ss_context * ctx ) {
  210.         int nmethods, i, num;
  211.         unsigned char buff[BUFFERSIZE];
  212.        
  213.         if( (ctx->handshake == FASE1) || (ctx->handshake == FASE2) ) {
  214.                 switch( ctx->last_request[0] ) {
  215.                         case SOCKS4 :
  216.                                 // Ignore this version
  217.                                 return -1;
  218.                                 break;
  219.                         case SOCKS5:
  220.                                 ctx->version = SOCKS5;
  221.                                 //printf( "SOCKS5\n" );
  222.                                 break;
  223.                         default:
  224.                                 //fprintf( stdout, "Richiesta non socks5\n" );
  225.                                 return -1;
  226.                 }
  227.         }
  228.        
  229.         // First phase of handshake
  230.         if( ctx->handshake == FASE1 ) {
  231.                 //printf("Fase1\n");
  232.                 // numbers of methods supported
  233.                 nmethods = ctx->last_request[1];
  234.                
  235.                 // Check no authentication methods into client methods list
  236.                 for( i = 0; ( i < nmethods ) && ( i < BUFFERSIZE - 2 ); i++ ){
  237.                         if( ctx->last_request[i+2] == NOAUTH ) {
  238.                                 buff[0] = SOCKS5;
  239.                                 buff[1] = NOAUTH;
  240.                                 if( ss_send( ctx, buff, 2 ) ) return -1;
  241.                                 ctx->handshake = FASE2;
  242.                                 return 0;
  243.                         }
  244.                 }
  245.                 return -1;
  246.         }
  247.        
  248.         // Second phase of handshake
  249.         if( ctx->handshake == FASE2 ) {
  250.                 //printf("Fase2\n");
  251.                 unsigned int i, s, len, DstPort = 0;
  252.                 unsigned char DstAddr[1024];
  253.        
  254.                 if( ctx->last_request[1] != TCPCONN ) return -1;
  255.                 if( ctx->last_request[2] != 00 ) return -1;
  256.                
  257.                 switch( ctx->last_request[3] ) {
  258.                         case IPV4:
  259.                                 //printf("IPv4\n");
  260.                                 ctx->type = IPV4;
  261.                                 len = 10;
  262.                                 DstPort += ctx->last_request[8];
  263.                                 DstPort <<= 8;
  264.                                 DstPort += ctx->last_request[9];
  265.                                 snprintf( (char *) DstAddr, sizeof(DstAddr), "%hu.%hu.%hu.%hu",         (unsigned char)ctx->last_request[4],
  266.                                                                                                                                                                         (unsigned char)ctx->last_request[5],
  267.                                                                                                                                                                         (unsigned char)ctx->last_request[6],
  268.                                                                                                                                                                         (unsigned char)ctx->last_request[7]
  269.                                                                                                                                                                         );
  270.                                 strcpy( (char *) ctx->DstAddr, (const char *) DstAddr );
  271.                                 ctx->DstPort = DstPort;
  272.                                
  273.                                 ss_fprintf( stdout, "[%s] Received request for %s:%d.\n", inet_ntoa( ctx->addrclient.sin_addr ), DstAddr, DstPort );
  274.                                
  275.                                 // Trying to connect
  276.                                 if( ss_connection( ctx ) < 0 ) {
  277.                                         // Connection error
  278.                                         buff[0] = SOCKS5;
  279.                                         buff[1] = REQ_FAIL;
  280.                                         buff[2] = 00;
  281.                                 }
  282.                                 else {
  283.                                         //Connection done
  284.                                         buff[0] = SOCKS5;
  285.                                         buff[1] = REQ_OK;
  286.                                         buff[2] = 00;
  287.                                 }
  288.                                
  289.                                 for( i = 3; i <= 7 + 2; i++ )
  290.                                         buff[i] = ctx->last_request[i];
  291.                                
  292.                                 if( ss_send( ctx, buff, len ) ) {
  293.                                         ss_fprintf( stderr, "ss_send problem.\n" );
  294.                                         return -1;
  295.                                 }
  296.                                 else {
  297.                                         if( buff[1] == REQ_FAIL ) return -1;
  298.                                         ctx->handshake = FASE3;
  299.                                         return 0;
  300.                                 }
  301.                                 break;
  302.                         case DOMAIN:
  303.                                 //printf("DOMAIN");
  304.                                 ctx->type = DOMAIN;
  305.                                 num = ctx->last_request[4]+5;
  306.                                 len = num+2;
  307.                                 DstPort += ctx->last_request[num];
  308.                                 DstPort <<= 8;
  309.                                 DstPort += ctx->last_request[num + 1];
  310.                                
  311.                                 for( i = 0, s = 5; s < num; s++, i++ ) {
  312.                                         if( i >= 64 ) break;
  313.                                         DstAddr[i] = ctx->last_request[s];
  314.                                 }
  315.                                 DstAddr[i] = '\0';
  316.                                
  317.                                 strcpy( (char *) ctx->DstAddr, (const char *) DstAddr );
  318.                                 ctx->DstPort = DstPort;
  319.                                
  320.                                 ss_fprintf( stdout, "[%s] Received request for %s:%d.\n", inet_ntoa( ctx->addrclient.sin_addr ), DstAddr, DstPort );
  321.                                
  322.                                 // Trying to connect
  323.                                 if( ss_connection( ctx ) < 0 ) {
  324.                                         // Connection error
  325.                                         buff[0] = SOCKS5;
  326.                                         buff[1] = REQ_FAIL;
  327.                                         buff[2] = 00;
  328.                                 }
  329.                                 else {
  330.                                         // Connection done
  331.                                         buff[0] = SOCKS5;
  332.                                         buff[1] = REQ_OK;
  333.                                         buff[2] = 00;
  334.                                 }
  335.  
  336.                                 for( i = 3; i <= 5 + ctx->last_request[4] + 2; i++ )
  337.                                         buff[i] = ctx->last_request[i];
  338.                                        
  339.                                 if( ss_send( ctx, buff, len ) ) {
  340.                                         ss_fprintf( stderr, "ss_send problem\n" );
  341.                                         return -1;
  342.                                 }
  343.                                 else {
  344.                                         if( buff[1] == REQ_FAIL ) return -1;
  345.                                         ctx->handshake = FASE3;
  346.                                         return 0;
  347.                                 }
  348.                                 break;
  349.                         case IPV6:
  350.                                 //strcpy( type, "IPV6 (no Supported)." );
  351.                                 return -1;
  352.                                 break;
  353.                         default:
  354.                                 return -1;
  355.                                 break;
  356.                 }
  357.                
  358.                
  359.                
  360.         }
  361.        
  362.         return -1;
  363. }
  364.  
  365. void timeout(int signo)
  366. {
  367.   return;
  368. }
  369.  
  370. void ss_pipe( ss_context * ctx ) {
  371.         fd_set                  rfds;
  372.         int                     nfds, sfd;
  373.         struct   timeval tv;
  374.         int                     mslen = 0;
  375.         unsigned char * buffer;
  376.        
  377.         buffer = ( unsigned char * ) calloc( sizeof(char) * BUFFERSIZE, 1 );
  378.        
  379.         set_timeout( ctx->socket_client );
  380.         set_timeout( ctx->socket_server );
  381.        
  382.         nfds = ( ctx->socket_server > ctx->socket_client ? ctx->socket_server : ctx->socket_client );
  383.         set_signal( SIGALRM, timeout );
  384.         for (;;) {
  385.                 FD_ZERO( &rfds );
  386.                 FD_SET( ctx->socket_client, &rfds );
  387.                 FD_SET( ctx->socket_server, &rfds );
  388.                
  389.                 tv.tv_sec = 60; tv.tv_usec = 0;
  390.                
  391.                 sfd = select( nfds+1, &rfds, NULL, NULL, &tv);
  392.                 if( sfd > 0 ) {
  393.                         if( FD_ISSET( ctx->socket_server, &rfds ) ) {
  394.                                 // Forward from server to client
  395.                                 if( ( mslen = read( ctx->socket_server, buffer, BUFFERSIZE ) ) > 0 ) {
  396.                                         send( ctx->socket_client, buffer, mslen, 0 );
  397.                                 }
  398.                                 if( mslen == 0 ) break;
  399.                                 //printf( "Forward from server to client\n" );
  400.                                 FD_CLR( ctx->socket_server, &rfds );
  401.                         }
  402.                        
  403.                         if ( FD_ISSET( ctx->socket_client, &rfds ) ) {
  404.                                 // Forward from client to server
  405.                                 if( ( mslen = read( ctx->socket_client, buffer, BUFFERSIZE ) ) > 0 ) {
  406.                                         send( ctx->socket_server, buffer, mslen, 0 );
  407.                                 }
  408.                                 if( mslen == 0 ) break;
  409.                                 //printf( "Forward from client to server\n" );
  410.                                 FD_CLR( ctx->socket_client, &rfds );
  411.                         }
  412.                        
  413.                 } else if( sfd < 0 ) {
  414.                         if( errno != EINTR ) break;
  415.                 }
  416.         }
  417.        
  418.         return;
  419. }
  420.  
  421. void * ss_manage( void * context ) {
  422.         ss_context * ctx = ( ss_context * )context;
  423.         int mslen = 0;
  424.         unsigned char * buffer;
  425.         buffer = ( unsigned char * ) calloc( sizeof(char)*BUFFERSIZE, 1 );
  426.         ctx->handshake = FASE1;
  427.        
  428.         while( ( mslen = read( ctx->socket_client, buffer, BUFFERSIZE ) ) > 0 || errno == EAGAIN ) {
  429.                 ctx->last_request = buffer;
  430.                 if( ss_pkt_parse( ctx ) < 0 ) {
  431.                         break;
  432.                 }
  433.                 if( ctx->handshake == FASE3 ) {
  434.                         ss_pipe( ctx );
  435.                         break;
  436.                 }
  437.         }
  438.        
  439.         //printf("Exit\n");
  440.         close( ctx->socket_server );
  441.         close( ctx->socket_client );
  442.         free( buffer );
  443.         pthread_exit(NULL);
  444. }
  445.  
  446. int main( int argc, char *argv[] ) {
  447.         struct sockaddr_in server;
  448.         struct sockaddr_in client;
  449.         int mainSocket, subSocket, c;
  450.         int port = PORT;
  451.        
  452.         ss_banner();
  453.        
  454.         while( ( c = getopt( argc, argv, "dhp:" ) ) != -1 ){
  455.                 switch(c){
  456.                         case 'd' : dm   = 1; break;
  457.                         case 'p' : port = atoi(optarg); break;
  458.                         case 'h':
  459.                         default  :
  460.                                            ss_usage( strdup( argv[0] ) );
  461.                                            return -1;
  462.                 }
  463.         }
  464.        
  465.         if( dm ) daemon(1,0);
  466.        
  467.         if( ( mainSocket = socket(PF_INET, SOCK_STREAM, 0) ) < 0 ) {
  468.                 die( strerror(errno) );
  469.         }
  470.        
  471.         set_timeout( mainSocket );
  472.        
  473.         memset( (void *)&server, 0, sizeof(server) );
  474.        
  475.         server.sin_family               = PF_INET;
  476.         server.sin_port                 = htons( port );
  477.         server.sin_addr.s_addr  = htonl(INADDR_ANY);
  478.        
  479.         /* Binding */
  480.         if( bind( mainSocket, (struct sockaddr *)&server, sizeof(server)) < 0){
  481.                 die( strerror(errno) );
  482.         }
  483.        
  484.         if ( listen( mainSocket, SOMAXCONN ) < 0 ) {
  485.                 die( strerror(errno) );
  486.         }
  487.        
  488.         ss_fprintf( stdout, "[@] Listening on port %d.\n", port );
  489.         ss_fprintf( stdout, "[@] Waiting for connection.\n" );
  490.         fflush(stdout);
  491.  
  492.        
  493.         while(1) {
  494.                 socklen_t addrlen = sizeof( client );
  495.                 while( ( ( subSocket = accept( mainSocket, (struct sockaddr *)&client, &addrlen ) ) < 0 ) && ( errno == EINTR ) );
  496.                
  497.                 if( subSocket > 0 ) {
  498.                         int on = 1;
  499.                         setsockopt( subSocket, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) );
  500.                        
  501.                         pthread_t       thread;
  502.                        
  503.                         ss_context *context;
  504.                         context = (ss_context *) calloc( sizeof(ss_context), 1 );
  505.                         context->socket_client = subSocket;
  506.                         context->addrclient    = client;
  507.                        
  508.                         ss_fprintf( stdout, "[@] Received connection from: %s.\n", inet_ntoa( client.sin_addr ) );
  509.                         fflush(stdout);
  510.                        
  511.                         pthread_create( &thread, 0, ss_manage, (void *) context );
  512.                 }
  513.         }
  514. }
  515.