aboutsummaryrefslogtreecommitdiffstats
path: root/debian/patches/0001-joeyh-patches.patch
blob: 14db716db15d4609b2f66c1e7c4d9e5e24163d11 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
From: Sean Whitton <spwhitton@spwhitton.name>
Date: Sat, 12 Dec 2015 16:06:55 -0700
Subject: joeyh-patches

---
 README.rst        | 32 +++++++++++++++++--
 git-remote-gcrypt | 93 +++++++++++++++++++++++++++++++++++++++++--------------
 2 files changed, 98 insertions(+), 27 deletions(-)

diff --git a/README.rst b/README.rst
index f177913..ba06259 100644
--- a/README.rst
+++ b/README.rst
@@ -60,10 +60,25 @@ The following ``git-config(1)`` variables are supported:
     The ``gcrypt-participants`` setting on the remote takes precedence
     over the repository variable ``gcrypt.participants``.
 
+``remote.<name>.gcrypt-publish-participants``
+    ..
+``gcrypt.publish-participants``
+    By default, the gpg key ids of the participants are obscured by
+    encrypting using `gpg -R`. Setting this option to `true` disables
+    that security measure.
+
+    The problem with using `gpg -R` is that to decrypt, gpg tries each
+    available secret key in turn until it finds a usable key.
+    This can result in unncessary passphrase prompts.
+
+``remote.<name>.gcrypt-signingkey``
+    ..
 ``user.signingkey``
-    (From regular git configuration) The key to use for signing.  You
-    should set ``user.signingkey`` if your default signing key is not
-    part of the participant list.
+    (The latter from regular git configuration) The key to use for signing.
+    You should set ``user.signingkey`` if your default signing key is not
+    part of the participant list. You may use the per-remote version
+    to sign different remotes using different keys.
+
 
 Environment Variables
 =====================
@@ -170,6 +185,17 @@ Each item extends until newline, and matches one of the following:
 ``extn <name> ...``
     Extension field, preserved but unused.
 
+Detecting gcrypt repos
+======================
+
+To detect if a git url is a gcrypt repo, use: git-remote-gcrypt --check url
+Exit status if 0 if the repo exists and can be decrypted, 1 if the repo
+uses gcrypt but could not be decrypted, and 100 if the repo is not
+encrypted with gcrypt (or could not be accessed).
+
+Note that this has to fetch the repo contents into the local git
+repository, the same as is done when using a gcrypt repo.
+
 See Also
 ========
 
diff --git a/git-remote-gcrypt b/git-remote-gcrypt
index bb19652..8d68669 100755
--- a/git-remote-gcrypt
+++ b/git-remote-gcrypt
@@ -18,7 +18,6 @@
 # See README.rst for usage instructions
 
 set -e # errexit
-set -u # nounset
 set -f # noglob
 set -C # noclobber
 
@@ -177,8 +176,10 @@ update_tree()
 {
 	local tab_="	"
 	# $2 is a filename from the repo format
-	(git ls-tree "$1" | xgrep -v -E '\b'"$2"'$';
-		xecho "100644 blob $3$tab_$2") | git mktree
+	(set +e;
+		git ls-tree "$1" | xgrep -v -E '\b'"$2"'$';
+		xecho "100644 blob $3$tab_$2"
+	) | git mktree
 }
 
 # Put giturl $1, file $2
@@ -313,14 +314,14 @@ CLEAN_FINAL()
 
 ENCRYPT()
 {
-	gpg --batch --force-mdc --compress-algo none --passphrase-fd 3 -c 3<<EOF
+	rungpg --batch --force-mdc --compress-algo none --trust-model=always --passphrase-fd 3 -c 3<<EOF
 $1
 EOF
 }
 
 DECRYPT()
 {
-	gpg -q --batch --no-default-keyring --secret-keyring /dev/null \
+	rungpg -q --batch --no-default-keyring --secret-keyring /dev/null \
 		--keyring /dev/null --passphrase-fd 3 -d  3<<EOF
 $1
 EOF
@@ -333,7 +334,7 @@ PRIVENCRYPT()
 	if isnonnull "$Conf_signkey"; then
 		set -- "$@" -u "$Conf_signkey"
 	fi
-	gpg --compress-algo none -se "$@"
+	rungpg --compress-algo none --trust-model=always -se "$@"
 }
 
 # $1 is the match for good signature, $2 is the textual signers list
