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