diff --git a/src/socks.c b/src/socks.c index 6cdff57..a48ffbf 100644 --- a/src/socks.c +++ b/src/socks.c @@ -48,29 +48,29 @@ void * sockschild(struct clientparam* param) { if(ver == 5){ if ((i = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);} /* nmethods */ for (; i; i--) { - if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(442);} + if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);} if (res == 2 && !param->srv->nouser) { havepass = res; } } buf[0] = 5; buf[1] = havepass; - if(socksend(param->clisock, buf, 2, conf.timeouts[STRING_S])!=2){RETURN(402);} + if(socksend(param->clisock, buf, 2, conf.timeouts[STRING_S])!=2){RETURN(401);} if (havepass) { if (((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_L], 0))) != 1) { RETURN(412); } - if ((i = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(443);} - if (i && (unsigned)(res = sockgetlinebuf(param, CLIENT, buf, i, 0, conf.timeouts[STRING_S])) != i){RETURN(444);}; + if ((i = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(451);} + if (i && (unsigned)(res = sockgetlinebuf(param, CLIENT, buf, i, 0, conf.timeouts[STRING_S])) != i){RETURN(441);}; buf[i] = 0; if(!param->username)param->username = (unsigned char *)mystrdup((char *)buf); if ((i = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(445);} - if (i && (unsigned)(res = sockgetlinebuf(param, CLIENT, buf, i, 0, conf.timeouts[STRING_S])) != i){RETURN(446);}; + if (i && (unsigned)(res = sockgetlinebuf(param, CLIENT, buf, i, 0, conf.timeouts[STRING_S])) != i){RETURN(441);}; buf[i] = 0; if(!param->password)param->password = (unsigned char *)mystrdup((char *)buf); buf[0] = 1; buf[1] = 0; - if(socksend(param->clisock, buf, 2, conf.timeouts[STRING_S])!=2){RETURN(402);} + if(socksend(param->clisock, buf, 2, conf.timeouts[STRING_S])!=2){RETURN(481);} } if ((c = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_L], 0)) != 5) { RETURN(421); @@ -82,9 +82,9 @@ void * sockschild(struct clientparam* param) { c = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0); /* atype */ } else { - if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(448);} + if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);} buf[0] = (unsigned char) res; - if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(449);} + if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);} buf[1] = (unsigned char) res; param->sins.sin_port = param->req.sin_port = *(unsigned short*)buf; c = 1; @@ -93,19 +93,19 @@ void * sockschild(struct clientparam* param) { switch(c) { case 1: for (i = 0; i<4; i++){ - if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(450);} + if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);} buf[i] = (unsigned char)res; } param->sins.sin_addr.s_addr = param->req.sin_addr.s_addr = *(unsigned long *)buf; if(command==1 && !param->req.sin_addr.s_addr) { - RETURN(422); + RETURN(421); } myinet_ntop(*SAFAMILY(¶m->sins), SAADDR(¶m->sins), (char *)buf + strlen((char *)buf), 64); break; case 3: if ((size = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(451);} /* nmethods */ for (i=0; ihostname)myfree(param->hostname); param->hostname = (unsigned char *)mystrdup((char *)buf); if (ver == 5) { - if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(453);} + if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);} buf[0] = (unsigned char) res; - if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(454);} + if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);} buf[1] = (unsigned char) res; param->sins.sin_port = param->req.sin_port = *(unsigned short*)buf; } @@ -139,7 +139,7 @@ void * sockschild(struct clientparam* param) { param->sins.sin_addr.s_addr = param->req.sin_addr.s_addr = getip(buf); } } - if(command == 1 && !param->req.sin_port) {RETURN(424);} + if(command == 1 && !param->req.sin_port) {RETURN(421);} param->sins.sin_family = AF_INET; switch(command) { case 1: @@ -161,12 +161,38 @@ void * sockschild(struct clientparam* param) { RETURN(997); } - if((res = (*param->srv->authfunc)(param))) {RETURN(res);} + errno = 0; + if((res = (*param->srv->authfunc)(param))) { + res *= 10; + switch (errno) { + /* If authfunc failed but errno stays intacts we assume ACL denied the access, + * otherwise we do our best to pick a good error code for SOCKSv5. */ + case 0: + res += 2; /* connection not allowed by ruleset */ + break; + case ENETUNREACH: + res += 3; /* Network unreachable */ + break; + case EHOSTUNREACH: + res += 4; /* Host unreachable */ + break; + case ECONNREFUSED: + res += 5; /* Connection refused */ + break; + case EPFNOSUPPORT: + case EAFNOSUPPORT: + res += 8; /* Address type not supported */ + break; + default: + res += 1; + } + RETURN(res); + } if(command > 1) { if(so._bind(param->remsock,(struct sockaddr *)¶m->sins,sizeof(param->sins))) { param->sins.sin_port = 0; - if(so._bind(param->remsock,(struct sockaddr *)¶m->sins,sizeof(param->sins)))RETURN (12); + if(so._bind(param->remsock,(struct sockaddr *)¶m->sins,sizeof(param->sins)))RETURN (11); #if SOCKSTRACE > 0 fprintf(stderr, "%s:%hu binded to communicate with server\n", inet_ntoa(param->sins.sin_addr), @@ -183,7 +209,7 @@ fflush(stderr); if(param->clisock == INVALID_SOCKET) {RETURN(11);} memcpy(&sin, ¶m->sincl, sizeof(&sin)); *SAPORT(&sin) = htons(0); - if(so._bind(param->clisock,(struct sockaddr *)&sin,sizeof(sin))) {RETURN (12);} + if(so._bind(param->clisock,(struct sockaddr *)&sin,sizeof(sin))) {RETURN (11);} #if SOCKSTRACE > 0 fprintf(stderr, "%hu binded to communicate with client\n", ntohs(*SAPORT(&sin)) @@ -220,7 +246,7 @@ fflush(stderr); } else{ buf[0] = 0; - buf[1] = 90 + (param->res%10); + buf[1] = 90 + !!(param->res%10); memcpy(buf+2, SAPORT(&sin), 2); memcpy(buf+4, SAADDR(&sin), 4); socksend(param->clisock, buf, 8, conf.timeouts[STRING_S]); @@ -329,7 +355,7 @@ fflush(stderr); param->sins.sin_addr.s_addr = getip(buf+4); break; default: - RETURN(996); + RETURN(997); } memcpy(¶m->sins.sin_port, buf+i, 2);