Skip to content
Commits on Source (70)
*~
src/agent-transfer/agent-transfer
replaced/
monkeysphere (0.42) unstable; urgency=medium
* bugfix release:
* use --send-keys instead of --send (closes: #908228)
* tests: Ensure that stale sockets don't fail socat (Closes: #899060)
* Remove deprecated option from test sshd config (Closes: #902320)
* write old-style PEM files to unbreak test suite (Closes: #909700)
* yet more colon fixes that escaped previous inspections
* fix more gnupg2 colons changes (Closes: #902367)
* Remove RSAAuthentication from test ssh config (Closes: #902318)
* clean up test suite failures when built against newer GnuPG
* use generic compiler (closes: #883015)
* make print_date_from_seconds_since_the_epoch deal better with bad input
-- Daniel Kahn Gillmor <dkg@fifthhorseman.net> Tue, 16 Oct 2018 11:38:39 -0400
monkeysphere (0.41) unstable; urgency=medium
* pem2openpgp now includes issuer fingerprint subpacket
in hashed self-sig, more compatible with GnuPG 2.1.16
(Closes: #846554)
* avoid blocking for entropy during test suite
(Closes: #841208)
* augment test suite for id certifier with a subkey, for better realism
* ensure that attempts to fetch primary key fingerprint only fetch
primary key fingerprint even if subkey fprs are emitted
(Closes: #846554)
* include $CPPFLAGS in agent-transfer build
-- Daniel Kahn Gillmor <dkg@fifthhorseman.net> Wed, 12 Oct 2016 01:12:27 -0400
monkeysphere (0.40) unstable; urgency=medium
* bugfix release:
* get tests to pass against GnuPG 2.1.15
* build more portably
-- Daniel Kahn Gillmor <dkg@fifthhorseman.net> Wed, 12 Oct 2016 01:12:27 -0400
monkeysphere (0.39) unstable; urgency=medium
* avoid warning about unused asprintf return value
* avoid treating src/share/common as an executable
* ensure that this works even if SYSSHAREDIR has whitespace
* Include local build of agent-transfer in $PATH (Closes: #835719)
* force bash as the shell during su (Closes: #827660)
-- Daniel Kahn Gillmor <dkg@fifthhorseman.net> Tue, 30 Aug 2016 03:10:53 -0400
monkeysphere (0.38) unstable; urgency=medium
* make tests work with modern gpg (2.1.x and later) as /usr/bin/gpg
* this introduces a new binary, agent-transfer, to transfer secret keys
from gpg-agent to ssh-agent.
-- Daniel Kahn Gillmor <dkg@fifthhorseman.net> Tue, 17 May 2016 00:44:32 -0400
monkeysphere (0.37) unstable; urgency=medium
* Bugfix release with minor improvements and dependency accomodations.
......
......@@ -15,8 +15,22 @@ PREFIX ?= /usr
MANPREFIX ?= $(PREFIX)/share/man
LOCALSTATEDIR ?= /var/lib
# nothing actually needs to be built now.
all:
CFLAGS += $(shell libassuan-config --cflags)
CFLAGS += $(shell libgcrypt-config --cflags)
CFLAGS += --pedantic -Wall -Werror -std=c99
LIBS += $(shell libassuan-config --libs)
LIBS += $(shell libgcrypt-config --libs)
REPLACEMENTS = src/monkeysphere src/monkeysphere-host \
src/monkeysphere-authentication src/share/defaultenv $(wildcard \
src/transitions/*)
REPLACED_COMPRESSED_MANPAGES = $(addsuffix .gz,$(addprefix replaced/,$(wildcard man/*/*)))
all: src/agent-transfer/agent-transfer $(addprefix replaced/,$(REPLACEMENTS)) $(REPLACED_COMPRESSED_MANPAGES)
src/agent-transfer/agent-transfer: src/agent-transfer/main.c src/agent-transfer/ssh-agent-proto.h
$(CC) -o $@ $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $< $(LIBS)
debian-package:
git buildpackage -uc -us
......@@ -30,9 +44,21 @@ macports-portfile:
./utils/build-macports-portfile
clean:
rm -f src/agent-transfer/agent-transfer
rm -rf replaced/
# clean up old monkeysphere packages lying around as well.
rm -f monkeysphere_*
replaced/%: %
mkdir -p $(dir $@)
sed < $< > $@ \
-e 's:__SYSSHAREDIR_PREFIX__:$(PREFIX):' \
-e 's:__SYSCONFDIR_PREFIX__:$(ETCPREFIX):' \
-e 's:__SYSDATADIR_PREFIX__:$(LOCALSTATEDIR):'
replaced/%.gz: replaced/%
gzip -n $<
# this target is to be called from the tarball, not from the git
# working dir!
install: all installman
......@@ -41,26 +67,20 @@ install: all installman
mkdir -p $(DESTDIR)$(ETCPREFIX)/etc/monkeysphere
mkdir -p $(DESTDIR)$(PREFIX)/share/doc/monkeysphere
printf "Monkeysphere %s\n" $(MONKEYSPHERE_VERSION) > $(DESTDIR)$(PREFIX)/share/monkeysphere/VERSION
install src/monkeysphere $(DESTDIR)$(PREFIX)/bin
sed -i 's:__SYSSHAREDIR_PREFIX__:$(PREFIX):' $(DESTDIR)$(PREFIX)/bin/monkeysphere
install src/monkeysphere-host $(DESTDIR)$(PREFIX)/sbin
sed -i 's:__SYSSHAREDIR_PREFIX__:$(PREFIX):' $(DESTDIR)$(PREFIX)/sbin/monkeysphere-host
install src/monkeysphere-authentication $(DESTDIR)$(PREFIX)/sbin
sed -i 's:__SYSSHAREDIR_PREFIX__:$(PREFIX):' $(DESTDIR)$(PREFIX)/sbin/monkeysphere-authentication
install replaced/src/monkeysphere $(DESTDIR)$(PREFIX)/bin
install replaced/src/monkeysphere-host $(DESTDIR)$(PREFIX)/sbin
install replaced/src/monkeysphere-authentication $(DESTDIR)$(PREFIX)/sbin
install src/monkeysphere-authentication-keys-for-user $(DESTDIR)$(PREFIX)/share/monkeysphere
install -m 0755 src/share/common $(DESTDIR)$(PREFIX)/share/monkeysphere
install -m 0644 src/share/defaultenv $(DESTDIR)$(PREFIX)/share/monkeysphere
sed -i 's:__SYSCONFDIR_PREFIX__:$(ETCPREFIX):' $(DESTDIR)$(PREFIX)/share/monkeysphere/defaultenv
sed -i 's:__SYSDATADIR_PREFIX__:$(LOCALSTATEDIR):' $(DESTDIR)$(PREFIX)/share/monkeysphere/defaultenv
install -m 0644 src/share/common $(DESTDIR)$(PREFIX)/share/monkeysphere
install -m 0644 replaced/src/share/defaultenv $(DESTDIR)$(PREFIX)/share/monkeysphere
install -m 0755 src/share/checkperms $(DESTDIR)$(PREFIX)/share/monkeysphere
install -m 0755 src/share/keytrans $(DESTDIR)$(PREFIX)/share/monkeysphere
ln -sf ../share/monkeysphere/keytrans $(DESTDIR)$(PREFIX)/bin/pem2openpgp
ln -sf ../share/monkeysphere/keytrans $(DESTDIR)$(PREFIX)/bin/openpgp2ssh
ln -sf ../share/monkeysphere/keytrans $(DESTDIR)$(PREFIX)/bin/openpgp2pem
ln -sf ../share/monkeysphere/keytrans $(DESTDIR)$(PREFIX)/bin/openpgp2spki
install -m 0744 src/transitions/* $(DESTDIR)$(PREFIX)/share/monkeysphere/transitions
sed -i 's:__SYSSHAREDIR_PREFIX__:$(PREFIX):' $(DESTDIR)$(PREFIX)/share/monkeysphere/transitions/0.23
sed -i 's:__SYSSHAREDIR_PREFIX__:$(PREFIX):' $(DESTDIR)$(PREFIX)/share/monkeysphere/transitions/0.28
install -m 0755 src/agent-transfer/agent-transfer $(DESTDIR)$(PREFIX)/bin
install -m 0744 replaced/src/transitions/* $(DESTDIR)$(PREFIX)/share/monkeysphere/transitions
install -m 0644 src/transitions/README.txt $(DESTDIR)$(PREFIX)/share/monkeysphere/transitions
install -m 0644 src/share/m/* $(DESTDIR)$(PREFIX)/share/monkeysphere/m
install -m 0644 src/share/mh/* $(DESTDIR)$(PREFIX)/share/monkeysphere/mh
......@@ -72,26 +92,13 @@ install: all installman
install -m 0644 etc/monkeysphere-host.conf $(DESTDIR)$(ETCPREFIX)/etc/monkeysphere/monkeysphere-host.conf$(ETCSUFFIX)
install -m 0644 etc/monkeysphere-authentication.conf $(DESTDIR)$(ETCPREFIX)/etc/monkeysphere/monkeysphere-authentication.conf$(ETCSUFFIX)
installman:
installman: $(REPLACED_COMPRESSED_MANPAGES)
mkdir -p $(DESTDIR)$(MANPREFIX)/man1 $(DESTDIR)$(MANPREFIX)/man7 $(DESTDIR)$(MANPREFIX)/man8
gzip -n man/*/*
install man/man1/* $(DESTDIR)$(MANPREFIX)/man1
install man/man7/* $(DESTDIR)$(MANPREFIX)/man7
install man/man8/* $(DESTDIR)$(MANPREFIX)/man8
ln -s openpgp2ssh.1.gz $(DESTDIR)$(MANPREFIX)/man1/openpgp2pem.1.gz
ln -s openpgp2ssh.1.gz $(DESTDIR)$(MANPREFIX)/man1/openpgp2spki.1.gz
gzip -d man/*/*
gzip -d $(DESTDIR)$(MANPREFIX)/man1/monkeysphere.1.gz
sed -i 's:__SYSCONFDIR_PREFIX__:$(ETCPREFIX):' $(DESTDIR)$(MANPREFIX)/man1/monkeysphere.1
gzip -n $(DESTDIR)$(MANPREFIX)/man1/monkeysphere.1
gzip -d $(DESTDIR)$(MANPREFIX)/man8/monkeysphere-host.8.gz
sed -i 's:__SYSCONFDIR_PREFIX__:$(ETCPREFIX):' $(DESTDIR)$(MANPREFIX)/man8/monkeysphere-host.8
sed -i 's:__SYSDATADIR_PREFIX__:$(LOCALSTATEDIR):' $(DESTDIR)$(MANPREFIX)/man8/monkeysphere-host.8
gzip -n $(DESTDIR)$(MANPREFIX)/man8/monkeysphere-host.8
gzip -d $(DESTDIR)$(MANPREFIX)/man8/monkeysphere-authentication.8.gz
sed -i 's:__SYSCONFDIR_PREFIX__:$(ETCPREFIX):' $(DESTDIR)$(MANPREFIX)/man8/monkeysphere-authentication.8
sed -i 's:__SYSDATADIR_PREFIX__:$(LOCALSTATEDIR):' $(DESTDIR)$(MANPREFIX)/man8/monkeysphere-authentication.8
gzip -n $(DESTDIR)$(MANPREFIX)/man8/monkeysphere-authentication.8
install replaced/man/man1/* $(DESTDIR)$(MANPREFIX)/man1
install replaced/man/man7/* $(DESTDIR)$(MANPREFIX)/man7
install replaced/man/man8/* $(DESTDIR)$(MANPREFIX)/man8
ln -sf openpgp2ssh.1.gz $(DESTDIR)$(MANPREFIX)/man1/openpgp2pem.1.gz
ln -sf openpgp2ssh.1.gz $(DESTDIR)$(MANPREFIX)/man1/openpgp2spki.1.gz
# this target depends on you having the monkeysphere-docs
# repo checked out as a peer of your monkeysphere repo.
......@@ -100,10 +107,12 @@ releasenote:
test: test-keytrans test-basic
test-basic:
check: test
test-basic: src/agent-transfer/agent-transfer
MONKEYSPHERE_TEST_NO_EXAMINE=true ./tests/basic
test-keytrans:
test-keytrans: src/agent-transfer/agent-transfer
MONKEYSPHERE_TEST_NO_EXAMINE=true ./tests/keytrans
.PHONY: all tarball debian-package freebsd-distinfo clean install installman releasenote test
.PHONY: all tarball debian-package freebsd-distinfo clean install installman releasenote test check
......@@ -92,6 +92,6 @@ export GNUPGHOME=/var/lib/monkeysphere/host
# default to looking for https keys.
proto="${1:-https}"
for fpr in $(gpg --fixed-list-mode --with-colons --fingerprint --list-secret-keys "${proto}://" | grep '^fpr:' | cut -f10 -d:); do
for fpr in $(gpg --fixed-list-mode --with-colons --fingerprint --list-secret-keys "${proto}://" | awk -F: '/^fpr:/{ if (ok) { print $10 } ; ok=0 } /^sec:/{ ok=1 }'); do
gencertreq "$fpr"
done
.TH AGENT-TRANSFER "1" "May 2016" "monkeysphere" "User Commands"
.SH NAME
agent-transfer - copy a secret key from gpg-agent to ssh-agent
.SH SYNOPSIS
.B agent-transfer [\fIoptions\fP] \fIKEYGRIP\fP [\fICOMMENT\fP]
.SH DESCRIPTION
\fBagent-transfer\fP extracts a secret key from a modern version of
GnuPG agent and sends it to the running SSH agent. This is useful for
people whose keys are managed in the long-term by GnuPG's gpg-agent,
but who prefer the semantics of OpenSSH's ssh-agent for regular use.
\fBagent-transfer\fP was written as part of the monkeysphere project.
The \fBKEYGRIP\fP should be specified as a sequence of 20 hexadecimal
characters. If you aren't sure of the keygrip, you can inspect the
output of:
gpg \-\-with\-keygrip \-\-list\-secret\-keys
The \fBCOMMENT\fP is optional, and will be stored alongside the key in
ssh-agent. It must not start with a \-, to avoid being mistaken for
an option.
.SH OPTIONS
\fBagent-transfer\fP also accepts options that would normally be
passed to \fBssh\-add\fP(1) to constrain the use of the transferred
key:
.TP
\-c
Indicates that added identities should be subject to confirmation
before being used for authentication.
.TP
\-t SECONDS
Indicates that the key should have a lifetime of SECONDS in the
running ssh\-agent.
.SH FILES
.TP
~/.gnupg/S.gpg\-agent
The socket where gpg\-agent is listening. This is the "standard
socket" for modern GnuPG.
.SH ENVIRONMENT VARIABLES
.TP
GNUPGHOME
The GnuPG home directory, where the standard socket for gpg\-agent
lives. If this is not set, it is assumed to be ~/.gnupg.
.TP
SSH_AUTH_SOCK
Specifies the location where the running ssh-agent is present.
.P
Several other environment variables are also passed in some form to
the gpg\-agent to help it figure out how to run a sensible pinentry,
including GPG_TTY, TERM, DISPLAY, XAUTHORITY, GTK_IM_MODULE,
DBUS_SESSION_BUS_ADDRESS, and LANG.
.SH AUTHOR
Written by:
Daniel Kahn Gillmor <dkg@fifthhorseman.net>
.SH SEE ALSO
.BR monkeysphere (7),
.BR ssh (1),
.BR ssh\-add (1),
.BR ssh\-agent (1),
.BR gpg (1)
.BR gpg\-agent (1),
......@@ -189,8 +189,9 @@ ssh) or without seeing a nasty "security warning" in their browsers
Note that \fBmonkeysphere\-host\fP currently caches a copy of all
imported secret keys (stored in OpenPGP form for future manipulation)
in __SYSDATADIR_PREFIX__/monkeysphere/host/secring.gpg. Cleartext backups of this
file could expose secret key material if not handled sensitively.
in __SYSDATADIR_PREFIX__/monkeysphere/host/. Cleartext backups of
files in this directory could expose secret key material if not
handled sensitively.
.SH ENVIRONMENT
......
This diff is collapsed.
/* see PROTOCOL.agent in openssh repo */
/* 3.2 Requests from client to agent for protocol 2 key operations */
#define SSH2_AGENTC_REQUEST_IDENTITIES 11
#define SSH2_AGENTC_SIGN_REQUEST 13
#define SSH2_AGENTC_ADD_IDENTITY 17
#define SSH2_AGENTC_REMOVE_IDENTITY 18
#define SSH2_AGENTC_REMOVE_ALL_IDENTITIES 19
#define SSH2_AGENTC_ADD_ID_CONSTRAINED 25
/* 3.3 Key-type independent requests from client to agent */
#define SSH_AGENTC_ADD_SMARTCARD_KEY 20
#define SSH_AGENTC_REMOVE_SMARTCARD_KEY 21
#define SSH_AGENTC_LOCK 22
#define SSH_AGENTC_UNLOCK 23
#define SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED 26
/* 3.4 Generic replies from agent to client */
#define SSH_AGENT_FAILURE 5
#define SSH_AGENT_SUCCESS 6
/* 3.6 Replies from agent to client for protocol 2 key operations */
#define SSH2_AGENT_IDENTITIES_ANSWER 12
#define SSH2_AGENT_SIGN_RESPONSE 14
/* 3.7 Key constraint identifiers */
#define SSH_AGENT_CONSTRAIN_LIFETIME 1
#define SSH_AGENT_CONSTRAIN_CONFIRM 2
/*
All protocol messages are prefixed with their length in bytes, encoded
as a 32 bit unsigned integer. Specifically:
uint32 message_length
byte[message_length] message
RSA keys may be added with this request:
byte SSH2_AGENTC_ADD_IDENTITY or
SSH2_AGENTC_ADD_ID_CONSTRAINED
string "ssh-rsa"
mpint rsa_n
mpint rsa_e
mpint rsa_d
mpint rsa_iqmp
mpint rsa_p
mpint rsa_q
string key_comment
constraint[] key_constraints
*/
......@@ -62,7 +62,7 @@ EOF
# user gpg command to define common options
gpg_user() {
LC_ALL=C gpg --fixed-list-mode --no-greeting --quiet --no-tty "$@"
LC_ALL=C "${GPG:-gpg}" --fixed-list-mode --no-greeting --quiet --no-tty "$@"
}
# output the ssh fingerprint of a gpg key
......
......@@ -97,7 +97,7 @@ core_fingerprint() {
log debug "determining core key fingerprint..."
gpg_core --list-secret-key --with-colons \
--with-fingerprint \
| grep ^fpr: | cut -d: -f10
| awk -F: '/^fpr:/{ if (ok) { print $10 } ; ok=0 } /^sec:/{ ok=1 }'
}
# export signatures from core to sphere
......
......@@ -95,7 +95,7 @@ gpg_host_edit() {
update_pgp_pub_file() {
log debug "updating openpgp public key file '$HOST_KEY_FILE'..."
gpg_host --export --armor --export-options export-minimal \
$(gpg_host --list-secret-keys --with-colons --fingerprint | grep ^fpr | cut -f10 -d:) \
$(gpg_host --list-secret-keys --with-colons --fingerprint | awk -F: '/^fpr:/{ if (ok) { print $10 } ; ok=0 } /^sec:/{ ok=1 }') \
> "$HOST_KEY_FILE"
}
......@@ -234,7 +234,7 @@ prompt_userid_exists() {
local fingerprint
if gpgOut=$(gpg_host_list_keys "=${userID}" 2>/dev/null) ; then
fingerprint=$(echo "$gpgOut" | grep '^fpr:' | cut -d: -f10)
fingerprint=$(echo "$gpgOut" | awk -F: '/^fpr:/{ if (ok) { print $10 } ; ok=0 } /^pub:/{ ok=1 }')
if [ "$PROMPT" != "false" ] ; then
printf "Service name '%s' is already being used by key '%s'.\nAre you sure you want to use it again? (y/N) " "$userID" "$fingerprint" >&2
read OK; OK=${OK:=N}
......@@ -287,8 +287,14 @@ show_key() {
# tmp gpghome dir
export GNUPGHOME=$(msmktempdir)
cleanup() {
if type gpgconf &>/dev/null; then
gpgconf --kill gpg-agent
fi
rm -rf "$GNUPGHOME"
}
# trap to remove tmp dir if break
trap "rm -rf $GNUPGHOME" EXIT
trap cleanup EXIT
# import the host key into the tmp dir
gpg --quiet --import <"$HOST_KEY_FILE"
......@@ -296,7 +302,7 @@ show_key() {
# get the gpg fingerprint
if gpg --quiet --list-keys \
--with-colons --with-fingerprint "$id" \
| grep '^fpr:' | cut -d: -f10 > "$GNUPGHOME"/fingerprint ; then
| awk -F: '/^fpr:/{ if (ok) { print $10 } ; ok=0 } /^pub:/{ ok=1 }' > "$GNUPGHOME"/fingerprint ; then
fingerprint=$(cat "$GNUPGHOME"/fingerprint)
else
failure "ID '$id' not found."
......@@ -306,7 +312,7 @@ show_key() {
# FIXME: make no-show-keyring work so we don't have to do the grep'ing
# FIXME: can we show uid validity somehow?
gpg --list-keys --list-options show-unusable-uids "$fingerprint" 2>/dev/null \
| grep -v "^${GNUPGHOME}/pubring.gpg$" \
| egrep -v "^${GNUPGHOME}/pubring.(gpg|kbx)$" \
| egrep -v '^-+$' \
| grep -v '^$'
......@@ -329,7 +335,7 @@ show_key() {
# remove the tmp file
trap - EXIT
rm -rf "$GNUPGHOME"
cleanup
}
########################################################################
......
#!/usr/bin/env bash
# -*-shell-script-*-
# This should be sourced by bash (though we welcome changes to make it POSIX sh compliant)
......@@ -118,7 +117,7 @@ su_monkeysphere_user() {
# if root, su command as monkeysphere user
'root')
# requote arguments using bash builtin feature (see "help printf"):
su "$MONKEYSPHERE_USER" -c "$(printf "%q " "$@")"
su "$MONKEYSPHERE_USER" -s "$(which bash)" -c "$(printf "%q " "$@")"
;;
# otherwise, fail
......@@ -244,10 +243,15 @@ advance_date() {
print_date_from_seconds_since_the_epoch() {
local seconds="$1"
local gnutry
if ! date '+%F %T' -d @"${seconds}" 2>/dev/null ; then
# try it the BSD date way:
date -r "${seconds}" '+%F %T'
if [ -z "$seconds" ] || [[ "$seconds" =~ [^0-9] ]]; then
# not a decimal number, don't bother trying to pass it to date
printf "<unknown>\n"
else
if ! date '+%F %T' -d @"${seconds}" 2>/dev/null ; then
# try it the BSD date way:
date -r "${seconds}" '+%F %T'
fi
fi
}
......@@ -951,12 +955,18 @@ process_authorized_user_ids() {
# fingerprints, one per line:
list_primary_fingerprints() {
local fake=$(msmktempdir)
trap "rm -rf $fake" EXIT
cleanup() {
if type gpgconf &>/dev/null; then
GNUPGHOME="$fake" gpgconf --kill gpg-agent
fi
rm -rf "$fake"
}
trap cleanup EXIT
GNUPGHOME="$fake" gpg --no-tty --quiet --import --ignore-time-conflict 2>/dev/null
GNUPGHOME="$fake" gpg --with-colons --fingerprint --list-keys | \
awk -F: '/^fpr:/{ print $10 }'
awk -F: '/^fpr:/{ if (ok) { print $10 } ; ok=0 } /^pub:/{ ok=1 }'
trap - EXIT
rm -rf "$fake"
cleanup
}
# takes an OpenPGP key or set of keys on stdin, a fingerprint or other
......@@ -964,11 +974,17 @@ list_primary_fingerprints() {
# the requested keys from the material on stdin
get_cert_info() {
local fake=$(msmktempdir)
trap "rm -rf $fake" EXIT
cleanup() {
if type gpgconf &>/dev/null; then
GNUPGHOME="$fake" gpgconf --kill gpg-agent
fi
rm -rf "$fake"
}
GNUPGHOME="$fake" gpg --no-tty --quiet --import --ignore-time-conflict 2>/dev/null
GNUPGHOME="$fake" gpg --with-colons --fingerprint --fixed-list-mode --list-keys "$1"
trap - EXIT
rm -rf "$fake"
cleanup
}
......@@ -1010,7 +1026,3 @@ report_cruft() {
printf "The directories above are backups left over from a monkeysphere transition.\nThey may contain copies of sensitive data (host keys, certifier lists), but\nthey are no longer needed by monkeysphere.\nYou may remove them at any time.\n\n" | log info
fi
}
if [ -n "$1" ] && [ "$(type -t "$1" || true)" = "function" ]; then
"$@"
fi
......@@ -184,6 +184,7 @@ my $subpacket_types = { sig_creation_time => 2,
features => 30,
signature_target => 31,
embedded_signature => 32,
issuer_fpr => 33,
};
# bitstring (see RFC 4880 section 5.2.3.24)
......@@ -214,9 +215,19 @@ sub simple_checksum {
# calculate/print the fingerprint of an openssh-style keyblob:
sub sshfpr {
sshfpr_sha256(shift);
}
sub sshfpr_md5 {
my $keyblob = shift;
use Digest::MD5;
return join(':', map({unpack("H*", $_)} split(//, Digest::MD5::md5($keyblob))));
return 'MD5:'.join(':', map({unpack("H*", $_)} split('', Digest::MD5::md5($keyblob))));
}
sub sshfpr_sha256 {
my $keyblob = shift;
use Digest::SHA;
return 'SHA256:'.Digest::SHA::sha256_base64($keyblob);
}
# calculate the multiplicative inverse of a mod b this is euclid's
......@@ -570,10 +581,13 @@ sub gensig {
if ($key_timestamp > $sig_timestamp) {
die "key timestamp must not be later than signature timestamp\n";
}
my $v4_fpr = fingerprint($rsa, $key_timestamp);
my $creation_time_packet = pack('CCN', 5, $subpacket_types->{sig_creation_time}, $sig_timestamp);
my $hashed_subs = $creation_time_packet.$args->{hashed_subpackets};
my $issuer_fpr_packet = pack('CCCa20', 22, $subpacket_types->{issuer_fpr}, 4, $v4_fpr);
my $hashed_subs = $issuer_fpr_packet.$creation_time_packet.$args->{hashed_subpackets};
my $subpacket_octets = pack('n', length($hashed_subs));
......@@ -593,7 +607,7 @@ sub gensig {
my $key_data = make_packet($packet_types->{pubkey}, $pubkey, {'packet_length'=>2});
# take the last 8 bytes of the fingerprint as the keyid:
my $keyid = substr(fingerprint($rsa, $key_timestamp), 20 - 8, 8);
my $keyid = substr($v4_fpr, 20 - 8, 8);
# the v4 signature trailer is:
......@@ -1187,9 +1201,8 @@ for (basename($0)) {
printf("%s\n", join("\n", map { uc(unpack('H*', $_)) } keys(%{$keys})));
} elsif (/^sshfpr$/) {
use MIME::Base64;
my $b64keyblob;
my $dummy;
while (($dummy,$b64keyblob) = split(/ /, <STDIN>)) {
while (<STDIN>) {
my ($dummy,$b64keyblob) = split(/ /, $_);
printf("%s\n", sshfpr(decode_base64($b64keyblob)));
}
} elsif (/^openpgp2sshfpr$/) {
......
......@@ -25,6 +25,7 @@ subkey_to_ssh_agent() {
local subkey
local publine
local kname
local awk_pgrm
# if there's no agent running, don't bother:
if [ -z "$SSH_AUTH_SOCK" ] || ! type ssh-add >/dev/null ; then
......@@ -49,17 +50,22 @@ subkey_to_ssh_agent() {
# (to work around bug https://bugs.g10code.com/gnupg/issue945):
secretkeys=$(gpg_user --list-secret-keys --with-colons \
--fingerprint | \
grep '^fpr:' | cut -f10 -d: | awk '{ print "0x" $1 "!" }')
awk -F: '/^fpr:/{ if (ok) { print "0x" $10 "!" } ; ok=0 } /^sec:/{ ok=1 }')
if [ -z "$secretkeys" ]; then
failure "You have no secret keys in your keyring!
You might want to run 'gpg --gen-key'."
fi
authsubkeys=$(gpg_user --list-secret-keys --with-colons \
--fingerprint --fingerprint $secretkeys | \
cut -f1,5,10,12 -d: | grep -A1 '^ssb:[^:]*::[^:]*a[^:]*$' | \
grep '^fpr::' | cut -f3 -d: | sort -u)
# $2 regex means "is some kind of valid, or at least not invalid"
# $12 ~ /a/ means "authentication-capable"
# $4 == 1 means "RSA"
awk_pgrm='
/^sub:/{ if (($2 ~ /^[somfuq-]$/) && ($12 ~ /a/) && ($4 == 1)) { ok = 1 }; };
/^fpr:/{ if (ok) { print $10 ; ok = 0; }; };'
authsubkeys=$(gpg_user --list-keys --with-colons \
--fingerprint --fingerprint $secretkeys | \
awk -F: "$awk_pgrm" | sort -u)
if [ -z "$authsubkeys" ]; then
failure "no authentication-capable subkeys available.
......@@ -78,9 +84,12 @@ You might want to run 'monkeysphere gen-subkey'."
for subkey in $authsubkeys; do
# test that the subkey has proper capability
capability=$(gpg_user --list-secret-keys --with-colons \
--fingerprint --fingerprint "0x${subkey}!" \
| egrep -B 1 "^fpr:::::::::${subkey}:$" | grep "^ssb:" | cut -d: -f12)
awk_pgrm='
/^[ps]ub:/{ caps = $12 }
/^fpr:/{ if ($10 == "'"${subkey}"'") { print caps }; }'
capability=$(gpg_user --with-colons --with-fingerprint --with-fingerprint \
--list-keys "0x${subkey}!" \
| awk -F: "$awk_pgrm")
if ! check_capability "$capability" 'a' ; then
log error "Did not find authentication-capable subkey with key ID '$subkey'."
continue
......@@ -104,15 +113,25 @@ You might want to run 'monkeysphere gen-subkey'."
gpg_user --export --no-armor "0x${subkey}!" | openpgp2ssh "$subkey" > "$workingdir/$kname"
(cd "$workingdir" && ssh-add -d "$kname") || keysuccess="$?"
else
# we're adding the subkey:
mkfifo "$workingdir/$kname"
gpg_user --batch --passphrase-fd 3 3<"$workingdir/passphrase" \
--export-options export-reset-subkey-passwd,export-minimal,no-export-attributes \
--export-secret-subkeys --no-armor "0x${subkey}!" | openpgp2ssh "$subkey" > "$workingdir/$kname" &
(cd "$workingdir" && DISPLAY=nosuchdisplay SSH_ASKPASS=/bin/false ssh-add "$@" "$kname" </dev/null )&
passphrase_prompt "Enter passphrase for key $kname: " "$workingdir/passphrase"
wait %2 || keysuccess="$?"
if is_gpg_version_greater_equal 2.1.0; then
awk_pgrm='
/^fpr:/{ fpr = $10 }
/^grp:/{ if (fpr == "'"${subkey}"'") { print $10; } }'
keygrip=$(gpg_user --with-colons --with-keygrip --with-fingerprint \
--with-fingerprint --list-keys "0x${subkey}!" \
| awk -F: "$awk_pgrm")
agent-transfer "$@" "$keygrip" "$kname" || keysuccess="$?"
else
# we're adding the subkey:
mkfifo "$workingdir/$kname"
gpg_user --batch --passphrase-fd 3 3<"$workingdir/passphrase" \
--export-options export-reset-subkey-passwd,export-minimal,no-export-attributes \
--export-secret-subkeys --no-armor "0x${subkey}!" | openpgp2ssh "$subkey" > "$workingdir/$kname" &
(cd "$workingdir" && DISPLAY=nosuchdisplay SSH_ASKPASS=/bin/false ssh-add "$@" "$kname" </dev/null )&
passphrase_prompt "Enter passphrase for key $kname: " "$workingdir/passphrase"
wait %2 || keysuccess="$?"
fi
fi
rm -f "$workingdir/$kname"
......
......@@ -101,7 +101,7 @@ if [ -f "$keyID" -o "$keyID" = '-' ] ; then
# check the key is ok as monkeysphere user before loading
log debug "checking keys in file..."
fingerprint=$(su_monkeysphere_user \
"${SYSSHAREDIR}/common" list_primary_fingerprints < "$keyID")
bash -c "$(printf ". %q && list_primary_fingerprints" "${SYSSHAREDIR}/common")" < "$keyID")
if [ $(printf "%s" "$fingerprint" | egrep -c '^[A-F0-9]{40}$') -ne 1 ] ; then
failure "There was not exactly one gpg key in the file."
......@@ -120,7 +120,7 @@ else
# get the full fingerprint of new certifier key
log debug "getting fingerprint of certifier key..."
fingerprint=$(gpg_sphere --list-key --with-colons --with-fingerprint "0x${keyID}!" \
| grep '^fpr:' | cut -d: -f10)
| awk -F: '/^fpr:/{ if (ok) { print $10 } ; ok=0 } /^pub:/{ ok=1 }')
# test that there is only a single fingerprint
if (( $(echo "$fingerprint" | wc -l) != 1 )) ; then
......
......@@ -70,7 +70,7 @@ elif (( "$keysfound" > 1 )); then
else
create=$(echo "$seckey" | grep ^sec: | cut -f6 -d:)
expire=$(echo "$seckey" | grep ^sec: | cut -f7 -d:)
fingerprint=$(echo "$seckey" | grep ^fpr: | head -n1 | cut -f10 -d:)
fingerprint=$(echo "$seckey" | awk -F: '/^fpr:/{ if (ok) { print $10 } ; ok=0 } /^pub:/{ ok=1 }')
# check for key expiration:
if [ "$expire" ]; then
if (( "$expire" < "$curdate" )); then
......
......@@ -79,7 +79,7 @@ for uname in $unames ; do
# process authorized_user_ids file, as monkeysphere user
su_monkeysphere_user \
/usr/bin/env "STRICT_MODES=$STRICT_MODES" "${SYSSHAREDIR}/common" process_authorized_user_ids - \
/usr/bin/env "STRICT_MODES=$STRICT_MODES" bash -c "$(printf ". %q && process_authorized_user_ids -" "${SYSSHAREDIR}/common")"\
< "$authorizedUserIDs" \
> "$tmpAuthorizedKeys"
......
......@@ -50,8 +50,10 @@ else
fi
# execute edit-key script
if PEM2OPENPGP_USAGE_FLAGS=authenticate \
<"$GNUPGHOME_HOST/secring.gpg" \
if ( if is_gpg_version_greater_equal 2.1.0; \
then gpg_host --export-secret-keys "$keyID"; \
else cat "$GNUPGHOME_HOST/secring.gpg" ; fi ) | \
PEM2OPENPGP_USAGE_FLAGS=authenticate \
"$SYSSHAREDIR/keytrans" adduserid "$keyID" "$serviceName" \
| gpg_host --import ; then
......
......@@ -52,7 +52,7 @@ if [ -f "$revokerKeyID" -o "$revokerKeyID" = '-' ] ; then
# check the key is ok as monkeysphere user before loading
log debug "checking keys in file..."
fingerprint=$(su_monkeysphere_user \
"${SYSSHAREDIR}/common" list_primary_fingerprints < "$revokerKeyID")
bash -c "$(printf ". %q && list_primary_fingerprints" "${SYSSHAREDIR}/common")" < "$revokerKeyID")
if [ $(printf "%s" "$fingerprint" | egrep -c '^[A-F0-9]{40}$') -ne 1 ] ; then
failure "There was not exactly one gpg key in the file."
......@@ -77,7 +77,7 @@ else
# get the full fingerprint of new revoker key
log debug "getting fingerprint of revoker key..."
fingerprint=$(su_monkeysphere_user "GNUPGHOME=$tmpDir" gpg --list-key --with-colons --with-fingerprint "${revokerKeyID}" \
| grep '^fpr:' | cut -d: -f10)
| awk -F: '/^fpr:/{ if (ok) { print $10 }; ok=0 } /^pub:/{ ok=1 }')
# test that there is only a single fingerprint
if (( $(echo "$fingerprint" | wc -l) != 1 )) ; then
......
......@@ -35,8 +35,14 @@ export GNUPGHOME=$(msmktempdir)
chmod 0700 "$GNUPGHOME"
chown "$MONKEYSPHERE_USER":"$MONKEYSPHERE_GROUP" "$GNUPGHOME"
cleanup() {
if type gpgconf &>/dev/null; then
gpgconf --kill gpg-agent
fi
rm -rf "$GNUPGHOME"
}
# trap to remove tmp dir if break
trap "rm -rf $GNUPGHOME" EXIT
trap cleanup EXIT
# import the key into the tmp dir
su_monkeysphere_user \
......@@ -57,6 +63,6 @@ su_monkeysphere_user \
# remove the tmp file
trap - EXIT
rm -rf "$GNUPGHOME"
cleanup
}