tc_proxy_info.cpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. /**
  2. * Tencent is pleased to support the open source community by making Tars available.
  3. *
  4. * Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
  5. *
  6. * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
  7. * in compliance with the License. You may obtain a copy of the License at
  8. *
  9. * https://opensource.org/licenses/BSD-3-Clause
  10. *
  11. * Unless required by applicable law or agreed to in writing, software distributed
  12. * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  13. * CONDITIONS OF ANY KIND, either express or implied. See the License for the
  14. * specific language governing permissions and limitations under the License.
  15. */
  16. #include "util/tc_proxy_info.h"
  17. #include "util/tc_http.h"
  18. #include "util/tc_base64.h"
  19. namespace tars
  20. {
  21. shared_ptr<TC_ProxyInfo> TC_ProxyInfo::createProxyInfo(const TC_ProxyInfo::ProxyBaseInfo &baseInfo)
  22. {
  23. shared_ptr<TC_ProxyInfo> proxyInfo;
  24. switch(baseInfo.type)
  25. {
  26. case eProxy_Type_Sock4:
  27. proxyInfo.reset(new TC_ProxySock4(baseInfo.ep));
  28. break;
  29. case eProxy_Type_Sock5:
  30. proxyInfo.reset(new TC_ProxySock5(baseInfo.ep, baseInfo.user, baseInfo.pass));
  31. break;
  32. case eProxy_Type_Http:
  33. proxyInfo.reset(new TC_ProxyHttp(baseInfo.ep, baseInfo.user, baseInfo.pass));
  34. break;
  35. }
  36. return proxyInfo;
  37. }
  38. void TC_ProxyInfo::onDisconnect()
  39. {
  40. setProxyStage(eProxy_Stage_DisConn);
  41. }
  42. void TC_ProxyInfo::onConnSuccess()
  43. {
  44. setProxyStage(eProxy_Stage_Connected);
  45. }
  46. void TC_ProxyInfo::setProxyStage(TC_ProxyInfo::EMProxyStageType proxyStage)
  47. {
  48. if (_stage == proxyStage) {
  49. return;
  50. }
  51. _stage = proxyStage;
  52. }
  53. ////////////////////////////////////////////////////////////////////////
  54. bool TC_ProxySock4::sendProxyPacket(vector<char> & buff, const TC_Endpoint & dst)
  55. {
  56. //first handshake
  57. buff.push_back(kProxy_Sock4_Req1_VN);
  58. buff.push_back(kProxy_Sock4_Req1_CD);
  59. unsigned short nPort = htons(dst.getPort());
  60. buff.insert(buff.end(), (const char *)&nPort, (const char *)&nPort + sizeof(nPort));
  61. struct in_addr addr;
  62. TC_Socket::parseAddr(dst.getHost(), addr);
  63. int32_t tmpLong = addr.s_addr;
  64. buff.insert(buff.end(), (const char *)&tmpLong, (const char *)&tmpLong + sizeof(tmpLong));
  65. buff.push_back('a');
  66. buff.push_back(0);
  67. return true;
  68. }
  69. bool TC_ProxySock4::recvProxyPacket(const char *buff, size_t length)
  70. {
  71. switch (_stage) {
  72. case eProxy_Stage_Establish: {
  73. //send first handshake
  74. if (sizeof(struct sock4ans1) != length) {
  75. _errMsg = "proxy disconnected: Establish protocol length error";
  76. onDisconnect();
  77. return false;
  78. }
  79. struct sock4ans1 *pSockAns1 = (struct sock4ans1 *) buff;
  80. if (pSockAns1->VN != kProxy_Sock4_Ans1_VN || pSockAns1->CD != kProxy_Sock4_Ans1_CD) {
  81. _errMsg = "proxy disconnected: Establish protocol version error";
  82. onDisconnect();
  83. return false;
  84. }
  85. //success
  86. onConnSuccess();
  87. return true;
  88. }
  89. default: {
  90. assert(false);
  91. }
  92. }
  93. return false;
  94. }
  95. ///////////////////////////////////////////////////////////////////////////////////
  96. bool TC_ProxySock5::sendProxyPacket(vector<char> & vBuffer, const TC_Endpoint & dst)
  97. {
  98. switch (_stage) {
  99. case eProxy_Stage_DisConn:
  100. case eProxy_Stage_Establish: {
  101. //first handshake
  102. vBuffer.push_back(kProxy_Sock5_Req1_Ver);
  103. vBuffer.push_back(kProxy_Sock5_Req1_nMethods);
  104. vBuffer.push_back(kProxy_Sock5_Req1_nMethods0);
  105. vBuffer.push_back(kProxy_Sock5_Req1_nMethods1);
  106. return true;
  107. }
  108. case eProxy_Stage_ACK1: {
  109. //second handshake user pwd
  110. char nUserLength = (char) _user.size();
  111. char nPwdLength = (char) _pass.size();
  112. vBuffer.push_back(1);
  113. vBuffer.push_back(nUserLength);
  114. vBuffer.insert(vBuffer.end(), _user.begin(), _user.end());
  115. vBuffer.push_back(nPwdLength);
  116. vBuffer.insert(vBuffer.end(), _pass.begin(), _pass.end());
  117. return true;
  118. }
  119. case eProxy_Stage_ACK2: {
  120. //third handshake
  121. vBuffer.push_back(kProxy_Sock5_Req3_Ver);
  122. vBuffer.push_back(kProxy_Sock5_Req3_Cmd);
  123. vBuffer.push_back(kProxy_Sock5_Req3_Rsv);
  124. if(dst.isIPv6())
  125. {
  126. vBuffer.push_back(kProxy_Sock5_Req3_AtypIpv6);
  127. }
  128. else
  129. {
  130. vBuffer.push_back(kProxy_Sock5_Req3_AtypIpv4);
  131. }
  132. struct in_addr addr;
  133. TC_Socket::parseAddr(dst.getHost(), addr);
  134. int32_t tmpLong = addr.s_addr;
  135. vBuffer.insert(vBuffer.end(), (const char *)&tmpLong, (const char *)&tmpLong + sizeof(tmpLong));
  136. unsigned short nPort = htons(dst.getPort());
  137. vBuffer.insert(vBuffer.end(), (const char *)&nPort, (const char *)&nPort + sizeof(nPort));
  138. return true;
  139. }
  140. default: {
  141. assert(false);
  142. }
  143. }
  144. return false;
  145. }
  146. bool TC_ProxySock5::recvProxyPacket(const char *buff, size_t length)
  147. {
  148. switch (_stage) {
  149. case eProxy_Stage_Establish: {
  150. //send first handshake
  151. if (sizeof(struct sock5ans1) != length) {
  152. _errMsg = "proxy disconnected: Establish protocol length error";
  153. onDisconnect();
  154. return false;
  155. }
  156. struct sock5ans1 *pSock5Ans1 = (struct sock5ans1 *) buff;
  157. if (pSock5Ans1->Ver != kProxy_Sock5_Ans1_Ver || (pSock5Ans1->Method != kProxy_Sock5_Ans1_Method_Anonymous && pSock5Ans1->Method != kProxy_Sock5_Ans1_Method_User))
  158. {
  159. _errMsg = "proxy disconnected: Establish protocol version error";
  160. onDisconnect();
  161. return false;
  162. }
  163. //need user
  164. if (pSock5Ans1->Method == kProxy_Sock5_Ans1_Method_User) {
  165. setProxyStage(eProxy_Stage_ACK1);
  166. return true;
  167. }
  168. else {
  169. //Anonymous
  170. setProxyStage(eProxy_Stage_ACK2);
  171. return true;
  172. }
  173. }
  174. case eProxy_Stage_ACK1: {
  175. //send second handshake
  176. if (sizeof(struct authans) != length) {
  177. _errMsg = "proxy disconnected: ACK1 protocol length error";
  178. onDisconnect();
  179. return false;
  180. }
  181. struct authans *pSock5Anthans = (struct authans *) buff;
  182. if (pSock5Anthans->Ver != kProxy_Sock5_Anthans_Ver || pSock5Anthans->Status != kProxy_Sock5_Anthans_Status) {
  183. _errMsg = "proxy disconnected: ACK1 protocol version error";
  184. onDisconnect();
  185. return false;
  186. }
  187. setProxyStage(eProxy_Stage_ACK2);
  188. return true;
  189. }
  190. case eProxy_Stage_ACK2: {
  191. if (sizeof(struct sock5ans2) != length) {
  192. _errMsg = "proxy disconnected: ACK2 protocol length error";
  193. onDisconnect();
  194. return false;
  195. }
  196. struct sock5ans2 *pSock5An2 = (struct sock5ans2 *) buff;
  197. if (pSock5An2->Ver != kProxy_Sock5_Ans2_Ver || pSock5An2->Rep != kProxy_Sock5_Ans2_Rep) {
  198. _errMsg = "proxy disconnected: ACK2 protocol version error";
  199. onDisconnect();
  200. return false;
  201. }
  202. //success
  203. onConnSuccess();
  204. return true;
  205. }
  206. default: {
  207. assert(false);
  208. }
  209. }
  210. return false;
  211. }
  212. ///////////////////////////////////////////////////////////////////////////////////
  213. bool TC_ProxyHttp::sendProxyPacket(vector<char> & buff, const TC_Endpoint & dst)
  214. {
  215. switch (_stage) {
  216. case eProxy_Stage_Establish: {
  217. ostringstream oss;
  218. //first handshake
  219. std::string strRev;
  220. if (_user.empty()) {
  221. oss << "CONNECT " << dst.getHost() << ":" << dst.getPort()
  222. << " HTTP/1.1\r\nUser-Agent: Mozilla/4.0\r\n\r\n";
  223. strRev = oss.str();
  224. }
  225. else {
  226. oss << "CONNECT " << dst.getHost() << ":" << dst.getPort()
  227. << " HTTP/1.1\r\nUser-Agent: Mozilla/4.0\r\n";
  228. oss << "Proxy-Authorization:Basic " << TC_Base64::encode(_user + ":" + _pass) << "\r\n\r\n";
  229. strRev = oss.str();
  230. }
  231. buff.insert(buff.end(), strRev.begin(), strRev.end());
  232. return true;
  233. }
  234. default: {
  235. assert(false);
  236. }
  237. }
  238. return false;
  239. }
  240. bool TC_ProxyHttp::recvProxyPacket(const char *buff, size_t length)
  241. {
  242. switch (_stage) {
  243. case eProxy_Stage_Establish: {
  244. TC_HttpResponse rsp;
  245. rsp.decode(buff, length);
  246. //send first handshake
  247. if (rsp.getStatus() != 200) {
  248. _errMsg = "proxy disconnected: " + TC_Common::tostr(rsp.getStatus()) + ", about:" + rsp.getAbout() + " error";
  249. onDisconnect();
  250. return false;
  251. }
  252. //success
  253. onConnSuccess();
  254. return true;
  255. }
  256. default: {
  257. assert(false);
  258. }
  259. }
  260. return false;
  261. }
  262. }