@@ -341,7 +342,7 @@ PRIVDECRYPT()
 {
 	local status_=
 	exec 4>&1 &&
-	status_=$(gpg  --status-fd 3 -q -d 3>&1 1>&4) &&
+	status_=$(rungpg --status-fd 3 -q -d 3>&1 1>&4) &&
 	xfeed "$status_" grep "^\[GNUPG:\] ENC_TO " >/dev/null &&
 	(xfeed "$status_" grep -e "$1" >/dev/null || {
 		echo_info "Failed to verify manifest signature!" &&
@@ -353,17 +354,29 @@ PRIVDECRYPT()
 # Generate $1 random bytes
 genkey()
 {
-	gpg --armor --gen-rand 1 "$1"
+	rungpg --armor --gen-rand 1 "$1"
 }
 
 gpg_hash()
 {
 	local hash_=
-	hash_=$(gpg --with-colons --print-md "$1" | tr A-F a-f)
+	hash_=$(rungpg --with-colons --print-md "$1" | tr A-F a-f)
 	hash_=${hash_#:*:}
 	xecho "${hash_%:}"
 }
 
+rungpg()
+{
+	# gpg will fail to run when there is no controlling tty,
+	# due to trying to print messages to it, even if a gpg agent is set
+	# up. --no-tty fixes this.
+	if [ "x$GPG_AGENT_INFO" != "x" ]; then
+		gpg --no-tty "$@"
+	else
+		gpg "$@"
+	fi
+}
+
 # Pass the branch/ref by pipe to git
 safe_git_rev_parse()
 {
@@ -388,10 +401,13 @@ make_new_repo()
 # $1 return var for goodsig match, $2 return var for signers text
 read_config()
 {
-	local recp_= r_keyinfo= cap_= conf_part= good_sig= signers_=
-	Conf_signkey=$(git config --path user.signingkey || :)
+	local recp_= r_keyinfo= r_keyfpr= gpg_list= cap_= conf_part= good_sig= signers_=
+	Conf_signkey=$(git config --get "remote.$NAME.gcrypt-signingkey" '.+' ||
+		git config --path user.signingkey || :)
 	conf_part=$(git config --get "remote.$NAME.gcrypt-participants" '.+' ||
 		    git config --get gcrypt.participants '.+' || :)
+	Conf_pubish_participants=$(git config --get --bool "remote.$NAME.gcrypt-publish-participants" '.+' ||
+		git config --get --bool gcrypt.publish-participants || :)
 
 	# Figure out which keys we should encrypt to or accept signatures from
 	if isnull "$conf_part" || iseq "$conf_part" simple
@@ -406,22 +422,33 @@ read_config()
 
 	for recp_ in $conf_part
 	do
-		filter_to @r_keyinfo "pub*" \
-			"$(gpg --with-colons --fast-list -k "$recp_")"
+		gpg_list=$(rungpg --with-colons --fingerprint -k "$recp_")
+		filter_to @r_keyinfo "pub*" "$gpg_list"
+		filter_to @r_keyfpr "fpr*" "$gpg_list"
 		isnull "$r_keyinfo" || isnonnull "${r_keyinfo##*"$Newline"*}" ||
 		echo_info "WARNING: '$recp_' matches multiple keys, using one"
+		isnull "$r_keyfpr" || isnonnull "${r_keyfpr##*"$Newline"*}" ||
+		echo_info "WARNING: '$recp_' matches multiple fingerprints, using one"
 		r_keyinfo=${r_keyinfo%%"$Newline"*}
+		r_keyfpr=${r_keyfpr%%"$Newline"*}
 		keyid_=$(xfeed "$r_keyinfo" cut -f 5 -d :)
+		fprid_=$(xfeed "$r_keyfpr" cut -f 10 -d :)
 
-		isnonnull "$keyid_" &&
+		isnonnull "$fprid_" &&
 		signers_="$signers_ $keyid_" &&
-		append_to @good_sig "^\[GNUPG:\] GOODSIG $keyid_" || {
+		append_to @good_sig "^\[GNUPG:\] VALIDSIG .*$fprid_$" || {
 			echo_info "WARNING: Skipping missing key $recp_"
 			continue
 		}
 		# Check 'E'ncrypt capability
 		cap_=$(xfeed "$r_keyinfo" cut -f 12 -d :)
-		iseq "${cap_#*E}" "$cap_" || Recipients="$Recipients -R $keyid_"
+		if ! iseq "${cap_#*E}" "$cap_"; then
+			if [ "$Conf_pubish_participants" = true ]; then
+				Recipients="$Recipients -r $keyid_"
+			else
+				Recipients="$Recipients -R $keyid_"
+			fi
+		fi
 	done
 
 	if isnull "$Recipients"
@@ -778,14 +805,8 @@ cleanup_tmpfiles()
 	rm -r -f -- "${Tempdir}" >&2
 }
 
-# handle git-remote-helpers protocol
-gcrypt_main_loop()
+setup()
 {
-	local input_= input_inner= r_args= temp_key=
-
-	NAME=$1  # Remote name
-	URL=$2   # Remote URL
-
 	mkdir -p "$Localdir"
 
 	# Set up a subdirectory in /tmp
@@ -797,6 +818,17 @@ gcrypt_main_loop()
 	trap 'exit 1' 1 2 3 15
 
 	echo_info "Development version -- Repository format MAY CHANGE"
+}
+
+# handle git-remote-helpers protocol
+gcrypt_main_loop()
+{
+	local input_= input_inner= r_args= temp_key=
+
+	NAME=$1  # Remote name
+	URL=$2   # Remote URL
+
+	setup
 
 	while read input_
 	do
@@ -848,4 +880,17 @@ gcrypt_main_loop()
 	done
 }
 
-gcrypt_main_loop "$@"
+if [ "x$1" = x--check ]
+then
+	NAME=dummy-gcrypt-check
+	URL=$2
+	setup
+	ensure_connected
+	git remote remove $NAME 2>/dev/null || true
+	if iseq "$Did_find_repo" "no"
+	then
+		exit 100
+	fi
+else
+	gcrypt_main_loop "$@"
+fi