gpgv.cc 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. // -*- mode: cpp; mode: fold -*-
  2. // Include Files /*{{{*/
  3. #include<config.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <sys/stat.h>
  7. #include <sys/types.h>
  8. #include <fcntl.h>
  9. #include <vector>
  10. #include <apt-pkg/error.h>
  11. #include <apt-pkg/strutl.h>
  12. #include <apt-pkg/fileutl.h>
  13. #include <apt-pkg/configuration.h>
  14. #include <apti18n.h>
  15. /*}}}*/
  16. using namespace std;
  17. // RunGPGV - returns the command needed for verify /*{{{*/
  18. // ---------------------------------------------------------------------
  19. /* Generating the commandline for calling gpgv is somehow complicated as
  20. we need to add multiple keyrings and user supplied options. */
  21. void ExecGPGV(std::string const &File, std::string const &FileGPG,
  22. int const &statusfd, int fd[2])
  23. {
  24. #define EINTERNAL 111
  25. if (File == FileGPG)
  26. {
  27. #define SIGMSG "-----BEGIN PGP SIGNED MESSAGE-----\n"
  28. char buffer[sizeof(SIGMSG)];
  29. FILE* gpg = fopen(File.c_str(), "r");
  30. if (gpg == NULL)
  31. {
  32. ioprintf(std::cerr, _("Could not open file %s"), File.c_str());
  33. exit(EINTERNAL);
  34. }
  35. char const * const test = fgets(buffer, sizeof(buffer), gpg);
  36. fclose(gpg);
  37. if (test == NULL || strcmp(buffer, SIGMSG) != 0)
  38. {
  39. ioprintf(std::cerr, _("File %s doesn't start with a clearsigned message"), File.c_str());
  40. exit(EINTERNAL);
  41. }
  42. #undef SIGMSG
  43. }
  44. string const gpgvpath = _config->Find("Dir::Bin::gpg", "/usr/bin/gpgv");
  45. // FIXME: remove support for deprecated APT::GPGV setting
  46. string const trustedFile = _config->Find("APT::GPGV::TrustedKeyring", _config->FindFile("Dir::Etc::Trusted"));
  47. string const trustedPath = _config->FindDir("Dir::Etc::TrustedParts");
  48. bool const Debug = _config->FindB("Debug::Acquire::gpgv", false);
  49. if (Debug == true)
  50. {
  51. std::clog << "gpgv path: " << gpgvpath << std::endl;
  52. std::clog << "Keyring file: " << trustedFile << std::endl;
  53. std::clog << "Keyring path: " << trustedPath << std::endl;
  54. }
  55. std::vector<string> keyrings;
  56. if (DirectoryExists(trustedPath))
  57. keyrings = GetListOfFilesInDir(trustedPath, "gpg", false, true);
  58. if (RealFileExists(trustedFile) == true)
  59. keyrings.push_back(trustedFile);
  60. std::vector<const char *> Args;
  61. Args.reserve(30);
  62. if (keyrings.empty() == true)
  63. {
  64. // TRANSLATOR: %s is the trusted keyring parts directory
  65. ioprintf(std::cerr, _("No keyring installed in %s."),
  66. _config->FindDir("Dir::Etc::TrustedParts").c_str());
  67. exit(EINTERNAL);
  68. }
  69. Args.push_back(gpgvpath.c_str());
  70. Args.push_back("--ignore-time-conflict");
  71. char statusfdstr[10];
  72. if (statusfd != -1)
  73. {
  74. Args.push_back("--status-fd");
  75. snprintf(statusfdstr, sizeof(fd), "%i", statusfd);
  76. Args.push_back(statusfdstr);
  77. }
  78. for (vector<string>::const_iterator K = keyrings.begin();
  79. K != keyrings.end(); ++K)
  80. {
  81. Args.push_back("--keyring");
  82. Args.push_back(K->c_str());
  83. }
  84. Configuration::Item const *Opts;
  85. Opts = _config->Tree("Acquire::gpgv::Options");
  86. if (Opts != 0)
  87. {
  88. Opts = Opts->Child;
  89. for (; Opts != 0; Opts = Opts->Next)
  90. {
  91. if (Opts->Value.empty() == true)
  92. continue;
  93. Args.push_back(Opts->Value.c_str());
  94. }
  95. }
  96. Args.push_back(FileGPG.c_str());
  97. if (FileGPG != File)
  98. Args.push_back(File.c_str());
  99. Args.push_back(NULL);
  100. if (Debug == true)
  101. {
  102. std::clog << "Preparing to exec: " << gpgvpath;
  103. for (std::vector<const char *>::const_iterator a = Args.begin(); *a != NULL; ++a)
  104. std::clog << " " << *a;
  105. std::clog << std::endl;
  106. }
  107. if (statusfd != -1)
  108. {
  109. int const nullfd = open("/dev/null", O_RDONLY);
  110. close(fd[0]);
  111. // Redirect output to /dev/null; we read from the status fd
  112. if (statusfd != STDOUT_FILENO)
  113. dup2(nullfd, STDOUT_FILENO);
  114. if (statusfd != STDERR_FILENO)
  115. dup2(nullfd, STDERR_FILENO);
  116. // Redirect the pipe to the status fd (3)
  117. dup2(fd[1], statusfd);
  118. putenv((char *)"LANG=");
  119. putenv((char *)"LC_ALL=");
  120. putenv((char *)"LC_MESSAGES=");
  121. }
  122. execvp(gpgvpath.c_str(), (char **) &Args[0]);
  123. ioprintf(std::cerr, "Couldn't execute %s to check %s", Args[0], File.c_str());
  124. exit(EINTERNAL);
  125. }
  126. /*}}}*/