ECChannel.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978
  1. /*
  2. * Copyright 2005 - 2016 Zarafa and its licensors
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU Affero General Public License, version 3,
  6. * as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU Affero General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU Affero General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. *
  16. */
  17. #include <kopano/platform.h>
  18. #include <memory>
  19. #include <new>
  20. #include <kopano/ECChannel.h>
  21. #include <kopano/stringutil.h>
  22. #include <csignal>
  23. #include <netdb.h>
  24. #include <poll.h>
  25. #include <sys/types.h>
  26. #include <sys/socket.h>
  27. #include <sys/stat.h>
  28. #include <sys/un.h>
  29. #include <netinet/in.h>
  30. #include <netinet/tcp.h>
  31. #include <arpa/inet.h>
  32. #ifdef LINUX
  33. #include <linux/rtnetlink.h>
  34. #endif
  35. #include <cerrno>
  36. #include <mapicode.h>
  37. #ifndef hrSuccess
  38. #define hrSuccess 0
  39. #endif
  40. namespace KC {
  41. /*
  42. To generate a RSA key:
  43. openssl genrsa -out privkey.pem 2048
  44. Creating a certificate request:
  45. openssl req -new -key privkey.pem -out cert.csr
  46. Creating a self-signed test certificate:
  47. openssl req -new -x509 -key privkey.pem -out cacert.pem -days 1095
  48. */
  49. // because of statics
  50. SSL_CTX* ECChannel::lpCTX = NULL;
  51. HRESULT ECChannel::HrSetCtx(ECConfig *lpConfig)
  52. {
  53. if (lpConfig == NULL) {
  54. ec_log_err("ECChannel::HrSetCtx(): invalid parameters");
  55. return MAPI_E_CALL_FAILED;
  56. }
  57. HRESULT hr = hrSuccess;
  58. const char *szFile = NULL;
  59. const char *szPath = NULL;
  60. std::unique_ptr<char> ssl_protocols(strdup(lpConfig->GetSetting("ssl_protocols")));
  61. const char *ssl_ciphers = lpConfig->GetSetting("ssl_ciphers");
  62. char *ssl_name = NULL;
  63. int ssl_op = 0, ssl_include = 0, ssl_exclude = 0;
  64. #if !defined(OPENSSL_NO_ECDH) && defined(NID_X9_62_prime256v1)
  65. EC_KEY *ecdh;
  66. #endif
  67. if (lpCTX) {
  68. SSL_CTX_free(lpCTX);
  69. lpCTX = NULL;
  70. }
  71. SSL_library_init();
  72. SSL_load_error_strings();
  73. // enable *all* server methods, not just ssl2 and ssl3, but also tls1 and tls1.1
  74. lpCTX = SSL_CTX_new(SSLv23_server_method());
  75. SSL_CTX_set_options(lpCTX, SSL_OP_ALL); // enable quirk and bug workarounds
  76. ssl_name = strtok(ssl_protocols.get(), " ");
  77. while(ssl_name != NULL) {
  78. int ssl_proto = 0;
  79. bool ssl_neg = false;
  80. if (*ssl_name == '!') {
  81. ++ssl_name;
  82. ssl_neg = true;
  83. }
  84. if (strcasecmp(ssl_name, SSL_TXT_SSLV3) == 0)
  85. ssl_proto = 0x02;
  86. #ifdef SSL_TXT_SSLV2
  87. else if (strcasecmp(ssl_name, SSL_TXT_SSLV2) == 0)
  88. ssl_proto = 0x01;
  89. #endif
  90. else if (strcasecmp(ssl_name, SSL_TXT_TLSV1) == 0)
  91. ssl_proto = 0x04;
  92. #ifdef SSL_TXT_TLSV1_1
  93. else if (strcasecmp(ssl_name, SSL_TXT_TLSV1_1) == 0)
  94. ssl_proto = 0x08;
  95. #endif
  96. #ifdef SSL_TXT_TLSV1_2
  97. else if (strcasecmp(ssl_name, SSL_TXT_TLSV1_2) == 0)
  98. ssl_proto = 0x10;
  99. #endif
  100. else {
  101. ec_log_err("Unknown protocol \"%s\" in ssl_protocols setting", ssl_name);
  102. hr = MAPI_E_CALL_FAILED;
  103. goto exit;
  104. }
  105. if (ssl_neg)
  106. ssl_exclude |= ssl_proto;
  107. else
  108. ssl_include |= ssl_proto;
  109. ssl_name = strtok(NULL, " ");
  110. }
  111. if (ssl_include != 0) {
  112. // Exclude everything, except those that are included (and let excludes still override those)
  113. ssl_exclude |= 0x1f & ~ssl_include;
  114. }
  115. if ((ssl_exclude & 0x01) != 0)
  116. ssl_op |= SSL_OP_NO_SSLv2;
  117. if ((ssl_exclude & 0x02) != 0)
  118. ssl_op |= SSL_OP_NO_SSLv3;
  119. if ((ssl_exclude & 0x04) != 0)
  120. ssl_op |= SSL_OP_NO_TLSv1;
  121. #ifdef SSL_OP_NO_TLSv1_1
  122. if ((ssl_exclude & 0x08) != 0)
  123. ssl_op |= SSL_OP_NO_TLSv1_1;
  124. #endif
  125. #ifdef SSL_OP_NO_TLSv1_2
  126. if ((ssl_exclude & 0x10) != 0)
  127. ssl_op |= SSL_OP_NO_TLSv1_2;
  128. #endif
  129. if (ssl_protocols) {
  130. SSL_CTX_set_options(lpCTX, ssl_op);
  131. }
  132. #if !defined(OPENSSL_NO_ECDH) && defined(NID_X9_62_prime256v1)
  133. ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
  134. if (ecdh != NULL) {
  135. /* SINGLE_ECDH_USE = renegotiate exponent for each handshake */
  136. SSL_CTX_set_options(lpCTX, SSL_OP_SINGLE_ECDH_USE);
  137. SSL_CTX_set_tmp_ecdh(lpCTX, ecdh);
  138. EC_KEY_free(ecdh);
  139. }
  140. #endif
  141. if (ssl_ciphers && SSL_CTX_set_cipher_list(lpCTX, ssl_ciphers) != 1) {
  142. ec_log_err("Can not set SSL cipher list to \"%s\": %s", ssl_ciphers, ERR_error_string(ERR_get_error(), 0));
  143. hr = MAPI_E_CALL_FAILED;
  144. goto exit;
  145. }
  146. if (parseBool(lpConfig->GetSetting("ssl_prefer_server_ciphers"))) {
  147. SSL_CTX_set_options(lpCTX, SSL_OP_CIPHER_SERVER_PREFERENCE);
  148. }
  149. SSL_CTX_set_default_verify_paths(lpCTX);
  150. if (SSL_CTX_use_certificate_chain_file(lpCTX, lpConfig->GetSetting("ssl_certificate_file")) != 1) {
  151. ec_log_err("SSL CTX certificate file error: %s", ERR_error_string(ERR_get_error(), 0));
  152. hr = MAPI_E_CALL_FAILED;
  153. goto exit;
  154. }
  155. if (SSL_CTX_use_PrivateKey_file(lpCTX, lpConfig->GetSetting("ssl_private_key_file"), SSL_FILETYPE_PEM) != 1) {
  156. ec_log_err("SSL CTX private key file error: %s", ERR_error_string(ERR_get_error(), 0));
  157. hr = MAPI_E_CALL_FAILED;
  158. goto exit;
  159. }
  160. if (SSL_CTX_check_private_key(lpCTX) != 1) {
  161. ec_log_err("SSL CTX check private key error: %s", ERR_error_string(ERR_get_error(), 0));
  162. hr = MAPI_E_CALL_FAILED;
  163. goto exit;
  164. }
  165. if (strcmp(lpConfig->GetSetting("ssl_verify_client"), "yes") == 0)
  166. SSL_CTX_set_verify(lpCTX, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);
  167. else
  168. SSL_CTX_set_verify(lpCTX, SSL_VERIFY_NONE, 0);
  169. if (lpConfig->GetSetting("ssl_verify_file")[0])
  170. szFile = lpConfig->GetSetting("ssl_verify_file");
  171. if (lpConfig->GetSetting("ssl_verify_path")[0])
  172. szPath = lpConfig->GetSetting("ssl_verify_path");
  173. if (szFile || szPath) {
  174. if (SSL_CTX_load_verify_locations(lpCTX, szFile, szPath) != 1)
  175. ec_log_err("SSL CTX error loading verify locations: %s", ERR_error_string(ERR_get_error(), 0));
  176. }
  177. exit:
  178. if (hr != hrSuccess)
  179. HrFreeCtx();
  180. return hr;
  181. }
  182. HRESULT ECChannel::HrFreeCtx() {
  183. if (lpCTX) {
  184. SSL_CTX_free(lpCTX);
  185. lpCTX = NULL;
  186. }
  187. return hrSuccess;
  188. }
  189. ECChannel::ECChannel(int fd) {
  190. int flag = 1;
  191. this->fd = fd;
  192. if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<const char *>(&flag), sizeof(flag)) < 0)
  193. /* silence Coverity */;
  194. *peer_atxt = '\0';
  195. memset(&peer_sockaddr, 0, sizeof(peer_sockaddr));
  196. }
  197. ECChannel::~ECChannel() {
  198. if (lpSSL) {
  199. SSL_shutdown(lpSSL);
  200. SSL_free(lpSSL);
  201. }
  202. close(fd);
  203. }
  204. HRESULT ECChannel::HrEnableTLS(void)
  205. {
  206. int rc = -1;
  207. HRESULT hr = hrSuccess;
  208. if (lpSSL || lpCTX == NULL) {
  209. hr = MAPI_E_CALL_FAILED;
  210. ec_log_err("ECChannel::HrEnableTLS(): invalid parameters");
  211. goto exit;
  212. }
  213. lpSSL = SSL_new(lpCTX);
  214. if (!lpSSL) {
  215. ec_log_err("ECChannel::HrEnableTLS(): SSL_new failed");
  216. hr = MAPI_E_CALL_FAILED;
  217. goto exit;
  218. }
  219. SSL_clear(lpSSL);
  220. if (SSL_set_fd(lpSSL, fd) != 1) {
  221. ec_log_err("ECChannel::HrEnableTLS(): SSL_set_fd failed");
  222. hr = MAPI_E_CALL_FAILED;
  223. goto exit;
  224. }
  225. SSL_set_accept_state(lpSSL);
  226. if ((rc = SSL_accept(lpSSL)) != 1) {
  227. ec_log_err("ECChannel::HrEnableTLS(): SSL_accept failed: %d", SSL_get_error(lpSSL, rc));
  228. hr = MAPI_E_CALL_FAILED;
  229. goto exit;
  230. }
  231. exit:
  232. if (hr != hrSuccess && lpSSL) {
  233. SSL_shutdown(lpSSL);
  234. SSL_free(lpSSL);
  235. lpSSL = NULL;
  236. }
  237. return hr;
  238. }
  239. HRESULT ECChannel::HrGets(char *szBuffer, ULONG ulBufSize, ULONG *lpulRead) {
  240. char *lpRet = NULL;
  241. int len = ulBufSize;
  242. if (!szBuffer || !lpulRead)
  243. return MAPI_E_INVALID_PARAMETER;
  244. if (lpSSL)
  245. lpRet = SSL_gets(szBuffer, &len);
  246. else
  247. lpRet = fd_gets(szBuffer, &len);
  248. if (lpRet) {
  249. *lpulRead = len;
  250. return hrSuccess;
  251. }
  252. return MAPI_E_CALL_FAILED;
  253. }
  254. /**
  255. * Read a line from a socket. Reads as much data until it encounters a
  256. * \n characters.
  257. *
  258. * @param[out] strBuffer network data will be placed in this buffer
  259. * @param[in] ulMaxBuffer optional, default 65k, breaks reading after this limit is reached
  260. *
  261. * @return MAPI_ERROR_CODE
  262. * @retval MAPI_E_TOO_BIG more data in the network buffer than requested to read
  263. */
  264. HRESULT ECChannel::HrReadLine(std::string * strBuffer, ULONG ulMaxBuffer) {
  265. HRESULT hr = hrSuccess;
  266. ULONG ulRead = 0;
  267. if(!strBuffer)
  268. return MAPI_E_INVALID_PARAMETER;
  269. char buffer[65536];
  270. // clear the buffer before appending
  271. strBuffer->clear();
  272. do {
  273. hr = HrGets(buffer, 65536, &ulRead);
  274. if (hr != hrSuccess)
  275. break;
  276. strBuffer->append(buffer, ulRead);
  277. if (strBuffer->size() > ulMaxBuffer) {
  278. hr = MAPI_E_TOO_BIG;
  279. break;
  280. }
  281. } while (ulRead == 65535); // zero-terminator is not counted
  282. return hr;
  283. }
  284. HRESULT ECChannel::HrWriteString(const char *szBuffer)
  285. {
  286. HRESULT hr = hrSuccess;
  287. if(!szBuffer)
  288. return MAPI_E_INVALID_PARAMETER;
  289. if (lpSSL) {
  290. if (SSL_write(lpSSL, szBuffer, (int)strlen(szBuffer)) < 1)
  291. hr = MAPI_E_NETWORK_ERROR;
  292. }
  293. else if (send(fd, szBuffer, (int)strlen(szBuffer), 0) < 1) {
  294. hr = MAPI_E_NETWORK_ERROR;
  295. }
  296. return hr;
  297. }
  298. HRESULT ECChannel::HrWriteString(const std::string & strBuffer) {
  299. HRESULT hr = hrSuccess;
  300. if (lpSSL) {
  301. if (SSL_write(lpSSL, strBuffer.c_str(), (int)strBuffer.size()) < 1)
  302. hr = MAPI_E_NETWORK_ERROR;
  303. } else if (send(fd, strBuffer.c_str(), (int)strBuffer.size(), 0) < 1) {
  304. hr = MAPI_E_NETWORK_ERROR;
  305. }
  306. return hr;
  307. }
  308. /**
  309. * Writes a line of data to socket
  310. *
  311. * Function takes specified lenght of data from the pointer,
  312. * if length is not specified all the data of pointed by buffer is used.
  313. * It then adds CRLF to the end of the data and writes it to the socket
  314. *
  315. * @param[in] szBuffer pointer to the data to be written to socket
  316. * @param[in] len optional paramter to specify lenght of data in szBuffer, if empty then all data of szBuffer is written to socket.
  317. *
  318. * @retval MAPI_E_CALL_FAILED unable to write data to socket
  319. */
  320. HRESULT ECChannel::HrWriteLine(const char *szBuffer, int len) {
  321. std::string strLine;
  322. if (len == 0)
  323. strLine.assign(szBuffer);
  324. else
  325. strLine.assign(szBuffer, len);
  326. strLine += "\r\n";
  327. return HrWriteString(strLine);
  328. }
  329. HRESULT ECChannel::HrWriteLine(const std::string & strBuffer) {
  330. return HrWriteString(strBuffer + "\r\n");
  331. }
  332. /**
  333. * Read and discard bytes
  334. *
  335. * Read from socket and discard the data
  336. *
  337. * @param[in] ulByteCount Amount of bytes to discard
  338. *
  339. * @retval MAPI_E_NETWORK_ERROR Unable to read bytes.
  340. * @retval MAPI_E_CALL_FAILED Reading wrong amount of data.
  341. */
  342. HRESULT ECChannel::HrReadAndDiscardBytes(ULONG ulByteCount) {
  343. ULONG ulTotRead = 0;
  344. char szBuffer[4096];
  345. while (ulTotRead < ulByteCount) {
  346. ULONG ulBytesLeft = ulByteCount - ulTotRead;
  347. ULONG ulRead = ulBytesLeft > sizeof szBuffer ? sizeof szBuffer : ulBytesLeft;
  348. if (lpSSL)
  349. ulRead = SSL_read(lpSSL, szBuffer, ulRead);
  350. else
  351. ulRead = recv(fd, szBuffer, ulRead, 0);
  352. if (ulRead == (ULONG)-1) {
  353. if (errno == EINTR)
  354. continue;
  355. return MAPI_E_NETWORK_ERROR;
  356. }
  357. if (ulRead == 0 || ulRead > ulByteCount)
  358. return MAPI_E_NETWORK_ERROR;
  359. ulTotRead += ulRead;
  360. }
  361. return (ulTotRead == ulByteCount) ? hrSuccess : MAPI_E_CALL_FAILED;
  362. }
  363. HRESULT ECChannel::HrReadBytes(char *szBuffer, ULONG ulByteCount) {
  364. ULONG ulRead = 0;
  365. ULONG ulTotRead = 0;
  366. if(!szBuffer)
  367. return MAPI_E_INVALID_PARAMETER;
  368. while(ulTotRead < ulByteCount) {
  369. if (lpSSL)
  370. ulRead = SSL_read(lpSSL, szBuffer + ulTotRead, ulByteCount - ulTotRead);
  371. else
  372. ulRead = recv(fd, szBuffer + ulTotRead, ulByteCount - ulTotRead, 0);
  373. if (ulRead == (ULONG)-1) {
  374. if (errno == EINTR)
  375. continue;
  376. return MAPI_E_NETWORK_ERROR;
  377. }
  378. if (ulRead == 0 || ulRead > ulByteCount)
  379. return MAPI_E_NETWORK_ERROR;
  380. ulTotRead += ulRead;
  381. }
  382. szBuffer[ulTotRead] = '\0';
  383. return (ulTotRead == ulByteCount) ? hrSuccess : MAPI_E_CALL_FAILED;
  384. }
  385. HRESULT ECChannel::HrReadBytes(std::string * strBuffer, ULONG ulByteCount) {
  386. HRESULT hr = hrSuccess;
  387. std::unique_ptr<char[]> buffer;
  388. if (strBuffer == nullptr)
  389. return MAPI_E_INVALID_PARAMETER;
  390. buffer.reset(new(std::nothrow) char[ulByteCount+1]);
  391. if (buffer == nullptr)
  392. return MAPI_E_NOT_ENOUGH_MEMORY;
  393. hr = HrReadBytes(buffer.get(), ulByteCount);
  394. if (hr != hrSuccess)
  395. return hr;
  396. strBuffer->assign(buffer.get(), ulByteCount);
  397. return hrSuccess;
  398. }
  399. HRESULT ECChannel::HrSelect(int seconds) {
  400. struct pollfd pollfd = {fd, POLLIN | POLLRDHUP, 0};
  401. if(lpSSL && SSL_pending(lpSSL))
  402. return hrSuccess;
  403. int res = poll(&pollfd, 1, seconds * 1000);
  404. if (res == -1) {
  405. if (errno == EINTR)
  406. /*
  407. * We _must_ return to the caller so it gets a chance
  408. * to e.g. shut down as a result of SIGTERM.
  409. */
  410. return MAPI_E_CANCEL;
  411. return MAPI_E_NETWORK_ERROR;
  412. }
  413. if (res == 0)
  414. return MAPI_E_TIMEOUT;
  415. return hrSuccess;
  416. }
  417. /**
  418. * read from buffer until \n is found, or buffer length is reached
  419. * return buffer always contains \0 in the end, so max read from network is *lpulLen -1
  420. *
  421. * @param[out] buf buffer to read network data in
  422. * @param[in,out] lpulLen input is max size to read, output is read bytes from network
  423. *
  424. * @return NULL on error, or buf
  425. */
  426. char * ECChannel::fd_gets(char *buf, int *lpulLen) {
  427. char *newline = NULL, *bp = buf;
  428. int len = *lpulLen;
  429. if (--len < 1)
  430. return NULL;
  431. do {
  432. /*
  433. * Return NULL when we read nothing:
  434. * other side has closed its writing socket.
  435. */
  436. int n = recv(fd, bp, len, MSG_PEEK);
  437. if (n == 0)
  438. return NULL;
  439. if (n == -1) {
  440. if (errno == EINTR)
  441. continue;
  442. return NULL;
  443. }
  444. if ((newline = (char *)memchr((void *)bp, '\n', n)) != NULL)
  445. n = newline - bp + 1;
  446. retry:
  447. int recv_n = recv(fd, bp, n, 0);
  448. if (recv_n == 0)
  449. return NULL;
  450. if (recv_n == -1) {
  451. if (errno == EINTR)
  452. goto retry;
  453. return NULL;
  454. }
  455. bp += recv_n;
  456. len -= recv_n;
  457. }
  458. while(!newline && len > 0);
  459. //remove the lf or crlf
  460. if(newline){
  461. --bp;
  462. --newline;
  463. if(newline >= buf && *newline == '\r')
  464. --bp;
  465. }
  466. *bp = '\0';
  467. *lpulLen = (int)(bp - buf);
  468. return buf;
  469. }
  470. char * ECChannel::SSL_gets(char *buf, int *lpulLen) {
  471. char *newline, *bp = buf;
  472. int len = *lpulLen;
  473. int n = 0;
  474. if (--len < 1)
  475. return NULL;
  476. do {
  477. /*
  478. * Return NULL when we read nothing:
  479. * other side has closed its writing socket.
  480. */
  481. if ((n = SSL_peek(lpSSL, bp, len)) <= 0)
  482. return NULL;
  483. if ((newline = (char *)memchr((void *)bp, '\n', n)) != NULL)
  484. n = newline - bp + 1;
  485. if ((n = SSL_read(lpSSL, bp, n)) < 0)
  486. return NULL;
  487. bp += n;
  488. len -= n;
  489. } while (!newline && len > 0);
  490. //remove the lf or crlf
  491. if(newline){
  492. --bp;
  493. --newline;
  494. if(newline >= buf && *newline == '\r')
  495. --bp;
  496. }
  497. *bp = '\0';
  498. *lpulLen = (int)(bp - buf);
  499. return buf;
  500. }
  501. void ECChannel::SetIPAddress(const struct sockaddr *sa, size_t slen)
  502. {
  503. char host[256], serv[16];
  504. if (getnameinfo(sa, slen, host, sizeof(host), serv, sizeof(serv),
  505. NI_NUMERICHOST | NI_NUMERICSERV) != 0)
  506. snprintf(peer_atxt, sizeof(peer_atxt), "<indeterminate>");
  507. else if (sa->sa_family == AF_INET6)
  508. snprintf(peer_atxt, sizeof(peer_atxt), "[%s]:%s", host, serv);
  509. else if (sa->sa_family == AF_UNIX)
  510. snprintf(peer_atxt, sizeof(peer_atxt), "unix:%s:%s", host, serv);
  511. else
  512. snprintf(peer_atxt, sizeof(peer_atxt), "%s:%s", host, serv);
  513. memcpy(&peer_sockaddr, sa, slen);
  514. peer_salen = slen;
  515. }
  516. #ifdef LINUX
  517. static int peer_is_local2(int rsk, const struct nlmsghdr *nlh)
  518. {
  519. if (send(rsk, nlh, nlh->nlmsg_len, 0) < 0)
  520. return -errno;
  521. char rspbuf[512];
  522. ssize_t ret = recv(rsk, rspbuf, sizeof(rspbuf), 0);
  523. if (ret < 0)
  524. return -errno;
  525. if (static_cast<size_t>(ret) < sizeof(struct nlmsghdr))
  526. return -ENODATA;
  527. nlh = reinterpret_cast<const struct nlmsghdr *>(rspbuf);
  528. if (!NLMSG_OK(nlh, nlh->nlmsg_len))
  529. return -EIO;
  530. auto rtm = reinterpret_cast<const struct rtmsg *>(NLMSG_DATA(nlh));
  531. return rtm->rtm_type == RTN_LOCAL;
  532. }
  533. #endif
  534. /**
  535. * Determine if a file descriptor refers to some kind of local connection,
  536. * so as to decide on flags like compression.
  537. *
  538. * Returns negative errno code if indeterminate, otherwise false/true.
  539. */
  540. int zcp_peeraddr_is_local(const struct sockaddr *peer_sockaddr,
  541. socklen_t peer_socklen)
  542. {
  543. if (peer_sockaddr->sa_family == AF_UNIX) {
  544. return true;
  545. } else if (peer_sockaddr->sa_family == AF_INET6) {
  546. if (peer_socklen < sizeof(struct sockaddr_in6))
  547. return -EIO;
  548. } else if (peer_sockaddr->sa_family == AF_INET) {
  549. if (peer_socklen < sizeof(struct sockaddr_in))
  550. return -EIO;
  551. } else {
  552. return -EPROTONOSUPPORT;
  553. }
  554. #ifdef LINUX
  555. int rsk = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
  556. if (rsk < 0) {
  557. fprintf(stderr, "socket AF_NETLINK: %s\n", strerror(errno));
  558. return -errno;
  559. }
  560. struct {
  561. struct nlmsghdr nh;
  562. struct rtmsg rth;
  563. char attrbuf[512];
  564. } req;
  565. memset(&req, 0, sizeof(req));
  566. req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(req.rth));
  567. req.nh.nlmsg_flags = NLM_F_REQUEST;
  568. req.nh.nlmsg_type = RTM_GETROUTE;
  569. req.rth.rtm_family = peer_sockaddr->sa_family;
  570. req.rth.rtm_protocol = RTPROT_UNSPEC;
  571. req.rth.rtm_type = RTN_UNSPEC;
  572. req.rth.rtm_scope = RT_SCOPE_UNIVERSE;
  573. req.rth.rtm_table = RT_TABLE_UNSPEC;
  574. auto rta = reinterpret_cast<struct rtattr *>(reinterpret_cast<char *>(&req) + NLMSG_ALIGN(req.nh.nlmsg_len));
  575. rta->rta_type = RTA_DST;
  576. int ret = -ENODATA;
  577. if (peer_sockaddr->sa_family == AF_INET6) {
  578. const struct in6_addr &ad = reinterpret_cast<const struct sockaddr_in6 *>(peer_sockaddr)->sin6_addr;
  579. static const uint8_t mappedv4[] =
  580. {0,0,0,0, 0,0,0,0, 0,0,0xff,0xff};
  581. req.rth.rtm_dst_len = sizeof(ad);
  582. if (memcmp(&ad, mappedv4, 12) == 0) {
  583. /* RTM_GETROUTE won't report RTN_LOCAL for ::ffff:127.0.0.1 */
  584. req.rth.rtm_family = AF_INET;
  585. rta->rta_len = RTA_LENGTH(sizeof(struct in_addr));
  586. req.nh.nlmsg_len = NLMSG_ALIGN(req.nh.nlmsg_len) + rta->rta_len;
  587. memcpy(RTA_DATA(rta), &ad.s6_addr[12], 4);
  588. } else {
  589. rta->rta_len = RTA_LENGTH(sizeof(ad));
  590. req.nh.nlmsg_len = NLMSG_ALIGN(req.nh.nlmsg_len) + rta->rta_len;
  591. memcpy(RTA_DATA(rta), &ad, sizeof(ad));
  592. }
  593. } else if (peer_sockaddr->sa_family == AF_INET) {
  594. const struct in_addr &ad = reinterpret_cast<const struct sockaddr_in *>(peer_sockaddr)->sin_addr;
  595. req.rth.rtm_dst_len = sizeof(ad);
  596. rta->rta_len = RTA_LENGTH(sizeof(ad));
  597. req.nh.nlmsg_len = NLMSG_ALIGN(req.nh.nlmsg_len) + rta->rta_len;
  598. memcpy(RTA_DATA(rta), &ad, sizeof(ad));
  599. }
  600. ret = peer_is_local2(rsk, &req.nh);
  601. close(rsk);
  602. return ret;
  603. #endif
  604. return -EPROTONOSUPPORT;
  605. }
  606. int zcp_peerfd_is_local(int fd)
  607. {
  608. struct sockaddr_storage peer_sockaddr;
  609. socklen_t peer_socklen = sizeof(sockaddr);
  610. auto sa = reinterpret_cast<struct sockaddr *>(&peer_sockaddr);
  611. int ret = getsockname(fd, sa, &peer_socklen);
  612. if (ret < 0)
  613. return -errno;
  614. return zcp_peeraddr_is_local(sa, peer_socklen);
  615. }
  616. int ECChannel::peer_is_local(void) const
  617. {
  618. return zcp_peeraddr_is_local(reinterpret_cast<const struct sockaddr *>(&peer_sockaddr), peer_salen);
  619. }
  620. /**
  621. * getaddrinfo() adheres to the preference weights given in /etc/gai.conf,
  622. * but only for connect sockets. For AI_PASSIVE, sockets may be returned in
  623. * any order. This function will reorder an addrinfo linked list and place
  624. * IPv6 in the front.
  625. */
  626. static struct addrinfo *reorder_addrinfo_ipv6(struct addrinfo *node)
  627. {
  628. struct addrinfo v6head, othead;
  629. v6head.ai_next = NULL;
  630. othead.ai_next = node;
  631. struct addrinfo *v6tail = &v6head, *prev = &othead;
  632. while (node != NULL) {
  633. if (node->ai_family != AF_INET6) {
  634. prev = node;
  635. node = node->ai_next;
  636. continue;
  637. }
  638. /* disconnect current node (INET6) */
  639. prev->ai_next = node->ai_next;
  640. node->ai_next = NULL;
  641. /* - reattach to v6 list */
  642. v6tail->ai_next = node;
  643. v6tail = node;
  644. /* continue in ot list */
  645. node = prev->ai_next;
  646. }
  647. /* join list */
  648. v6tail->ai_next = othead.ai_next;
  649. return v6head.ai_next;
  650. }
  651. HRESULT HrListen(const char *szPath, int *lpulListenSocket)
  652. {
  653. HRESULT hr = hrSuccess;
  654. int fd = -1;
  655. struct sockaddr_un sun_addr;
  656. mode_t prevmask = 0;
  657. if (szPath == NULL || strlen(szPath) >= sizeof(sun_addr.sun_path) ||
  658. lpulListenSocket == NULL) {
  659. hr = MAPI_E_INVALID_PARAMETER;
  660. goto exit;
  661. }
  662. memset(&sun_addr, 0, sizeof(sun_addr));
  663. sun_addr.sun_family = AF_UNIX;
  664. kc_strlcpy(sun_addr.sun_path, szPath, sizeof(sun_addr.sun_path));
  665. if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) {
  666. ec_log_crit("Unable to create AF_UNIX socket");
  667. hr = MAPI_E_NETWORK_ERROR;
  668. goto exit;
  669. }
  670. unlink(szPath);
  671. // make files with permissions 0666
  672. prevmask = umask(0111);
  673. if (bind(fd, (struct sockaddr *)&sun_addr, sizeof(sun_addr)) == -1) {
  674. ec_log_crit("Unable to bind to socket %s (%s). This is usually caused by another process (most likely another kopano-server) already using this port. This program will terminate now.", szPath, strerror(errno));
  675. kill(0, SIGTERM);
  676. exit(1);
  677. }
  678. // TODO: backlog of SOMAXCONN should be configurable
  679. if (listen(fd, SOMAXCONN) == -1) {
  680. ec_log_crit("Unable to start listening on socket \"%s\".", szPath);
  681. hr = MAPI_E_NETWORK_ERROR;
  682. goto exit;
  683. }
  684. *lpulListenSocket = fd;
  685. exit:
  686. if (prevmask)
  687. umask(prevmask);
  688. if (hr != hrSuccess && fd != -1)
  689. close(fd);
  690. return hr;
  691. }
  692. int zcp_bindtodevice(int fd, const char *i)
  693. {
  694. if (i == NULL || strcmp(i, "any") == 0 || strcmp(i, "all") == 0 ||
  695. strcmp(i, "") == 0)
  696. return 0;
  697. #ifdef LINUX
  698. if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, i, strlen(i)) >= 0)
  699. return 0;
  700. ec_log_err("Unable to bind to interface %s: %s", i, strerror(errno));
  701. return -errno;
  702. #else
  703. ec_log_err("Bind-to-interface not supported.");
  704. return -ENOSYS;
  705. #endif
  706. }
  707. HRESULT HrListen(const char *szBind, uint16_t ulPort, int *lpulListenSocket)
  708. {
  709. HRESULT hr = hrSuccess;
  710. int fd = -1, opt = 1, ret;
  711. struct addrinfo *sock_res = NULL, sock_hints;
  712. const struct addrinfo *sock_addr, *sock_last = NULL;
  713. char port_string[sizeof("65535")];
  714. if (lpulListenSocket == NULL || ulPort == 0 || szBind == NULL) {
  715. hr = MAPI_E_INVALID_PARAMETER;
  716. goto exit;
  717. }
  718. snprintf(port_string, sizeof(port_string), "%u", ulPort);
  719. memset(&sock_hints, 0, sizeof(sock_hints));
  720. /*
  721. * AI_NUMERICHOST is reflected in the kopano documentation:
  722. * an address is required for the "server_bind" parameter.
  723. */
  724. sock_hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV | AI_PASSIVE;
  725. sock_hints.ai_socktype = SOCK_STREAM;
  726. ret = getaddrinfo(*szBind == '\0' ? NULL : szBind,
  727. port_string, &sock_hints, &sock_res);
  728. if (ret != 0) {
  729. hr = MAPI_E_INVALID_PARAMETER;
  730. ec_log_err("getaddrinfo(%s,%u): %s", szBind, ulPort, gai_strerror(ret));
  731. goto exit;
  732. }
  733. sock_res = reorder_addrinfo_ipv6(sock_res);
  734. errno = 0;
  735. for (sock_addr = sock_res; sock_addr != NULL;
  736. sock_addr = sock_addr->ai_next)
  737. {
  738. sock_last = sock_addr;
  739. fd = socket(sock_addr->ai_family, sock_addr->ai_socktype,
  740. sock_addr->ai_protocol);
  741. if (fd < 0)
  742. continue;
  743. if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
  744. reinterpret_cast<const char *>(&opt), sizeof(opt)) < 0)
  745. ec_log_warn("Unable to set reuseaddr socket option: %s",
  746. strerror(errno));
  747. ret = bind(fd, sock_addr->ai_addr, sock_addr->ai_addrlen);
  748. if (ret < 0 && errno == EADDRINUSE) {
  749. /*
  750. * If the port is used, drop out early. Do not let it
  751. * happen that we move to an AF where it happens to be
  752. * unused.
  753. */
  754. int saved_errno = errno;
  755. close(fd);
  756. fd = -1;
  757. errno = saved_errno;
  758. break;
  759. }
  760. if (ret < 0) {
  761. int saved_errno = errno;
  762. close(fd);
  763. fd = -1;
  764. errno = saved_errno;
  765. continue;
  766. }
  767. if (listen(fd, SOMAXCONN) < 0) {
  768. ec_log_err("Unable to start listening on port %d: %s",
  769. ulPort, strerror(errno));
  770. hr = MAPI_E_NETWORK_ERROR;
  771. goto exit;
  772. }
  773. /*
  774. * Function signature currently only permits a single fd, so if
  775. * we have a good socket, try no more. The IPv6 socket is
  776. * generally returned first, and is also IPv4-capable
  777. * (through mapped addresses).
  778. */
  779. break;
  780. }
  781. if (fd < 0 && sock_last != NULL) {
  782. ec_log_crit("Unable to create socket(%u,%u,%u) port %s: %s",
  783. sock_last->ai_family, sock_last->ai_socktype,
  784. sock_last->ai_protocol, port_string, strerror(errno));
  785. hr = MAPI_E_NETWORK_ERROR;
  786. goto exit;
  787. } else if (fd < 0) {
  788. ec_log_err("no sockets proposed");
  789. hr = MAPI_E_NETWORK_ERROR;
  790. goto exit;
  791. }
  792. *lpulListenSocket = fd;
  793. exit:
  794. if (sock_res != NULL)
  795. freeaddrinfo(sock_res);
  796. if (hr != hrSuccess && fd >= 0)
  797. close(fd);
  798. return hr;
  799. }
  800. HRESULT HrAccept(int ulListenFD, ECChannel **lppChannel)
  801. {
  802. int socket = 0;
  803. struct sockaddr_storage client;
  804. std::unique_ptr<ECChannel> lpChannel;
  805. socklen_t len = sizeof(client);
  806. if (ulListenFD < 0 || lppChannel == NULL) {
  807. ec_log_err("HrAccept: invalid parameters");
  808. return MAPI_E_INVALID_PARAMETER;
  809. }
  810. #ifdef TCP_FASTOPEN
  811. static const int qlen = SOMAXCONN;
  812. if (setsockopt(ulListenFD, SOL_TCP, TCP_FASTOPEN, &qlen, sizeof(qlen)) < 0)
  813. /* ignore - no harm in not having fastopen */;
  814. #endif
  815. memset(&client, 0, sizeof(client));
  816. socket = accept(ulListenFD, (struct sockaddr *)&client, &len);
  817. if (socket == -1) {
  818. ec_log_err("Unable to accept(): %s", strerror(errno));
  819. return MAPI_E_NETWORK_ERROR;
  820. }
  821. lpChannel.reset(new ECChannel(socket));
  822. lpChannel->SetIPAddress(reinterpret_cast<const struct sockaddr *>(&client), len);
  823. ec_log_info("Accepted connection from %s", lpChannel->peer_addr());
  824. *lppChannel = lpChannel.release();
  825. return hrSuccess;
  826. }
  827. } /* namespace */