summaryrefslogtreecommitdiff
path: root/apt-pkg/contrib/gpgv.cc
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg/contrib/gpgv.cc')
-rw-r--r--apt-pkg/contrib/gpgv.cc50
1 files changed, 46 insertions, 4 deletions
diff --git a/apt-pkg/contrib/gpgv.cc b/apt-pkg/contrib/gpgv.cc
index cdf1e7f42..d4ccf47c7 100644
--- a/apt-pkg/contrib/gpgv.cc
+++ b/apt-pkg/contrib/gpgv.cc
@@ -146,7 +146,6 @@ void ExecGPGV(std::string const &File, std::string const &FileGPG,
}
enum { DETACHED, CLEARSIGNED } releaseSignature = (FileGPG != File) ? DETACHED : CLEARSIGNED;
- std::vector<std::string> dataHeader;
char * sig = NULL;
char * data = NULL;
char * conf = nullptr;
@@ -205,7 +204,7 @@ void ExecGPGV(std::string const &File, std::string const &FileGPG,
message.OpenDescriptor(dataFd, FileFd::WriteOnly, true);
if (signature.Failed() == true || message.Failed() == true ||
- SplitClearSignedFile(File, &message, &dataHeader, &signature) == false)
+ SplitClearSignedFile(File, &message, nullptr, &signature) == false)
{
apt_error(std::cerr, statusfd, fd, "Splitting up %s into data and signature failed", File.c_str());
local_exit(112);
@@ -304,6 +303,20 @@ void ExecGPGV(std::string const &File, std::string const &FileGPG,
}
/*}}}*/
// SplitClearSignedFile - split message into data/signature /*{{{*/
+static int GetLineErrno(char **lineptr, size_t *n, FILE *stream, std::string const &InFile)
+{
+ int result;
+
+ errno = 0;
+ result = getline(lineptr, n, stream);
+ if (errno != 0)
+ {
+ _error->Errno("getline", "Could not read from %s", InFile.c_str());
+ return -1;
+ }
+
+ return result;
+}
bool SplitClearSignedFile(std::string const &InFile, FileFd * const ContentFile,
std::vector<std::string> * const ContentHeader, FileFd * const SignatureFile)
{
@@ -316,10 +329,13 @@ bool SplitClearSignedFile(std::string const &InFile, FileFd * const ContentFile,
bool skip_until_empty_line = false;
bool found_signature = false;
bool first_line = true;
+ bool signed_message_not_on_first_line = false;
+ bool found_garbage = false;
char *buf = NULL;
size_t buf_size = 0;
- while (getline(&buf, &buf_size, in) != -1)
+ _error->PushToStack();
+ while (GetLineErrno(&buf, &buf_size, in, InFile) != -1)
{
_strrstrip(buf);
if (found_message_start == false)
@@ -329,6 +345,8 @@ bool SplitClearSignedFile(std::string const &InFile, FileFd * const ContentFile,
found_message_start = true;
skip_until_empty_line = true;
}
+ else
+ signed_message_not_on_first_line = found_garbage = true;
}
else if (skip_until_empty_line == true)
{
@@ -366,6 +384,8 @@ bool SplitClearSignedFile(std::string const &InFile, FileFd * const ContentFile,
if (ContentFile != NULL)
ContentFile->Write(dashfree, strlen(dashfree));
}
+ else
+ found_garbage = true;
}
else if (found_signature == true)
{
@@ -378,11 +398,33 @@ bool SplitClearSignedFile(std::string const &InFile, FileFd * const ContentFile,
found_signature = false; // look for other signatures
}
// all the rest is whitespace, unsigned garbage or additional message blocks we ignore
+ else
+ found_garbage = true;
}
fclose(in);
if (buf != NULL)
free(buf);
+ // Flush the files. Errors will be checked below.
+ if (SignatureFile != nullptr)
+ SignatureFile->Flush();
+ if (ContentFile != nullptr)
+ ContentFile->Flush();
+
+ if (found_message_start)
+ {
+ if (signed_message_not_on_first_line)
+ _error->Warning("Clearsigned file '%s' does not start with a signed message block.", InFile.c_str());
+ else if (found_garbage)
+ _error->Warning("Clearsigned file '%s' contains unsigned lines.", InFile.c_str());
+ }
+
+ // An error occurred during reading - propagate it up
+ bool const hasErrored = _error->PendingError();
+ _error->MergeWithStack();
+ if (hasErrored)
+ return false;
+
if (found_signature == true)
return _error->Error("Signature in file %s wasn't closed", InFile.c_str());
@@ -406,7 +448,7 @@ bool OpenMaybeClearSignedFile(std::string const &ClearSignedFileName, FileFd &Me
free(message);
return _error->Errno("mkstemp", "Couldn't create temporary file to work with %s", ClearSignedFileName.c_str());
}
- // we have the fd, thats enough for us
+ // we have the fd, that's enough for us
unlink(message);
free(message);