You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1029 lines
33 KiB

  1. // -*- mode: cpp; mode: fold -*-
  2. // Description /*{{{*/
  3. /* ######################################################################
  4. Connect - Replacement connect call
  5. This was originally authored by Jason Gunthorpe <jgg@debian.org>
  6. and is placed in the Public Domain, do with it what you will.
  7. ##################################################################### */
  8. /*}}}*/
  9. // Include Files /*{{{*/
  10. #include <config.h>
  11. #include <apt-pkg/acquire-method.h>
  12. #include <apt-pkg/configuration.h>
  13. #include <apt-pkg/error.h>
  14. #include <apt-pkg/fileutl.h>
  15. #include <apt-pkg/srvrec.h>
  16. #include <apt-pkg/strutl.h>
  17. #include <gnutls/gnutls.h>
  18. #include <gnutls/x509.h>
  19. #include <list>
  20. #include <set>
  21. #include <sstream>
  22. #include <string>
  23. #include <errno.h>
  24. #include <stdio.h>
  25. #include <string.h>
  26. #include <unistd.h>
  27. // Internet stuff
  28. #include <netdb.h>
  29. #include <arpa/inet.h>
  30. #include <netinet/in.h>
  31. #include <sys/select.h>
  32. #include <sys/socket.h>
  33. #include "aptmethod.h"
  34. #include "connect.h"
  35. #include "rfc2553emu.h"
  36. #include <apti18n.h>
  37. /*}}}*/
  38. static std::string LastHost;
  39. static int LastPort = 0;
  40. static struct addrinfo *LastHostAddr = 0;
  41. static struct addrinfo *LastUsed = 0;
  42. static std::vector<SrvRec> SrvRecords;
  43. // Set of IP/hostnames that we timed out before or couldn't resolve
  44. static std::set<std::string> bad_addr;
  45. // RotateDNS - Select a new server from a DNS rotation /*{{{*/
  46. // ---------------------------------------------------------------------
  47. /* This is called during certain errors in order to recover by selecting a
  48. new server */
  49. void RotateDNS()
  50. {
  51. if (LastUsed != 0 && LastUsed->ai_next != 0)
  52. LastUsed = LastUsed->ai_next;
  53. else
  54. LastUsed = LastHostAddr;
  55. }
  56. /*}}}*/
  57. static bool ConnectionAllowed(char const * const Service, std::string const &Host)/*{{{*/
  58. {
  59. if (unlikely(Host.empty())) // the only legal empty host (RFC2782 '.' target) is detected by caller
  60. return false;
  61. if (APT::String::Endswith(Host, ".onion") && _config->FindB("Acquire::BlockDotOnion", true))
  62. {
  63. // TRANSLATOR: %s is e.g. Tor's ".onion" which would likely fail or leak info (RFC7686)
  64. _error->Error(_("Direct connection to %s domains is blocked by default."), ".onion");
  65. if (strcmp(Service, "http") == 0)
  66. _error->Error(_("If you meant to use Tor remember to use %s instead of %s."), "tor+http", "http");
  67. return false;
  68. }
  69. return true;
  70. }
  71. /*}}}*/
  72. // File Descriptor based Fd /*{{{*/
  73. struct FdFd : public MethodFd
  74. {
  75. int fd = -1;
  76. int Fd() APT_OVERRIDE { return fd; }
  77. ssize_t Read(void *buf, size_t count) APT_OVERRIDE { return ::read(fd, buf, count); }
  78. ssize_t Write(void *buf, size_t count) APT_OVERRIDE { return ::write(fd, buf, count); }
  79. int Close() APT_OVERRIDE
  80. {
  81. int result = 0;
  82. if (fd != -1)
  83. result = ::close(fd);
  84. fd = -1;
  85. return result;
  86. }
  87. };
  88. bool MethodFd::HasPending()
  89. {
  90. return false;
  91. }
  92. std::unique_ptr<MethodFd> MethodFd::FromFd(int iFd)
  93. {
  94. FdFd *fd = new FdFd();
  95. fd->fd = iFd;
  96. return std::unique_ptr<MethodFd>(fd);
  97. }
  98. /*}}}*/
  99. // DoConnect - Attempt a connect operation /*{{{*/
  100. // ---------------------------------------------------------------------
  101. /* This helper function attempts a connection to a single address. */
  102. struct Connection
  103. {
  104. struct addrinfo *Addr;
  105. std::string Host;
  106. aptMethod *Owner;
  107. std::unique_ptr<FdFd> Fd;
  108. char Name[NI_MAXHOST];
  109. char Service[NI_MAXSERV];
  110. Connection(struct addrinfo *Addr, std::string const &Host, aptMethod *Owner) : Addr(Addr), Host(Host), Owner(Owner), Fd(new FdFd()), Name{0}, Service{0}
  111. {
  112. }
  113. // Allow moving values, but not connections.
  114. Connection(Connection &&Conn) = default;
  115. Connection(const Connection &Conn) = delete;
  116. Connection &operator=(const Connection &) = delete;
  117. Connection &operator=(Connection &&Conn) = default;
  118. ~Connection()
  119. {
  120. if (Fd != nullptr)
  121. {
  122. Fd->Close();
  123. }
  124. }
  125. std::unique_ptr<MethodFd> Take()
  126. {
  127. /* Store the IP we are using.. If something goes
  128. wrong this will get tacked onto the end of the error message */
  129. std::stringstream ss;
  130. ioprintf(ss, _("[IP: %s %s]"), Name, Service);
  131. Owner->SetIP(ss.str());
  132. Owner->Status(_("Connected to %s (%s)"), Host.c_str(), Name);
  133. _error->Discard();
  134. Owner->SetFailReason("");
  135. LastUsed = Addr;
  136. return std::move(Fd);
  137. }
  138. ResultState DoConnect();
  139. ResultState CheckError();
  140. };
  141. ResultState Connection::DoConnect()
  142. {
  143. getnameinfo(Addr->ai_addr,Addr->ai_addrlen,
  144. Name,sizeof(Name),Service,sizeof(Service),
  145. NI_NUMERICHOST|NI_NUMERICSERV);
  146. Owner->Status(_("Connecting to %s (%s)"),Host.c_str(),Name);
  147. // if that addr did timeout before, we do not try it again
  148. if(bad_addr.find(std::string(Name)) != bad_addr.end())
  149. return ResultState::TRANSIENT_ERROR;
  150. // Get a socket
  151. if ((static_cast<FdFd *>(Fd.get())->fd = socket(Addr->ai_family, Addr->ai_socktype,
  152. Addr->ai_protocol)) < 0)
  153. {
  154. _error->Errno("socket", _("Could not create a socket for %s (f=%u t=%u p=%u)"),
  155. Name, Addr->ai_family, Addr->ai_socktype, Addr->ai_protocol);
  156. return ResultState::FATAL_ERROR;
  157. }
  158. SetNonBlock(Fd->Fd(), true);
  159. if (connect(Fd->Fd(), Addr->ai_addr, Addr->ai_addrlen) < 0 &&
  160. errno != EINPROGRESS)
  161. {
  162. _error->Errno("connect", _("Cannot initiate the connection "
  163. "to %s:%s (%s)."),
  164. Host.c_str(), Service, Name);
  165. return ResultState::TRANSIENT_ERROR;
  166. }
  167. return ResultState::SUCCESSFUL;
  168. }
  169. ResultState Connection::CheckError()
  170. {
  171. // Check the socket for an error condition
  172. unsigned int Err;
  173. unsigned int Len = sizeof(Err);
  174. if (getsockopt(Fd->Fd(), SOL_SOCKET, SO_ERROR, &Err, &Len) != 0)
  175. {
  176. _error->Errno("getsockopt", _("Failed"));
  177. return ResultState::FATAL_ERROR;
  178. }
  179. if (Err != 0)
  180. {
  181. errno = Err;
  182. if(errno == ECONNREFUSED)
  183. Owner->SetFailReason("ConnectionRefused");
  184. else if (errno == ETIMEDOUT)
  185. Owner->SetFailReason("ConnectionTimedOut");
  186. bad_addr.insert(bad_addr.begin(), std::string(Name));
  187. _error->Errno("connect", _("Could not connect to %s:%s (%s)."), Host.c_str(),
  188. Service, Name);
  189. return ResultState::TRANSIENT_ERROR;
  190. }
  191. Owner->SetFailReason("");
  192. return ResultState::SUCCESSFUL;
  193. }
  194. /*}}}*/
  195. // Order the given host names returned by getaddrinfo() /*{{{*/
  196. static std::vector<struct addrinfo *> OrderAddresses(struct addrinfo *CurHost)
  197. {
  198. std::vector<struct addrinfo *> preferredAddrs;
  199. std::vector<struct addrinfo *> otherAddrs;
  200. std::vector<struct addrinfo *> allAddrs;
  201. // Partition addresses into preferred and other address families
  202. while (CurHost != 0)
  203. {
  204. if (preferredAddrs.empty() || CurHost->ai_family == preferredAddrs[0]->ai_family)
  205. preferredAddrs.push_back(CurHost);
  206. else
  207. otherAddrs.push_back(CurHost);
  208. // Ignore UNIX domain sockets
  209. do
  210. {
  211. CurHost = CurHost->ai_next;
  212. } while (CurHost != 0 && CurHost->ai_family == AF_UNIX);
  213. /* If we reached the end of the search list then wrap around to the
  214. start */
  215. if (CurHost == 0 && LastUsed != 0)
  216. CurHost = LastHostAddr;
  217. // Reached the end of the search cycle
  218. if (CurHost == LastUsed)
  219. break;
  220. }
  221. // Build a new address vector alternating between preferred and other
  222. for (auto prefIter = preferredAddrs.cbegin(), otherIter = otherAddrs.cbegin();
  223. prefIter != preferredAddrs.end() || otherIter != otherAddrs.end();)
  224. {
  225. if (prefIter != preferredAddrs.end())
  226. allAddrs.push_back(*prefIter++);
  227. if (otherIter != otherAddrs.end())
  228. allAddrs.push_back(*otherIter++);
  229. }
  230. return std::move(allAddrs);
  231. }
  232. /*}}}*/
  233. // Check for errors and report them /*{{{*/
  234. static ResultState WaitAndCheckErrors(std::list<Connection> &Conns, std::unique_ptr<MethodFd> &Fd, long TimeoutMsec, bool ReportTimeout)
  235. {
  236. // The last error detected
  237. ResultState Result = ResultState::TRANSIENT_ERROR;
  238. struct timeval tv = {
  239. // Split our millisecond timeout into seconds and microseconds
  240. .tv_sec = TimeoutMsec / 1000,
  241. .tv_usec = (TimeoutMsec % 1000) * 1000,
  242. };
  243. // We will return once we have no more connections, a time out, or
  244. // a success.
  245. while (!Conns.empty())
  246. {
  247. fd_set Set;
  248. int nfds = -1;
  249. FD_ZERO(&Set);
  250. for (auto &Conn : Conns)
  251. {
  252. int fd = Conn.Fd->Fd();
  253. FD_SET(fd, &Set);
  254. nfds = std::max(nfds, fd);
  255. }
  256. {
  257. int Res;
  258. do
  259. {
  260. Res = select(nfds + 1, 0, &Set, 0, (TimeoutMsec != 0 ? &tv : 0));
  261. } while (Res < 0 && errno == EINTR);
  262. if (Res == 0)
  263. {
  264. if (ReportTimeout)
  265. {
  266. for (auto &Conn : Conns)
  267. {
  268. Conn.Owner->SetFailReason("Timeout");
  269. _error->Error(_("Could not connect to %s:%s (%s), "
  270. "connection timed out"),
  271. Conn.Host.c_str(), Conn.Service, Conn.Name);
  272. }
  273. }
  274. return ResultState::TRANSIENT_ERROR;
  275. }
  276. }
  277. // iterate over connections, remove failed ones, and return if
  278. // there was a successful one.
  279. for (auto ConnI = Conns.begin(); ConnI != Conns.end();)
  280. {
  281. if (!FD_ISSET(ConnI->Fd->Fd(), &Set))
  282. {
  283. ConnI++;
  284. continue;
  285. }
  286. Result = ConnI->CheckError();
  287. if (Result == ResultState::SUCCESSFUL)
  288. {
  289. Fd = ConnI->Take();
  290. return Result;
  291. }
  292. // Connection failed. Erase it and continue to next position
  293. ConnI = Conns.erase(ConnI);
  294. }
  295. }
  296. return Result;
  297. }
  298. /*}}}*/
  299. // Connect to a given Hostname /*{{{*/
  300. static ResultState ConnectToHostname(std::string const &Host, int const Port,
  301. const char *const Service, int DefPort, std::unique_ptr<MethodFd> &Fd,
  302. unsigned long const TimeOut, aptMethod *const Owner)
  303. {
  304. if (ConnectionAllowed(Service, Host) == false)
  305. return ResultState::FATAL_ERROR;
  306. // Convert the port name/number
  307. char ServStr[300];
  308. if (Port != 0)
  309. snprintf(ServStr,sizeof(ServStr),"%i", Port);
  310. else
  311. snprintf(ServStr,sizeof(ServStr),"%s", Service);
  312. /* We used a cached address record.. Yes this is against the spec but
  313. the way we have setup our rotating dns suggests that this is more
  314. sensible */
  315. if (LastHost != Host || LastPort != Port)
  316. {
  317. Owner->Status(_("Connecting to %s"),Host.c_str());
  318. // Free the old address structure
  319. if (LastHostAddr != 0)
  320. {
  321. freeaddrinfo(LastHostAddr);
  322. LastHostAddr = 0;
  323. LastUsed = 0;
  324. }
  325. // We only understand SOCK_STREAM sockets.
  326. struct addrinfo Hints;
  327. memset(&Hints,0,sizeof(Hints));
  328. Hints.ai_socktype = SOCK_STREAM;
  329. Hints.ai_flags = 0;
  330. #ifdef AI_IDN
  331. if (_config->FindB("Acquire::Connect::IDN", true) == true)
  332. Hints.ai_flags |= AI_IDN;
  333. #endif
  334. // see getaddrinfo(3): only return address if system has such a address configured
  335. // useful if system is ipv4 only, to not get ipv6, but that fails if the system has
  336. // no address configured: e.g. offline and trying to connect to localhost.
  337. if (_config->FindB("Acquire::Connect::AddrConfig", true) == true)
  338. Hints.ai_flags |= AI_ADDRCONFIG;
  339. Hints.ai_protocol = 0;
  340. if(_config->FindB("Acquire::ForceIPv4", false) == true)
  341. Hints.ai_family = AF_INET;
  342. else if(_config->FindB("Acquire::ForceIPv6", false) == true)
  343. Hints.ai_family = AF_INET6;
  344. else
  345. Hints.ai_family = AF_UNSPEC;
  346. // if we couldn't resolve the host before, we don't try now
  347. if (bad_addr.find(Host) != bad_addr.end())
  348. {
  349. _error->Error(_("Could not resolve '%s'"), Host.c_str());
  350. return ResultState::TRANSIENT_ERROR;
  351. }
  352. // Resolve both the host and service simultaneously
  353. while (1)
  354. {
  355. int Res;
  356. if ((Res = getaddrinfo(Host.c_str(),ServStr,&Hints,&LastHostAddr)) != 0 ||
  357. LastHostAddr == 0)
  358. {
  359. if (Res == EAI_NONAME || Res == EAI_SERVICE)
  360. {
  361. if (DefPort != 0)
  362. {
  363. snprintf(ServStr, sizeof(ServStr), "%i", DefPort);
  364. DefPort = 0;
  365. continue;
  366. }
  367. bad_addr.insert(bad_addr.begin(), Host);
  368. Owner->SetFailReason("ResolveFailure");
  369. _error->Error(_("Could not resolve '%s'"), Host.c_str());
  370. return ResultState::TRANSIENT_ERROR;
  371. }
  372. if (Res == EAI_AGAIN)
  373. {
  374. Owner->SetFailReason("TmpResolveFailure");
  375. _error->Error(_("Temporary failure resolving '%s'"),
  376. Host.c_str());
  377. return ResultState::TRANSIENT_ERROR;
  378. }
  379. if (Res == EAI_SYSTEM)
  380. _error->Errno("getaddrinfo", _("System error resolving '%s:%s'"),
  381. Host.c_str(), ServStr);
  382. else
  383. _error->Error(_("Something wicked happened resolving '%s:%s' (%i - %s)"),
  384. Host.c_str(), ServStr, Res, gai_strerror(Res));
  385. return ResultState::TRANSIENT_ERROR;
  386. }
  387. break;
  388. }
  389. LastHost = Host;
  390. LastPort = Port;
  391. }
  392. // When we have an IP rotation stay with the last IP.
  393. auto Addresses = OrderAddresses(LastUsed != nullptr ? LastUsed : LastHostAddr);
  394. std::list<Connection> Conns;
  395. ResultState Result = ResultState::SUCCESSFUL;
  396. for (auto Addr : Addresses)
  397. {
  398. Connection Conn(Addr, Host, Owner);
  399. if (Conn.DoConnect() != ResultState::SUCCESSFUL)
  400. continue;
  401. Conns.push_back(std::move(Conn));
  402. Result = WaitAndCheckErrors(Conns, Fd, Owner->ConfigFindI("ConnectionAttemptDelayMsec", 250), false);
  403. if (Result == ResultState::SUCCESSFUL)
  404. return ResultState::SUCCESSFUL;
  405. }
  406. if (!Conns.empty())
  407. return WaitAndCheckErrors(Conns, Fd, TimeOut * 1000, true);
  408. if (Result != ResultState::SUCCESSFUL)
  409. return Result;
  410. if (_error->PendingError() == true)
  411. return ResultState::FATAL_ERROR;
  412. _error->Error(_("Unable to connect to %s:%s:"), Host.c_str(), ServStr);
  413. return ResultState::TRANSIENT_ERROR;
  414. }
  415. /*}}}*/
  416. // Connect - Connect to a server /*{{{*/
  417. // ---------------------------------------------------------------------
  418. /* Performs a connection to the server (including SRV record lookup) */
  419. ResultState Connect(std::string Host, int Port, const char *Service,
  420. int DefPort, std::unique_ptr<MethodFd> &Fd,
  421. unsigned long TimeOut, aptMethod *Owner)
  422. {
  423. if (_error->PendingError() == true)
  424. return ResultState::FATAL_ERROR;
  425. if (ConnectionAllowed(Service, Host) == false)
  426. return ResultState::FATAL_ERROR;
  427. if(LastHost != Host || LastPort != Port)
  428. {
  429. SrvRecords.clear();
  430. if (_config->FindB("Acquire::EnableSrvRecords", true) == true)
  431. {
  432. GetSrvRecords(Host, DefPort, SrvRecords);
  433. // RFC2782 defines that a lonely '.' target is an abort reason
  434. if (SrvRecords.size() == 1 && SrvRecords[0].target.empty())
  435. {
  436. _error->Error("SRV records for %s indicate that "
  437. "%s service is not available at this domain",
  438. Host.c_str(), Service);
  439. return ResultState::FATAL_ERROR;
  440. }
  441. }
  442. }
  443. size_t stackSize = 0;
  444. // try to connect in the priority order of the srv records
  445. std::string initialHost{std::move(Host)};
  446. auto const initialPort = Port;
  447. while(SrvRecords.empty() == false)
  448. {
  449. _error->PushToStack();
  450. ++stackSize;
  451. // PopFromSrvRecs will also remove the server
  452. auto Srv = PopFromSrvRecs(SrvRecords);
  453. Host = Srv.target;
  454. Port = Srv.port;
  455. auto const ret = ConnectToHostname(Host, Port, Service, DefPort, Fd, TimeOut, Owner);
  456. if (ret == ResultState::SUCCESSFUL)
  457. {
  458. while(stackSize--)
  459. _error->RevertToStack();
  460. return ret;
  461. }
  462. }
  463. Host = std::move(initialHost);
  464. Port = initialPort;
  465. // we have no (good) SrvRecords for this host, connect right away
  466. _error->PushToStack();
  467. ++stackSize;
  468. auto const ret = ConnectToHostname(Host, Port, Service, DefPort, Fd,
  469. TimeOut, Owner);
  470. while(stackSize--)
  471. if (ret == ResultState::SUCCESSFUL)
  472. _error->RevertToStack();
  473. else
  474. _error->MergeWithStack();
  475. return ret;
  476. }
  477. /*}}}*/
  478. // UnwrapSocks - Handle SOCKS setup /*{{{*/
  479. // ---------------------------------------------------------------------
  480. /* This does socks magic */
  481. static bool TalkToSocksProxy(int const ServerFd, std::string const &Proxy,
  482. char const *const type, bool const ReadWrite, uint8_t *const ToFrom,
  483. unsigned int const Size, unsigned int const Timeout)
  484. {
  485. if (WaitFd(ServerFd, ReadWrite, Timeout) == false)
  486. {
  487. if (ReadWrite)
  488. return _error->Error("Timed out while waiting to write '%s' to proxy %s", type, URI::SiteOnly(Proxy).c_str());
  489. else
  490. return _error->Error("Timed out while waiting to read '%s' from proxy %s", type, URI::SiteOnly(Proxy).c_str());
  491. }
  492. if (ReadWrite == false)
  493. {
  494. if (FileFd::Read(ServerFd, ToFrom, Size) == false)
  495. return _error->Error("Reading the %s from SOCKS proxy %s failed", type, URI::SiteOnly(Proxy).c_str());
  496. }
  497. else
  498. {
  499. if (FileFd::Write(ServerFd, ToFrom, Size) == false)
  500. return _error->Error("Writing the %s to SOCKS proxy %s failed", type, URI::SiteOnly(Proxy).c_str());
  501. }
  502. return true;
  503. }
  504. ResultState UnwrapSocks(std::string Host, int Port, URI Proxy, std::unique_ptr<MethodFd> &Fd,
  505. unsigned long Timeout, aptMethod *Owner)
  506. {
  507. /* We implement a very basic SOCKS5 client here complying mostly to RFC1928 expect
  508. * for not offering GSSAPI auth which is a must (we only do no or user/pass auth).
  509. * We also expect the SOCKS5 server to do hostname lookup (aka socks5h) */
  510. std::string const ProxyInfo = URI::SiteOnly(Proxy);
  511. Owner->Status(_("Connecting to %s (%s)"), "SOCKS5h proxy", ProxyInfo.c_str());
  512. #define APT_WriteOrFail(TYPE, DATA, LENGTH) \
  513. if (TalkToSocksProxy(Fd->Fd(), ProxyInfo, TYPE, true, DATA, LENGTH, Timeout) == false) \
  514. return ResultState::TRANSIENT_ERROR
  515. #define APT_ReadOrFail(TYPE, DATA, LENGTH) \
  516. if (TalkToSocksProxy(Fd->Fd(), ProxyInfo, TYPE, false, DATA, LENGTH, Timeout) == false) \
  517. return ResultState::TRANSIENT_ERROR
  518. if (Host.length() > 255)
  519. {
  520. _error->Error("Can't use SOCKS5h as hostname %s is too long!", Host.c_str());
  521. return ResultState::FATAL_ERROR;
  522. }
  523. if (Proxy.User.length() > 255 || Proxy.Password.length() > 255)
  524. {
  525. _error->Error("Can't use user&pass auth as they are too long (%lu and %lu) for the SOCKS5!", Proxy.User.length(), Proxy.Password.length());
  526. return ResultState::FATAL_ERROR;
  527. }
  528. if (Proxy.User.empty())
  529. {
  530. uint8_t greeting[] = {0x05, 0x01, 0x00};
  531. APT_WriteOrFail("greet-1", greeting, sizeof(greeting));
  532. }
  533. else
  534. {
  535. uint8_t greeting[] = {0x05, 0x02, 0x00, 0x02};
  536. APT_WriteOrFail("greet-2", greeting, sizeof(greeting));
  537. }
  538. uint8_t greeting[2];
  539. APT_ReadOrFail("greet back", greeting, sizeof(greeting));
  540. if (greeting[0] != 0x05)
  541. {
  542. _error->Error("SOCKS proxy %s greets back with wrong version: %d", ProxyInfo.c_str(), greeting[0]);
  543. return ResultState::FATAL_ERROR;
  544. }
  545. if (greeting[1] == 0x00)
  546. ; // no auth has no method-dependent sub-negotiations
  547. else if (greeting[1] == 0x02)
  548. {
  549. if (Proxy.User.empty())
  550. {
  551. _error->Error("SOCKS proxy %s negotiated user&pass auth, but we had not offered it!", ProxyInfo.c_str());
  552. return ResultState::FATAL_ERROR;
  553. }
  554. // user&pass auth sub-negotiations are defined by RFC1929
  555. std::vector<uint8_t> auth = {{0x01, static_cast<uint8_t>(Proxy.User.length())}};
  556. std::copy(Proxy.User.begin(), Proxy.User.end(), std::back_inserter(auth));
  557. auth.push_back(static_cast<uint8_t>(Proxy.Password.length()));
  558. std::copy(Proxy.Password.begin(), Proxy.Password.end(), std::back_inserter(auth));
  559. APT_WriteOrFail("user&pass auth", auth.data(), auth.size());
  560. uint8_t authstatus[2];
  561. APT_ReadOrFail("auth report", authstatus, sizeof(authstatus));
  562. if (authstatus[0] != 0x01)
  563. {
  564. _error->Error("SOCKS proxy %s auth status response with wrong version: %d", ProxyInfo.c_str(), authstatus[0]);
  565. return ResultState::FATAL_ERROR;
  566. }
  567. if (authstatus[1] != 0x00)
  568. {
  569. _error->Error("SOCKS proxy %s reported authorization failure: username or password incorrect? (%d)", ProxyInfo.c_str(), authstatus[1]);
  570. return ResultState::FATAL_ERROR;
  571. }
  572. }
  573. else
  574. {
  575. _error->Error("SOCKS proxy %s greets back having not found a common authorization method: %d", ProxyInfo.c_str(), greeting[1]);
  576. return ResultState::FATAL_ERROR;
  577. }
  578. union {
  579. uint16_t *i;
  580. uint8_t *b;
  581. } portu;
  582. uint16_t port = htons(static_cast<uint16_t>(Port));
  583. portu.i = &port;
  584. std::vector<uint8_t> request = {{0x05, 0x01, 0x00, 0x03, static_cast<uint8_t>(Host.length())}};
  585. std::copy(Host.begin(), Host.end(), std::back_inserter(request));
  586. request.push_back(portu.b[0]);
  587. request.push_back(portu.b[1]);
  588. APT_WriteOrFail("request", request.data(), request.size());
  589. uint8_t response[4];
  590. APT_ReadOrFail("first part of response", response, sizeof(response));
  591. if (response[0] != 0x05)
  592. {
  593. _error->Error("SOCKS proxy %s response with wrong version: %d", ProxyInfo.c_str(), response[0]);
  594. return ResultState::FATAL_ERROR;
  595. }
  596. if (response[2] != 0x00)
  597. {
  598. _error->Error("SOCKS proxy %s has unexpected non-zero reserved field value: %d", ProxyInfo.c_str(), response[2]);
  599. return ResultState::FATAL_ERROR;
  600. }
  601. std::string bindaddr;
  602. if (response[3] == 0x01) // IPv4 address
  603. {
  604. uint8_t ip4port[6];
  605. APT_ReadOrFail("IPv4+Port of response", ip4port, sizeof(ip4port));
  606. portu.b[0] = ip4port[4];
  607. portu.b[1] = ip4port[5];
  608. port = ntohs(*portu.i);
  609. strprintf(bindaddr, "%d.%d.%d.%d:%d", ip4port[0], ip4port[1], ip4port[2], ip4port[3], port);
  610. }
  611. else if (response[3] == 0x03) // hostname
  612. {
  613. uint8_t namelength;
  614. APT_ReadOrFail("hostname length of response", &namelength, 1);
  615. uint8_t hostname[namelength + 2];
  616. APT_ReadOrFail("hostname of response", hostname, sizeof(hostname));
  617. portu.b[0] = hostname[namelength];
  618. portu.b[1] = hostname[namelength + 1];
  619. port = ntohs(*portu.i);
  620. hostname[namelength] = '\0';
  621. strprintf(bindaddr, "%s:%d", hostname, port);
  622. }
  623. else if (response[3] == 0x04) // IPv6 address
  624. {
  625. uint8_t ip6port[18];
  626. APT_ReadOrFail("IPv6+port of response", ip6port, sizeof(ip6port));
  627. portu.b[0] = ip6port[16];
  628. portu.b[1] = ip6port[17];
  629. port = ntohs(*portu.i);
  630. strprintf(bindaddr, "[%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X]:%d",
  631. ip6port[0], ip6port[1], ip6port[2], ip6port[3], ip6port[4], ip6port[5], ip6port[6], ip6port[7],
  632. ip6port[8], ip6port[9], ip6port[10], ip6port[11], ip6port[12], ip6port[13], ip6port[14], ip6port[15],
  633. port);
  634. }
  635. else
  636. {
  637. _error->Error("SOCKS proxy %s destination address is of unknown type: %d",
  638. ProxyInfo.c_str(), response[3]);
  639. return ResultState::FATAL_ERROR;
  640. }
  641. if (response[1] != 0x00)
  642. {
  643. char const *errstr = nullptr;
  644. auto errcode = response[1];
  645. bool Transient = false;
  646. // Tor error reporting can be a bit arcane, lets try to detect & fix it up
  647. if (bindaddr == "0.0.0.0:0")
  648. {
  649. auto const lastdot = Host.rfind('.');
  650. if (lastdot == std::string::npos || Host.substr(lastdot) != ".onion")
  651. ;
  652. else if (errcode == 0x01)
  653. {
  654. auto const prevdot = Host.rfind('.', lastdot - 1);
  655. if (prevdot == std::string::npos && (lastdot == 16 || lastdot == 56))
  656. ; // valid .onion address
  657. else if (prevdot != std::string::npos && ((lastdot - prevdot) == 17 || (lastdot - prevdot) == 57))
  658. ; // valid .onion address with subdomain(s)
  659. else
  660. {
  661. errstr = "Invalid hostname: onion service name must be either 16 or 56 characters long";
  662. Owner->SetFailReason("SOCKS");
  663. }
  664. }
  665. // in all likelihood the service is either down or the address has
  666. // a typo and so "Host unreachable" is the better understood error
  667. // compared to the technically correct "TLL expired".
  668. else if (errcode == 0x06)
  669. errcode = 0x04;
  670. }
  671. if (errstr == nullptr)
  672. {
  673. switch (errcode)
  674. {
  675. case 0x01:
  676. errstr = "general SOCKS server failure";
  677. Owner->SetFailReason("SOCKS");
  678. break;
  679. case 0x02:
  680. errstr = "connection not allowed by ruleset";
  681. Owner->SetFailReason("SOCKS");
  682. break;
  683. case 0x03:
  684. errstr = "Network unreachable";
  685. Owner->SetFailReason("ConnectionTimedOut");
  686. Transient = true;
  687. break;
  688. case 0x04:
  689. errstr = "Host unreachable";
  690. Owner->SetFailReason("ConnectionTimedOut");
  691. Transient = true;
  692. break;
  693. case 0x05:
  694. errstr = "Connection refused";
  695. Owner->SetFailReason("ConnectionRefused");
  696. Transient = true;
  697. break;
  698. case 0x06:
  699. errstr = "TTL expired";
  700. Owner->SetFailReason("Timeout");
  701. Transient = true;
  702. break;
  703. case 0x07:
  704. errstr = "Command not supported";
  705. Owner->SetFailReason("SOCKS");
  706. break;
  707. case 0x08:
  708. errstr = "Address type not supported";
  709. Owner->SetFailReason("SOCKS");
  710. break;
  711. default:
  712. errstr = "Unknown error";
  713. Owner->SetFailReason("SOCKS");
  714. break;
  715. }
  716. }
  717. _error->Error("SOCKS proxy %s could not connect to %s (%s) due to: %s (%d)",
  718. ProxyInfo.c_str(), Host.c_str(), bindaddr.c_str(), errstr, response[1]);
  719. return Transient ? ResultState::TRANSIENT_ERROR : ResultState::FATAL_ERROR;
  720. }
  721. else if (Owner->DebugEnabled())
  722. ioprintf(std::clog, "http: SOCKS proxy %s connection established to %s (%s)\n",
  723. ProxyInfo.c_str(), Host.c_str(), bindaddr.c_str());
  724. if (WaitFd(Fd->Fd(), true, Timeout) == false)
  725. {
  726. _error->Error("SOCKS proxy %s reported connection to %s (%s), but timed out",
  727. ProxyInfo.c_str(), Host.c_str(), bindaddr.c_str());
  728. return ResultState::TRANSIENT_ERROR;
  729. }
  730. #undef APT_ReadOrFail
  731. #undef APT_WriteOrFail
  732. return ResultState::SUCCESSFUL;
  733. }
  734. /*}}}*/
  735. // UnwrapTLS - Handle TLS connections /*{{{*/
  736. // ---------------------------------------------------------------------
  737. /* Performs a TLS handshake on the socket */
  738. struct TlsFd : public MethodFd
  739. {
  740. std::unique_ptr<MethodFd> UnderlyingFd;
  741. gnutls_session_t session;
  742. gnutls_certificate_credentials_t credentials;
  743. std::string hostname;
  744. int Fd() APT_OVERRIDE { return UnderlyingFd->Fd(); }
  745. ssize_t Read(void *buf, size_t count) APT_OVERRIDE
  746. {
  747. return HandleError(gnutls_record_recv(session, buf, count));
  748. }
  749. ssize_t Write(void *buf, size_t count) APT_OVERRIDE
  750. {
  751. return HandleError(gnutls_record_send(session, buf, count));
  752. }
  753. template <typename T>
  754. T HandleError(T err)
  755. {
  756. if (err < 0 && gnutls_error_is_fatal(err))
  757. errno = EIO;
  758. else if (err < 0)
  759. errno = EAGAIN;
  760. else
  761. errno = 0;
  762. return err;
  763. }
  764. int Close() APT_OVERRIDE
  765. {
  766. auto err = HandleError(gnutls_bye(session, GNUTLS_SHUT_RDWR));
  767. auto lower = UnderlyingFd->Close();
  768. return err < 0 ? HandleError(err) : lower;
  769. }
  770. bool HasPending() APT_OVERRIDE
  771. {
  772. return gnutls_record_check_pending(session) > 0;
  773. }
  774. };
  775. ResultState UnwrapTLS(std::string Host, std::unique_ptr<MethodFd> &Fd,
  776. unsigned long Timeout, aptMethod *Owner)
  777. {
  778. if (_config->FindB("Acquire::AllowTLS", true) == false)
  779. {
  780. _error->Error("TLS support has been disabled: Acquire::AllowTLS is false.");
  781. return ResultState::FATAL_ERROR;
  782. }
  783. int err;
  784. TlsFd *tlsFd = new TlsFd();
  785. tlsFd->hostname = Host;
  786. tlsFd->UnderlyingFd = MethodFd::FromFd(-1); // For now
  787. if ((err = gnutls_init(&tlsFd->session, GNUTLS_CLIENT | GNUTLS_NONBLOCK)) < 0)
  788. {
  789. _error->Error("Internal error: could not allocate credentials: %s", gnutls_strerror(err));
  790. return ResultState::FATAL_ERROR;
  791. }
  792. FdFd *fdfd = dynamic_cast<FdFd *>(Fd.get());
  793. if (fdfd != nullptr)
  794. {
  795. gnutls_transport_set_int(tlsFd->session, fdfd->fd);
  796. }
  797. else
  798. {
  799. gnutls_transport_set_ptr(tlsFd->session, Fd.get());
  800. gnutls_transport_set_pull_function(tlsFd->session,
  801. [](gnutls_transport_ptr_t p, void *buf, size_t size) -> ssize_t {
  802. return reinterpret_cast<MethodFd *>(p)->Read(buf, size);
  803. });
  804. gnutls_transport_set_push_function(tlsFd->session,
  805. [](gnutls_transport_ptr_t p, const void *buf, size_t size) -> ssize_t {
  806. return reinterpret_cast<MethodFd *>(p)->Write((void *)buf, size);
  807. });
  808. }
  809. if ((err = gnutls_certificate_allocate_credentials(&tlsFd->credentials)) < 0)
  810. {
  811. _error->Error("Internal error: could not allocate credentials: %s", gnutls_strerror(err));
  812. return ResultState::FATAL_ERROR;
  813. }
  814. // Credential setup
  815. std::string fileinfo = Owner->ConfigFind("CaInfo", "");
  816. if (fileinfo.empty())
  817. {
  818. // No CaInfo specified, use system trust store.
  819. err = gnutls_certificate_set_x509_system_trust(tlsFd->credentials);
  820. if (err == 0)
  821. Owner->Warning("No system certificates available. Try installing ca-certificates.");
  822. else if (err < 0)
  823. {
  824. _error->Error("Could not load system TLS certificates: %s", gnutls_strerror(err));
  825. return ResultState::FATAL_ERROR;
  826. }
  827. }
  828. else
  829. {
  830. // CA location has been set, use the specified one instead
  831. gnutls_certificate_set_verify_flags(tlsFd->credentials, GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
  832. err = gnutls_certificate_set_x509_trust_file(tlsFd->credentials, fileinfo.c_str(), GNUTLS_X509_FMT_PEM);
  833. if (err < 0)
  834. {
  835. _error->Error("Could not load certificates from %s (CaInfo option): %s", fileinfo.c_str(), gnutls_strerror(err));
  836. return ResultState::FATAL_ERROR;
  837. }
  838. }
  839. if (!Owner->ConfigFind("IssuerCert", "").empty())
  840. {
  841. _error->Error("The option '%s' is not supported anymore", "IssuerCert");
  842. return ResultState::FATAL_ERROR;
  843. }
  844. if (!Owner->ConfigFind("SslForceVersion", "").empty())
  845. {
  846. _error->Error("The option '%s' is not supported anymore", "SslForceVersion");
  847. return ResultState::FATAL_ERROR;
  848. }
  849. // For client authentication, certificate file ...
  850. std::string const cert = Owner->ConfigFind("SslCert", "");
  851. std::string const key = Owner->ConfigFind("SslKey", "");
  852. if (cert.empty() == false)
  853. {
  854. if ((err = gnutls_certificate_set_x509_key_file(
  855. tlsFd->credentials,
  856. cert.c_str(),
  857. key.empty() ? cert.c_str() : key.c_str(),
  858. GNUTLS_X509_FMT_PEM)) < 0)
  859. {
  860. _error->Error("Could not load client certificate (%s, SslCert option) or key (%s, SslKey option): %s", cert.c_str(), key.c_str(), gnutls_strerror(err));
  861. return ResultState::FATAL_ERROR;
  862. }
  863. }
  864. // CRL file
  865. std::string const crlfile = Owner->ConfigFind("CrlFile", "");
  866. if (crlfile.empty() == false)
  867. {
  868. if ((err = gnutls_certificate_set_x509_crl_file(tlsFd->credentials,
  869. crlfile.c_str(),
  870. GNUTLS_X509_FMT_PEM)) < 0)
  871. {
  872. _error->Error("Could not load custom certificate revocation list %s (CrlFile option): %s", crlfile.c_str(), gnutls_strerror(err));
  873. return ResultState::FATAL_ERROR;
  874. }
  875. }
  876. if ((err = gnutls_credentials_set(tlsFd->session, GNUTLS_CRD_CERTIFICATE, tlsFd->credentials)) < 0)
  877. {
  878. _error->Error("Internal error: Could not add certificates to session: %s", gnutls_strerror(err));
  879. return ResultState::FATAL_ERROR;
  880. }
  881. if ((err = gnutls_set_default_priority(tlsFd->session)) < 0)
  882. {
  883. _error->Error("Internal error: Could not set algorithm preferences: %s", gnutls_strerror(err));
  884. return ResultState::FATAL_ERROR;
  885. }
  886. if (Owner->ConfigFindB("Verify-Peer", true))
  887. {
  888. gnutls_session_set_verify_cert(tlsFd->session, Owner->ConfigFindB("Verify-Host", true) ? tlsFd->hostname.c_str() : nullptr, 0);
  889. }
  890. // set SNI only if the hostname is really a name and not an address
  891. {
  892. struct in_addr addr4;
  893. struct in6_addr addr6;
  894. if (inet_pton(AF_INET, tlsFd->hostname.c_str(), &addr4) == 1 ||
  895. inet_pton(AF_INET6, tlsFd->hostname.c_str(), &addr6) == 1)
  896. /* not a host name */;
  897. else if ((err = gnutls_server_name_set(tlsFd->session, GNUTLS_NAME_DNS, tlsFd->hostname.c_str(), tlsFd->hostname.length())) < 0)
  898. {
  899. _error->Error("Could not set host name %s to indicate to server: %s", tlsFd->hostname.c_str(), gnutls_strerror(err));
  900. return ResultState::FATAL_ERROR;
  901. }
  902. }
  903. // Set the FD now, so closing it works reliably.
  904. tlsFd->UnderlyingFd = std::move(Fd);
  905. Fd.reset(tlsFd);
  906. // Do the handshake. Our socket is non-blocking, so we need to call WaitFd()
  907. // accordingly.
  908. do
  909. {
  910. err = gnutls_handshake(tlsFd->session);
  911. if ((err == GNUTLS_E_INTERRUPTED || err == GNUTLS_E_AGAIN) &&
  912. WaitFd(Fd->Fd(), gnutls_record_get_direction(tlsFd->session) == 1, Timeout) == false)
  913. {
  914. _error->Errno("select", "Could not wait for server fd");
  915. return ResultState::TRANSIENT_ERROR;
  916. }
  917. } while (err < 0 && gnutls_error_is_fatal(err) == 0);
  918. if (err < 0)
  919. {
  920. // Print reason why validation failed.
  921. if (err == GNUTLS_E_CERTIFICATE_VERIFICATION_ERROR)
  922. {
  923. gnutls_datum_t txt;
  924. auto type = gnutls_certificate_type_get(tlsFd->session);
  925. auto status = gnutls_session_get_verify_cert_status(tlsFd->session);
  926. if (gnutls_certificate_verification_status_print(status,
  927. type, &txt, 0) == 0)
  928. {
  929. _error->Error("Certificate verification failed: %s", txt.data);
  930. }
  931. gnutls_free(txt.data);
  932. }
  933. _error->Error("Could not handshake: %s", gnutls_strerror(err));
  934. return ResultState::FATAL_ERROR;
  935. }
  936. return ResultState::SUCCESSFUL;
  937. }
  938. /*}}}*/