summaryrefslogtreecommitdiff
path: root/gpg-interface.c
AgeCommit message (Collapse)AuthorFilesLines
2016-06-17gpg-interface: check gpg signature creation statusLibravatar Michael J Gruber1-2/+6
When we create a signature, it may happen that gpg returns with "success" but not with an actual detached signature on stdout. Check for the correct signature creation status to catch these cases better. Really, --status-fd parsing is the only way to check gpg status reliably. We do the same for verify already. Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net> Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-06-17sign_buffer: use pipe_commandLibravatar Jeff King1-19/+5
Similar to the prior commit for verify_signed_buffer, the motivation here is both to make the code simpler, and to avoid any possible deadlocks with gpg. In this case we have the same "write to stdin, then read from stdout" that the verify case had. This is unlikely to be a problem in practice, since stdout has the detached signature, which it cannot compute until it has read all of stdin (if it were a non-detached signature, that would be a problem, though). We don't read from stderr at all currently. However, we will want to in a future patch, so this also prepares us there (and in that case gpg _does_ write before reading all of the input, though again, it is unlikely that a key uid will fill up a pipe buffer). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-06-17verify_signed_buffer: use pipe_commandLibravatar Jeff King1-19/+3
This is shorter and should make the function easier to follow. But more importantly, it removes the possibility of any deadlocks based on reading or writing to gpg. It's not clear if such a deadlock is possible in practice. We do write the whole payload before reading anything, so we could deadlock there. However, in practice gpg will need to read our whole input to verify the signature, so it will drain our payload first. It could write an error to stderr before reading, but it's unlikely that such an error wouldn't be followed by it immediately exiting, or that the error would actually be larger than a pipe buffer. On the writing side, we drain stderr (with the human-readable output) in its entirety before reading stdout (with the status-fd data). Running strace on "gpg --verify" does show interleaved output on the two descriptors: write(2, "gpg: ", 5) = 5 write(2, "Signature made Thu 16 Jun 2016 0"..., 73) = 73 write(1, "[GNUPG:] SIG_ID tQw8KGcs9rBfLvAj"..., 66) = 66 write(1, "[GNUPG:] GOODSIG 69808639F9430ED"..., 60) = 60 write(2, "gpg: ", 5) = 5 write(2, "Good signature from \"Jeff King <"..., 47) = 47 write(2, "\n", 1) = 1 write(2, "gpg: ", 5) = 5 write(2, " aka \"Jeff King <"..., 49) = 49 write(2, "\n", 1) = 1 write(1, "[GNUPG:] VALIDSIG C49CE24156AF08"..., 135) = 135 write(1, "[GNUPG:] TRUST_ULTIMATE\n", 24) = 24 The second line written to stdout there contains the signer's UID, which can be arbitrarily long. If it fills the pipe buffer, then gpg would block writing to its stdout, while we are blocked trying to read its stderr. In practice, GPG seems to limit UIDs to 2048 bytes, so unless your pipe buffer size is quite small, or unless gpg does not enforce the limit under some conditions, this seems unlikely in practice. Still, it is not hard for us to be cautious and just use pipe_command. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-06-17verify_signed_buffer: use tempfile objectLibravatar Jeff King1-8/+13
We use git_mkstemp to create a temporary file, and try to clean it up in all exit paths from the function. But that misses any cases where we die by signal, or by calling die() in a sub-function. In addition, we missed one of the exit paths. Let's convert to using a tempfile object, which handles the hard cases for us, and add the missing cleanup call. Note that we would not simply want to rely on program exit to catch our missed cleanup, as this function may be called many times in a single program (for the same reason, we use a static tempfile instead of heap-allocating a new one; that gives an upper bound on our memory usage). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-06-17verify_signed_buffer: drop pbuf variableLibravatar Jeff King1-5/+4
If our caller gave us a non-NULL gpg_status parameter, we write the gpg status into their strbuf. If they didn't, then we write it to a temporary local strbuf (since we still need to look at it). The variable "pbuf" adds an extra layer of indirection so that the rest of the function can just access whichever is appropriate. However, the name "pbuf" isn't very descriptive, and it's easy to get confused about what is supposed to be in it (especially because we are reading both "status" and "output" from gpg). Rather than give it a more descriptive name, we can just use gpg_status as our indirection pointer. Either it points to the caller's input, or we can point it directly to our temporary buffer. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-06-17gpg-interface: use child_process.argsLibravatar Jeff King1-10/+9
Our argv allocations are relatively straightforward, but this avoids us having to manually keep the count up to date (or create new to-be-replaced slots in the declaration) when we add new arguments. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-05-17Merge branch 'nd/error-errno'Libravatar Junio C Hamano1-4/+2
The code for warning_errno/die_errno has been refactored and a new error_errno() reporting helper is introduced. * nd/error-errno: (41 commits) wrapper.c: use warning_errno() vcs-svn: use error_errno() upload-pack.c: use error_errno() unpack-trees.c: use error_errno() transport-helper.c: use error_errno() sha1_file.c: use {error,die,warning}_errno() server-info.c: use error_errno() sequencer.c: use error_errno() run-command.c: use error_errno() rerere.c: use error_errno() and warning_errno() reachable.c: use error_errno() mailmap.c: use error_errno() ident.c: use warning_errno() http.c: use error_errno() and warning_errno() grep.c: use error_errno() gpg-interface.c: use error_errno() fast-import.c: use error_errno() entry.c: use error_errno() editor.c: use error_errno() diff-no-index.c: use error_errno() ...
2016-05-09gpg-interface.c: use error_errno()Libravatar Nguyễn Thái Ngọc Duy1-4/+2
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-04-06builtin/verify-tag.c: ignore SIGPIPE in gpg-interfaceLibravatar Santiago Torres1-0/+2
The verify_signed_buffer() function may trigger a SIGPIPE when the GPG child process terminates early (due to a bad keyid, for example) and Git tries to write to it afterwards. Previously, ignoring SIGPIPE was done in builtin/verify-tag.c to avoid this issue. However, any other caller who wants to call verify_signed_buffer() would have to do the same. Use sigchain_push(SIGPIPE, SIG_IGN) in verify_signed_buffer(), pretty much like in sign_buffer(), so that any caller is not required to perform this task. This will avoid possible mistakes by further developers using verify_signed_buffer(). Signed-off-by: Santiago Torres <santiago@nyu.edu> Reviewed-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-22verify-commit: add option to print raw gpg status informationLibravatar brian m. carlson1-2/+5
verify-commit by default displays human-readable output on standard error. However, it can also be useful to get access to the raw gpg status information, which is machine-readable, allowing automated implementation of signing policy. Add a --raw option to make verify-commit produce the gpg status information on standard error instead of the human-readable format. Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-22gpg: centralize printing signature buffersLibravatar brian m. carlson1-0/+9
The code to handle printing of signature data from a struct signature_check is very similar between verify-commit and verify-tag. Place this in a single function. verify-tag retains its special case behavior of printing the tag even when no valid signature is found. Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-22gpg: centralize signature checkLibravatar brian m. carlson1-1/+3
verify-commit and verify-tag both share a central codepath for verifying commits: check_signature. However, verify-tag exited successfully for untrusted signature, while verify-commit exited unsuccessfully. Centralize this signature check and make verify-commit adopt the older verify-tag behavior. This behavior is more logical anyway, as the signature is in fact valid, whether or not there's a path of trust to the author. Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-22verify-tag: share code with verify-commitLibravatar brian m. carlson1-0/+23
verify-tag was executing an entirely different codepath than verify-commit, except for the underlying verify_signed_buffer. Move much of the code from check_commit_signature to a generic check_signature function and adjust both codepaths to call it. Update verify-tag to explicitly output the signature text, as we now call verify_signed_buffer with strbufs to catch the output, which prevents it from being printed automatically. Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-10-08Merge branch 'jc/push-cert'Libravatar Junio C Hamano1-0/+57
Allow "git push" request to be signed, so that it can be verified and audited, using the GPG signature of the person who pushed, that the tips of branches at a public repository really point the commits the pusher wanted to, without having to "trust" the server. * jc/push-cert: (24 commits) receive-pack::hmac_sha1(): copy the entire SHA-1 hash out signed push: allow stale nonce in stateless mode signed push: teach smart-HTTP to pass "git push --signed" around signed push: fortify against replay attacks signed push: add "pushee" header to push certificate signed push: remove duplicated protocol info send-pack: send feature request on push-cert packet receive-pack: GPG-validate push certificates push: the beginning of "git push --signed" pack-protocol doc: typofix for PKT-LINE gpg-interface: move parse_signature() to where it should be gpg-interface: move parse_gpg_output() to where it should be send-pack: clarify that cmds_sent is a boolean send-pack: refactor inspecting and resetting status and sending commands send-pack: rename "new_refs" to "need_pack_data" receive-pack: factor out capability string generation send-pack: factor out capability string generation send-pack: always send capabilities send-pack: refactor decision to send update per ref send-pack: move REF_STATUS_REJECT_NODELETE logic a bit higher ...
2014-09-15gpg-interface: move parse_signature() to where it should beLibravatar Junio C Hamano1-0/+21
Our signed-tag objects set the standard format used by Git to store GPG-signed payload (i.e. the payload followed by its detached signature) [*1*], and it made sense to have a helper to find the boundary between the payload and its signature in tag.c back then. Newer code added later to parse other kinds of objects that learned to use the same format to store GPG-signed payload (e.g. signed commits), however, kept using the helper from the same location. Move it to gpg-interface; the helper is no longer about signed tag, but it is how our code and data interact with GPG. [Reference] *1* http://thread.gmane.org/gmane.linux.kernel/297998/focus=1383 Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-09-15gpg-interface: move parse_gpg_output() to where it should beLibravatar Junio C Hamano1-0/+36
Earlier, ffb6d7d5 (Move commit GPG signature verification to commit.c, 2013-03-31) moved this helper that used to be in pretty.c (i.e. the output code path) to commit.c for better reusability. It was a good first step in the right direction, but still suffers from a myopic view that commits will be the only thing we would ever want to sign---we would actually want to be able to reuse it even wider. The function interprets what GPG said; gpg-interface is obviously a better place. Move it there. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-08-20run-command: introduce CHILD_PROCESS_INITLibravatar René Scharfe1-4/+2
Most struct child_process variables are cleared using memset first after declaration. Provide a macro, CHILD_PROCESS_INIT, that can be used to initialize them statically instead. That's shorter, doesn't require a function call and is slightly more readable (especially given that we already have STRBUF_INIT, ARGV_ARRAY_INIT etc.). Helped-by: Johannes Sixt <j6t@kdbg.org> Signed-off-by: Rene Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-23gpg-interface: provide access to the payloadLibravatar Michael J Gruber1-0/+2
In contrast to tag signatures, commit signatures are put into the header, that is between the other header parts and commit messages. Provide access to the commit content sans the signature, which is the payload that is actually signed. Commit signature verification does the parsing anyways, and callers may wish to act on or display the commit object sans the signature. Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-23gpg-interface: provide clear helper for struct signature_checkLibravatar Michael J Gruber1-0/+12
The struct has been growing members whose malloced memory needs to be freed. Do this with one helper function so that no malloced memory shall be left unfreed. Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-03-21Merge branch 'mg/gpg-interface-using-status'Libravatar Junio C Hamano1-3/+15
Call "gpg" using the right API when validating the signature on tags. * mg/gpg-interface-using-status: pretty: make %GK output the signing key for signed commits pretty: parse the gpg status lines rather than the output gpg_interface: allow to request status return log-tree: rely upon the check in the gpg_interface gpg-interface: check good signature in a reliable way
2013-02-14gpg_interface: allow to request status returnLibravatar Michael J Gruber1-4/+7
Currently, verify_signed_buffer() returns the user facing output only. Allow callers to request the status output also. Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-02-14gpg-interface: check good signature in a reliable wayLibravatar Michael J Gruber1-2/+11
Currently, verify_signed_buffer() only checks the return code of gpg, and some callers implement additional unreliable checks for "Good signature" in the gpg output meant for the user. Use the status output instead and parse for a line beinning with "[GNUPG:] GOODSIG ". This is the only reliable way of checking for a good gpg signature. If needed we can change this easily to "[GNUPG:] VALIDSIG " if we want to take into account the trust model. Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-02-07Merge branch 'sb/gpg-plug-fd-leak' into maintLibravatar Junio C Hamano1-1/+3
We forgot to close the file descriptor reading from "gpg" output, killing "git log --show-signature" on a long history. * sb/gpg-plug-fd-leak: gpg: close stderr once finished with it in verify_signed_buffer()
2013-02-07Merge branch 'sb/gpg-i18n'Libravatar Junio C Hamano1-3/+3
* sb/gpg-i18n: gpg: allow translation of more error messages
2013-02-05Merge branch 'sb/gpg-plug-fd-leak'Libravatar Junio C Hamano1-1/+3
We forgot to close the file descriptor reading from "gpg" output, killing "git log --show-signature" on a long history. * sb/gpg-plug-fd-leak: gpg: close stderr once finished with it in verify_signed_buffer()
2013-01-31gpg: close stderr once finished with it in verify_signed_buffer()Libravatar Stephen Boyd1-1/+3
Failing to close the stderr pipe in verify_signed_buffer() causes git to run out of file descriptors if there are many calls to verify_signed_buffer(). An easy way to trigger this is to run git log --show-signature --merges | grep "key" on the linux kernel git repo. Eventually it will fail with error: cannot create pipe for gpg: Too many open files error: could not run gpg. Close the stderr pipe so that this can't happen. Suggested-by: Jeff King <peff@peff.net> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-01-31gpg: allow translation of more error messagesLibravatar Stephen Boyd1-3/+3
Mark these strings for translation so that error messages are printed in the user's language of choice. Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> Reviewed-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-05-24ident: rename IDENT_ERROR_ON_NO_NAME to IDENT_STRICTLibravatar Jeff King1-1/+1
Callers who ask for ERROR_ON_NO_NAME are not so much concerned that the name will be blank (because, after all, we will fall back to using the username), but rather it is a check to make sure that low-quality identities do not end up in things like commit messages or emails (whereas it is OK for them to end up in things like reflogs). When future commits add more quality checks on the identity, each of these callers would want to use those checks, too. Rather than modify each of them later to add a new flag, let's refactor the flag. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-01-05verify_signed_buffer: fix stale commentLibravatar Junio C Hamano1-4/+1
The function used to take an integer flag to specify where the output should go, but these days we supply a strbuf to receive it. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-11-29gpg-interface: allow use of a custom GPG binaryLibravatar Junio C Hamano1-3/+8
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-11-04Split GPG interface into its own helper libraryLibravatar Junio C Hamano1-0/+138
This mostly moves existing code from builtin/tag.c (for signing) and builtin/verify-tag.c (for verifying) to a new gpg-interface.c file to provide a more generic library interface. - sign_buffer() takes a payload strbuf, a signature strbuf, and a signing key, runs "gpg" to produce a detached signature for the payload, and appends it to the signature strbuf. The contents of a signed tag that concatenates the payload and the detached signature can be produced by giving the same strbuf as payload and signature strbuf. - verify_signed_buffer() takes a payload and a detached signature as <ptr, len> pairs, and runs "gpg --verify" to see if the payload matches the signature. It can optionally capture the output from GPG to allow the callers to pretty-print it in a way more suitable for their contexts. "verify-tag" (aka "tag -v") used to save the whole tag contents as if it is a detached signature, and fed gpg the payload part of the tag. It relied on gpg to fail when the given tag is not signed but just is annotated. The updated run_gpg_verify() function detects the lack of detached signature in the input, and errors out without bothering "gpg". Signed-off-by: Junio C Hamano <gitster@pobox.com>