AuthLogic.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  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_epoll_server.h"
  17. #include "util/tc_des.h"
  18. #include "util/tc_sha.h"
  19. #include "util/tc_md5.h"
  20. #include "servant/Application.h"
  21. #include "servant/AuthLogic.h"
  22. #include <iostream>
  23. #include <cassert>
  24. #include "tup/tup.h"
  25. namespace tars
  26. {
  27. AUTH_STATE processAuthReqHelper(const BasicAuthPackage& pkg, const BasicAuthInfo& info)
  28. {
  29. // 明文:objName, accessKey, time, hashMethod
  30. // 密文:use TmpKey to enc secret1;
  31. // and tmpKey = sha1(secret2 | timestamp);
  32. if (pkg.sObjName != info.sObjName)
  33. return AUTH_WRONG_OBJ;
  34. if (pkg.sAccessKey != info.sAccessKey)
  35. return AUTH_WRONG_AK;
  36. time_t now = TNOW;
  37. const int range = 60 * 60;
  38. if (!(pkg.iTime > (now - range) && pkg.iTime < (now + range)))
  39. return AUTH_WRONG_TIME;
  40. if (pkg.sHashMethod != "sha1")
  41. return AUTH_NOT_SUPPORT_ENC;
  42. // 用secret1 = sha1(password); secret2 = sha1(secret1);
  43. // 1.client create TmpKey use timestamp and secret2;
  44. // 2.client use TmpKey to enc secret1;
  45. // 3.server use TmpKey same as client, to dec secret1;
  46. // 4.server got secret1, then sha1(secret1), to compare secret2;
  47. // 下面这个是123456的两次sha1值
  48. //assert (info.sHashSecretKey2 == "69c5fcebaa65b560eaf06c3fbeb481ae44b8d618");
  49. string tmpKey;
  50. string hash2;
  51. {
  52. string hash1 = TC_SHA::sha1str(info.sHashSecretKey2.data(), info.sHashSecretKey2.size());
  53. hash2 = TC_SHA::sha1str(hash1.data(), hash1.size());
  54. string tmp = hash2;
  55. const char* pt = (const char* )&pkg.iTime;
  56. for (size_t i = 0; i < sizeof pkg.iTime; ++ i)
  57. {
  58. tmp[i] |= pt[i];
  59. }
  60. tmpKey = TC_MD5::md5str(tmp);
  61. }
  62. string secret1;
  63. {
  64. try
  65. {
  66. secret1 = TC_Des::decrypt3(tmpKey.data(), pkg.sSignature.data(), pkg.sSignature.size());
  67. }
  68. catch (const TC_DES_Exception& )
  69. {
  70. return AUTH_DEC_FAIL;
  71. }
  72. }
  73. // 4.server got secret1, then sha1(secret1), to compare secret2;
  74. string clientSecret2 = TC_SHA::sha1str(secret1.data(), secret1.size());
  75. if (clientSecret2.size() != hash2.size() ||
  76. !std::equal(clientSecret2.begin(), clientSecret2.end(), hash2.begin()))
  77. {
  78. return AUTH_ERROR;
  79. }
  80. return AUTH_SUCC;
  81. }
  82. // 只需要传入 expect 的objname;
  83. // 内部根据obj查找access账号集
  84. AUTH_STATE defaultProcessAuthReq(const char* request, size_t len, TC_EpollServer::BindAdapterPtr& adapter, const string &expectObj)
  85. {
  86. if (len <= 20)
  87. return AUTH_PROTO_ERR;
  88. BasicAuthPackage pkg;
  89. TarsInputStream<BufferReader> is;
  90. is.setBuffer(request, len);
  91. try {
  92. pkg.readFrom(is);
  93. }
  94. catch(...) {
  95. return AUTH_PROTO_ERR;
  96. }
  97. // TC_EpollServer::BindAdapterPtr bap = Application::getEpollServer()->getBindAdapter(expectObj);
  98. // if (!bap)
  99. // return AUTH_WRONG_OBJ;
  100. BasicAuthInfo info;
  101. string expectServantName = expectObj;
  102. info.sObjName = expectServantName;
  103. info.sAccessKey = pkg.sAccessKey;
  104. info.sHashSecretKey2 = adapter->getSk(info.sAccessKey);
  105. if (info.sHashSecretKey2.empty())
  106. return AUTH_WRONG_AK;
  107. return processAuthReqHelper(pkg, info);
  108. }
  109. AUTH_STATE defaultProcessAuthReq(const string& request, TC_EpollServer::BindAdapterPtr& adapter, const string& expectObj)
  110. {
  111. return defaultProcessAuthReq(request.data(), request.size(), adapter, expectObj);
  112. }
  113. vector<char> defaultCreateAuthReq(const BasicAuthInfo& info /*, const string& hashMethod*/ )
  114. {
  115. // 明文:objName, accessKey, time, hashMethod
  116. // 密文:use TmpKey to enc secret1;
  117. TarsOutputStream<BufferWriterVector> os;
  118. BasicAuthPackage pkg;
  119. pkg.sObjName = info.sObjName;
  120. pkg.sAccessKey = info.sAccessKey;
  121. pkg.iTime = TNOW;
  122. string secret1 = TC_SHA::sha1str(info.sSecretKey.data(), info.sSecretKey.size());
  123. string secret2 = TC_SHA::sha1str(secret1.data(), secret1.size());
  124. // create tmpKey
  125. string tmpKey;
  126. {
  127. string tmp = secret2;
  128. const char* pt = (const char* )&pkg.iTime;
  129. for (size_t i = 0; i < sizeof pkg.iTime; ++ i)
  130. {
  131. tmp[i] |= pt[i];
  132. }
  133. // 保证key是16字节
  134. tmpKey = TC_MD5::md5str(tmp);
  135. }
  136. pkg.sSignature = TC_Des::encrypt3(tmpKey.data(), secret1.data(), secret1.size());
  137. pkg.writeTo(os);
  138. return os.getByteBuffer();
  139. }
  140. pair<TC_NetWorkBuffer::PACKET_TYPE, shared_ptr<TC_NetWorkBuffer::Buffer>> serverVerifyAuthCallback(TC_NetWorkBuffer &buff, TC_Transceiver* trans, weak_ptr<TC_EpollServer::BindAdapter> adapterPtr, const string &expectObj)
  141. {
  142. shared_ptr<TC_NetWorkBuffer::Buffer> data = std::make_shared<TC_NetWorkBuffer::Buffer>();
  143. auto adapter = adapterPtr.lock();
  144. if(!adapter)
  145. {
  146. data->addBuffer("adapter release");
  147. return std::make_pair(TC_NetWorkBuffer::PACKET_ERR, data);
  148. }
  149. // got auth request
  150. RequestPacket request;
  151. if (adapter->isTarsProtocol())
  152. {
  153. TarsInputStream<BufferReader> is;
  154. is.setBuffer(buff.mergeBuffers(), buff.getBufferLength());
  155. try
  156. {
  157. request.readFrom(is);
  158. }
  159. catch(...)
  160. {
  161. adapter->getEpollServer()->error("serverVerifyCallback protocol decode error, close connection.");
  162. return std::make_pair(TC_NetWorkBuffer::PACKET_ERR, data);
  163. }
  164. }
  165. else
  166. {
  167. request.sBuffer = buff.getBuffers();
  168. }
  169. AUTH_STATE newstate = tars::defaultProcessAuthReq(request.sBuffer.data(), request.sBuffer.size(), adapter, expectObj);
  170. std::string out = tars::etos((tars::AUTH_STATE)newstate);
  171. if (newstate != AUTH_SUCC)
  172. {
  173. // 验证错误,断开连接
  174. adapter->getEpollServer()->error("authProcess failed with new state [" + out + "]");
  175. return std::make_pair(TC_NetWorkBuffer::PACKET_ERR, data);
  176. }
  177. buff.clearBuffers();
  178. string host;
  179. uint16_t port;
  180. TC_Socket::parseAddr(trans->getClientAddr(), host, port);
  181. adapter->getEpollServer()->info(host+ ":" + TC_Common::tostr(port) + ", auth response succ: [" + out + "]");
  182. if (adapter->isTarsProtocol())
  183. {
  184. TarsOutputStream<BufferWriter> os;
  185. ResponsePacket response;
  186. response.iVersion = TARSVERSION;
  187. response.iRequestId = request.iRequestId;
  188. response.iMessageType = request.iMessageType;
  189. response.cPacketType = request.cPacketType;
  190. response.iRet = 0;
  191. response.sBuffer.assign(out.begin(), out.end());
  192. tars::Int32 iHeaderLen = 0;
  193. os.writeBuf((const char *)&iHeaderLen, sizeof(iHeaderLen));
  194. response.writeTo(os);
  195. iHeaderLen = htonl((int)(os.getLength()));
  196. memcpy((void*)os.getBuffer(), (const char *)&iHeaderLen, sizeof(iHeaderLen));
  197. data = ProxyProtocol::toBuffer(os);
  198. }
  199. else
  200. {
  201. data->addBuffer(out.c_str(), out.size());
  202. }
  203. return std::make_pair(TC_NetWorkBuffer::PACKET_FULL, data);
  204. }
  205. } // end namespace tars