00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <ListenSocket.h>
00025
00026 #include "Socks4Handler.h"
00027 #include "RemoteSocket.h"
00028 #include "Socks4Socket.h"
00029
00030
00031
00032
00033 Socks4Socket::Socks4Socket(ISocketHandler& h)
00034 :TcpSocket(h)
00035 ,m_state(STATE_VN)
00036 ,m_userid_ptr(0)
00037 ,m_pRemote(NULL)
00038 ,m_bSocks5(false)
00039 ,m_state5(STATE5_VER)
00040 ,m_s5_method(0)
00041 {
00042 }
00043
00044
00045 Socks4Socket::~Socks4Socket()
00046 {
00047 }
00048
00049
00050
00051
00052 void Socks4Socket::OnRead()
00053 {
00054
00055 TcpSocket::OnRead();
00056 if (m_bSocks5)
00057 Socks5Read();
00058 else
00059 Socks4Read();
00060 }
00061
00062
00063 void Socks4Socket::Socks4Read()
00064 {
00065 bool need_more = false;
00066 while (ibuf.GetLength() && !need_more && !CloseAndDelete() )
00067 {
00068 size_t l = ibuf.GetLength();
00069 switch (m_state)
00070 {
00071 case STATE_VN:
00072 ibuf.Read( (char *)&m_vn, 1);
00073 if (m_vn == 5)
00074 {
00075 m_bSocks5 = true;
00076 m_state5 = STATE5_NMETHODS;
00077 }
00078 else
00079 if (m_vn == 4)
00080 {
00081 m_state = STATE_CD;
00082 }
00083 else
00084 {
00085 Handler().LogError(this, "OnRead", m_vn, "Unsupported socks version", LOG_LEVEL_FATAL);
00086 SetCloseAndDelete();
00087 }
00088 break;
00089 case STATE_CD:
00090 ibuf.Read( (char *)&m_cd, 1);
00091 if (m_cd != 1 && m_cd != 2)
00092 {
00093 Handler().LogError(this, "OnRead", m_cd, "Bad command code", LOG_LEVEL_FATAL);
00094 SetCloseAndDelete();
00095 }
00096 else
00097 {
00098 m_state = STATE_DSTPORT;
00099 }
00100 break;
00101 case STATE_DSTPORT:
00102 if (l > 1)
00103 {
00104 ibuf.Read( (char *)&m_dstport, 2);
00105 m_state = STATE_DSTIP;
00106 }
00107 else
00108 {
00109 need_more = true;
00110 }
00111 break;
00112 case STATE_DSTIP:
00113 if (l > 3)
00114 {
00115 ibuf.Read( (char *)&m_dstip, 4);
00116 m_state = STATE_USERID;
00117 }
00118 else
00119 {
00120 need_more = true;
00121 }
00122 break;
00123 case STATE_USERID:
00124 if (m_userid_ptr < MAXLEN_USERID)
00125 {
00126 ibuf.Read(m_userid + m_userid_ptr, 1);
00127 if (m_userid[m_userid_ptr] == 0)
00128 {
00129 switch (m_cd)
00130 {
00131 case 1:
00132 SetupConnect();
00133 break;
00134 case 2:
00135 SetupBind();
00136 break;
00137 }
00138 }
00139 m_userid_ptr++;
00140 }
00141 else
00142 {
00143 Handler().LogError(this, "OnRead", m_userid_ptr, "Userid too long", LOG_LEVEL_FATAL);
00144 SetCloseAndDelete();
00145 }
00146 break;
00147 case STATE_TRY_CONNECT:
00148 break;
00149 case STATE_CONNECTED:
00150 {
00151 char buf[TCP_BUFSIZE_READ];
00152 ibuf.Read(buf, l);
00153 if (m_pRemote && Handler().Valid(m_pRemote))
00154 {
00155 m_pRemote -> SendBuf(buf, l);
00156 }
00157 }
00158 break;
00159 case STATE_FAILED:
00160 SetCloseAndDelete();
00161 break;
00162 case STATE_ACCEPT:
00163 break;
00164 }
00165 }
00166 }
00167
00168
00169 void Socks4Socket::Connected()
00170 {
00171 if (m_state == STATE_TRY_CONNECT)
00172 {
00173 char reply[8];
00174 reply[0] = 0;
00175 reply[1] = 90;
00176 memcpy(reply + 2, &m_dstport, 2);
00177 memcpy(reply + 4, &m_dstip, 4);
00178 SendBuf(reply, 8);
00179 m_state = STATE_CONNECTED;
00180 }
00181 else
00182 {
00183 Handler().LogError(this, "Connected", m_state, "bad state", LOG_LEVEL_FATAL);
00184 SetCloseAndDelete();
00185 }
00186 }
00187
00188
00189 void Socks4Socket::ConnectFailed()
00190 {
00191 if (m_state == STATE_TRY_CONNECT)
00192 {
00193 char reply[8];
00194 reply[0] = 0;
00195 reply[1] = 91;
00196 memcpy(reply + 2, &m_dstport, 2);
00197 memcpy(reply + 4, &m_dstip, 4);
00198 SendBuf(reply, 8);
00199 m_state = STATE_FAILED;
00200 SetCloseAndDelete();
00201 }
00202 else
00203 {
00204 Handler().LogError(this, "ConnectFailed", m_state, "bad state", LOG_LEVEL_FATAL);
00205 SetCloseAndDelete();
00206 }
00207 }
00208
00209
00210 void Socks4Socket::SetupConnect()
00211 {
00212 m_pRemote = new RemoteSocket(Handler());
00213 port_t port = ntohs(m_dstport);
00214 ipaddr_t addr = m_dstip;
00215 m_pRemote -> Open(addr, port);
00216 m_pRemote -> SetDeleteByHandler();
00217 m_pRemote -> SetRemote(this);
00218 Handler().Add(m_pRemote);
00219
00220 m_state = STATE_TRY_CONNECT;
00221 }
00222
00223
00224 void Socks4Socket::SetupBind()
00225 {
00226 ListenSocket<RemoteSocket> *p = new ListenSocket<RemoteSocket>(Handler());
00227 p -> SetDeleteByHandler();
00228 p -> Bind(0);
00229 Handler().Add(p);
00230 static_cast<Socks4Handler&>(Handler()).SetBind(p, this);
00231
00232 char reply[8];
00233 reply[0] = 0;
00234 reply[1] = 90;
00235 port_t port = p -> GetPort();
00236 unsigned short s = htons(port);
00237 memcpy(reply + 2,&s,2);
00238 memset(reply + 4,0,4);
00239 SendBuf(reply, 8);
00240
00241 m_state = STATE_ACCEPT;
00242 }
00243
00244
00245 void Socks4Socket::Accept()
00246 {
00247 if (m_state == STATE_ACCEPT)
00248 {
00249 ipaddr_t remote = m_pRemote -> GetRemoteIP4();
00250 ipaddr_t dstip = ntohl(m_dstip);
00251 char reply[8];
00252 reply[0] = 0;
00253 reply[1] = (dstip == remote) ? 90 : 91;
00254 memcpy(reply + 2, &m_dstport, 2);
00255 memcpy(reply + 4, &m_dstip, 4);
00256 SendBuf(reply, 8);
00257 m_state = (dstip == remote) ? STATE_CONNECTED : STATE_FAILED;
00258 if (m_state == STATE_FAILED)
00259 {
00260 Handler().LogError(this, "Accept", remote, "Remote ip mismatch", LOG_LEVEL_FATAL);
00261 SetCloseAndDelete();
00262 }
00263 }
00264 else
00265 {
00266 Handler().LogError(this, "Accept", m_state, "bad state", LOG_LEVEL_FATAL);
00267 SetCloseAndDelete();
00268 }
00269 }
00270
00271
00272 void Socks4Socket::Socks5Read()
00273 {
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292 bool need_more = false;
00293 while (ibuf.GetLength() && !need_more && !CloseAndDelete() )
00294 {
00295 size_t l = ibuf.GetLength();
00296 switch (m_state5)
00297 {
00298 case STATE5_VER:
00299 break;
00300 case STATE5_NMETHODS:
00301 ibuf.Read( (char *)&m_s5_nmethods, 1);
00302 m_state5 = STATE5_METHODS;
00303 m_s5_method = 0;
00304 memset(m_s5_methods, 0, sizeof(m_s5_methods));
00305 break;
00306 case STATE5_METHODS:
00307 while (ibuf.GetLength() && m_s5_method < m_s5_nmethods)
00308 {
00309 unsigned char c;
00310 ibuf.Read( (char *)&c, 1);
00311 m_s5_methods[c] = 1;
00312 m_s5_method++;
00313 }
00314 if (m_s5_method == m_s5_nmethods)
00315 {
00316 char reply[2];
00317
00318 if (m_s5_methods[2])
00319 {
00320 reply[0] = 5;
00321 reply[1] = 2;
00322 SendBuf(reply, 2);
00323 m_state5 = STATE5_USERPASSWORD_VER;
00324 }
00325 else
00326 if (m_s5_methods[0])
00327 {
00328 reply[0] = 5;
00329 reply[1] = 0;
00330 SendBuf(reply, 2);
00331 m_state5 = STATE5_VER2;
00332 }
00333 else
00334 {
00335 reply[0] = 5;
00336 reply[1] = 255;
00337 SendBuf(reply, 2);
00338 m_state5 = STATE5_FAILED;
00339 }
00340 }
00341 else
00342 {
00343 need_more = true;
00344 }
00345 break;
00346 case STATE5_FAILED:
00347 break;
00348 case STATE5_GSSAPI:
00349 break;
00350 case STATE5_USERPASSWORD_VER:
00351 ibuf.Read( &m_s5_userpassword_ver, 1);
00352 if (m_s5_userpassword_ver == 1)
00353 m_state5 = STATE5_USERPASSWORD_ULEN;
00354 else
00355 {
00356 Handler().LogError(this, "Socks5", m_s5_userpassword_ver, "Username/Password version number != 1", LOG_LEVEL_FATAL);
00357 m_state5 = STATE5_FAILED;
00358 SetCloseAndDelete();
00359 }
00360 break;
00361 case STATE5_USERPASSWORD_ULEN:
00362 ibuf.Read( (char *)&m_s5_userpassword_ulen, 1);
00363 m_state5 = STATE5_USERPASSWORD_UNAME;
00364 m_s5_uptr = 0;
00365 break;
00366 case STATE5_USERPASSWORD_UNAME:
00367 while (ibuf.GetLength() && m_s5_uptr < m_s5_userpassword_ulen)
00368 {
00369 ibuf.Read( &m_s5_userpassword_uname[m_s5_uptr], 1);
00370 m_s5_uptr++;
00371 }
00372 if (m_s5_uptr == m_s5_userpassword_ulen)
00373 {
00374 m_s5_userpassword_uname[m_s5_uptr] = 0;
00375 m_state5 = STATE5_USERPASSWORD_PLEN;
00376 }
00377 else
00378 {
00379 need_more = true;
00380 }
00381 break;
00382 case STATE5_USERPASSWORD_PLEN:
00383 ibuf.Read( (char *)&m_s5_userpassword_plen, 1);
00384 m_state5 = STATE5_USERPASSWORD_PASSWD;
00385 m_s5_pptr = 0;
00386 break;
00387 case STATE5_USERPASSWORD_PASSWD:
00388 while (ibuf.GetLength() && m_s5_pptr < m_s5_userpassword_plen)
00389 {
00390 ibuf.Read( &m_s5_userpassword_passwd[m_s5_pptr], 1);
00391 m_s5_pptr++;
00392 }
00393 if (m_s5_pptr == m_s5_userpassword_plen)
00394 {
00395 m_s5_userpassword_passwd[m_s5_pptr] = 0;
00396
00397 m_state5 = STATE5_VER2;
00398 }
00399 else
00400 {
00401 need_more = true;
00402 }
00403 break;
00404 case STATE5_VER2:
00405 ibuf.Read(&m_s5_ver2, 1);
00406 if (m_s5_ver2 == 5)
00407 m_state5 = STATE5_CMD;
00408 else
00409 {
00410 Handler().LogError(this, "Socks5", m_s5_ver2, "Version != 5", LOG_LEVEL_FATAL);
00411 m_state5 = STATE5_FAILED;
00412 SetCloseAndDelete();
00413 }
00414 break;
00415 case STATE5_CMD:
00416 ibuf.Read(&m_s5_cmd, 1);
00417 if (m_s5_cmd == 1 || m_s5_cmd == 2 || m_s5_cmd == 3)
00418 m_state5 = STATE5_RSV;
00419 else
00420 {
00421 Handler().LogError(this, "Socks5", m_s5_cmd, "Bad command code", LOG_LEVEL_FATAL);
00422 m_state5 = STATE5_FAILED;
00423 SetCloseAndDelete();
00424 }
00425 break;
00426 case STATE5_RSV:
00427 m_state5 = STATE5_ATYP;
00428 break;
00429 case STATE5_ATYP:
00430 ibuf.Read(&m_s5_atyp, 1);
00431 switch (m_s5_atyp)
00432 {
00433 case 1:
00434 m_state5 = STATE5_DST_ADDR;
00435 m_s5_alen = 4;
00436 break;
00437 case 3:
00438 m_state5 = STATE5_ALEN;
00439 break;
00440 case 4:
00441 m_state5 = STATE5_DST_ADDR;
00442 m_s5_alen = 6;
00443 break;
00444 default:
00445 Handler().LogError(this, "Socks5", m_s5_atyp, "Bad address type", LOG_LEVEL_FATAL);
00446 m_state5 = STATE5_FAILED;
00447 SetCloseAndDelete();
00448 }
00449 m_s5_aptr = 0;
00450 break;
00451 case STATE5_ALEN:
00452 ibuf.Read( (char *)&m_s5_alen,1);
00453 m_state5 = STATE5_DST_ADDR;
00454 break;
00455 case STATE5_DST_ADDR:
00456 while (ibuf.GetLength() && m_s5_aptr < m_s5_alen)
00457 {
00458 ibuf.Read( (char *)&m_s5_dst_addr[m_s5_aptr], 1);
00459 m_s5_aptr++;
00460 }
00461 if (m_s5_aptr == m_s5_alen)
00462 {
00463 m_s5_dst_addr[m_s5_aptr] = 0;
00464 m_state5 = STATE5_DST_PORT;
00465 }
00466 else
00467 {
00468 need_more = true;
00469 }
00470 break;
00471 case STATE5_DST_PORT:
00472 if (l > 1)
00473 {
00474 ibuf.Read( (char *)&m_s5_dst_port, 2);
00475 DoSocks5();
00476 }
00477 else
00478 {
00479 need_more = true;
00480 }
00481 break;
00482 }
00483 }
00484 }
00485
00486
00487 void Socks4Socket::DoSocks5()
00488 {
00489 switch (m_s5_cmd)
00490 {
00491 case 1:
00492 break;
00493 case 2:
00494 break;
00495 case 3:
00496 break;
00497 }
00498 }
00499
00500