📄 rconnect.c
字号:
#include <sys/types.h>#include <sys/time.h>#include <sys/socket.h>#include <netinet/in.h>#include <sys/errno.h>#if defined(ISC)#include <net/errno.h>#endif /* #if defined(ISC) */#include <stdio.h>#include <netdb.h>#include <arpa/nameser.h>#include <resolv.h>#include <pwd.h>#include <syslog.h>#if (defined(sun) && !defined(SOLARIS)) || defined(sgi)#include <strings.h>#else#include <string.h>#endif#include "socks.h"#ifdef LINUX#include <linux/time.h>#endif/* >>> K. Shackelford */#if defined(hpux) || defined(ultrix) || defined (__NetBSD__) || defined(__FreeBSD__) || defined(AIX) || defined(__bsdi__) || defined(SCO) || defined(ISC) || defined(BIND_RESOLVER)extern int h_errno;#endif/* <<< K.Shackelford */#include <signal.h>#include <sys/wait.h>#define NAMELEN 128char socks_dst_name[NAMELEN], socks_dst_serv[NAMELEN];char socks_src_name[NAMELEN], socks_src_user[NAMELEN], socks_real_user[NAMELEN];char *socks_def_server;char *socks_server;char *socks_serverlist;char socks_cmd[] = "connect";extern int errno;extern char *getenv();extern char *getlogin();static struct sockaddr_in cursin;u_int32 SocksHost;static unsigned short socks_port;static int socks_conn_sock = 0;static int socks_conn_init = 0;static unsigned short socks_conn_port = 0;static u_int32 socks_conn_host = 0;static int socks_conn_code = 0;static unsigned short socks_last_conn_port = 0;static u_int32 socks_last_conn_host = 0;static int socks_init_done = 0;struct sockaddr_in socks_nsin;static struct sockaddr_in me;static struct passwd *pw;static int direct = 0;extern char *socks_porttoserv();extern char *socks_saddrtoname();static int check_result(code)char code;{ switch (code) { case SOCKS_FAIL:/* errno = ETIMEDOUT;*/ errno = ECONNREFUSED; return -1; case SOCKS_NO_IDENTD: errno = ECONNREFUSED; fprintf(stderr, "Error: SOCKS proxy server cannot connect to identd on your machine.\n"); return -1; case SOCKS_BAD_ID: errno = ECONNREFUSED; fprintf(stderr, "Error: user-id does not agree with the one reported by identd on your machine.\n"); return -1; default: return 0; }}/* SOCKSinit() must be called once in the application program. */SOCKSinit(Progname)char *Progname; /* name of the calling program, "rfinger", "rftp", etc. */{#ifdef SOCKS_DEFAULT_NS static char *defaultNS = SOCKS_DEFAULT_NS;#endif#ifdef SOCKS_DEFAULT_DNAME static char *defaultDNAME = SOCKS_DEFAULT_DNAME;#endif static char *defaultSERVER = SOCKS_DEFAULT_SERVER; char *cp, *ns, *dp; struct hostent *hp; struct servent *sp; int v,uid;/* >>> YDL 94/01/25 */ if (socks_init_done) return; socks_init_done = 1;/* <<< YDL 94/01/25 */ socks_port = htons(SOCKS_DEF_PORT); bzero((char *)&cursin, sizeof(cursin)); bzero((char *)&socks_nsin, sizeof(socks_nsin)); bzero((char *)&me, sizeof(me)); /* skip the path if included in Progname */ if( (cp = rindex(Progname, '/')) == NULL) cp = Progname; else cp++;#ifndef LOG_DAEMON (void) openlog(cp, LOG_PID);#else (void) openlog(cp, LOG_PID, SYSLOG_FAC);#endif gethostname(socks_src_name, sizeof(socks_src_name)); if ( (hp = gethostbyname(socks_src_name)) == NULL ) { fprintf (stderr, "gethostbyname(%s): error #%d\n", socks_src_name, h_errno); return (1); } bcopy(hp->h_addr_list[0], &me.sin_addr.s_addr, hp->h_length);#if !defined(DNS_THROUGH_NIS) if ((ns = getenv("SOCKS_NS")) == NULL) {#ifdef SOCKS_DEFAULT_NS ns = defaultNS;#else ;#endif } if ((dp = getenv("SOCKS_DNAME")) == NULL) {#ifdef SOCKS_DEFAULT_DNAME dp = defaultDNAME;#else ;#endif } if ((ns != NULL) || (dp != NULL)) { res_init();#ifdef sgi sethostresorder("local:nis:bind");#endif } if (ns != NULL) {#ifdef ultrix _res.ns_list[0].addr.sin_addr.s_addr = inet_addr(ns);#else _res.nsaddr_list[0].sin_addr.s_addr = inet_addr(ns);#endif _res.nscount = 1; } if (dp != NULL) { strncpy(_res.defdname, dp, sizeof(_res.defdname)-1); }/* >>> jon r. luini <jonl@hal.com> *//*#ifdef SOCKS_DEFAULT_DNAME bzero (_res.defdname, sizeof (_res.defdname)); if ( (cp = getenv("SOCKS_DNAME")) != NULL ) { strncpy (_res.defdname, cp, sizeof (_res.defdname)-1); } else { strncpy (_res.defdname, SOCKS_DEFAULT_DNAME, sizeof (_res.defdname)-1); }#endif*//* <<< jon r. luini <jonl@hal.com> */#endif /* #if !defined(DNS_THROUGH_NIS) */ if ((socks_def_server = getenv("SOCKS_SERVER")) == NULL) socks_def_server = defaultSERVER; socks_server = socks_def_server; if ((cp = getenv("SOCKS_BANNER")) != NULL) { fprintf(stderr, "CSTC version %s SOCKS client. Default SOCKS server: %s\n", CSTC_RELEASE, socks_def_server); } if ((hp = gethostbyname(socks_server)) == NULL) { SocksHost = inet_addr(socks_server); } else { bcopy(hp->h_addr_list[0], &SocksHost, hp->h_length); } if ((sp = getservbyname("socks", "tcp")) != NULL) socks_port = sp->s_port; if ((cp = getlogin()) == NULL) { if ((pw = getpwuid(uid=getuid())) == NULL) { fprintf(stderr, "Unknown user-id %d\n",uid); return (1); } cp = pw->pw_name; } strncpy(socks_real_user, cp, sizeof(socks_real_user)); if ((pw = getpwuid(uid=geteuid())) == NULL) { fprintf(stderr, "Unknown user-id %d\n",uid); return (1); } strncpy(socks_src_user, pw->pw_name, sizeof(socks_src_user)); socks_nsin.sin_family = AF_INET; socks_nsin.sin_port = socks_port; socks_nsin.sin_addr.s_addr = SocksHost; }static int connect_sockd(sock, lport)int sock;int *lport;/* returns 0 if successfully connected to a SOCKS server, returns -1 otherwise */{#ifndef VERSATILE_CLIENTS if (connect(sock, &socks_nsin, sizeof(struct sockaddr_in)) == 0) return 0; else { syslog(LOG_LOW, "Failed to connect to sockd at %s: %m", socks_server); return -1; }#else /* Now the version when VERSATILE_CLIENTS is defined */ int last = 0; int new_sock; struct hostent *hp; while (socks_server = socks_serverlist) { if (socks_serverlist = index(socks_serverlist, ','))/* >>> YDL 94/11/14 */ *socks_serverlist = '\0';/* <<< YDL 94/11/14 */ if ((hp = gethostbyname(socks_server)) == NULL) socks_nsin.sin_addr.s_addr = inet_addr(socks_server); else bcopy(hp->h_addr_list[0], &socks_nsin.sin_addr, hp->h_length); if (connect(sock, (struct sockaddr *)&socks_nsin, sizeof(struct sockaddr_in)) == 0) return 0; else {#ifdef SVR4 if ((errno == EISCONN) || (errno == EINPROGRESS) || (errno == EAGAIN))#else if ((errno == EISCONN) || (errno == EINPROGRESS))#endif return -1; syslog(LOG_LOW, "Failed to connect to sockd at %s: %m", socks_server); if (!(socks_serverlist)) { return -1; }#if defined(SUPPORT_RCMD) if ((*lport < IPPORT_RESERVED) && (*lport >= IPPORT_RESERVED/2)) new_sock = rresvport(lport); else new_sock = socket(PF_INET, SOCK_STREAM, 0);#else /* SUPPORT_RCMD is not defined */ new_sock = socket(PF_INET, SOCK_STREAM, 0);#endif /* #if defined(SUPPORT_RCMD) */ if (new_sock < 0) { return -1; } if (dup2(new_sock, sock) < 0) { close(new_sock); return -1; } else { close(new_sock); } }/* >>> YDL 94/11/14 */ if (socks_serverlist) *socks_serverlist++ =',';/* <<< YDL 94/11/14 */ } errno = ECONNREFUSED; return -1;#endif /* #ifndef VERSATILE_CLIENTS */ }static int send_src_user(s, user)int s;char *user;{ char *p = user; int i, n, ret; fd_set fds; int fdsbits = s + 1; struct timeval timeout; i = strlen(user) + 1; while ( i > 0) { FD_ZERO(&fds); FD_SET(s, &fds); timeout.tv_sec = 15; timeout.tv_usec = 0; if ((ret = select(fdsbits, NULL, &fds, NULL, &timeout)) < 0) { if (errno == EINTR) continue; return(-1); } if (ret == 0) continue; if((n = write(s, p, i)) <= 0) { return(-2); } p += n; i -= n; } return(0);}static int socksC_proto(s, dst)int s;Socks_t *dst;{ int sta; if ((sta = socks_SendDst(s, dst)) < 0) { if (sta == -1) perror("select in socks_SendDst"); else perror("write in socks_SendDst"); return(sta); } if ((sta = send_src_user(s, socks_src_user)) < 0) { if (sta == -1) perror("select in send_src_user"); else perror("write in send_src_user"); return(sta); } if ((sta = socks_GetDst(s, dst)) < 0) { if (sta == -1) perror("select in socks_GetDst"); else perror("read in socks_GetDst"); return(sta); } return(0);}static void quit_C_proto(){ exit(SOCKS_FAIL);}static void do_C_proto(sock, port, addr)int sock;unsigned short port;u_int32 addr;{ Socks_t dst; signal(SIGALRM, quit_C_proto); alarm(CLIENT_CONN_TIMEOUT); dst.version = SOCKS_VERSION; dst.cmd = SOCKS_CONNECT; dst.port = port; dst.host = addr; if (socksC_proto(sock, &dst) < 0) { alarm(0); exit(SOCKS_FAIL); } alarm(0); if ((dst.cmd == SOCKS_FAIL) || (dst.cmd == SOCKS_NO_IDENTD) || (dst.cmd == SOCKS_BAD_ID)) { exit(dst.cmd); } exit(SOCKS_RESULT);}Rconnect(sock, sin, size)int sock;struct sockaddr_in *sin;int size;{ Socks_t dst; int i; int res_ret, con_ret, con_errno; int lport = 0; int status, wait_ret, child_pid; if (socks_init_done == 0) SOCKSinit("SOCKSclient");#ifdef DEBUGfprintf(stderr, "Rconnect 10\n");fprintf(stderr,"socks_conn_sock=%d, socks_conn_host=%ld, socks_conn_port=%d, socks_conn_init=%d\n", socks_conn_sock, socks_conn_host, socks_conn_port, socks_conn_init);fprintf(stderr,"sock=%d, sin->sin_addr.s_addr=%ld, sin->sin_port=%d\n", sock, sin->sin_addr.s_addr, sin->sin_port);#endif /* #ifdef DEBUG */ if ((sock != socks_conn_sock) || (sin->sin_port != socks_conn_port) || (sin->sin_addr.s_addr != socks_conn_host)) { if (socks_conn_init) kill(socks_conn_init, SIGKILL); socks_conn_code = 0; socks_conn_init = 0; strcpy(socks_cmd, "connect"); socks_saddrtoname(&sin->sin_addr, socks_dst_name, sizeof(socks_dst_name)); socks_porttoserv(sin->sin_port, socks_dst_serv, sizeof(socks_dst_serv));#ifdef DEBUGfprintf(stderr, "Rconnect 100, Rconnect(%d, %s, %s)\n", sock, socks_dst_name, socks_dst_serv);#endif /* #ifdef DEBUG */ } else if (status = socks_conn_code) { socks_conn_init = 0; socks_conn_code = 0; socks_conn_sock = 0; socks_conn_port = 0; socks_conn_host = 0; res_ret = check_result(status); if (status == SOCKS_RESULT) { errno = EISCONN; socks_last_conn_host = sin->sin_addr.s_addr; socks_last_conn_port = sin->sin_port; } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -