Merge commit 'dkg/master'
authorMatt Goins <mjgoins@openflows.com>
Tue, 10 Mar 2009 13:33:05 +0000 (09:33 -0400)
committerMatt Goins <mjgoins@openflows.com>
Tue, 10 Mar 2009 13:33:05 +0000 (09:33 -0400)
55 files changed:
Makefile
doc/george/changelog
man/man1/monkeysphere.1
man/man1/openpgp2ssh.1
man/man1/pem2openpgp.1
man/man7/monkeysphere.7
man/man8/monkeysphere-authentication.8
man/man8/monkeysphere-host.8
packaging/debian/changelog
packaging/debian/control
packaging/debian/copyright
packaging/debian/monkeysphere.postinst
packaging/debian/monkeysphere.postrm
packaging/debian/monkeysphere.preinst [deleted file]
packaging/debian/monkeysphere.prerm
packaging/freebsd/security/gnutls/files/patch-lib__opencdk__opencdk__use-GNU-dummy.diff [deleted file]
packaging/freebsd/security/monkeysphere/Makefile
packaging/freebsd/security/monkeysphere/distinfo
packaging/freebsd/security/monkeysphere/files/patch-etclocation [deleted file]
packaging/freebsd/security/monkeysphere/files/patch-sharelocation [deleted file]
packaging/freebsd/security/monkeysphere/files/patch-src_monkeysphere-host [new file with mode: 0644]
packaging/freebsd/security/monkeysphere/files/patch-src_share_keytrans [new file with mode: 0644]
packaging/freebsd/security/monkeysphere/files/patch-varlocation [deleted file]
packaging/freebsd/security/monkeysphere/pkg-deinstall
packaging/freebsd/security/monkeysphere/pkg-install
packaging/freebsd/security/monkeysphere/pkg-plist
patches/gnutls/build
src/keytrans/Makefile [deleted file]
src/keytrans/gnutls-helpers.c [deleted file]
src/keytrans/gnutls-helpers.h [deleted file]
src/keytrans/openpgp2ssh.c [deleted file]
src/keytrans/pem2openpgp [deleted file]
src/monkeysphere
src/monkeysphere-authentication
src/monkeysphere-host
src/openpgp2ssh [new symlink]
src/pem2openpgp [new symlink]
src/share/common
src/share/defaultenv [new file with mode: 0644]
src/share/keytrans [new file with mode: 0755]
src/share/m/subkey_to_ssh_agent
src/share/ma/add_certifier
src/share/ma/diagnostics
src/share/ma/setup
src/share/ma/update_users
src/share/mh/diagnostics
src/transitions/0.23
tests/basic
tests/common
utils/preparing-release [new file with mode: 0644]
website/download.mdwn
website/index.mdwn
website/local.css
website/news/release-0.23.1-1.mdwn [new file with mode: 0644]
website/news/release-0.24-1.mdwn [new file with mode: 0644]

index 71df92b935e1d955a0c596da784ed73a564275db..9873d32bc1752a8893048c8bc725ecf608552c6d 100755 (executable)
--- a/Makefile
+++ b/Makefile
@@ -14,16 +14,15 @@ ETCSUFFIX ?=
 PREFIX ?= /usr
 MANPREFIX ?= $(PREFIX)/share/man
 
-all: keytrans
-
-keytrans:
-       $(MAKE) -C src/keytrans
+# nothing actually needs to be built now.
+all: 
 
 tarball: clean
        rm -rf monkeysphere-$(MONKEYSPHERE_VERSION)
        mkdir -p monkeysphere-$(MONKEYSPHERE_VERSION)/doc
        ln -s ../../website/getting-started-user.mdwn ../../website/getting-started-admin.mdwn ../../doc/TODO ../../doc/MonkeySpec monkeysphere-$(MONKEYSPHERE_VERSION)/doc
        ln -s ../COPYING ../etc ../Makefile ../man ../src ../tests monkeysphere-$(MONKEYSPHERE_VERSION)
+       echo $(MONKEYSPHERE_VERSION) > monkeysphere-$(MONKEYSPHERE_VERSION)/VERSION
        tar -ch --exclude='*~' monkeysphere-$(MONKEYSPHERE_VERSION) | gzip -n > monkeysphere_$(MONKEYSPHERE_VERSION).orig.tar.gz
        rm -rf monkeysphere-$(MONKEYSPHERE_VERSION)
 
@@ -39,7 +38,6 @@ freebsd-distinfo:
        ./utils/build-freebsd-distinfo
 
 clean:
-       $(MAKE) -C src/keytrans clean
        # clean up old monkeysphere packages lying around as well.
        rm -f monkeysphere_*
 
@@ -50,9 +48,14 @@ install: all installman
        mkdir -p $(DESTDIR)$(PREFIX)/share/monkeysphere/m $(DESTDIR)$(PREFIX)/share/monkeysphere/mh $(DESTDIR)$(PREFIX)/share/monkeysphere/ma $(DESTDIR)$(PREFIX)/share/monkeysphere/transitions
        mkdir -p $(DESTDIR)$(ETCPREFIX)/etc/monkeysphere
        mkdir -p $(DESTDIR)$(PREFIX)/share/doc/monkeysphere
-       install src/monkeysphere src/keytrans/openpgp2ssh src/keytrans/pem2openpgp $(DESTDIR)$(PREFIX)/bin
+       install -m 0644 VERSION $(DESTDIR)$(PREFIX)/share/monkeysphere
+       install src/monkeysphere $(DESTDIR)$(PREFIX)/bin
        install src/monkeysphere-host src/monkeysphere-authentication $(DESTDIR)$(PREFIX)/sbin
        install -m 0644 src/share/common $(DESTDIR)$(PREFIX)/share/monkeysphere
+       install -m 0644 src/share/defaultenv $(DESTDIR)$(PREFIX)/share/monkeysphere
+       install -m 0755 src/share/keytrans $(DESTDIR)$(PREFIX)/share/monkeysphere
+       ln -s ../share/monkeysphere/keytrans $(DESTDIR)$(PREFIX)/bin/pem2openpgp
+       ln -s ../share/monkeysphere/keytrans $(DESTDIR)$(PREFIX)/bin/openpgp2ssh
        install -m 0744 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
@@ -74,4 +77,7 @@ installman:
 releasenote:
        ./utils/build-releasenote
 
-.PHONY: all tarball debian-package freebsd-distinfo clean install installman releasenote
+test:
+       ./tests/basic
+
+.PHONY: all tarball debian-package freebsd-distinfo clean install installman releasenote test
index 7cd700cac65c65b9ffba034c7234a285270f267a..a4e0289abcd8c8769b9f51e3b6bf05e88cd54300 100644 (file)
@@ -6,7 +6,20 @@
 *  Please add new entries in reverse chronological order whenever you make   *
 *  changes to this system (first command at top, last at bottom)             *
 ******************************************************************************
+2009-02-22 - jrollins
+       * fixed /etc/crontab line for update-users (was trying to run
+       monkeysphere-server instead of monkeysphere-authentication).
 
+2009-02-21 - dkg
+       * upgraded to the latest versions of packages for lenny.
+       * upgraded george to monkeysphere 0.23.1.  the transition upgrade
+       failed due to the way that gpg exports self-signatures secret
+       keys; it only exports the first self-sig for each user id, even if
+       that one is expired.  Then any subsequent import fails, even if
+       the target import keyring knows about some valid self-signatures.
+       * i man-handled the upgrade into place so that george doesn't just
+       fail on us, but this is a pretty major bug in the transition process.
+       
 2009-01-31 - jrollins
        * applied diff represented in commit
        f75a5747a8b99e04c02c475791c476f1fbd2b674 to change log level for
index 887b5df1d9de1a59b1179240ba08ca99c629949c..327a62334a77be5e043b2238c23ed45066421382 100644 (file)
@@ -2,7 +2,7 @@
 
 .SH NAME
 
-monkeysphere \- Monkeysphere client user interface
+monkeysphere - Monkeysphere client user interface
 
 .SH SYNOPSIS
 
@@ -21,7 +21,7 @@ connection authentication.
 
 \fBmonkeysphere\fP takes various subcommands:
 .TP
-.B update-known_hosts [HOST]...
+.B update\-known_hosts [HOST]...
 Update the known_hosts file.  For each specified host, gpg will be
 queried for a key associated with the host URI (see HOST
 IDENTIFICATION in
@@ -37,9 +37,9 @@ known_hosts file will be processed.  This subcommand will exit with a
 status of 0 if at least one acceptable key was found for a specified
 host, 1 if no matching keys were found at all, and 2 if matching keys
 were found but none were acceptable.  `k' may be used in place of
-`update-known_hosts'.
+`update\-known_hosts'.
 .TP
-.B update-authorized_keys
+.B update\-authorized_keys
 Update the authorized_keys file for the user executing the command
 (see MONKEYSPHERE_AUTHORIZED_KEYS in ENVIRONMENT, below).  First all
 monkeysphere keys are cleared from the authorized_keys file.  Then, or
@@ -54,18 +54,18 @@ is found for the user ID, nothing is done.  This subcommand will exit
 with a status of 0 if at least one acceptable key was found for a user
 ID, 1 if no matching keys were found at all, and 2 if matching keys
 were found but none were acceptable.  `a' may be used in place of
-`update-authorized_keys'.
+`update\-authorized_keys'.
 .TP
-.B gen-subkey [KEYID]
+.B gen\-subkey [KEYID]
 Generate an authentication subkey for a private key in your GnuPG
 keyring.  KEYID is the key ID for the primary key for which the subkey
 with "authentication" capability will be generated.  If no key ID is
 specified, but only one key exists in the secret keyring, that key
 will be used.  The length of the generated key can be specified with
-the `--length` or `-l` option.  `g' may be used in place of
-`gen-subkey'.
+the `\-\-length' or `\-l' option.  `g' may be used in place of
+`gen\-subkey'.
 .TP
-.B ssh-proxycommand
+.B ssh\-proxycommand
 An ssh ProxyCommand that can be used to trigger a monkeysphere update
 of the ssh known_hosts file for a host that is being connected to with
 ssh.  This works by updating the known_hosts file for the host first,
@@ -78,16 +78,16 @@ more info).
 This command is meant to be run as the ssh "ProxyCommand".  This can
 either be done by specifying the proxy command on the command line:
 
-.B ssh -o ProxyCommand="monkeysphere ssh-proxycommand %h %p" ...
+.B ssh \-o ProxyCommand="monkeysphere ssh\-proxycommand %h %p" ...
 
 or by adding the following line to your ~/.ssh/config script:
 
-.B ProxyCommand monkeysphere ssh-proxycommand %h %p
+.B ProxyCommand monkeysphere ssh\-proxycommand %h %p
 
 The script can easily be incorporated into other ProxyCommand scripts
-by calling it with the "--no-connect" option, i.e.:
+by calling it with the "\-\-no\-connect" option, i.e.:
 
-.B monkeysphere ssh-proxycommand --no-connect "$HOST" "$PORT"
+.B monkeysphere ssh\-proxycommand \-\-no\-connect "$HOST" "$PORT"
 
 This will run everything except the final exec of netcat to make the
 TCP connection to the host.  In this way this command can be added to
@@ -114,14 +114,17 @@ MONKEYSPHERE_CHECK_KEYSERVER environment variable to either `true' or
 either always or never check the keyserver for host key updates.
 
 .TP
-.B subkey-to-ssh-agent [ssh-add arguments]
+.B subkey\-to\-ssh\-agent [ssh\-add arguments]
 Push all authentication-capable subkeys in your GnuPG secret keyring
 into your running ssh-agent.  Additional arguments are passed through
 to
-.BR ssh-add (1).
+.BR ssh\-add (1).
 For example, to remove the authentication subkeys, pass an additional
-`-d' argument.  To require confirmation on each use of the key, pass
-`-c'.  `s' may be used in place of `subkey-to-ssh-agent'.
+`\-d' argument.  To require confirmation on each use of the key, pass
+`\-c'.  The MONKEYSPHERE_SUBKEYS_FOR_AGENT environment can be used to
+specify the full fingerprints of specific keys to add to the agent
+(space separated), instead of adding them all.  `s' may be used in
+place of `subkey\-to\-ssh\-agent'.
 .TP
 .B help
 Output a brief usage summary.  `h' or `?' may be used in place of
@@ -133,29 +136,33 @@ The following environment variables will override those specified in
 the monkeysphere.conf configuration file (defaults in parentheses):
 .TP
 MONKEYSPHERE_LOG_LEVEL
-Set the log level (INFO).  Can be SILENT, ERROR, INFO, VERBOSE, DEBUG,
-in increasing order of verbosity.
+Set the log level.  Can be SILENT, ERROR, INFO, VERBOSE, DEBUG,
+in increasing order of verbosity. (INFO)
 .TP
 MONKEYSPHERE_GNUPGHOME, GNUPGHOME
-GnuPG home directory (~/.gnupg).
+GnuPG home directory. (~/.gnupg)
 .TP
 MONKEYSPHERE_KEYSERVER
-OpenPGP keyserver to use (subkeys.pgp.net).
+OpenPGP keyserver to use. (pool.sks-keyservers.net)
 .TP
 MONKEYSPHERE_CHECK_KEYSERVER
-Whether or not to check keyserver when making gpg queries (`true').
+Whether or not to check keyserver when making gpg queries. (true)
 .TP
 MONKEYSPHERE_KNOWN_HOSTS
-Path to ssh known_hosts file (~/.ssh/known_hosts).
+Path to ssh known_hosts file. (~/.ssh/known_hosts)
 .TP
 MONKEYSPHERE_HASH_KNOWN_HOSTS
-Whether or not to hash to the known_hosts file entries (`true').
+Whether or not to hash to the known_hosts file entries. (true)
 .TP
 MONKEYSPHERE_AUTHORIZED_KEYS
-Path to ssh authorized_keys file (~/.ssh/authorized_keys).
+Path to ssh authorized_keys file. (~/.ssh/authorized_keys)
 .TP
 MONKEYSPHERE_PROMPT
 If set to `false', never prompt the user for confirmation. (true)
+.TP
+MONKEYSPHERE_SUBKEYS_FOR_AGENT
+A space-separated list of authentication-capable subkeys to add to the
+ssh agent with subkey-to-ssh-agent.
 
 .SH FILES
 
@@ -178,9 +185,9 @@ Daniel Kahn Gillmor <dkg@fifthhorseman.net>
 
 .SH SEE ALSO
 
-.BR monkeysphere-host (8),
-.BR monkeysphere-authentication (8),
+.BR monkeysphere\-host (8),
+.BR monkeysphere\-authentication (8),
 .BR monkeysphere (7),
 .BR ssh (1),
-.BR ssh-add (1),
+.BR ssh\-add (1),
 .BR gpg (1)
index 8374a9f7858765bbfd139b89039857fb08f360a8..304a442577b3f60e3765737b999a8d87688bda8c 100644 (file)
@@ -1,5 +1,5 @@
 .\"  -*- nroff -*-
-.Dd $Mdocdate: June 11, 2008 $
+.Dd $Mdocdate: March 1, 2009 $
 .Dt OPENPGP2SSH 1
 .Os
 .Sh NAME
@@ -8,9 +8,9 @@ openpgp2ssh
 .Sh SYNOPSIS
 .Nm openpgp2ssh < mykey.gpg 
 .Pp
-.Nm gpg --export $KEYID | openpgp2ssh $KEYID
+.Nm gpg \-\-export $KEYID | openpgp2ssh $KEYID
 .Pp
-.Nm gpg --export-secret-key $KEYID | openpgp2ssh $KEYID
+.Nm gpg \-\-export\-secret\-key $KEYID | openpgp2ssh $KEYID
 .Sh DESCRIPTION
 .Nm
 takes an OpenPGP-formatted primary key and associated
@@ -28,13 +28,13 @@ fingerprint of the key or subkey desired, but
 will accept as few as the last 8 digits of the fingerprint as a key
 ID.
 .Pp
-If the input contains an OpenPGP RSA or DSA public key, it will be
-converted to the OpenSSH-style single-line keystring, prefixed with
-the key type.  This format is suitable (with minor alterations) for
+If the input contains an OpenPGP RSA public key, it will be converted
+to the OpenSSH-style single-line keystring, prefixed with the key type
+(`ssh\-rsa').  This format is suitable (with minor alterations) for
 insertion into known_hosts files and authorized_keys files.
 .Pp
-If the input contains an OpenPGP RSA or DSA secret key, it will be
-converted to the equivalent PEM-encoded private key.
+If the input contains an OpenPGP RSA secret key, it will be converted
+to the equivalent PEM-encoded private key.
 .Pp
 .Nm
 is part of the
@@ -47,24 +47,19 @@ intentional, since ssh attaches no inherent significance to these
 features.
 .Pp
 .Nm
-only works with RSA or DSA keys, because those are the
-only ones which work with ssh.
-.Pp
-Assuming a valid key type, though, 
-.Nm
-will produce output for
-any requested key.  This means, among other things, that it will
-happily export revoked keys, unverifiable keys, expired keys, etc.
-Make sure you do your own key validation before using this tool!
+will produce output for any requested RSA key.  This means, among
+other things, that it will happily export revoked keys, unverifiable
+keys, expired keys, etc.  Make sure you do your own key validation
+before using this tool!
 .Sh EXAMPLES
-.Nm gpg --export-secret-key $KEYID | openpgp2ssh $KEYID | ssh-add -c /dev/stdin
+.Nm gpg \-\-export\-secret\-key $KEYID | openpgp2ssh $KEYID | ssh\-add \-c /dev/stdin
 .Pp
 This pushes the secret key into the active
-.Xr ssh-agent 1 . 
+.Xr ssh\-agent 1 . 
 Tools such as 
 .Xr ssh 1
 which know how to talk to the 
-.Xr ssh-agent 1
+.Xr ssh\-agent 1
 can now rely on the key.
 .Sh AUTHOR
 .Nm
@@ -72,26 +67,28 @@ and this man page were written by Daniel Kahn Gillmor
 <dkg@fifthhorseman.net>.
 .Sh BUGS
 .Nm
+only works with RSA keys.  DSA keys are the only other key type
+available in both OpenPGP and SSH, but they are currently unsupported
+by this utility.
+.Pp
+.Nm
+only accepts raw OpenPGP packets on standard input.  It does not
+accept ASCII-armored input.
+.Nm
 Currently only exports into formats used by the OpenSSH.
 It should support other key output formats, such as those used by
-lsh(1) and putty(1).
+.Xr lsh 1
+and
+.Xr putty 1 .
 .Pp
 Secret key output is currently not passphrase-protected.
 .Pp
 .Nm
 currently cannot handle passphrase-protected secret keys on input.
-.Pp
-Key identifiers consisting of an odd number of hex digits are not
-accepted.  Users who use a key ID with a standard length of 8, 16, or
-40 hex digits should not be affected by this.
-.Pp
-.Nm
-only acts on keys associated with the first primary key
-passed in.  If you send it more than one primary key, it will silently
-ignore later ones.
 .Sh SEE ALSO
 .Xr pem2openpgp 1 ,
 .Xr monkeysphere 1 ,
 .Xr monkeysphere 7 ,
 .Xr ssh 1 ,
-.Xr monkeysphere-server 8
+.Xr monkeysphere-authentication 8 ,
+.Xr monkeysphere-host 8
index ae75b113701d0871cb14beea351804aca9953c40..45fd1eeb27fa9fdf8f5ddca3f288a08a835fe9bc 100644 (file)
@@ -1,12 +1,12 @@
 .\"  -*- nroff -*-
-.Dd $Mdocdate: January 25, 2009 $
+.Dd $Mdocdate: March 1, 2009 $
 .Dt PEM2OPENPGP 1
 .Os
 .Sh NAME
 pem2openpgp
 .Nd translate PEM-encoded RSA keys to OpenPGP certificates
 .Sh SYNOPSIS
-.Nm pem2openpgp "$USERID" < mykey.pem | gpg --import
+.Nm pem2openpgp "$USERID" < mykey.pem | gpg \-\-import
 .Pp
 .Nm PEM2OPENPGP_EXPIRATION=$((86400 * $DAYS)) PEM2OPENPGP_USAGE_FLAGS=authentication,certify pem2openpgp "$USERID" <mykey.pem
 .Sh DESCRIPTION
@@ -61,7 +61,7 @@ will read the key from stdin.
 and this man page were written by Daniel Kahn Gillmor
 <dkg@fifthhorseman.net>.
 .Sh BUGS
-Only handles RSA keys at the moment.  It would be nice to handle DSA
+Only handles RSA keys at the moment.  It might be nice to handle DSA
 keys as well.
 .Pp
 Currently only creates certificates with a single User ID.  Should be
@@ -81,5 +81,5 @@ https://labs.riseup.net/code/projects/show/monkeysphere
 .Xr monkeysphere 1 ,
 .Xr monkeysphere 7 ,
 .Xr ssh 1 ,
-.Xr monkeysphere-host 8 ,
-.Xr monkeysphere-authentication 8
+.Xr monkeysphere\-host 8 ,
+.Xr monkeysphere\-authentication 8
index 578d96cef5f4408692478b569de7be6ae5cfb685..f5a23718c933d0138923eb32c785f7e7feb34282 100644 (file)
@@ -1,8 +1,8 @@
-.TH MONKEYSPHERE "7" "June 2008" "monkeysphere" "System Frameworks"
+.TH MONKEYSPHERE "7" "March 2009" "monkeysphere" "System Frameworks"
 
 .SH NAME
 
-monkeysphere \- ssh authentication framework using OpenPGP Web of
+monkeysphere - ssh authentication framework using OpenPGP Web of
 Trust
 
 .SH DESCRIPTION
@@ -14,7 +14,33 @@ connection authentication.
 
 .SH IDENTITY CERTIFIERS
 
-FIXME: describe identity certifier concept
+Each host that uses the \fBMonkeysphere\fP to authenticate its remote
+users needs some way to determine that those users are who they claim
+to be.  SSH permits key-based authentication, but we want instead to
+bind authenticators to human-comprehensible user identities.  This
+switch from raw keys to User IDs makes it possible for administrators
+to see intuitively who has access to an account, and it also enables
+end users to transition keys (and revoke compromised ones)
+automatically across all \fBMonkeysphere\fP-enabled hosts.  The User
+IDs and certifications that the \fBMonkeysphere\fP relies on are found
+in the OpenPGP Web of Trust.
+
+However, in order to establish this binding, each host must know whose
+cerifications to trust.  Someone who a host trusts to certify User
+Identities is called an Identity Certifier.  A host must have at least
+one Identity Certifier in order to bind User IDs to keys.  Commonly,
+every ID Certifier would be trusted by the host to fully identify any
+User ID, but more nuanced approaches are possible as well.  For
+example, a given host could specify a dozen ID certifiers, but assign
+them all "marginal" trust.  Then any given User ID would need to be
+certified in the OpenPGP Web of Trust by at least three of those
+certifiers. 
+
+It is also possible to limit the scope of trust for a given ID
+Certifier to a particular domain.  That is, a host can be configured
+to fully (or marginally) trust a particular ID Certifier only when
+they certify identities within, say, example.org (based on the e-mail
+address in the User ID).
 
 .SH KEY ACCEPTABILITY
 
@@ -24,7 +50,7 @@ ssh authentication.  OpenPGP keys are considered acceptable if the
 following criteria are met:
 .TP
 .B capability
-The key must have the "authentication" ("a") usage flag set.
+The key must have the `authentication' (`a') usage flag set.
 .TP
 .B validity
 The key itself must be valid, i.e. it must be well-formed, not
@@ -36,7 +62,7 @@ The relevant user ID must be signed by a trusted identity certifier.
 .SH HOST IDENTIFICATION
 
 The OpenPGP keys for hosts have associated user IDs that use the ssh
-URI specification for the host, i.e. "ssh://host.full.domain[:port]".
+URI specification for the host, i.e. `ssh://host.full.domain[:port]'.
 
 .SH AUTHOR
 
@@ -47,11 +73,11 @@ Daniel Kahn Gillmor <dkg@fifthhorseman.net>
 .SH SEE ALSO
 
 .BR monkeysphere (1),
-.BR monkeysphere-host (8),
-.BR monkeysphere-authentication (8),
+.BR monkeysphere\-host (8),
+.BR monkeysphere\-authentication (8),
 .BR openpgp2ssh (1),
 .BR pem2openpgp (1),
 .BR gpg (1),
 .BR http://tools.ietf.org/html/rfc4880,
 .BR ssh (1),
-.BR http://tools.ietf.org/wg/secsh/draft-ietf-secsh-scp-sftp-ssh-uri/
+.BR http://tools.ietf.org/wg/secsh/draft\-ietf\-secsh\-scp\-sftp\-ssh\-uri/
index 361822d4382b9fe6bb742c50a3a2868a31c79e26..a28922c7cb071887661b52691eacde97781be1f8 100644 (file)
@@ -1,29 +1,29 @@
-.TH MONKEYSPHERE-SERVER "8" "June 2008" "monkeysphere" "User Commands"
+.TH MONKEYSPHERE-SERVER "8" "March 2009" "monkeysphere" "User Commands"
 
 .SH NAME
 
-monkeysphere-authentication \- Monkeysphere authentication admin tool.
+monkeysphere\-authentication - Monkeysphere authentication admin tool.
 
 .SH SYNOPSIS
 
-.B monkeysphere-authentication \fIsubcommand\fP [\fIargs\fP]
-.br
-.B monkeysphere-authentication expert \fIexpert-subcommand\fP [\fIargs\fP]
+.B monkeysphere\-authentication \fIsubcommand\fP [\fIargs\fP]
 
 .SH DESCRIPTION
 
-\fBMonkeysphere\fP is a framework to leverage the OpenPGP web of trust for
-OpenSSH authentication.  OpenPGP keys are tracked via GnuPG, and added to the
-authorized_keys and known_hosts files used by OpenSSH for connection
-authentication.
+\fBMonkeysphere\fP is a framework to leverage the OpenPGP Web of Trust
+(WoT) for OpenSSH authentication.  OpenPGP keys are tracked via GnuPG,
+and added to the authorized_keys and known_hosts files used by OpenSSH
+for connection authentication.
 
-\fBmonkeysphere-authentication\fP is a Monkeysphere server admin utility.
+\fBmonkeysphere\-authentication\fP is a Monkeysphere server admin
+utility for configuring and managing SSH user authentication through
+the WoT.
 
 .SH SUBCOMMANDS
 
-\fBmonkeysphere-authentication\fP takes various subcommands:
+\fBmonkeysphere\-authentication\fP takes various subcommands:
 .TP
-.B update-users [ACCOUNT]...
+.B update\-users [ACCOUNT]...
 Rebuild the monkeysphere-controlled authorized_keys files.  For each
 specified account, the user ID's listed in the account's
 authorized_user_ids file are processed.  For each user ID, gpg will be
@@ -35,29 +35,29 @@ RAW_AUTHORIZED_KEYS variable is set, then a separate authorized_keys
 file (usually ~USER/.ssh/authorized_keys) is appended to the
 monkeysphere-controlled authorized_keys file.  If no accounts are
 specified, then all accounts on the system are processed.  `u' may be
-used in place of `update-users'.
+used in place of `update\-users'.
 .TP
-.B add-id-certifier KEYID|FILE
+.B add\-id\-certifier KEYID|FILE
 Instruct system to trust user identity certifications made by KEYID.
 The key ID will be loaded from the keyserver.  A file may be loaded
 instead of pulling the key from the keyserver by specifying the path
-to the file as the argument, or by specifying `-` to load from stdin.
-Using the `-n' or `--domain' option allows you to indicate that you
+to the file as the argument, or by specifying `\-' to load from stdin.
+Using the `\-n' or `\-\-domain' option allows you to indicate that you
 only trust the given KEYID to make identifications within a specific
 domain (e.g. "trust KEYID to certify user identities within the
 @example.org domain").  A certifier trust level can be specified with
-the `-t' or `--trust' option (possible values are `marginal' and
+the `\-t' or `\-\-trust' option (possible values are `marginal' and
 `full' (default is `full')).  A certifier trust depth can be specified
-with the `-d' or `--depth' option (default is 1).  `c+' may be used in
-place of `add-id-certifier'.
+with the `\-d' or `\-\-depth' option (default is 1).  `c+' may be used in
+place of `add\-id\-certifier'.
 .TP
-.B remove-id-certifier KEYID
+.B remove\-id\-certifier KEYID
 Instruct system to ignore user identity certifications made by KEYID.
-`c-' may be used in place of `remove-id-certifier'.
+`c\-' may be used in place of `remove\-id\-certifier'.
 .TP
-.B list-id-certifiers
+.B list\-id\-certifiers
 List key IDs trusted by the system to certify user identities.  `c'
-may be used in place of `list-id-certifiers'.
+may be used in place of `list\-id\-certifiers'.
 .TP
 .B help
 Output a brief usage summary.  `h' or `?' may be used in place of
@@ -69,30 +69,30 @@ show version number
 Other commands:
 .TP
 .B setup
-Setup the server for Monkeysphere user authentication.  This command
-is idempotent and run automatically by the other commands, and should
-therefore not usually need to be run manually.  `s' may be used in
-place of `setup'.
+Setup the server in preparation for Monkeysphere user authentication.
+This command is idempotent and run automatically by the other
+commands, and should therefore not usually need to be run manually.
+`s' may be used in place of `setup'.
 .TP
 .B diagnostics
 Review the state of the server with respect to authentication.  `d'
 may be used in place of `diagnostics'.
 .TP
-.B gpg-cmd
+.B gpg\-cmd
 Execute a gpg command, as the monkeysphere user, on the monkeysphere
-authentication "sphere" keyring.  This takes a single argument
-(multiple gpg arguments need to be quoted).  Use this command with
-caution, as modifying the authentication sphere keyring can affect ssh
-user authentication.
+authentication `sphere' keyring.  This takes a single argument
+(i.e. multiple gpg arguments need to be quoted all together).  Use
+this command with caution, as modifying the authentication sphere
+keyring can affect ssh user authentication.
 
 .SH SETUP USER AUTHENTICATION
 
 If the server will handle user authentication through
 monkeysphere-generated authorized_keys files, the server must be told
 which keys will act as identity certifiers.  This is done with the
-\fBadd-id-certifier\fP command:
+\fBadd\-id\-certifier\fP command:
 
-$ monkeysphere-authentication add-id-certifier KEYID
+# monkeysphere\-authentication add\-id\-certifier KEYID
 
 where KEYID is the key ID of the server admin, or whoever's
 certifications should be acceptable to the system for the purposes of
@@ -100,32 +100,34 @@ authenticating remote users.  You can run this command multiple times
 to indicate that multiple certifiers are trusted.  You may also
 specify a filename instead of a key ID, as long as the file contains a
 single OpenPGP public key.  Certifiers can be removed with the
-\fBremove-id-certifier\fP command, and listed with the
-\fBlist-id-certifiers\fP command.
+\fBremove\-id\-certifier\fP command, and listed with the
+\fBlist\-id\-certifiers\fP command.
 
-Remote users will then be granted access to a local account based on
-the appropriately-signed and valid keys associated with user IDs
-listed in that account's authorized_user_ids file.  By default, the
+A remote user will be granted access to a local account based on the
+appropriately-signed and valid keys associated with user IDs listed in
+that account's authorized_user_ids file.  By default, the
 authorized_user_ids file for an account is
 ~/.monkeysphere/authorized_user_ids.  This can be changed in the
-monkeysphere-authentication.conf file.
+monkeysphere\-authentication.conf file.
 
-The \fBupdate-users\fP command can then be used to generate
-authorized_keys file for local accounts based on the authorized user
-IDs listed in the account's authorized_user_ids file:
+The \fBupdate\-users\fP command is used to generate authorized_keys
+files for a local account based on the user IDs listed in the
+account's authorized_user_ids file:
 
-$ monkeysphere-authentication update-users USER
+# monkeysphere\-authentication update\-users USER
 
 Not specifying USER will cause all accounts on the system to updated.
-sshd can then use these monkeysphere generated authorized_keys files
-to grant access to user accounts for remote users.  You must also tell
+The ssh server can use these monkeysphere-generated authorized_keys
+files to grant access to user accounts for remote users.  In order for
 sshd to look at the monkeysphere-generated authorized_keys file for
-user authentication by setting the following in the sshd_config:
+user authentication, the AuthorizedKeysFile parameter must be set in
+the sshd_config to point to the monkeysphere\-generated
+authorized_keys files:
 
 AuthorizedKeysFile /var/lib/monkeysphere/authentication/authorized_keys/%u
 
-It is recommended to add "monkeysphere-authentication update-users" to a
-system crontab, so that user keys are kept up-to-date, and key
+It is recommended to add "monkeysphere\-authentication update\-users"
+to a system crontab, so that user keys are kept up-to-date, and key
 revocations and expirations can be processed in a timely manner.
 
 .SH ENVIRONMENT
@@ -141,7 +143,7 @@ Set the log level.  Can be SILENT, ERROR, INFO, VERBOSE, DEBUG, in
 increasing order of verbosity. (INFO)
 .TP
 MONKEYSPHERE_KEYSERVER
-OpenPGP keyserver to use. (pool.sks-keyservers.net)
+OpenPGP keyserver to use. (pool.sks\-keyservers.net)
 .TP
 MONKEYSPHERE_AUTHORIZED_USER_IDS
 Path to user's authorized_user_ids file. %h gets replaced with the
@@ -157,11 +159,10 @@ raw authorized_keys file.  %h gets replaced with the user's homedir,
 MONKEYSPHERE_PROMPT
 If set to `false', never prompt the user for confirmation. (true)
 
-
 .SH FILES
 
 .TP
-/etc/monkeysphere/monkeysphere-authentication.conf
+/etc/monkeysphere/monkeysphere\-authentication.conf
 System monkeysphere-authentication config file.
 .TP
 /var/lib/monkeysphere/authorized_keys/USER
@@ -169,7 +170,7 @@ Monkeysphere-generated user authorized_keys files.
 
 .SH AUTHOR
 
-Written by:
+This man page was written by:
 Jameson Rollins <jrollins@fifthhorseman.net>,
 Daniel Kahn Gillmor <dkg@fifthhorseman.net>,
 Matthew Goins <mjgoins@openflows.com>
@@ -177,7 +178,9 @@ Matthew Goins <mjgoins@openflows.com>
 .SH SEE ALSO
 
 .BR monkeysphere (1),
-.BR monkeysphere-host (8),
+.BR monkeysphere\-host (8),
 .BR monkeysphere (7),
 .BR gpg (1),
-.BR ssh (1)
+.BR ssh (1),
+.BR sshd (8),
+.BR sshd_config (5)
index 7909b62789472d4b3d0f9416527a8349844d8153..3e01105b660a03fb0e434276b74cd212ad1679d0 100644 (file)
@@ -1,14 +1,12 @@
-.TH MONKEYSPHERE-SERVER "8" "June 2008" "monkeysphere" "User Commands"
+.TH MONKEYSPHERE-SERVER "8" "March 2009" "monkeysphere" "User Commands"
 
 .SH NAME
 
-monkeysphere-host \- Monkeysphere host admin tool.
+monkeysphere\-host - Monkeysphere host admin tool.
 
 .SH SYNOPSIS
 
-.B monkeysphere-host \fIsubcommand\fP [\fIargs\fP]
-.br
-.B monkeysphere-host expert \fIexpert-subcommand\fP [\fIargs\fP]
+.B monkeysphere\-host \fIsubcommand\fP [\fIargs\fP]
 
 .SH DESCRIPTION
 
@@ -17,29 +15,31 @@ for OpenSSH authentication.  OpenPGP keys are tracked via GnuPG, and
 added to the authorized_keys and known_hosts files used by OpenSSH for
 connection authentication.
 
-\fBmonkeysphere-host\fP is a Monkeysphere server admin utility.
+\fBmonkeysphere\-host\fP is a Monkeysphere server admin utility for
+managing the host's OpenPGP host key.
 
 .SH SUBCOMMANDS
 
-\fBmonkeysphere-host\fP takes various subcommands:
+\fBmonkeysphere\-host\fP takes various subcommands:
 .TP
-.B import-key FILE NAME[:PORT]
-Import a pem-encoded ssh secret host key from file FILE.  If FILE
-is '-', then the key will be imported from stdin.  NAME[:PORT] is used
-to specify the fully-qualified hostname (and port) used in the user ID
-of the new OpenPGP key.  If PORT is not specified, the no port is
-added to the user ID, which means port 22 is assumed.  `i' may be used
-in place of `import-key'.
+.B import\-key FILE NAME[:PORT]
+Import a pem-encoded ssh secret host key from file FILE.  If FILE is
+`\-', then the key will be imported from stdin.  Only RSA keys are
+supported at the moment.  NAME[:PORT] is used to specify the
+fully-qualified hostname (and port) used in the user ID of the new
+OpenPGP key.  If PORT is not specified, the no port is added to the
+user ID, which means port 22 is assumed.  `i' may be used in place of
+`import\-key'.
 .TP
-.B show-key
+.B show\-key
 Output information about host's OpenPGP and SSH keys.  `s' may be used
-in place of `show-key'.
+in place of `show\-key'.
 .TP
-.B extend-key [EXPIRE]
+.B set\-expire [EXPIRE]
 Extend the validity of the OpenPGP key for the host until EXPIRE from
 the present.  If EXPIRE is not specified, then the user will be
 prompted for the extension term.  Expiration is specified as with
-GnuPG:
+GnuPG (measured from today's date):
 .nf
          0 = key does not expire
       <n>  = key expires in n days
@@ -47,24 +47,24 @@ GnuPG:
       <n>m = key expires in n months
       <n>y = key expires in n years
 .fi
-`e' may be used in place of `extend-key'.
+`e' may be used in place of `set\-expire'.
 .TP
-.B add-hostname HOSTNAME
+.B add\-hostname HOSTNAME
 Add a hostname user ID to the server host key.  `n+' may be used in
-place of `add-hostname'.
+place of `add\-hostname'.
 .TP
-.B revoke-hostname HOSTNAME
-Revoke a hostname user ID from the server host key.  `n-' may be used
-in place of `revoke-hostname'.
+.B revoke\-hostname HOSTNAME
+Revoke a hostname user ID from the server host key.  `n\-' may be used
+in place of `revoke\-hostname'.
 .TP
-.B add-revoker KEYID|FILE
+.B add\-revoker KEYID|FILE
 Add a revoker to the host's OpenPGP key.  The key ID will be loaded
 from the keyserver.  A file may be loaded instead of pulling the key
 from the keyserver by specifying the path to the file as the argument,
-or by specifying `-` to load from stdin.  `r+' may be be used in place
+or by specifying `\-' to load from stdin.  `r+' may be be used in place
 of `add-revoker'.
 .TP
-.B revoke-key
+.B revoke\-key
 Generate (with the option to publish) a revocation certificate for the
 host's OpenPGP key.  If such a certificate is published, your host key
 will be permanently revoked.  This subcommand will ask you a series of
@@ -73,9 +73,10 @@ to stdout.  If you explicitly tell it to publish the revocation
 certificate immediately, it will send it to the public keyservers.
 USE WITH CAUTION!
 .TP
-.B publish-key
-Publish the host's OpenPGP key to the keyserver.  `p' may be used in
-place of `publish-key'.
+.B publish\-key
+Publish the host's OpenPGP key to the public keyservers.  `p' may be
+used in place of `publish-key'.  Note that there is no way to remove a
+key from the public keyservers once it is published!
 .TP
 .B help
 Output a brief usage summary.  `h' or `?' may be used in place of
@@ -90,25 +91,41 @@ Other commands:
 .B diagnostics
 Review the state of the monkeysphere server host key and report on
 suggested changes.  Among other checks, this includes making sure
-there is a valid host key, that the key is published, that the sshd
+there is a valid host key, that the key is not expired, that the sshd
 configuration points to the right place, etc.  `d' may be used in
 place of `diagnostics'.
 
 .SH SETUP HOST AUTHENTICATION
 
-To enable host verification via the monkeysphere, the host's key must
-be published to the Web of Trust.  This is not done by default.  To
-publish the host key to the keyservers, run the following command:
+To enable host verification via the monkeysphere, an OpenPGP key must
+be made out of the host's ssh key, and the key must be published to
+the Web of Trust.  This is not done by default.  The first step is to
+import the host's ssh key into a monkeysphere-style OpenPGP key.  This
+is done with the import\-key command.  When importing a key, you must
+specify the path to the host's ssh RSA key to import, and a hostname
+to use as the key's user ID:
 
-$ monkeysphere-host publish-key
+# monkeysphere\-host import\-key /etc/ssh/ssh_host_rsa_key host.example.org
+
+On most systems, the ssh host RSA key is stored at
+/etc/ssh/ssh_host_rsa_key.
+
+Once the host key has been imported, it must be published to the Web
+of Trust so that users can retrieve the key when sshing to the host.
+The host key is published to the keyserver with the publish\-key
+command:
+
+$ monkeysphere\-host publish\-key
 
 In order for users logging into the system to be able to identify the
 host via the monkeysphere, at least one person (e.g. a server admin)
 will need to sign the host's key.  This is done using standard OpenPGP
 keysigning techniques, usually: pull the key from the keyserver,
-verify and sign the key, and then re-publish the signature.  Once an
-admin's signature is published, users logging into the host can use it
-to validate the host's key.
+verify and sign the key, and then re-publish the signature.  Please
+see http://web.monkeysphere.info/signing-host-keys/ for more
+information.  Once an admin's signature is published, users logging
+into the host can use it to validate the host's key without having to
+manually check the host key's fingerprint.
 
 .SH ENVIRONMENT
 
@@ -116,29 +133,28 @@ The following environment variables will override those specified in
 the config file (defaults in parentheses):
 .TP
 MONKEYSPHERE_LOG_LEVEL
-Set the log level (INFO).  Can be SILENT, ERROR, INFO, VERBOSE, DEBUG, in
-increasing order of verbosity.
+Set the log level.  Can be SILENT, ERROR, INFO, VERBOSE, DEBUG, in
+increasing order of verbosity. (INFO)
 .TP
 MONKEYSPHERE_KEYSERVER
-OpenPGP keyserver to use (pool.sks-keyservers.net).
+OpenPGP keyserver to use. (pool.sks\-keyservers.net)
 .TP
 MONKEYSPHERE_PROMPT
 If set to `false', never prompt the user for confirmation. (true)
 
-
 .SH FILES
 
 .TP
-/etc/monkeysphere/monkeysphere-host.conf
-System monkeysphere-host config file.
+/etc/monkeysphere/monkeysphere\-host.conf
+System monkeysphere\-host config file.
 .TP
-/var/lib/monkeysphere/host/ssh_host_rsa_key
-Copy of the host's private key in ssh format, suitable for use by
-sshd.
+/var/lib/monkeysphere/host/ssh_host_rsa_key.pub.gpg
+A world-readable copy of the host's public key in OpenPGP format,
+including all relevant self-signatures.
 
 .SH AUTHOR
 
-Written by:
+This man page was written by:
 Jameson Rollins <jrollins@fifthhorseman.net>,
 Daniel Kahn Gillmor <dkg@fifthhorseman.net>,
 Matthew Goins <mjgoins@openflows.com>
@@ -146,7 +162,8 @@ Matthew Goins <mjgoins@openflows.com>
 .SH SEE ALSO
 
 .BR monkeysphere (1),
-.BR monkeysphere-authentication (8),
+.BR monkeysphere\-authentication (8),
 .BR monkeysphere (7),
 .BR gpg (1),
-.BR ssh (1)
+.BR ssh (1),
+.BR sshd (8)
index 50a7071f72c12b3070a51a5f53936d2889530c59..873b0587785f389c263c7ea578cb973daeaeaac2 100644 (file)
@@ -1,3 +1,31 @@
+monkeysphere (0.24-1) unstable; urgency=low
+
+  * New upstream release:
+    - fixed how version information is stored/retrieved
+    - now uses perl-based keytrans for both pem2openpgp and openpgp2ssh
+    - no longer needs base64 in PATH
+    - added "test" make target
+    - improved transitions/0.23 script so it no longer fails in common
+      circumstances (Closes: #517779)
+    - RSA only: no longer handles DSA keys
+    - added ability to specify subkeys to add to ssh agent with
+      new MONKEYSPHERE_SUBKEYS_FOR_AGENT environment variable
+  * update/cleanup maintainer scripts
+  * remove GnuTLS dependency
+  * remove versioned coreutils | base64 dependency
+  * added Build-Deps for dh_autotest
+  * switch to Architecture: all
+  * added cron to Recommends
+
+ -- Jameson Graef Rollins <jrollins@finestructure.net>  Tue, 03 Mar 2009 19:38:33 -0500
+
+monkeysphere (0.23.1-1) unstable; urgency=low
+
+  * New Upstrem "Brown Paper Bag" Release:
+   - adjusts internal version numbers
+
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Sat, 21 Feb 2009 18:09:47 -0500
+
 monkeysphere (0.23-1) unstable; urgency=low
   
   "The Golden Bezoar Release"
index c20b97897f2fba594077ab95be8a497c436c95c0..616a95a373184cb1752571655a7977528f810885 100644 (file)
@@ -3,16 +3,16 @@ Section: net
 Priority: extra
 Maintainer: Jameson Graef Rollins <jrollins@finestructure.net>
 Uploaders: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
-Build-Depends: debhelper (>= 7.0), libgnutls-dev (>= 2.4.0)
+Build-Depends: debhelper (>= 7.0), socat, openssh-server, gnupg, libcrypt-openssl-rsa-perl, libdigest-sha1-perl, lockfile-progs | procmail
 Standards-Version: 3.8.0.1
 Homepage: http://web.monkeysphere.info/
 Vcs-Git: git://git.monkeysphere.info/monkeysphere
 Dm-Upload-Allowed: yes
 
 Package: monkeysphere
-Architecture: any
-Depends: openssh-client, gnupg, coreutils (>= 6) | base64, libcrypt-openssl-rsa-perl, libdigest-sha1-perl, lockfile-progs | procmail, adduser, ${shlibs:Depends}
-Recommends: netcat | socat, ssh-askpass
+Architecture: all
+Depends: openssh-client, gnupg, libcrypt-openssl-rsa-perl, libdigest-sha1-perl, lockfile-progs | procmail, adduser, ${misc:Depends}
+Recommends: netcat | socat, ssh-askpass, cron
 Enhances: openssh-client, openssh-server
 Description: use the OpenPGP web of trust to verify ssh connections
  SSH key-based authentication is tried-and-true, but it lacks a true
index 4c25286e687fa9919a5cc22313e0e9c357a3b41c..c85128fb9364e8acfa0c9decb5fe56449e5a1bfd 100644 (file)
@@ -21,4 +21,4 @@ License: GPL-3+
  (at your option) any later version.
  .
  On Debian systems, the complete text of the GNU General Public License
can be found in file "/usr/share/common-licenses/GPL".
version 3 can be found in file "/usr/share/common-licenses/GPL-3".
index 3d0d66ff1417a365dd9bf0f1b4f2351a75c22bc2..4e811672cb7237ec9508c50a81819a863763c121 100755 (executable)
@@ -1,27 +1,40 @@
-#!/bin/sh -e
+#!/bin/sh
 
 # postinst script for monkeysphere
 
 # Author: Jameson Rollins <jrollins@finestructure.net>
 # Copyright 2008-2009
 
+set -e
+
 VARLIB="/var/lib/monkeysphere"
 
-# add a monkeysphere user if one does not already exist
-if ! getent passwd monkeysphere >/dev/null ; then
-    echo "adding monkeysphere user..."
-    adduser --quiet --system --no-create-home --group \
-       --home "$VARLIB" \
-       --shell '/bin/bash' \
-       --gecos 'monkeysphere authentication user,,,' \
-       monkeysphere
-fi
-
-# try to transition from to 0.23:
-/usr/share/monkeysphere/transitions/0.23
-
-# setup monkeysphere authentication
-monkeysphere-authentication setup
+case $1 in
+    configure)
+       # add a monkeysphere user if one does not already exist
+       if ! getent passwd monkeysphere >/dev/null ; then
+           echo "adding monkeysphere user..."
+           adduser --quiet --system --no-create-home --group \
+               --home "$VARLIB" \
+               --shell '/bin/bash' \
+               --gecos 'monkeysphere authentication user,,,' \
+               monkeysphere
+       fi
+
+       # try all available transitions:
+       for trans in 0.23 ; do
+           /usr/share/monkeysphere/transitions/$trans || { \
+               RET=$?
+               echo "Failed running transition script /usr/share/monkeysphere/transitions/$trans" >&2
+               exit $RET
+           }
+       done
+           
+
+       # setup monkeysphere authentication
+       monkeysphere-authentication setup
+       ;;
+esac
 
 # dh_installdeb will replace this with shell code automatically
 # generated by other debhelper scripts.
index 79f7245c738411594df1e4d61c496bc0f3cee9eb..d78901263f201c5b7bd0b9bc5ef1b693600a449b 100755 (executable)
@@ -1,14 +1,21 @@
-#!/bin/sh -e
+#!/bin/sh
 
 # postrm script for monkeysphere
 
 # Author: Jameson Rollins <jrollins@finestructure.net>
 # Copyright 2008-2009
 
+set -e
+
 case $1 in
     purge)
-        echo "removing monkeysphere user..."
-        userdel monkeysphere > /dev/null || true
+       # delete monkeysphere user
+       # http://wiki.debian.org/AccountHandlingInMaintainerScripts
+       if which deluser >/dev/null 2>&1 ; then
+           deluser --quiet --system monkeysphere > /dev/null || true
+       else
+           echo >&2 "not removing monkeysphere system account because deluser command was not found"
+       fi
         ;;
 esac
 
diff --git a/packaging/debian/monkeysphere.preinst b/packaging/debian/monkeysphere.preinst
deleted file mode 100755 (executable)
index fd22f6f..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/sh -e
-
-# preinst script for monkeysphere
-
-# Author: Jameson Rollins <jrollins@finestructure.net>
-# Copyright 2008-2009
-
-ETC="/etc/monkeysphere"
-
-# move the old server conf file to be the authentication conf file
-if [ -f "$ETC"/monkeysphere-server.conf -a \
-    ! -f "$ETC"/monkeysphere-authentication.conf ] ; then
-    mv "$ETC"/monkeysphere-server.conf "$ETC"/monkeysphere-authentication.conf
-fi
-
-# remove the old gpg-*.conf files
-rm -f "$ETC"/gpg-host.conf
-rm -f "$ETC"/gpg-authentication.conf
-
-# dh_installdeb will replace this with shell code automatically
-# generated by other debhelper scripts.
-
-#DEBHELPER#
-
-exit 0
index 5835f535291ecc6ea21fd70e316c03b25d9b5b7e..1a5135a5e9cdc9418956cda090876083878972c7 100755 (executable)
@@ -2,10 +2,31 @@
 
 # prerm script for monkeysphere
 
-# Author: Jameson Rollins <jrollins@finestructure.net>
-# Copyright 2008-2009
+# the only thing we're doing here is making sure that the local
+# administrator is not trying to downgrade to a version below 0.23,
+# since there was such a major reorganization of system data during
+# the transition to 0.23.
 
-true
+# Author: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+# Copyright 2009
+
+set -e
+
+case "$1" in
+    upgrade)
+       if dpkg --compare-versions "$2" lt 0.23 ; then
+           cat >&2 <<EOF
+
+Downgrading the monkeysphere to a version earlier than 0.23 can have
+BAD CONSEQUENCES, including potentially locking you out of the system.
+Downgrading in this fashion is NOT SUPPORTED.
+
+EOF
+
+           exit 1
+       fi
+    ;;
+esac
 
 # dh_installdeb will replace this with shell code automatically
 # generated by other debhelper scripts.
diff --git a/packaging/freebsd/security/gnutls/files/patch-lib__opencdk__opencdk__use-GNU-dummy.diff b/packaging/freebsd/security/gnutls/files/patch-lib__opencdk__opencdk__use-GNU-dummy.diff
deleted file mode 100644 (file)
index 2450bc3..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
---- ./lib/opencdk/opencdk.h.orig       2008-06-30 16:45:51.000000000 -0400
-+++ ./lib/opencdk/opencdk.h    2008-08-21 19:23:44.000000000 -0400
-@@ -214,7 +214,11 @@
- enum cdk_s2k_type_t {
-     CDK_S2K_SIMPLE     = 0,
-     CDK_S2K_SALTED     = 1,
--    CDK_S2K_ITERSALTED = 3
-+    CDK_S2K_ITERSALTED = 3,
-+    CDK_S2K_GNU_EXT = 101 
-+ /* GNU S2K extensions: refer to DETAILS from GnuPG: 
-+  http://cvs.gnupg.org/cgi-bin/viewcvs.cgi/trunk/doc/DETAILS?root=GnuPG
-+ */
- };
---- ./lib/opencdk/read-packet.c.orig   2008-06-30 16:45:51.000000000 -0400
-+++ ./lib/opencdk/read-packet.c        2008-08-21 19:30:09.000000000 -0400
-@@ -78,10 +78,35 @@
- }
--static int
-+/* read about S2K at http://tools.ietf.org/html/rfc4880#section-3.7.1 */
-+static cdk_error_t
- read_s2k (cdk_stream_t inp, cdk_s2k_t s2k)
- {
--  return CDK_Not_Implemented;
-+  size_t nread;
-+
-+  s2k->mode = cdk_stream_getc (inp);
-+  s2k->hash_algo = cdk_stream_getc (inp);
-+  if (s2k->mode == CDK_S2K_SIMPLE) 
-+      return 0;
-+  else if (s2k->mode == CDK_S2K_SALTED || s2k->mode == CDK_S2K_ITERSALTED)
-+    {
-+      if (stream_read (inp, s2k->salt, DIM (s2k->salt), &nread))
-+      return CDK_Inv_Packet;
-+      if (nread != DIM (s2k->salt))
-+      return CDK_Inv_Packet;
-+      
-+      if (s2k->mode == CDK_S2K_ITERSALTED)
-+      s2k->count = cdk_stream_getc (inp);
-+    }
-+  else if (s2k->mode == CDK_S2K_GNU_EXT)
-+    {
-+      /* GNU extensions to the S2K : read DETAILS from gnupg */
-+      return 0;
-+    }
-+  else
-+    return CDK_Not_Implemented;
-+
-+  return 0;
- }
-@@ -194,6 +219,7 @@
- static cdk_error_t
- read_symkey_enc (cdk_stream_t inp, size_t pktlen, cdk_pkt_symkey_enc_t ske)
- {
-+  cdk_error_t ret;
-   cdk_s2k_t s2k;
-   size_t minlen;
-   size_t nread, nleft;
-@@ -213,7 +239,9 @@
-     return CDK_Out_Of_Core;
-   
-   ske->cipher_algo = cdk_stream_getc (inp);
--  s2k->mode = cdk_stream_getc (inp);
-+  ret = read_s2k(inp, s2k);
-+  if (ret != 0)
-+    return ret;
-   switch (s2k->mode)
-     {
-     case CDK_S2K_SIMPLE    : minlen = 0; break;
-@@ -225,18 +253,6 @@
-       return CDK_Inv_Packet;
-     }
-   
--  s2k->hash_algo = cdk_stream_getc (inp);
--  if (s2k->mode == CDK_S2K_SALTED || s2k->mode == CDK_S2K_ITERSALTED)
--    {
--      if (stream_read (inp, s2k->salt, DIM (s2k->salt), &nread))
--      return CDK_Inv_Packet;
--      if (nread != DIM (s2k->salt))
--      return CDK_Inv_Packet;
--      
--      if (s2k->mode == CDK_S2K_ITERSALTED)
--      s2k->count = cdk_stream_getc (inp);
--    }
--  
-   ske->seskeylen = pktlen - 4 - minlen;
-   /* We check if there is an encrypted session key and if it fits into
-      the buffer. The maximal key length is 256-bit. */
-@@ -421,14 +437,19 @@
-       rc = read_s2k (inp, sk->protect.s2k);
-       if (rc) 
-       return rc;
--      sk->protect.ivlen = gcry_cipher_get_algo_blklen (sk->protect.algo);
--      if (!sk->protect.ivlen)
--      return CDK_Inv_Packet;
--      rc = stream_read (inp, sk->protect.iv, sk->protect.ivlen, &nread);
--      if (rc)
--      return rc;
--      if (nread != sk->protect.ivlen)
--      return CDK_Inv_Packet;
-+      /* refer to --export-secret-subkeys in gpg(1) */
-+      if (sk->protect.s2k->mode == CDK_S2K_GNU_EXT) 
-+      sk->protect.ivlen = 0;
-+      else {
-+      sk->protect.ivlen = gcry_cipher_get_algo_blklen (sk->protect.algo);
-+      if (!sk->protect.ivlen)
-+        return CDK_Inv_Packet;
-+      rc = stream_read (inp, sk->protect.iv, sk->protect.ivlen, &nread);
-+      if (rc)
-+        return rc;
-+      if (nread != sk->protect.ivlen)
-+        return CDK_Inv_Packet;
-+      }
-     }
-   else
-     sk->protect.algo = sk->s2k_usage;
-@@ -476,6 +497,22 @@
-       return CDK_Out_Of_Core;
-       if (stream_read (inp, sk->encdata, sk->enclen, &nread))
-       return CDK_Inv_Packet;
-+      /* Handle the GNU S2K extensions we know (just gnu-dummy right now): */
-+      if (sk->protect.s2k->mode == CDK_S2K_GNU_EXT) {
-+      unsigned char gnumode;
-+      if ((sk->enclen < strlen("GNU") + 1) ||
-+          (0 != memcmp("GNU", sk->encdata, strlen("GNU"))))
-+        return CDK_Inv_Packet;
-+      gnumode = sk->encdata[strlen("GNU")];
-+      /* we only handle gnu-dummy (mode 1).
-+         mode 2 should refer to external smart cards.
-+      */
-+      if (gnumode != 1)
-+        return CDK_Inv_Packet;
-+      /* gnu-dummy should have no more data */
-+      if (sk->enclen != strlen("GNU") + 1)
-+        return CDK_Inv_Packet;
-+      }
-       nskey = cdk_pk_get_nskey (sk->pk->pubkey_algo);
-       if (!nskey)
-       return CDK_Inv_Algo;
index 24f9b2b65d4e9c1383a3a7a1f2949db6d0776fb6..65d71f4bcef66b9f1f9c293b7f66828b4f86914e 100644 (file)
@@ -5,46 +5,62 @@
 # $FreeBSD$
 #
 
-PORTNAME=      monkeysphere
-PORTVERSION=   0.22
-CATEGORIES=    security
-MASTER_SITES=  http://archive.monkeysphere.info/debian/pool/monkeysphere/m/monkeysphere/
+PORTNAME=      monkeysphere
+PORTVERSION=   0.24
+CATEGORIES=    security
+MASTER_SITES=  http://archive.monkeysphere.info/debian/pool/monkeysphere/m/monkeysphere/
 # hack for debian orig tarballs
-DISTFILES=      ${PORTNAME}_${DISTVERSION}.orig.tar.gz
+DISTFILES=     ${PORTNAME}_${DISTVERSION}.orig.tar.gz
 
-MAINTAINER=    dkg@fifthhorseman.net
-COMMENT=       use the OpenPGP web of trust to verify ssh connections
+MAINTAINER=    dkg@fifthhorseman.net
+COMMENT=       Use the OpenPGP web of trust to verify ssh connections
 
-LIB_DEPENDS=   gnutls.26:${PORTSDIR}/security/gnutls
-RUN_DEPENDS=    base64:${PORTSDIR}/converters/base64 \
-               gpg:${PORTSDIR}/security/gnupg1 \
+RUN_DEPENDS=   gpg:${PORTSDIR}/security/gnupg1 \
                lockfile:${PORTSDIR}/mail/procmail \
-               /usr/local/bin/getopt:${PORTSDIR}/misc/getopt \
-               bash:${PORTSDIR}/shells/bash
+               bash:${PORTSDIR}/shells/bash \
+               ${SITE_PERL}/${PERL_ARCH}/Crypt/OpenSSL/RSA.pm:${PORTSDIR}/security/p5-Crypt-OpenSSL-RSA \
+               ${SITE_PERL}/${PERL_ARCH}/Digest/SHA1.pm:${PORTSDIR}/security/p5-Digest-SHA1
 
-MAN1=          monkeysphere.1 openpgp2ssh.1 monkeysphere-ssh-proxycommand.1
+MAN1=          monkeysphere.1 openpgp2ssh.1 pem2openpgp.1
 MAN7=          monkeysphere.7
-MAN8=          monkeysphere-server.8
-MANCOMPRESSED= yes
+MAN8=          monkeysphere-host.8 monkeysphere-authentication.8
+MANCOMPRESSED= yes
 
-MAKE_ARGS= ETCPREFIX=${PREFIX} MANPREFIX=${PREFIX}/man ETCSUFFIX=.sample
+MAKE_ARGS=     ETCPREFIX=${PREFIX} MANPREFIX=${PREFIX}/man ETCSUFFIX=.sample
 
-# get rid of cruft after the patching:
+# use proper system paths for FreeBSD instead of debian's:
 post-patch:
-       find . -iname '*.orig' -delete
+       @${REINPLACE_CMD} -e 's|/etc/monkeysphere|/usr/local/etc/monkeysphere|g' \
+         ${WRKSRC}/src/share/defaultenv \
+         ${WRKSRC}/src/transitions/0.23 \
+         ${WRKSRC}/man/man1/monkeysphere.1 \
+         ${WRKSRC}/man/man8/monkeysphere-authentication.8 \
+         ${WRKSRC}/man/man8/monkeysphere-host.8 \
+         ${WRKSRC}/etc/monkeysphere-authentication.conf
+       @${REINPLACE_CMD} -e 's|/var/lib/monkeysphere|/var/monkeysphere|g' \
+         ${WRKSRC}/src/transitions/0.23 \
+         ${WRKSRC}/man/man1/monkeysphere.1 \
+         ${WRKSRC}/man/man8/monkeysphere-authentication.8 \
+         ${WRKSRC}/man/man8/monkeysphere-host.8 \
+         ${WRKSRC}/src/monkeysphere-host \
+         ${WRKSRC}/src/monkeysphere-authentication \
+         ${WRKSRC}/doc/getting-started-admin.mdwn
+       @${REINPLACE_CMD} -e 's|/usr/share/monkeysphere|/usr/local/share/monkeysphere|g' \
+         ${WRKSRC}/src/monkeysphere-host \
+         ${WRKSRC}/src/monkeysphere-authentication \
+         ${WRKSRC}/src/monkeysphere
+       # and clean up cruft from the sed replacements:
+       ${FIND} ${WRKSRC} -name '*.bak' -delete
 
 post-install:
-       @if [ ! -f ${PREFIX}/etc/monkeysphere/gnupg-host.conf ]; then \
-               ${CP} -p ${PREFIX}/etc/monkeysphere/gnupg-host.conf.sample ${PREFIX}/etc/monkeysphere/gnupg-host.conf ; \
-       fi
-       @if [ ! -f ${PREFIX}/etc/monkeysphere/gnupg-authentication.conf ]; then \
-               ${CP} -p ${PREFIX}/etc/monkeysphere/gnupg-authentication.conf.sample ${PREFIX}/etc/monkeysphere/gnupg-authentication.conf ; \
-       fi
        @if [ ! -f ${PREFIX}/etc/monkeysphere/monkeysphere.conf ]; then \
                ${CP} -p ${PREFIX}/etc/monkeysphere/monkeysphere.conf.sample ${PREFIX}/etc/monkeysphere/monkeysphere.conf ; \
        fi
-       @if [ ! -f ${PREFIX}/etc/monkeysphere/monkeysphere-server.conf ]; then \
-               ${CP} -p ${PREFIX}/etc/monkeysphere/monkeysphere-server.conf.sample ${PREFIX}/etc/monkeysphere/monkeysphere-server.conf ; \
+       @if [ ! -f ${PREFIX}/etc/monkeysphere/monkeysphere-host.conf ]; then \
+               ${CP} -p ${PREFIX}/etc/monkeysphere/monkeysphere-host.conf.sample ${PREFIX}/etc/monkeysphere/monkeysphere-host.conf ; \
+       fi
+       @if [ ! -f ${PREFIX}/etc/monkeysphere/monkeysphere-authentication.conf ]; then \
+               ${CP} -p ${PREFIX}/etc/monkeysphere/monkeysphere-authentication.conf.sample ${PREFIX}/etc/monkeysphere/monkeysphere-authentication.conf ; \
        fi
 .if !defined(PACKAGE_BUILDING)
        @${SETENV} ${SH} ${PKGINSTALL} ${PKGNAME} POST-INSTALL
index d6c6e5e1754f0d20cbea669deb3d406f8b91a7b1..a0a9df9e98e6ac233b22660d1414aa2f960976d0 100644 (file)
@@ -1,3 +1,3 @@
-MD5 (monkeysphere_0.22.orig.tar.gz) = 2bb00c86323409b98aff53f94d9ce0a6
-SHA256 (monkeysphere_0.22.orig.tar.gz) = 2566facda807a67a4d2d6de3833cccfa0b78b454909e8d25f47a235a9e621b24
-SIZE (monkeysphere_0.22.orig.tar.gz) = 70245
+MD5 (monkeysphere_0.24.orig.tar.gz) = 8590532f4702fa44027a6a583657c9ef
+SHA256 (monkeysphere_0.24.orig.tar.gz) = 2a58cee998ddb1b21b953826fc746a743e17d94e6fa34ac9cbee4262873b5c5f
+SIZE (monkeysphere_0.24.orig.tar.gz) = 86044
diff --git a/packaging/freebsd/security/monkeysphere/files/patch-etclocation b/packaging/freebsd/security/monkeysphere/files/patch-etclocation
deleted file mode 100644 (file)
index 2ab3ac0..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-diff --git etc/monkeysphere-server.conf etc/monkeysphere-server.conf
-index c001f2d..d33fd36 100644
---- etc/monkeysphere-server.conf
-+++ etc/monkeysphere-server.conf
-@@ -17,7 +17,7 @@
- # authorized_keys file.  '%h' will be replaced by the home directory
- # of the user, and %u will be replaced by the username of the user.
- # For purely admin-controlled authorized_user_ids, you might put them
--# in /etc/monkeysphere/authorized_user_ids/%u, for instance.
-+# in /usr/local/etc/monkeysphere/authorized_user_ids/%u, for instance.
- #AUTHORIZED_USER_IDS="%h/.monkeysphere/authorized_user_ids"
- # Whether to add user controlled authorized_keys file to
-diff --git man/man1/monkeysphere.1 man/man1/monkeysphere.1
-index 3ece735..09320d2 100644
---- man/man1/monkeysphere.1
-+++ man/man1/monkeysphere.1
-@@ -111,7 +111,7 @@ Path to ssh authorized_keys file (~/.ssh/authorized_keys).
- ~/.monkeysphere/monkeysphere.conf
- User monkeysphere config file.
- .TP
--/etc/monkeysphere/monkeysphere.conf
-+/usr/local/etc/monkeysphere/monkeysphere.conf
- System-wide monkeysphere config file.
- .TP
- ~/.monkeysphere/authorized_user_ids
-diff --git man/man8/monkeysphere-server.8 man/man8/monkeysphere-server.8
-index f207e2c..360408e 100644
---- man/man8/monkeysphere-server.8
-+++ man/man8/monkeysphere-server.8
-@@ -203,10 +203,10 @@ User to control authentication keychain (monkeysphere).
- .SH FILES
- .TP
--/etc/monkeysphere/monkeysphere-server.conf
-+/usr/local/etc/monkeysphere/monkeysphere-server.conf
- System monkeysphere-server config file.
- .TP
--/etc/monkeysphere/monkeysphere.conf
-+/usr/local/etc/monkeysphere/monkeysphere.conf
- System-wide monkeysphere config file.
- .TP
- /var/lib/monkeysphere/authorized_keys/USER
---- src/common.orig    2008-10-12 14:58:00.000000000 -0400
-+++ src/common 2008-10-25 17:40:34.000000000 -0400
-@@ -16,7 +16,7 @@
- ### COMMON VARIABLES
- # managed directories
--SYSCONFIGDIR=${MONKEYSPHERE_SYSCONFIGDIR:-"/etc/monkeysphere"}
-+SYSCONFIGDIR=${MONKEYSPHERE_SYSCONFIGDIR:-"/usr/local/etc/monkeysphere"}
- export SYSCONFIGDIR
- ########################################################################
diff --git a/packaging/freebsd/security/monkeysphere/files/patch-sharelocation b/packaging/freebsd/security/monkeysphere/files/patch-sharelocation
deleted file mode 100644 (file)
index e41c479..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
---- src/monkeysphere.orig      2008-10-12 14:58:00.000000000 -0400
-+++ src/monkeysphere   2008-10-25 17:41:41.000000000 -0400
-@@ -13,7 +13,7 @@
- ########################################################################
- PGRM=$(basename $0)
--SYSSHAREDIR=${MONKEYSPHERE_SYSSHAREDIR:-"/usr/share/monkeysphere"}
-+SYSSHAREDIR=${MONKEYSPHERE_SYSSHAREDIR:-"/usr/local/share/monkeysphere"}
- export SYSSHAREDIR
- . "${SYSSHAREDIR}/common" || exit 1
---- src/monkeysphere-server.orig       2008-10-25 14:17:50.000000000 -0400
-+++ src/monkeysphere-server    2008-10-25 17:42:50.000000000 -0400
-@@ -13,7 +13,7 @@
- ########################################################################
- PGRM=$(basename $0)
--SYSSHAREDIR=${MONKEYSPHERE_SYSSHAREDIR:-"/usr/share/monkeysphere"}
-+SYSSHAREDIR=${MONKEYSPHERE_SYSSHAREDIR:-"/usr/local/share/monkeysphere"}
- export SYSSHAREDIR
- . "${SYSSHAREDIR}/common" || exit 1
---- src/monkeysphere-ssh-proxycommand.orig
-+++ src/monkeysphere-ssh-proxycommand
-@@ -16,7 +16,7 @@
- ########################################################################
- PGRM=$(basename $0)
--SYSSHAREDIR=${MONKEYSPHERE_SYSSHAREDIR:-"/usr/share/monkeysphere"}
-+SYSSHAREDIR=${MONKEYSPHERE_SYSSHAREDIR:-"/usr/local/share/monkeysphere"}
- export SYSSHAREDIR
- . "${SYSSHAREDIR}/common" || exit 1
diff --git a/packaging/freebsd/security/monkeysphere/files/patch-src_monkeysphere-host b/packaging/freebsd/security/monkeysphere/files/patch-src_monkeysphere-host
new file mode 100644 (file)
index 0000000..9414c73
--- /dev/null
@@ -0,0 +1,11 @@
+--- src/monkeysphere-host
++++ src/monkeysphere-host
+@@ -103,7 +103,7 @@ update_gpg_pub_file() {
+ load_fingerprint() {
+     if [ -f "$HOST_KEY_FILE" ] ; then
+       HOST_FINGERPRINT=$( \
+-          (FUBAR=$(mktemp -d) && export GNUPGHOME="$FUBAR" \
++          (FUBAR=$(msmktempdir) && export GNUPGHOME="$FUBAR" \
+           && gpg --quiet --import \
+           && gpg --quiet --list-keys --with-colons --with-fingerprint \
+           && rm -rf "$FUBAR") <"$HOST_KEY_FILE" \
diff --git a/packaging/freebsd/security/monkeysphere/files/patch-src_share_keytrans b/packaging/freebsd/security/monkeysphere/files/patch-src_share_keytrans
new file mode 100644 (file)
index 0000000..9d584ac
--- /dev/null
@@ -0,0 +1,11 @@
+--- src/share/keytrans 2009-03-01 13:39:50.000000000 -0500
++++ src/share/keytrans 2009-03-10 00:39:53.681890554 -0400
+@@ -199,7 +199,7 @@
+ sub simple_checksum {
+   my $bytes = shift;
+-  return unpack("%32W*",$bytes) % 65536;
++  return unpack("%32U*",$bytes) % 65536;
+ }
+ # calculate the multiplicative inverse of a mod b this is euclid's
diff --git a/packaging/freebsd/security/monkeysphere/files/patch-varlocation b/packaging/freebsd/security/monkeysphere/files/patch-varlocation
deleted file mode 100644 (file)
index c4d8dcd..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-diff --git man/man8/monkeysphere-server.8 man/man8/monkeysphere-server.8
-index f207e2c..29c7b6a 100644
---- man/man8/monkeysphere-server.8
-+++ man/man8/monkeysphere-server.8
-@@ -128,7 +128,7 @@ command to push the key to a keyserver.  You must also modify the
- sshd_config on the server to tell sshd where the new server host key
- is located:
--HostKey /var/lib/monkeysphere/ssh_host_rsa_key
-+HostKey /var/monkeysphere/ssh_host_rsa_key
- In order for users logging into the system to be able to verify the
- host via the monkeysphere, at least one person (e.g. a server admin)
-@@ -170,7 +170,7 @@ users.  You must also tell sshd to look at the monkeysphere-generated
- authorized_keys file for user authentication by setting the following
- in the sshd_config:
--AuthorizedKeysFile /var/lib/monkeysphere/authorized_keys/%u
-+AuthorizedKeysFile /var/monkeysphere/authorized_keys/%u
- It is recommended to add "monkeysphere-server update-users" to a
- system crontab, so that user keys are kept up-to-date, and key
-@@ -209,17 +209,17 @@ System monkeysphere-server config file.
- /etc/monkeysphere/monkeysphere.conf
- System-wide monkeysphere config file.
- .TP
--/var/lib/monkeysphere/authorized_keys/USER
-+/var/monkeysphere/authorized_keys/USER
- Monkeysphere-generated user authorized_keys files.
- .TP
--/var/lib/monkeysphere/ssh_host_rsa_key
-+/var/monkeysphere/ssh_host_rsa_key
- Copy of the host's private key in ssh format, suitable for use by
- sshd.
- .TP
--/var/lib/monkeysphere/gnupg-host
-+/var/monkeysphere/gnupg-host
- Monkeysphere host GNUPG home directory.
- .TP
--/var/lib/monkeysphere/gnupg-authentication
-+/var/monkeysphere/gnupg-authentication
- Monkeysphere authentication GNUPG home directory.
- .SH AUTHOR
-diff --git doc/getting-started-admin.mdwn doc/getting-started-admin.mdwn
-index 6c8ad53..67fdda1 100644
---- doc/getting-started-admin.mdwn
-+++ doc/getting-started-admin.mdwn
-@@ -30,7 +30,7 @@ To use the newly-generated host key for ssh connections, put the
- following line in `/etc/ssh/sshd_config` (be sure to remove references
- to any other keys):
--      HostKey /var/lib/monkeysphere/ssh_host_rsa_key
-+      HostKey /var/monkeysphere/ssh_host_rsa_key
- FIXME: should we just suggest symlinks in the filesystem here instead?
-@@ -40,7 +40,7 @@ To enable users to use the monkeysphere to authenticate using the
- OpenPGP web of trust, add this line to `/etc/ssh/sshd_config` (again,
- making sure that no other AuthorizedKeysFile directive exists):
--      AuthorizedKeysFile /var/lib/monkeysphere/authorized_keys/%u
-+      AuthorizedKeysFile /var/monkeysphere/authorized_keys/%u
- And then read the section below about how to ensure these files are
- maintained.  You'll need to restart `sshd` to have your changes take
---- src/monkeysphere-server.orig       2008-10-25 18:01:19.000000000 -0400
-+++ src/monkeysphere-server    2008-10-25 18:01:24.000000000 -0400
-@@ -17,7 +17,7 @@
- export SYSSHAREDIR
- . "${SYSSHAREDIR}/common" || exit 1
--SYSDATADIR=${MONKEYSPHERE_SYSDATADIR:-"/var/lib/monkeysphere"}
-+SYSDATADIR=${MONKEYSPHERE_SYSDATADIR:-"/var/monkeysphere"}
- export SYSDATADIR
- # UTC date in ISO 8601 format if needed
---- etc/gnupg-authentication.conf.orig 2008-10-25 18:02:58.000000000 -0400
-+++ etc/gnupg-authentication.conf      2008-10-25 18:03:04.000000000 -0400
-@@ -4,8 +4,8 @@
- # It is highly recommended that you
- #    DO NOT MODIFY
- # these variables.
--primary-keyring /var/lib/monkeysphere/gnupg-authentication/pubring.gpg
--keyring /var/lib/monkeysphere/gnupg-host/pubring.gpg
-+primary-keyring /var/monkeysphere/gnupg-authentication/pubring.gpg
-+keyring /var/monkeysphere/gnupg-host/pubring.gpg
- # PGP keyserver to use for PGP queries.
- keyserver hkp://pgp.mit.edu
index 30008784182a835c800541d5e7f9a33617c750d1..3e69eabbb1dde8896a3bb71b94d075c058623048 100755 (executable)
@@ -4,9 +4,9 @@
 # monkeysphere's debian/monkeysphere.postrm)
 
 # Author: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
-# Copyright 2008
+# Copyright 2008,2009
 
-# FIXME: is /var/lib/monkeysphere the right place for this stuff on
+# FIXME: is /var/monkeysphere the right place for this stuff on
 # FreeBSD?
 VARLIB="/var/monkeysphere"
 
index 70d37b57514be6bd090a5e897d11d180d813b916..435c69ad12c0c42ea63875be84686a7d7605660f 100755 (executable)
@@ -5,9 +5,9 @@
 # debian/monkeysphere.postinst)
 
 # Author: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
-# Copyright 2008
+# Copyright 2008,2009
 
-# FIXME: is /var/lib/monkeysphere the right place for this stuff on
+# FIXME: is /var/monkeysphere the right place for this stuff on
 # FreeBSD?
 
 # PostgreSQL puts its data in /usr/local/pgsql/data
@@ -57,16 +57,8 @@ POST-INSTALL)
                 fi
         fi
 
-       ## set up the cache directories, and link them to the config files:
+       ## set up the monkeysphere authentication cache directory:
 
-       install -d -o root -g monkeysphere -m 750 "$VARLIB"/gnupg-host
-       ln -sf "$ETCDIR"/gnupg-host.conf  "$VARLIB"/gnupg-host/gpg.conf
-
-       install -d -o monkeysphere -g monkeysphere -m 700 "$VARLIB"/gnupg-authentication
-       ln -sf "$ETCDIR"/gnupg-authentication.conf  "$VARLIB"/gnupg-authentication/gpg.conf
-
-       install -d "$VARLIB"/tmp "$VARLIB"/authorized_keys
-
-       monkeysphere-server diagnostics
+       monkeysphere-authentication setup
         ;;
 esac
index 9d9d40a35e7ceb82a45fdb6fc66957d1e38aa88d..95afa0111dd0df727de11b37c008ca847f9df46c 100644 (file)
@@ -1,24 +1,49 @@
-sbin/monkeysphere-server
+sbin/monkeysphere-host
+sbin/monkeysphere-authentication
 share/doc/monkeysphere/TODO
 share/doc/monkeysphere/MonkeySpec
 share/doc/monkeysphere/getting-started-user.mdwn
 share/doc/monkeysphere/getting-started-admin.mdwn
 bin/openpgp2ssh
-bin/monkeysphere-ssh-proxycommand
+bin/pem2openpgp
 bin/monkeysphere
+share/monkeysphere/mh/publish_key
+share/monkeysphere/mh/import_key
+share/monkeysphere/mh/set_expire
+share/monkeysphere/mh/diagnostics
+share/monkeysphere/mh/add_hostname
+share/monkeysphere/mh/add_revoker
+share/monkeysphere/mh/revoke_hostname
+share/monkeysphere/mh/revoke_key
+share/monkeysphere/keytrans
+share/monkeysphere/defaultenv
+share/monkeysphere/VERSION
+share/monkeysphere/transitions/0.23
+share/monkeysphere/transitions/README.txt
+share/monkeysphere/ma/list_certifiers
+share/monkeysphere/ma/add_certifier
+share/monkeysphere/ma/update_users
+share/monkeysphere/ma/setup
+share/monkeysphere/ma/remove_certifier
+share/monkeysphere/ma/diagnostics
 share/monkeysphere/common
+share/monkeysphere/m/gen_subkey
+share/monkeysphere/m/ssh_proxycommand
+share/monkeysphere/m/subkey_to_ssh_agent
+share/monkeysphere/m/import_subkey
 @unexec if cmp -s %D/etc/monkeysphere/monkeysphere.conf.sample %D/etc/monkeysphere/monkeysphere.conf; then rm -f %D/etc/monkeysphere/monkeysphere.conf; fi
 etc/monkeysphere/monkeysphere.conf.sample
 @exec if [ ! -f %D/etc/monkeysphere/monkeysphere.conf ] ; then cp -p %D/%F %B/monkeysphere.conf; fi
-@unexec if cmp -s %D/etc/monkeysphere/monkeysphere-server.conf.sample %D/etc/monkeysphere/monkeysphere-server.conf; then rm -f %D/etc/monkeysphere/monkeysphere-server.conf; fi
-etc/monkeysphere/monkeysphere-server.conf.sample
-@exec if [ ! -f %D/etc/monkeysphere/monkeysphere-server.conf ] ; then cp -p %D/%F %B/monkeysphere-server.conf; fi
-@unexec if cmp -s %D/etc/monkeysphere/gnupg-host.conf.sample %D/etc/monkeysphere/gnupg-host.conf; then rm -f %D/etc/monkeysphere/gnupg-host.conf; fi
-etc/monkeysphere/gnupg-host.conf.sample
-@exec if [ ! -f %D/etc/monkeysphere/gnupg-host.conf ] ; then cp -p %D/%F %B/gnupg-host.conf; fi
-@unexec if cmp -s %D/etc/monkeysphere/gnupg-authentication.conf.sample %D/etc/monkeysphere/gnupg-authentication.conf; then rm -f %D/etc/monkeysphere/gnupg-authentication.conf; fi
-etc/monkeysphere/gnupg-authentication.conf.sample
-@exec if [ ! -f %D/etc/monkeysphere/gnupg-authentication.conf ] ; then cp -p %D/%F %B/gnupg-authentication.conf; fi
+@unexec if cmp -s %D/etc/monkeysphere/monkeysphere-host.conf.sample %D/etc/monkeysphere/monkeysphere-host.conf; then rm -f %D/etc/monkeysphere/monkeysphere-host.conf; fi
+etc/monkeysphere/monkeysphere-host.conf.sample
+@exec if [ ! -f %D/etc/monkeysphere/monkeysphere-host.conf ] ; then cp -p %D/%F %B/monkeysphere-host.conf; fi
+@unexec if cmp -s %D/etc/monkeysphere/monkeysphere-authentication.conf.sample %D/etc/monkeysphere/monkeysphere-authentication.conf; then rm -f %D/etc/monkeysphere/monkeysphere-authentication.conf; fi
+etc/monkeysphere/monkeysphere-authentication.conf.sample
+@exec if [ ! -f %D/etc/monkeysphere/monkeysphere-authentication.conf ] ; then cp -p %D/%F %B/monkeysphere-authentication.conf; fi
 @dirrm share/doc/monkeysphere
+@dirrm share/monkeysphere/transitions
+@dirrm share/monkeysphere/mh
+@dirrm share/monkeysphere/ma
+@dirrm share/monkeysphere/m
 @dirrm share/monkeysphere
 @dirrm etc/monkeysphere
index 77f5900de079656d1fe29a27637b675f33b44793..b42832a84023a8d91e5e84c77c4e10210eca0b29 100755 (executable)
@@ -16,6 +16,8 @@
 # Note: please run this from the current directory, so it can find and
 # transfer the patch it needs.
 
+set -e
+
 if ! dpkg -l devscripts fakeroot >/dev/null ; then
     exit 1
 fi
diff --git a/src/keytrans/Makefile b/src/keytrans/Makefile
deleted file mode 100644 (file)
index 4d54be7..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-CFLAGS=`libgnutls-config --libs --cflags` -g -Wall --pedantic
-CC=gcc
-
-all: openpgp2ssh
-
-openpgp2ssh: openpgp2ssh.c gnutls-helpers.o
-       $(CC) $(CFLAGS) -o openpgp2ssh openpgp2ssh.c gnutls-helpers.o
-
-.c.o: 
-       $(CC) $(CFLAGS) -c $<
-
-clean: 
-       rm -f openpgp2ssh *.o
-
-.PHONY: clean all
diff --git a/src/keytrans/gnutls-helpers.c b/src/keytrans/gnutls-helpers.c
deleted file mode 100644 (file)
index 8d8ec17..0000000
+++ /dev/null
@@ -1,466 +0,0 @@
-/* Author: Daniel Kahn Gillmor <dkg@fifthhorseman.net> */
-/* Date: Fri, 04 Apr 2008 19:31:16 -0400 */
-/* License: GPL v3 or later */
-
-#include "gnutls-helpers.h"
-/* for htonl() */
-#include <arpa/inet.h>
-
-/* for setlocale() */
-#include <locale.h>
-
-/* for isalnum() */
-#include <ctype.h>
-
-/* for exit() */
-#include <unistd.h>
-
-#include <assert.h>
-
-/* higher levels allow more frivolous error messages through. 
-   this is set with the MONKEYSPHERE_DEBUG variable */
-static int loglevel = 0;
-
-void err(int level, const char* fmt, ...) {
-  va_list ap;
-  if (level > loglevel)
-    return;
-  va_start(ap, fmt);
-  vfprintf(stderr, fmt, ap);
-  va_end(ap);
-  fflush(stderr);
-}
-
-void logfunc(int level, const char* string) {
-  fprintf(stderr, "GnuTLS Logging (%d): %s\n", level, string);
-}
-
-void init_keyid(gnutls_openpgp_keyid_t keyid) {
-  memset(keyid, 'x', sizeof(gnutls_openpgp_keyid_t));
-}
-
-
-
-void make_keyid_printable(printable_keyid out, gnutls_openpgp_keyid_t keyid)
-{
-  assert(sizeof(out) >= 2*sizeof(keyid));
-  hex_print_data((char*)out, (const unsigned char*)keyid, sizeof(keyid));
-}
-
-/* you must have twice as many bytes in the out buffer as in the in buffer */
-void hex_print_data(char* out, const unsigned char* in, size_t incount)
-{
-  static const char hex[16] = "0123456789ABCDEF";
-  unsigned int inix = 0, outix = 0;
-  
-  while (inix < incount) {
-    out[outix] = hex[(in[inix] >> 4) & 0x0f];
-    out[outix + 1] = hex[in[inix] & 0x0f];
-    inix++;
-    outix += 2;
-  }
-}
-
-unsigned char hex2bin(unsigned char x) {
-  if ((x >= '0') && (x <= '9')) 
-    return x - '0';
-  if ((x >= 'A') && (x <= 'F')) 
-    return 10 + x - 'A';
-  if ((x >= 'a') && (x <= 'f')) 
-    return 10 + x - 'a';
-  return 0xff;
-}
-
-void collapse_printable_keyid(gnutls_openpgp_keyid_t out, printable_keyid in) {
-  unsigned int pkix = 0, outkix = 0;
-  while (pkix < sizeof(printable_keyid)) {
-    unsigned hi = hex2bin(in[pkix]);
-    unsigned lo = hex2bin(in[pkix + 1]);
-    if (hi == 0xff) {
-      err(0, "character '%c' is not a hex char\n", in[pkix]);
-      exit(1);
-    }
-    if (lo == 0xff) {
-      err(0, "character '%c' is not a hex char\n", in[pkix + 1]);
-      exit(1);
-    }
-    out[outkix] = lo | (hi << 4);
-
-    pkix += 2;
-    outkix++;
-  }
-}
-
-unsigned int hexstring2bin(unsigned char* out, const char* in) {
-  unsigned int pkix = 0, outkix = 0;
-  int hi = 0; /* which nybble is it? */
-  
-  while (in[pkix]) {
-    unsigned char z = hex2bin(in[pkix]);
-    if (z != 0xff) {
-      if (!hi) {
-       if (out) out[outkix] = (z << 4);
-       hi = 1;
-      } else {
-       if (out) out[outkix] |= z;
-       hi = 0;
-       outkix++;
-      }
-      pkix++;
-    }      
-  }
-  return outkix*8 + (hi ? 4 : 0);
-}
-
-int convert_string_to_keyid(gnutls_openpgp_keyid_t out, const char* str) {
-  printable_keyid p;
-  int ret;
-
-  ret = convert_string_to_printable_keyid(p, str);
-  if (ret == 0) 
-    collapse_printable_keyid(out, p);
-  return ret;
-}
-int convert_string_to_printable_keyid(printable_keyid pkeyid, const char* str) {
-  int arglen, x;
-  arglen = 0;
-  x = 0;
-  while ((arglen <= sizeof(printable_keyid)) &&
-        (str[x] != '\0')) {
-    if (isxdigit(str[x])) {
-      if (arglen == sizeof(printable_keyid)) {
-       err(0, "There are more than %d hex digits in the keyid '%s'\n", sizeof(printable_keyid), str);
-       return 1;
-      }
-      pkeyid[arglen] = str[x];
-      arglen++;
-    }
-    x++;
-  }
-  
-  if (arglen != sizeof(printable_keyid)) {
-    err(0, "Keyid '%s' is not %d hex digits in length\n", str, sizeof(printable_keyid));
-    return 1;
-  }
-  return 0;
-}
-
-
-
-int init_gnutls() {
-  const char* version = NULL;
-  const char* debug_string = NULL;
-  int ret;
-
-  if (debug_string = getenv("MONKEYSPHERE_DEBUG"), debug_string) {
-    loglevel = atoi(debug_string);
-  }
-
-  if (ret = gnutls_global_init(), ret) {
-    err(0, "Failed to do gnutls_global_init() (error: %d)\n", ret);
-    return 1;
-  }
-
-  version = gnutls_check_version(NULL);
-
-  if (version) 
-    err(1, "gnutls version: %s\n", version);
-  else {
-    err(0, "no gnutls version found!\n");
-    return 1;
-  }
-
-  gnutls_global_set_log_function(logfunc);
-  
-  gnutls_global_set_log_level(loglevel);
-  err(1, "set log level to %d\n", loglevel);
-
-  return 0;
-}
-
-void init_datum(gnutls_datum_t* d) {
-  d->data = NULL;
-  d->size = 0;
-}
-void copy_datum(gnutls_datum_t* dest, const gnutls_datum_t* src) {
-  dest->data = gnutls_realloc(dest->data, src->size);
-  dest->size = src->size;
-  memcpy(dest->data, src->data, src->size);
-}
-int compare_data(const gnutls_datum_t* a, const gnutls_datum_t* b) {
-  if (a->size > b->size) {
-    err(0,"a is larger\n");
-    return 1;
-  }
-  if (a->size < b->size) {
-    err(0,"b is larger\n");
-    return -1;
-  }
-  return memcmp(a->data, b->data, a->size);
-}
-void free_datum(gnutls_datum_t* d) {
-  gnutls_free(d->data);
-  d->data = NULL;
-  d->size = 0;
-}
-
-/* read the passed-in string, store in a single datum */
-int set_datum_string(gnutls_datum_t* d, const char* s) {
-  unsigned int x = strlen(s)+1;
-  unsigned char* c = NULL;
-
-  c = gnutls_realloc(d->data, x);
-  if (NULL == c)
-    return -1;
-  d->data = c;
-  d->size = x;
-  memcpy(d->data, s, x);
-  return 0;
-}
-
-/* read the passed-in file descriptor until EOF, store in a single
-   datum */
-int set_datum_fd(gnutls_datum_t* d, int fd) {
-  unsigned int bufsize = 1024;
-  unsigned int len = 0;
-
-  FILE* f = fdopen(fd, "r");
-  if (bufsize > d->size) {
-    bufsize = 1024;
-    d->data = gnutls_realloc(d->data, bufsize);
-    if (d->data == NULL) {
-      err(0,"out of memory!\n");
-      return -1;
-    }
-    d->size = bufsize;
-  } else {
-    bufsize = d->size;
-  }
-  f = fdopen(fd, "r");
-  if (NULL == f) {
-    err(0,"could not fdopen FD %d\n", fd);
-  }
-  clearerr(f);
-  while (!feof(f) && !ferror(f)) { 
-    if (len == bufsize) {
-      /* allocate more space by doubling: */
-      bufsize *= 2;
-      d->data = gnutls_realloc(d->data, bufsize);
-      if (d->data == NULL) {
-       err(0,"out of memory!\n"); 
-       return -1;
-      };
-      d->size = bufsize;
-    }
-    len += fread(d->data + len, 1, bufsize - len, f);
-    /*     err(0,"read %d bytes\n", len); */
-  }
-  if (ferror(f)) {
-    err(0,"Error reading from fd %d (error: %d) (error: %d '%s')\n", fd, ferror(f), errno, strerror(errno));
-    return -1;
-  }
-    
-  /* touch up buffer size to match reality: */
-  d->data = gnutls_realloc(d->data, len);
-  d->size = len;
-  return 0;
-}
-
-/* read the file indicated (by name) in the fname parameter.  store
-   its entire contents in a single datum. */
-int set_datum_file(gnutls_datum_t* d, const char* fname) {
-  struct stat sbuf;
-  unsigned char* c = NULL;
-  FILE* file = NULL;
-  size_t x = 0;
-
-  if (0 != stat(fname, &sbuf)) {
-    err(0,"failed to stat '%s'\n", fname);
-    return -1;
-  }
-  
-  c = gnutls_realloc(d->data, sbuf.st_size);
-  if (NULL == c) {
-    err(0,"failed to allocate %d bytes for '%s'\n", sbuf.st_size, fname);
-    return -1;
-  }
-
-  d->data = c;
-  d->size = sbuf.st_size;
-  file = fopen(fname, "r");
-  if (NULL == file) {
-    err(0,"failed to open '%s' for reading\n",  fname);
-    return -1;
-  }
-
-  x = fread(d->data, d->size, 1, file);
-  if (x != 1) {
-    err(0,"tried to read %d bytes, read %d instead from '%s'\n", d->size, x, fname);
-    fclose(file);
-    return -1;
-  }
-  fclose(file);
-  return 0;
-}
-
-int write_datum_fd(int fd, const gnutls_datum_t* d) {
-  if (d->size != write(fd, d->data, d->size)) {
-    err(0,"failed to write body of datum.\n");
-    return -1;
-  }
-  return 0;
-}
-
-
-int write_datum_fd_with_length(int fd, const gnutls_datum_t* d) {
-  uint32_t len;
-  int looks_negative = (d->data[0] & 0x80);
-  unsigned char zero = 0;
-
-  /* if the first bit is 1, then the datum will appear negative in the
-     MPI encoding style used by OpenSSH.  In that case, we'll increase
-     the length by one, and dump out one more byte */
-
-  if (looks_negative) {
-    len = htonl(d->size + 1);
-  } else {
-    len = htonl(d->size);
-  }
-  if (write(fd, &len, sizeof(len)) != sizeof(len)) {
-    err(0,"failed to write size of datum.\n");
-    return -2;
-  }
-  if (looks_negative) {
-    if (write(fd, &zero, 1) != 1) {
-      err(0,"failed to write padding byte for MPI.\n");
-      return -2;
-    }
-  }
-  return write_datum_fd(fd, d);
-}
-
-int write_data_fd_with_length(int fd, const gnutls_datum_t** d, unsigned int num) {
-  unsigned int i;
-  int ret;
-
-  for (i = 0; i < num; i++)
-    if (ret = write_datum_fd_with_length(fd, d[i]), ret != 0)
-      return ret;
-
-  return 0;
-}
-
-
-int datum_from_string(gnutls_datum_t* d, const char* str) {
-  d->size = strlen(str);
-  d->data = gnutls_realloc(d->data, d->size);
-  if (d->data == 0)
-    return ENOMEM;
-  memcpy(d->data, str, d->size);
-  return 0;
-}
-
-
-int create_writing_pipe(pid_t* pid, const char* path, char* const argv[]) {
-  int p[2];
-  int ret;
-
-  if (pid == NULL) {
-    err(0,"bad pointer passed to create_writing_pipe()\n");
-    return -1;
-  }
-
-  if (ret = pipe(p), ret == -1) {
-    err(0,"failed to create a pipe (error: %d \"%s\")\n", errno, strerror(errno));
-    return -1;
-  }
-
-  *pid = fork();
-  if (*pid == -1) {
-    err(0,"Failed to fork (error: %d \"%s\")\n", errno, strerror(errno));
-    return -1;
-  }
-  if (*pid == 0) { /* this is the child */
-    close(p[1]); /* close unused write end */
-    
-    if (0 != dup2(p[0], 0)) { /* map the reading end into stdin */
-      err(0,"Failed to transfer reading file descriptor to stdin (error: %d \"%s\")\n", errno, strerror(errno));
-      exit(1);
-    }
-    execvp(path, argv);
-    err(0,"exec %s failed (error: %d \"%s\")\n", path, errno, strerror(errno));
-    /* close the open file descriptors */
-    close(p[0]);
-    close(0);
-
-    exit(1);
-  } else { /* this is the parent */
-    close(p[0]); /* close unused read end */
-    return p[1];
-  }
-}
-
-int validate_ssh_host_userid(const char* userid) {
-  char* oldlocale = setlocale(LC_ALL, "C");
-  
-  /* choke if userid does not match the expected format
-     ("ssh://fully.qualified.domain.name") */
-  if (strncmp("ssh://", userid, strlen("ssh://")) != 0) {
-    err(0,"The user ID should start with ssh:// for a host key\n");
-    goto fail;
-  }
-  /* so that isalnum will work properly */
-  userid += strlen("ssh://");
-  while (0 != (*userid)) {
-    if (!isalnum(*userid)) {
-      err(0,"label did not start with a letter or a digit! (%s)\n", userid);
-      goto fail;
-    }
-    userid++;
-    while (isalnum(*userid) || ('-' == (*userid)))
-      userid++;
-    if (('.' == (*userid)) || (0 == (*userid))) { /* clean end of label:
-                                                check last char
-                                                isalnum */
-      if (!isalnum(*(userid - 1))) {
-       err(0,"label did not end with a letter or a digit!\n");
-       goto fail;
-      }
-      if ('.' == (*userid)) /* advance to the start of the next label */
-       userid++;
-    } else {
-      err(0,"invalid character in domain name: %c\n", *userid);
-      goto fail;
-    }
-  }
-  /* ensure that the last character is valid: */
-  if (!isalnum(*(userid - 1))) {
-    err(0,"hostname did not end with a letter or a digit!\n");
-    goto fail;
-  }
-  /* FIXME: fqdn's can be unicode now, thanks to RFC 3490 -- how do we
-     make sure that we've got an OK string? */
-
-  return 0;
-
- fail:
-  setlocale(LC_ALL, oldlocale);
-  return 1;
-}
-
-/* http://tools.ietf.org/html/rfc4880#section-5.5.2 */
-size_t get_openpgp_mpi_size(gnutls_datum_t* d) {
-  return 2 + d->size;
-}
-
-int write_openpgp_mpi_to_fd(int fd, gnutls_datum_t* d) {
-  uint16_t x;
-
-  x = d->size * 8;
-  x = htons(x);
-  
-  write(fd, &x, sizeof(x));
-  write(fd, d->data, d->size);
-  
-  return 0;
-}
diff --git a/src/keytrans/gnutls-helpers.h b/src/keytrans/gnutls-helpers.h
deleted file mode 100644 (file)
index bf54af0..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/* Author: Daniel Kahn Gillmor <dkg@fifthhorseman.net> */
-/* Date: Fri, 04 Apr 2008 19:31:16 -0400 */
-/* License: GPL v3 or later */
-
-
-#include <gnutls/gnutls.h>
-#include <gnutls/openpgp.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <stdarg.h>
-
-/* Functions to help dealing with GnuTLS for monkeysphere key
-   translation projects: */
-
-/* set everything up, including logging levels.  Return 0 on
-   success */
-int init_gnutls();
-
-/* logging and output functions: */
-
-void err(int level, const char* fmt, ...);
-void logfunc(int level, const char* string);
-
-/* basic datum manipulations: */
-
-void init_datum(gnutls_datum_t* d);
-void copy_datum(gnutls_datum_t* dest, const gnutls_datum_t* src);
-int compare_data(const gnutls_datum_t* a, const gnutls_datum_t* b);
-void free_datum(gnutls_datum_t* d);
-int write_datum_fd(int fd, const gnutls_datum_t* d);
-int write_datum_fd_with_length(int fd, const gnutls_datum_t* d);
-int write_data_fd_with_length(int fd, const gnutls_datum_t** d, unsigned int num);
-
-/* set up a datum from a null-terminated string */
-int datum_from_string(gnutls_datum_t* d, const char* str);
-
-/* keyid manipulations: */
-typedef unsigned char printable_keyid[16];
-
-void init_keyid(gnutls_openpgp_keyid_t keyid);
-void make_keyid_printable(printable_keyid out, gnutls_openpgp_keyid_t keyid);
-void collapse_printable_keyid(gnutls_openpgp_keyid_t out, printable_keyid in);
-int convert_string_to_keyid(gnutls_openpgp_keyid_t out, const char* str);
-int convert_string_to_printable_keyid(printable_keyid out, const char* str);
-
-/* you must have twice as many bytes in the out buffer as in the in buffer */
-void hex_print_data(char* out, const unsigned char* in, size_t incount);
-
-/* expects a null-terminated string as in, containing an even number
-   of hexadecimal characters.
-
-   returns length in *bits* of raw data as output. 
-
-   the out buffer must be at least half as long as in to hold the
-   output.  if out is NULL, no output will be generated, but the
-   length will still be returned.
-*/
-unsigned int hexstring2bin(unsigned char* out, const char* in);
-
-/* functions to get data into datum objects: */
-
-/* read the passed-in string, store in a single datum */
-int set_datum_string(gnutls_datum_t* d, const char* s);
-
-/* read the passed-in file descriptor until EOF, store in a single
-   datum */
-int set_datum_fd(gnutls_datum_t* d, int fd);
-
-/* read the file indicated (by name) in the fname parameter.  store
-   its entire contents in a single datum. */
-int set_datum_file(gnutls_datum_t* d, const char* fname);
-
-/* set up file descriptor pipe for writing (child process pid gets
-   stored in pid, fd is returned)*/
-int create_writing_pipe(pid_t* pid, const char* path, char* const argv[]);
-
-/* return 0 if userid matches the monkeysphere spec for ssh host user IDs */
-int validate_ssh_host_userid(const char* userid);
-
-/* how many bytes will it take to write out this datum in OpenPGP MPI form? */
-size_t get_openpgp_mpi_size(gnutls_datum_t* d);
-
-/* write the MPI stored in gnutls_datum_t to file descriptor fd: */
-int write_openpgp_mpi_to_fd(int fd, gnutls_datum_t* d);
diff --git a/src/keytrans/openpgp2ssh.c b/src/keytrans/openpgp2ssh.c
deleted file mode 100644 (file)
index f16eac5..0000000
+++ /dev/null
@@ -1,507 +0,0 @@
-#include "gnutls-helpers.h"
-
-#include <gnutls/openpgp.h>
-#include <gnutls/x509.h>
-
-/* for waitpid() */
-#include <sys/types.h>
-#include <sys/wait.h>
-
-/* 
-   Author: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
-   Date: 2008-06-12 13:47:41-0400
-   License: GPL v3 or later
-
-   monkeysphere key translator: execute this with an OpenPGP key on
-   stdin, (please indicate the specific keyid that you want as the
-   first argument if there are subkeys).  At the moment, only public
-   keys and passphraseless secret keys work.
-
-   For secret keys, it will spit out a PEM-encoded version of the key
-   on stdout, which can be fed into ssh-add like this:
-
-    gpg --export-secret-keys $KEYID | openpgp2ssh $KEYID | ssh-add -c /dev/stdin
-
-   For public keys, it will spit out a single line of text that can
-   (with some massaging) be used in an openssh known_hosts or
-   authorized_keys file.  For example:
-
-    echo server.example.org $(gpg --export $KEYID | openpgp2ssh $KEYID) >> ~/.ssh/known_hosts
-
-   Requirements: I've only built this so far with GnuTLS v2.3.x.
-   GnuTLS 2.2.x does not contain the appropriate functionality.
-
- */
-
-
-/* FIXME: keyid should be const as well */
-int convert_private_pgp_to_x509(gnutls_x509_privkey_t* output, const gnutls_openpgp_privkey_t* pgp_privkey, const unsigned char* keyfpr, unsigned int fprlen) {
-  gnutls_datum_t m, e, d, p, q, u, g, y, x;
-  gnutls_pk_algorithm_t pgp_algo;
-  unsigned int pgp_bits;
-  int ret;
-  int subkeyidx;
-  int subkeycount;
-  int found = 0;
-  unsigned char fingerprint[20];
-  size_t fingerprint_length = sizeof(fingerprint); 
-
-  init_datum(&m);
-  init_datum(&e);
-  init_datum(&d);
-  init_datum(&p);
-  init_datum(&q);
-  init_datum(&u);
-  init_datum(&g);
-  init_datum(&y);
-  init_datum(&x);
-
-  subkeycount = gnutls_openpgp_privkey_get_subkey_count(*pgp_privkey);
-  if (subkeycount < 0) {
-    err(0,"Could not determine subkey count (got value %d)\n", subkeycount);
-    return 1;
-  }
-
-  if ((keyfpr == NULL) && 
-      (subkeycount > 0)) {
-    err(0,"No key identifier passed in, but there were %d keys to choose from\n", subkeycount + 1);
-    return 1;
-  }
-
-  if (keyfpr != NULL) {
-    ret = gnutls_openpgp_privkey_get_fingerprint(*pgp_privkey, fingerprint, &fingerprint_length);
-    if (ret) {
-      err(0,"Could not get fingerprint (error: %d)\n", ret);
-      return 1;
-    }
-    if (fprlen > fingerprint_length) {
-      err(0, "Requested key identifier is longer than computed fingerprint\n");
-      return 1;
-    }
-    if (fingerprint_length > fprlen) {
-      err(0, "Only comparing last %d bits of key fingerprint\n", fprlen*8);
-    }
-  }
-  if ((keyfpr == NULL) || (memcmp(fingerprint + (fingerprint_length - fprlen), keyfpr, fprlen) == 0)) {
-    /* we want to export the primary key: */
-    err(0,"exporting primary key\n");
-
-    /* FIXME: this is almost identical to the block below for subkeys.
-       This clumsiness seems inherent in the gnutls OpenPGP API,
-       though.  ugh. */
-    pgp_algo = gnutls_openpgp_privkey_get_pk_algorithm(*pgp_privkey, &pgp_bits);
-    if (pgp_algo < 0) {
-      err(0, "failed to get OpenPGP key algorithm (error: %d)\n", pgp_algo);
-      return 1;
-    }
-    if (pgp_algo == GNUTLS_PK_RSA) {
-      err(0,"OpenPGP RSA Key, with %d bits\n", pgp_bits);
-      ret = gnutls_openpgp_privkey_export_rsa_raw(*pgp_privkey, &m, &e, &d, &p, &q, &u);
-      if (GNUTLS_E_SUCCESS != ret) {
-       err(0, "failed to export RSA key parameters (error: %d)\n", ret);
-       return 1;
-      }
-      
-    } else if (pgp_algo == GNUTLS_PK_DSA) {
-      err(0,"OpenPGP DSA Key, with %d bits\n", pgp_bits);
-      ret = gnutls_openpgp_privkey_export_dsa_raw(*pgp_privkey, &p, &q, &g, &y, &x);
-      if (GNUTLS_E_SUCCESS != ret) {
-       err(0,"failed to export DSA key parameters (error: %d)\n", ret);
-       return 1;
-      }
-    }
-    found = 1;
-  } else {
-    /* lets trawl through the subkeys until we find the one we want: */
-    for (subkeyidx = 0; (subkeyidx < subkeycount) && !found; subkeyidx++) {
-      ret = gnutls_openpgp_privkey_get_subkey_fingerprint(*pgp_privkey, subkeyidx, fingerprint, &fingerprint_length);
-      if (ret) {
-       err(0,"Could not get fingerprint of subkey with index %d (error: %d)\n", subkeyidx, ret);
-       return 1;
-      }
-      if (fprlen > fingerprint_length) {
-       err(0, "Requested key identifier is longer than computed fingerprint\n");
-       return 1;
-      }
-      if (fingerprint_length > fprlen) {
-       err(1, "Only comparing last %d bits of key fingerprint\n", fprlen*8);
-      }
-      if (memcmp(fingerprint + (fingerprint_length - fprlen), keyfpr, fprlen) == 0) {
-       err(0,"exporting subkey index %d\n", subkeyidx);
-
-       /* FIXME: this is almost identical to the block above for the
-          primary key. */
-       pgp_algo = gnutls_openpgp_privkey_get_subkey_pk_algorithm(*pgp_privkey, subkeyidx, &pgp_bits);
-       if (pgp_algo < 0) {
-         err(0,"failed to get the algorithm of the OpenPGP public key (error: %d)\n", pgp_algo);
-         return pgp_algo;
-       } else if (pgp_algo == GNUTLS_PK_RSA) {
-         err(0,"OpenPGP RSA key, with %d bits\n", pgp_bits);
-         ret = gnutls_openpgp_privkey_export_subkey_rsa_raw(*pgp_privkey, subkeyidx, &m, &e, &d, &p, &q, &u);
-         if (GNUTLS_E_SUCCESS != ret) {
-           err(0,"failed to export RSA key parameters (error: %d)\n", ret);
-           return 1;
-         }
-       } else if (pgp_algo == GNUTLS_PK_DSA) {
-         err(0,"OpenPGP DSA Key, with %d bits\n", pgp_bits);
-         ret = gnutls_openpgp_privkey_export_subkey_dsa_raw(*pgp_privkey, subkeyidx, &p, &q, &g, &y, &x);
-         if (GNUTLS_E_SUCCESS != ret) {
-           err(0,"failed to export DSA key parameters (error: %d)\n", ret);
-           return 1;
-         }
-       }
-       found = 1;
-      }
-    }
-  }
-
-  if (!found) {
-    err(0,"Could not find key in input\n");
-    return 1;
-  }
-
-  if (pgp_algo == GNUTLS_PK_RSA) {
-    ret = gnutls_x509_privkey_import_rsa_raw (*output, &m, &e, &d, &p, &q, &u); 
-    if (GNUTLS_E_SUCCESS != ret) {
-      err(0, "failed to import RSA key parameters (error: %d)\n", ret);
-      return 1;
-    }
-  } else if (pgp_algo == GNUTLS_PK_DSA) {
-    ret = gnutls_x509_privkey_import_dsa_raw (*output, &p, &q, &g, &y, &x); 
-    if (GNUTLS_E_SUCCESS != ret) {
-      err(0,"failed to import DSA key parameters (error: %d)\n", ret);
-      return 1;
-    }
-  } else {
-    err(0,"OpenPGP Key was not RSA or DSA -- can't deal! (actual algorithm was: %d)\n", pgp_algo);
-    return 1;
-  }
-  
-  ret = gnutls_x509_privkey_fix(*output);
-  if (ret != 0) {
-    err(0,"failed to fix up the private key in X.509 format (error: %d)\n", ret);
-    return 1; 
-  }
-
-  return 0;
-}
-
-/* FIXME: keyid should be const also */
-int emit_public_openssh_from_pgp(const gnutls_openpgp_crt_t* pgp_crt, const unsigned char* keyfpr, size_t fprlen) {
-  int ret;
-  int subkeyidx;
-  int subkeycount;
-  int found = 0;
-  gnutls_datum_t m, e, p, q, g, y, algolabel;
-  unsigned int bits;
-  gnutls_pk_algorithm_t algo;
-  const gnutls_datum_t* all[5];
-  const char* algoname;
-  int mpicount;
-  /* output_data must be at least 2 chars longer than the maximum possible
-     algorithm name: */
-  char output_data[20];
-
-  unsigned char fingerprint[20];
-  size_t fingerprint_length = sizeof(fingerprint); 
-
-  /* variables for the output conversion: */
-  int pipestatus;
-  int pipefd, child_pid;
-  char* const b64args[] = {"sh", "-c", "base64 | tr -c -d '[A-Za-z0-9=+/]'", NULL};
-
-  init_datum(&m);
-  init_datum(&e);
-  init_datum(&p);
-  init_datum(&q);
-  init_datum(&g);
-  init_datum(&algolabel);
-
-
-  /* figure out if we've got the right thing: */
-  subkeycount = gnutls_openpgp_crt_get_subkey_count(*pgp_crt);
-  if (subkeycount < 0) {
-    err(0,"Could not determine subkey count (got value %d)\n", subkeycount);
-    return 1;
-  }
-
-  if ((keyfpr == NULL) && 
-      (subkeycount > 0)) {
-    err(0,"No key identifier passed in, but there were %d keys to choose from\n", subkeycount + 1);
-    return 1;
-  }
-
-  if (keyfpr != NULL) {
-    ret = gnutls_openpgp_crt_get_fingerprint(*pgp_crt, fingerprint, &fingerprint_length);
-    if (ret) {
-      err(0,"Could not get key fingerprint (error: %d)\n", ret);
-      return 1;
-    }
-    if (fprlen > fingerprint_length) {
-      err(0, "Requested key identifier is longer than computed fingerprint\n");
-      return 1;
-    }
-    if (fingerprint_length > fprlen) {
-      err(0, "Only comparing last %d bits of key fingerprint\n", fprlen*8);
-    }
-  }
-  if ((keyfpr == NULL) || (memcmp(fingerprint + (fingerprint_length - fprlen), keyfpr, fprlen) == 0)) {
-    /* we want to export the primary key: */
-    err(0,"exporting primary key\n");
-
-    /* FIXME: this is almost identical to the block below for subkeys.
-       This clumsiness seems inherent in the gnutls OpenPGP API,
-       though.  ugh. */
-    algo = gnutls_openpgp_crt_get_pk_algorithm(*pgp_crt, &bits);
-    if (algo < 0) {
-      err(0,"failed to get the algorithm of the OpenPGP public key (error: %d)\n", algo);
-      return algo;
-    } else if (algo == GNUTLS_PK_RSA) {
-      err(0,"OpenPGP RSA certificate, with %d bits\n", bits);
-      ret = gnutls_openpgp_crt_get_pk_rsa_raw(*pgp_crt, &m, &e);
-      if (GNUTLS_E_SUCCESS != ret) {
-       err(0,"failed to export RSA certificate parameters (error: %d)\n", ret);
-       return 1;
-      }
-    } else if (algo == GNUTLS_PK_DSA) {
-      err(0,"OpenPGP DSA certificate, with %d bits\n", bits);
-      ret = gnutls_openpgp_crt_get_pk_dsa_raw(*pgp_crt, &p, &q, &g, &y);
-      if (GNUTLS_E_SUCCESS != ret) {
-       err(0,"failed to export DSA certificate parameters (error: %d)\n", ret);
-       return 1;
-      }
-    }
-    found = 1;
-
-  } else {
-    /* lets trawl through the subkeys until we find the one we want: */
-    for (subkeyidx = 0; (subkeyidx < subkeycount) && !found; subkeyidx++) {
-      ret = gnutls_openpgp_crt_get_subkey_fingerprint(*pgp_crt, subkeyidx, fingerprint, &fingerprint_length);
-      if (ret) {
-       err(0,"Could not get fingerprint of subkey with index %d (error: %d)\n", subkeyidx, ret);
-       return 1;
-      }
-      if (fprlen > fingerprint_length) {
-       err(0, "Requested key identifier is longer than computed fingerprint\n");
-       return 1;
-      }
-      if (fingerprint_length > fprlen) {
-       err(1, "Only comparing last %d bits of key fingerprint\n", fprlen*8);
-      }
-      if (memcmp(fingerprint + (fingerprint_length - fprlen), keyfpr, fprlen) == 0) {
-       err(0,"exporting subkey index %d\n", subkeyidx);
-
-       /* FIXME: this is almost identical to the block above for the
-          primary key. */
-       algo = gnutls_openpgp_crt_get_subkey_pk_algorithm(*pgp_crt, subkeyidx, &bits);
-       if (algo < 0) {
-         err(0,"failed to get the algorithm of the OpenPGP public key (error: %d)\n", algo);
-         return algo;
-       } else if (algo == GNUTLS_PK_RSA) {
-         err(0,"OpenPGP RSA certificate, with %d bits\n", bits);
-         ret = gnutls_openpgp_crt_get_subkey_pk_rsa_raw(*pgp_crt, subkeyidx, &m, &e);
-         if (GNUTLS_E_SUCCESS != ret) {
-           err(0,"failed to export RSA certificate parameters (error: %d)\n", ret);
-           return 1;
-         }
-       } else if (algo == GNUTLS_PK_DSA) {
-         err(0,"OpenPGP DSA certificate, with %d bits\n", bits);
-         ret = gnutls_openpgp_crt_get_subkey_pk_dsa_raw(*pgp_crt, subkeyidx, &p, &q, &g, &y);
-         if (GNUTLS_E_SUCCESS != ret) {
-           err(0,"failed to export DSA certificate parameters (error: %d)\n", ret);
-           return 1;
-         }
-       }
-       found = 1;
-       
-      }
-    }
-  }
-
-  if (!found) {
-    err(0,"Could not find key in input\n");
-    return 1;
-  }
-
-  /* if we made it this far, we've got MPIs, and we've got the
-     algorithm, so we just need to emit the info */
-  if (algo == GNUTLS_PK_RSA) {
-    algoname = "ssh-rsa";
-    mpicount = 3;
-
-    all[0] = &algolabel;
-    all[1] = &e;
-    all[2] = &m;
-  } else if (algo == GNUTLS_PK_DSA) {
-    algoname = "ssh-dss";
-    mpicount = 5;
-
-    all[0] = &algolabel;
-    all[1] = &p;
-    all[2] = &q;
-    all[3] = &g;
-    all[4] = &y;
-  } else {
-    err(0,"Key algorithm was neither DSA nor RSA (it was %d).  Can't deal.  Sorry!\n", algo);
-    return 1;
-  }
-
-  if (ret = datum_from_string(&algolabel, algoname), ret) {
-    err(0,"couldn't label string (error: %d)\n", ret);
-    return ret;
-  }
-
-  snprintf(output_data, sizeof(output_data), "%s ", algoname);
-
-  pipefd = create_writing_pipe(&child_pid, b64args[0], b64args);
-  if (pipefd < 0) {
-    err(0,"failed to create a writing pipe (returned %d)\n", pipefd);
-    return pipefd;
-  }
-    
-  write(1, output_data, strlen(output_data));
-
-  if (0 != write_data_fd_with_length(pipefd, all, mpicount)) {
-    err(0,"was not able to write out RSA key data\n");
-    return 1;
-  }
-  close(pipefd);
-  if (child_pid != waitpid(child_pid, &pipestatus, 0)) {
-    err(0,"could not wait for child process to return for some reason.\n");
-    return 1;
-  }
-  if (pipestatus != 0) {
-    err(0,"base64 pipe died with return code %d\n", pipestatus);
-    return pipestatus;
-  }
-
-  write(1, "\n", 1);
-  
-  return 0;
-}
-
-int main(int argc, char* argv[]) {
-  gnutls_datum_t data;
-  int ret = 0;
-  gnutls_x509_privkey_t x509_privkey;
-  gnutls_openpgp_privkey_t pgp_privkey;
-  gnutls_openpgp_crt_t pgp_crt;
-
-  char output_data[10240];
-  size_t ods = sizeof(output_data);
-  
-  unsigned char * fingerprint = NULL;
-  size_t fpr_size;
-  char * prettyfpr = NULL;
-
-  init_gnutls();
-
-  /* figure out what key we should be looking for: */
-  if (argv[1] != NULL) {
-    if (strlen(argv[1]) > 81) {
-      /* safety check to avoid some sort of wacky overflow situation:
-        there's no reason that the key id should be longer than twice
-        a sane fingerprint (one byte between chars, and then another
-        two at the beginning and end) */
-      err(0, "Key identifier is way too long.  Please use at most 40 hex digits.\n");
-      return 1;
-    }
-
-    fpr_size = hexstring2bin(NULL, argv[1]);
-    if (fpr_size > 40*4) {
-      err(0, "Key identifier is longer than 40 hex digits\n");
-      return 1;
-    }
-    /* since fpr_size is initially in bits: */
-    if (fpr_size % 8 != 0) {
-      err(0, "Please provide an even number of hex digits for the key identifier\n");
-      return 1;
-    }
-    fpr_size /= 8;
-
-    fingerprint = malloc(sizeof(unsigned char) * fpr_size);
-    bzero(fingerprint, sizeof(unsigned char) * fpr_size);
-    hexstring2bin(fingerprint, argv[1]);
-
-    prettyfpr = malloc(sizeof(unsigned char)*fpr_size*2 + 1);
-    if (prettyfpr != NULL) {
-      hex_print_data(prettyfpr, fingerprint, fpr_size);
-      prettyfpr[sizeof(unsigned char)*fpr_size*2] = '\0';
-      err(1, "searching for key with fingerprint '%s'\n", prettyfpr);
-      free(prettyfpr);
-    }
-
-    if (fpr_size < 4) {
-      err(0, "You MUST provide at least 8 hex digits in any key identifier\n");
-      return 1;
-    }
-    if (fpr_size < 8)
-      err(0, "You should provide at least 16 hex digits in any key identifier (proceeding with %d digits anyway)\n", fpr_size*2);
-   
-  }
-
-  
-  init_datum(&data);
-
-  /* slurp in the key from stdin */
-  if (ret = set_datum_fd(&data, 0), ret) {
-    err(0,"didn't read file descriptor 0\n");
-    return 1;
-  }
-
-
-  if (ret = gnutls_openpgp_privkey_init(&pgp_privkey), ret) {
-    err(0,"Failed to initialized OpenPGP private key (error: %d)\n", ret);
-    return 1;
-  }
-  /* check whether it's a private key or a public key, by trying them: */
-  if ((gnutls_openpgp_privkey_import(pgp_privkey, &data, GNUTLS_OPENPGP_FMT_RAW, NULL, 0) == 0) || 
-      (gnutls_openpgp_privkey_import(pgp_privkey, &data, GNUTLS_OPENPGP_FMT_BASE64, NULL, 0) == 0)) {
-    /* we're dealing with a private key */
-    err(0,"Translating private key\n");
-    if (ret = gnutls_x509_privkey_init(&x509_privkey), ret) {
-      err(0,"Failed to initialize X.509 private key for output (error: %d)\n", ret);
-      return 1;
-    }
-    
-    ret = convert_private_pgp_to_x509(&x509_privkey, &pgp_privkey, fingerprint, fpr_size);
-
-    gnutls_openpgp_privkey_deinit(pgp_privkey);
-    if (ret)
-      return ret;
-
-    ret = gnutls_x509_privkey_export (x509_privkey,
-                                     GNUTLS_X509_FMT_PEM,
-                                     output_data,
-                                     &ods);
-    if (ret == 0) {
-      write(1, output_data, ods);
-    }
-    gnutls_x509_privkey_deinit(x509_privkey);
-  
-  } else {
-    if (ret = gnutls_openpgp_crt_init(&pgp_crt), ret) {
-      err(0,"Failed to initialized OpenPGP certificate (error: %d)\n", ret);
-      return 1;
-    }
-    
-    if ((gnutls_openpgp_crt_import(pgp_crt, &data, GNUTLS_OPENPGP_FMT_RAW) == 0) || 
-       (gnutls_openpgp_crt_import(pgp_crt, &data, GNUTLS_OPENPGP_FMT_BASE64) == 0)) {
-      /* we're dealing with a public key */
-      err(0,"Translating public key\n");
-
-      ret = emit_public_openssh_from_pgp(&pgp_crt, fingerprint, fpr_size);
-      if (ret != 0) 
-       return ret;
-      
-    } else {
-      /* we have no idea what kind of key this is at all anyway! */
-      err(0,"Input does not contain any form of OpenPGP key I recognize.\n");
-      return 1;
-    }
-  }
-
-  gnutls_global_deinit();
-  free(fingerprint);
-  return 0;
-}
diff --git a/src/keytrans/pem2openpgp b/src/keytrans/pem2openpgp
deleted file mode 100755 (executable)
index 2631da6..0000000
+++ /dev/null
@@ -1,519 +0,0 @@
-#!/usr/bin/perl -w -T
-
-# pem2openpgp: take a PEM-encoded RSA private-key on standard input, a
-# User ID as the first argument, and generate an OpenPGP secret key
-# and certificate from it.
-
-# WARNING: the secret key material *will* appear on stdout (albeit in
-# OpenPGP form) -- if you redirect stdout to a file, make sure the
-# permissions on that file are appropriately locked down!
-
-# Usage:
-
-# pem2openpgp 'ssh://'$(hostname -f) < /etc/ssh/ssh_host_rsa_key | gpg --import
-
-# Authors:
-#  Jameson Rollins <jrollins@finestructure.net>
-#  Daniel Kahn Gillmor <dkg@fifthhorseman.net>
-
-# Started on: 2009-01-07 02:01:19-0500
-
-# License: GPL v3 or later (we may need to adjust this given that this
-# connects to OpenSSL via perl)
-
-use strict;
-use warnings;
-use Crypt::OpenSSL::RSA;
-use Crypt::OpenSSL::Bignum;
-use Crypt::OpenSSL::Bignum::CTX;
-use Digest::SHA1;
-use MIME::Base64;
-
-## make sure all length() and substr() calls use bytes only:
-use bytes;
-
-my $uid = shift;
-
-# FIXME: fail if there is no given user ID; or should we default to
-# hostname_long() from Sys::Hostname::Long ?
-
-
-my $old_format_packet_lengths = { one => 0,
-                                 two => 1,
-                                 four => 2,
-                                 indeterminate => 3,
-};
-
-# see RFC 4880 section 9.1 (ignoring deprecated algorithms for now)
-my $asym_algos = { rsa => 1,
-                  elgamal => 16,
-                  dsa => 17,
-                  };
-
-# see RFC 4880 section 9.2
-my $ciphers = { plaintext => 0,
-               idea => 1,
-               tripledes => 2,
-               cast5 => 3,
-               blowfish => 4,
-               aes128 => 7,
-               aes192 => 8,
-               aes256 => 9,
-               twofish => 10,
-             };
-
-# see RFC 4880 section 9.3
-my $zips = { uncompressed => 0,
-            zip => 1,
-            zlib => 2,
-            bzip2 => 3,
-          };
-
-# see RFC 4880 section 9.4
-my $digests = { md5 => 1,
-               sha1 => 2,
-               ripemd160 => 3,
-               sha256 => 8,
-               sha384 => 9,
-               sha512 => 10,
-               sha224 => 11,
-             };
-
-# see RFC 4880 section 5.2.3.21
-my $usage_flags = { certify => 0x01,
-                   sign => 0x02,
-                   encrypt_comms => 0x04,
-                   encrypt_storage => 0x08,
-                   encrypt => 0x0c, ## both comms and storage
-                   split => 0x10, # the private key is split via secret sharing
-                   authenticate => 0x20,
-                   shared => 0x80, # more than one person holds the entire private key
-                 };
-
-# see RFC 4880 section 4.3
-my $packet_types = { pubkey_enc_session => 1,
-                    sig => 2,
-                    symkey_enc_session => 3,
-                    onepass_sig => 4,
-                    seckey => 5,
-                    pubkey => 6,
-                    sec_subkey => 7,
-                    compressed_data => 8,
-                    symenc_data => 9,
-                    marker => 10,
-                    literal => 11,
-                    trust => 12,
-                    uid => 13,
-                    pub_subkey => 14,
-                    uat => 17,
-                    symenc_w_integrity => 18,
-                    mdc => 19,
-                  };
-
-# see RFC 4880 section 5.2.1
-my $sig_types = { binary_doc => 0x00,
-                 text_doc => 0x01,
-                 standalone => 0x02,
-                 generic_certification => 0x10,
-                 persona_certification => 0x11,
-                 casual_certification => 0x12,
-                 positive_certification => 0x13,
-                 subkey_binding => 0x18,
-                 primary_key_binding => 0x19,
-                 key_signature => 0x1f,
-                 key_revocation => 0x20,
-                 subkey_revocation => 0x28,
-                 certification_revocation => 0x30,
-                 timestamp => 0x40,
-                 thirdparty => 0x50,
-               };
-
-
-# see RFC 4880 section 5.2.3.1
-my $subpacket_types = { sig_creation_time => 2,
-                       sig_expiration_time => 3,
-                       exportable => 4,
-                       trust_sig => 5,
-                       regex => 6,
-                       revocable => 7,
-                       key_expiration_time => 9,
-                       preferred_cipher => 11,
-                       revocation_key => 12,
-                       issuer => 16,
-                       notation => 20,
-                       preferred_digest => 21,
-                       preferred_compression => 22,
-                       keyserver_prefs => 23,
-                       preferred_keyserver => 24,
-                       primary_uid => 25,
-                       policy_uri => 26,
-                       usage_flags => 27,
-                       signers_uid => 28,
-                       revocation_reason => 29,
-                       features => 30,
-                       signature_target => 31,
-                       embedded_signature => 32,
-                      };
-
-# bitstring (see RFC 4880 section 5.2.3.24)
-my $features = { mdc => 0x01
-              };
-
-# bitstring (see RFC 4880 5.2.3.17)
-my $keyserver_prefs = { nomodify => 0x80
-                     };
-
-###### end lookup tables ######
-
-# FIXME: if we want to be able to interpret openpgp data as well as
-# produce it, we need to produce key/value-swapped lookup tables as well.
-
-
-########### Math/Utility Functions ##############
-
-
-# see the bottom of page 43 of RFC 4880
-sub simple_checksum {
-  my $bytes = shift;
-
-  return unpack("%32W*",$bytes) % 65536;
-}
-
-# calculate the multiplicative inverse of a mod b this is euclid's
-# extended algorithm.  For more information see:
-# http://en.wikipedia.org/wiki/Extended_Euclidean_algorithm the
-# arguments here should be Crypt::OpenSSL::Bignum objects.  $a should
-# be the larger of the two values, and the two values should be
-# coprime.
-
-sub modular_multi_inverse {
-  my $a = shift;
-  my $b = shift;
-
-
-  my $origdivisor = $b->copy();
-
-  my $ctx = Crypt::OpenSSL::Bignum::CTX->new();
-  my $x = Crypt::OpenSSL::Bignum->zero();
-  my $y = Crypt::OpenSSL::Bignum->one();
-  my $lastx = Crypt::OpenSSL::Bignum->one();
-  my $lasty = Crypt::OpenSSL::Bignum->zero();
-
-  my $finalquotient;
-  my $finalremainder;
-
-  while (! $b->is_zero()) {
-    my ($quotient, $remainder) = $a->div($b, $ctx);
-
-    $a = $b;
-    $b = $remainder;
-
-    my $temp = $x;
-    $x = $lastx->sub($quotient->mul($x, $ctx));
-    $lastx = $temp;
-
-    $temp = $y;
-    $y = $lasty->sub($quotient->mul($y, $ctx));
-    $lasty = $temp;
-  }
-
-  if (!$a->is_one()) {
-    die "did this math wrong.\n";
-  }
-
-  # let's make sure that we return a positive value because RFC 4880,
-  # section 3.2 only allows unsigned values:
-
-  ($finalquotient, $finalremainder) = $lastx->add($origdivisor)->div($origdivisor, $ctx);
-
-  return $finalremainder;
-}
-
-
-############ OpenPGP formatting functions ############
-
-# make an old-style packet out of the given packet type and body.
-# old-style  (see RFC 4880 section 4.2)
-sub make_packet {
-  my $type = shift;
-  my $body = shift;
-  my $options = shift;
-
-  my $len = length($body);
-  my $pseudolen = $len;
-
-  # if the caller wants to use at least N octets of packet length,
-  # pretend that we're using that many.
-  if (defined $options && defined $options->{'packet_length'}) {
-      $pseudolen = 2**($options->{'packet_length'} * 8) - 1;
-  }
-  if ($pseudolen < $len) {
-      $pseudolen = $len;
-  }
-
-  my $lenbytes;
-  my $lencode;
-
-  if ($pseudolen < 2**8) {
-    $lenbytes = $old_format_packet_lengths->{one};
-    $lencode = 'C';
-  } elsif ($pseudolen < 2**16) {
-    $lenbytes = $old_format_packet_lengths->{two};
-    $lencode = 'n';
-  } elsif ($pseudolen < 2**31) {
-    ## not testing against full 32 bits because i don't want to deal
-    ## with potential overflow.
-    $lenbytes = $old_format_packet_lengths->{four};
-    $lencode = 'N';
-  } else {
-    ## what the hell do we do here?
-    $lenbytes = $old_format_packet_lengths->{indeterminate};
-    $lencode = '';
-  }
-
-  return pack('C'.$lencode, 0x80 + ($type * 4) + $lenbytes, $len).
-    $body;
-}
-
-
-# takes a Crypt::OpenSSL::Bignum, returns it formatted as OpenPGP MPI
-# (RFC 4880 section 3.2)
-sub mpi_pack {
-  my $num = shift;
-
-  my $val = $num->to_bin();
-  my $mpilen = length($val)*8;
-
-# this is a kludgy way to get the number of significant bits in the
-# first byte:
-  my $bitsinfirstbyte = length(sprintf("%b", ord($val)));
-
-  $mpilen -= (8 - $bitsinfirstbyte);
-
-  return pack('n', $mpilen).$val;
-}
-
-# FIXME: genericize these to accept either RSA or DSA keys:
-sub make_rsa_pub_key_body {
-  my $key = shift;
-  my $timestamp = shift;
-
-  my ($n, $e) = $key->get_key_parameters();
-
-  return
-    pack('CN', 4, $timestamp).
-      pack('C', $asym_algos->{rsa}).
-       mpi_pack($n).
-         mpi_pack($e);
-}
-
-sub make_rsa_sec_key_body {
-  my $key = shift;
-  my $timestamp = shift;
-
-  # we're not using $a and $b, but we need them to get to $c.
-  my ($n, $e, $d, $p, $q) = $key->get_key_parameters();
-
-  my $c3 = modular_multi_inverse($p, $q);
-
-  my $secret_material = mpi_pack($d).
-    mpi_pack($p).
-      mpi_pack($q).
-       mpi_pack($c3);
-
-  # according to Crypt::OpenSSL::RSA, the closest value we can get out
-  # of get_key_parameters is 1/q mod p; but according to sec 5.5.3 of
-  # RFC 4880, we're actually looking for u, the multiplicative inverse
-  # of p, mod q.  This is why we're calculating the value directly
-  # with modular_multi_inverse.
-
-  return
-    pack('CN', 4, $timestamp).
-      pack('C', $asym_algos->{rsa}).
-       mpi_pack($n).
-         mpi_pack($e).
-           pack('C', 0). # seckey material is not encrypted -- see RFC 4880 sec 5.5.3
-             $secret_material.
-               pack('n', simple_checksum($secret_material));
-}
-
-# expects an RSA key (public or private) and a timestamp
-sub fingerprint {
-  my $key = shift;
-  my $timestamp = shift;
-
-  my $rsabody = make_rsa_pub_key_body($key, $timestamp);
-
-  return Digest::SHA1::sha1(pack('Cn', 0x99, length($rsabody)).$rsabody);
-}
-
-
-my $rsa;
-if (defined $ENV{PEM2OPENPGP_NEWKEY}) {
-  $rsa = Crypt::OpenSSL::RSA->generate_key($ENV{PEM2OPENPGP_NEWKEY});
-} else {
-  # we're just not dealing with newline business right now.  slurp in
-  # the whole file.
-  undef $/;
-  $rsa = Crypt::OpenSSL::RSA->new_private_key(<STDIN>);
-}
-
-$rsa->use_sha1_hash();
-
-# see page 22 of RFC 4880 for why i think this is the right padding
-# choice to use:
-$rsa->use_pkcs1_padding();
-
-if (! $rsa->check_key()) {
-  die "key does not check";
-}
-
-my $version = pack('C', 4);
-# strong assertion of identity:
-my $sigtype = pack('C', $sig_types->{positive_certification});
-# RSA
-my $pubkey_algo = pack('C', $asym_algos->{rsa});
-# SHA1
-my $hash_algo = pack('C', $digests->{sha1});
-
-# FIXME: i'm worried about generating a bazillion new OpenPGP
-# certificates from the same key, which could easily happen if you run
-# this script more than once against the same key (because the
-# timestamps will differ).  How can we prevent this?
-
-# this environment variable (if set) overrides the current time, to
-# be able to create a standard key?  If we read the key from a file
-# instead of stdin, should we use the creation time on the file?
-my $timestamp = 0;
-if (defined $ENV{PEM2OPENPGP_TIMESTAMP}) {
-  $timestamp = ($ENV{PEM2OPENPGP_TIMESTAMP} + 0);
-} else {
-  $timestamp = time();
-}
-
-my $creation_time_packet = pack('CCN', 5, $subpacket_types->{sig_creation_time}, $timestamp);
-
-
-my $flags = 0;
-if (! defined $ENV{PEM2OPENPGP_USAGE_FLAGS}) {
-  $flags = $usage_flags->{certify};
-} else {
-  my @ff = split(",", $ENV{PEM2OPENPGP_USAGE_FLAGS});
-  foreach my $f (@ff) {
-    if (! defined $usage_flags->{$f}) {
-      die "No such flag $f";
-    }
-    $flags |= $usage_flags->{$f};
-  }
-}
-
-my $usage_packet = pack('CCC', 2, $subpacket_types->{usage_flags}, $flags);
-
-
-# how should we determine how far off to set the expiration date?
-# default is no expiration.  Specify the timestamp in seconds from the
-# key creation.
-my $expiration_packet = '';
-if (defined $ENV{PEM2OPENPGP_EXPIRATION}) {
-  my $expires_in = $ENV{PEM2OPENPGP_EXPIRATION} + 0;
-  $expiration_packet = pack('CCN', 5, $subpacket_types->{key_expiration_time}, $expires_in);
-}
-
-
-# prefer AES-256, AES-192, AES-128, CAST5, 3DES:
-my $pref_sym_algos = pack('CCCCCCC', 6, $subpacket_types->{preferred_cipher},
-                         $ciphers->{aes256},
-                         $ciphers->{aes192},
-                         $ciphers->{aes128},
-                         $ciphers->{cast5},
-                         $ciphers->{tripledes}
-                        );
-
-# prefer SHA-1, SHA-256, RIPE-MD/160
-my $pref_hash_algos = pack('CCCCC', 4, $subpacket_types->{preferred_digest},
-                          $digests->{sha1},
-                          $digests->{sha256},
-                          $digests->{ripemd160}
-                         );
-
-# prefer ZLIB, BZip2, ZIP
-my $pref_zip_algos = pack('CCCCC', 4, $subpacket_types->{preferred_compression},
-                         $zips->{zlib},
-                         $zips->{bzip2},
-                         $zips->{zip}
-                        );
-
-# we support the MDC feature:
-my $feature_subpacket = pack('CCC', 2, $subpacket_types->{features},
-                            $features->{mdc});
-
-# keyserver preference: only owner modify (???):
-my $keyserver_pref = pack('CCC', 2, $subpacket_types->{keyserver_prefs},
-                         $keyserver_prefs->{nomodify});
-
-my $subpackets_to_be_hashed =
-  $creation_time_packet.
-  $usage_packet.
-  $expiration_packet.
-  $pref_sym_algos.
-  $pref_hash_algos.
-  $pref_zip_algos.
-  $feature_subpacket.
-  $keyserver_pref;
-
-my $subpacket_octets = pack('n', length($subpackets_to_be_hashed));
-
-my $sig_data_to_be_hashed =
-  $version.
-  $sigtype.
-  $pubkey_algo.
-  $hash_algo.
-  $subpacket_octets.
-  $subpackets_to_be_hashed;
-
-my $pubkey = make_rsa_pub_key_body($rsa, $timestamp);
-my $seckey = make_rsa_sec_key_body($rsa, $timestamp);
-
-# this is for signing.  it needs to be an old-style header with a
-# 2-packet octet count.
-
-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, $timestamp), 20 - 8, 8);
-
-# the v4 signature trailer is:
-
-# version number, literal 0xff, and then a 4-byte count of the
-# signature data itself.
-my $trailer = pack('CCN', 4, 0xff, length($sig_data_to_be_hashed));
-
-my $uid_data =
-  pack('CN', 0xb4, length($uid)).
-  $uid;
-
-my $datatosign =
-  $key_data.
-  $uid_data.
-  $sig_data_to_be_hashed.
-  $trailer;
-
-my $data_hash = Digest::SHA1::sha1_hex($datatosign);
-
-my $issuer_packet = pack('CCa8', 9, $subpacket_types->{issuer}, $keyid);
-
-my $sig = Crypt::OpenSSL::Bignum->new_from_bin($rsa->sign($datatosign));
-
-my $sig_body =
-  $sig_data_to_be_hashed.
-  pack('n', length($issuer_packet)).
-  $issuer_packet.
-  pack('n', hex(substr($data_hash, 0, 4))).
-  mpi_pack($sig);
-
-print
-  make_packet($packet_types->{seckey}, $seckey).
-  make_packet($packet_types->{uid}, $uid).
-  make_packet($packet_types->{sig}, $sig_body);
-
-
index 371983f2fb82ac962fedb04475789d0e1389aa11..f721108ef5e9d59688566d0dd1a539cb5853823f 100755 (executable)
@@ -18,7 +18,8 @@ PGRM=$(basename $0)
 
 SYSSHAREDIR=${MONKEYSPHERE_SYSSHAREDIR:-"/usr/share/monkeysphere"}
 export SYSSHAREDIR
-. "${SYSSHAREDIR}/common" || exit 1
+. "${SYSSHAREDIR}/defaultenv"
+. "${SYSSHAREDIR}/common"
 
 # sharedir for host functions
 MSHAREDIR="${SYSSHAREDIR}/m"
@@ -69,7 +70,7 @@ check_gpg_sec_key_id() {
            gpgSecOut=$(gpg_user --fixed-list-mode --list-secret-keys --with-colons 2>/dev/null | egrep '^sec:')
            ;;
        1)
-           gpgSecOut=$(gpg_user --fixed-list-mode --list-secret-keys --with-colons "$keyID" | egrep '^sec:') || failure
+           gpgSecOut=$(gpg_user --fixed-list-mode --list-secret-keys --with-colons "$1" | egrep '^sec:') || failure
            ;;
        *)
            failure "You must specify only a single primary key ID."
@@ -86,10 +87,10 @@ check_gpg_sec_key_id() {
            echo "$gpgSecOut" | cut -d: -f5
            ;;
        *)
-           echo "Multiple primary secret keys found:"
-           echo "$gpgSecOut" | cut -d: -f5
-           echo "Please specify which primary key to use."
-           failure
+           local seckeys=$(echo "$gpgSecOut" | cut -d: -f5)
+           failure "Multiple primary secret keys found:
+$seckeys
+Please specify which primary key to use."
            ;;
     esac
 }
@@ -181,6 +182,7 @@ AUTHORIZED_KEYS=${MONKEYSPHERE_AUTHORIZED_KEYS:=$AUTHORIZED_KEYS}
 AUTHORIZED_USER_IDS=${MONKEYSPHERE_AUTHORIZED_USER_IDS:="${MONKEYSPHERE_HOME}/authorized_user_ids"}
 REQUIRED_HOST_KEY_CAPABILITY=${MONKEYSPHERE_REQUIRED_HOST_KEY_CAPABILITY:="a"}
 REQUIRED_USER_KEY_CAPABILITY=${MONKEYSPHERE_REQUIRED_USER_KEY_CAPABILITY:="a"}
+LOG_PREFIX=${MONKEYSPHERE_LOG_PREFIX:='ms: '}
 
 # export GNUPGHOME and make sure gpg home exists with proper
 # permissions
@@ -239,7 +241,7 @@ case $COMMAND in
        ;;
 
     'version'|'v')
-       echo "$VERSION"
+       version
        ;;
 
     '--help'|'help'|'-h'|'h'|'?')
index 497470dc88fc5d36d260c20f4832096042f0a2f7..85ff04fc5ddd31b74c0c776530ee4f043afb53d6 100755 (executable)
@@ -21,7 +21,8 @@ PGRM=$(basename $0)
 
 SYSSHAREDIR=${MONKEYSPHERE_SYSSHAREDIR:-"/usr/share/monkeysphere"}
 export SYSSHAREDIR
-. "${SYSSHAREDIR}/common" || exit 1
+. "${SYSSHAREDIR}/defaultenv"
+. "${SYSSHAREDIR}/common"
 
 SYSDATADIR=${MONKEYSPHERE_SYSDATADIR:-"/var/lib/monkeysphere"}
 export SYSDATADIR
@@ -42,9 +43,6 @@ DATE=$(date -u '+%FT%T')
 # unset some environment variables that could screw things up
 unset GREP_OPTIONS
 
-# default return code
-RETURN=0
-
 ########################################################################
 # FUNCTIONS
 ########################################################################
@@ -55,17 +53,17 @@ usage: $PGRM <subcommand> [options] [args]
 Monkeysphere authentication admin tool.
 
 subcommands:
- update-users (u) [USER]...          update user authorized_keys files
+ update-users (u) [USER]...        update user authorized_keys files
 
- add-id-certifier (c+) [KEYID|FILE]  import and tsign a certification key
-   --domain (-n) DOMAIN                limit ID certifications to DOMAIN
-   --trust (-t) TRUST                  trust level of certifier (full)
-   --depth (-d) DEPTH                  trust depth for certifier (1)
- remove-id-certifier (c-) KEYID      remove a certification key
- list-id-certifiers (c)              list certification keys
+ add-id-certifier (c+) KEYID|FILE  import and tsign a certification key
+   [--domain (-n) DOMAIN]            limit ID certifications to DOMAIN
+   [--trust (-t) TRUST]              trust level of certifier (default: full)
+   [--depth (-d) DEPTH]              trust depth for certifier (default: 1)
+ remove-id-certifier (c-) KEYID    remove a certification key
+ list-id-certifiers (c)            list certification keys
 
- version (v)                         show version number
- help (h,?)                          this help
+ version (v)                       show version number
+ help (h,?)                        this help
 
 See ${PGRM}(8) for more info.
 EOF
@@ -102,7 +100,7 @@ core_fingerprint() {
 gpg_core_sphere_sig_transfer() {
     log debug "exporting core local sigs to sphere..."
     gpg_core --export-options export-local-sigs --export | \
-       gpg_sphere "--import-options import-local-sigs --import"
+       gpg_sphere "--import-options import-local-sigs --import" 2>&1 | log debug
 }
 
 ########################################################################
@@ -131,6 +129,7 @@ REQUIRED_USER_KEY_CAPABILITY=${MONKEYSPHERE_REQUIRED_USER_KEY_CAPABILITY:="a"}
 GNUPGHOME_CORE=${MONKEYSPHERE_GNUPGHOME_CORE:="${MADATADIR}/core"}
 GNUPGHOME_SPHERE=${MONKEYSPHERE_GNUPGHOME_SPHERE:="${MADATADIR}/sphere"}
 CORE_KEYLENGTH=${MONKEYSPHERE_CORE_KEYLENGTH:="2048"}
+LOG_PREFIX=${MONKEYSPHERE_LOG_PREFIX:='ms: '}
 
 # export variables needed in su invocation
 export DATE
@@ -199,7 +198,7 @@ case $COMMAND in
        ;;
 
     'version'|'v')
-       echo "$VERSION"
+       version
        ;;
 
     '--help'|'help'|'-h'|'h'|'?')
@@ -211,5 +210,3 @@ case $COMMAND in
 Type '$PGRM help' for usage."
         ;;
 esac
-
-exit "$RETURN"
index 1b0de0cd7c4a60eec47af82d48eb663d3302da41..6136399643eb70e46da8e19df0b1485d49e821a8 100755 (executable)
@@ -21,7 +21,8 @@ PGRM=$(basename $0)
 
 SYSSHAREDIR=${MONKEYSPHERE_SYSSHAREDIR:-"/usr/share/monkeysphere"}
 export SYSSHAREDIR
-. "${SYSSHAREDIR}/common" || exit 1
+. "${SYSSHAREDIR}/defaultenv"
+. "${SYSSHAREDIR}/common"
 
 SYSDATADIR=${MONKEYSPHERE_SYSDATADIR:-"/var/lib/monkeysphere"}
 export SYSDATADIR
@@ -41,9 +42,6 @@ DATE=$(date -u '+%FT%T')
 # unset some environment variables that could screw things up
 unset GREP_OPTIONS
 
-# default return code
-RETURN=0
-
 ########################################################################
 # FUNCTIONS
 ########################################################################
@@ -60,7 +58,7 @@ subcommands:
  set-expire (e) [EXPIRE]             set host key expiration
  add-hostname (n+) NAME[:PORT]       add hostname user ID to host key
  revoke-hostname (n-) NAME[:PORT]    revoke hostname user ID
- add-revoker (r+) [KEYID|FILE]        add a revoker to the host key
+ add-revoker (r+) KEYID|FILE         add a revoker to the host key
  revoke-key                          generate and/or publish revocation
                                      certificate for host key
 
@@ -105,7 +103,7 @@ update_gpg_pub_file() {
 load_fingerprint() {
     if [ -f "$HOST_KEY_FILE" ] ; then
        HOST_FINGERPRINT=$( \
-           (FUBAR=$(mktemp -d) && export GNUPGHOME="$FUBAR" \
+           (FUBAR=$(msmktempdir) && export GNUPGHOME="$FUBAR" \
            && gpg --quiet --import \
            && gpg --quiet --list-keys --with-colons --with-fingerprint \
            && rm -rf "$FUBAR") <"$HOST_KEY_FILE" \
@@ -177,7 +175,7 @@ show_key() {
 
     # create the ssh key
     TMPSSH="$GNUPGHOME"/ssh_host_key_rsa_pub
-    openpgp2ssh <"$HOST_KEY_FILE" 2>/dev/null >"$TMPSSH"
+    gpg --export | openpgp2ssh 2>/dev/null >"$TMPSSH"
 
     # get the gpg fingerprint
     HOST_FINGERPRINT=$(gpg --quiet --list-keys --with-colons --with-fingerprint \
@@ -232,6 +230,7 @@ PROMPT=${MONKEYSPHERE_PROMPT:=$PROMPT}
 
 # other variables
 GNUPGHOME_HOST=${MONKEYSPHERE_GNUPGHOME_HOST:="${MHDATADIR}"}
+LOG_PREFIX=${MONKEYSPHERE_LOG_PREFIX:='ms: '}
 
 # export variables needed in su invocation
 export DATE
@@ -315,7 +314,7 @@ case $COMMAND in
        ;;
 
     'version'|'v')
-       echo "$VERSION"
+       version
        ;;
 
     '--help'|'help'|'-h'|'h'|'?')
@@ -327,5 +326,3 @@ case $COMMAND in
 Type '$PGRM help' for usage."
         ;;
 esac
-
-exit "$RETURN"
diff --git a/src/openpgp2ssh b/src/openpgp2ssh
new file mode 120000 (symlink)
index 0000000..edcb6a3
--- /dev/null
@@ -0,0 +1 @@
+share/keytrans
\ No newline at end of file
diff --git a/src/pem2openpgp b/src/pem2openpgp
new file mode 120000 (symlink)
index 0000000..edcb6a3
--- /dev/null
@@ -0,0 +1 @@
+share/keytrans
\ No newline at end of file
index 5e0cb6a4a00ec1d5d79eb594f43f673f4239aabf..ea872ba17abe39ec1a8a721876b6bf74d42ab069 100644 (file)
 # all-caps variables are meant to be user supplied (ie. from config
 # file) and are considered global
 
-########################################################################
-### COMMON VARIABLES
-
-# managed directories
-SYSCONFIGDIR=${MONKEYSPHERE_SYSCONFIGDIR:-"/etc/monkeysphere"}
-export SYSCONFIGDIR
-
-# monkeysphere version
-VERSION=0.23~pre
-
-# default log level
-LOG_LEVEL="INFO"
-
-# default keyserver
-KEYSERVER="pool.sks-keyservers.net"
-
-# whether or not to check keyservers by defaul
-CHECK_KEYSERVER="true"
-
-# default monkeysphere user
-MONKEYSPHERE_USER="monkeysphere"
-
-# default about whether or not to prompt
-PROMPT="true"
-
 ########################################################################
 ### UTILITY FUNCTIONS
 
+# output version info
+version() {
+    cat "${SYSSHAREDIR}/VERSION"
+}
+
 # failure function.  exits with code 255, unless specified otherwise.
 failure() {
     [ "$1" ] && echo "$1" >&2
@@ -96,11 +76,10 @@ log() {
        fi
        if [ "$priority" = "$level" -a "$output" = 'true' ] ; then
            if [ "$1" ] ; then
-               echo -n "ms: " >&2
-               echo "$@" >&2
+               echo "$@"
            else
-               cat >&2
-           fi
+               cat
+           fi | sed 's/^/'"${LOG_PREFIX}"'/' >&2
        fi
     done
 }
@@ -334,52 +313,6 @@ passphrase_prompt() {
     fi
 }
 
-test_gnu_dummy_s2k_extension() {
-
-# this block contains a demonstration private key that has had the
-# primary key stripped out using the GNU S2K extension known as
-# "gnu-dummy" (see /usr/share/doc/gnupg/DETAILS.gz).  The subkey is
-# present in cleartext, however.
-
-# openpgp2ssh will be able to deal with this based on whether the
-# local copy of GnuTLS contains read_s2k support that can handle it.
-
-# read up on that here:
-
-# http://lists.gnu.org/archive/html/gnutls-devel/2008-08/msg00005.html
-
-echo "
------BEGIN PGP PRIVATE KEY BLOCK-----
-Version: GnuPG v1.4.9 (GNU/Linux)
-
-lQCVBEO3YdABBACRqqEnucag4+vyZny2M67Pai5+5suIRRvY+Ly8Ms5MvgCi3EVV
-xT05O/+0ShiRaf+QicCOFrhbU9PZzzU+seEvkeW2UCu4dQfILkmj+HBEIltGnHr3
-G0yegHj5pnqrcezERURf2e17gGFWX91cXB9Cm721FPXczuKraphKwCA9PwARAQAB
-/gNlAkdOVQG0OURlbW9uc3RyYXRpb24gS2V5IGZvciBTMksgR05VIGV4dGVuc2lv
-biAxMDAxIC0tIGdudS1kdW1teYi8BBMBAgAmBQJDt2HQAhsDBQkB4TOABgsJCAcD
-AgQVAggDBBYCAwECHgECF4AACgkQQZUwSa4UDezTOQP/TMQXUVrWzHYZGopoPZ2+
-ZS3qddiznBHsgb7MGYg1KlTiVJSroDUBCHIUJvdQKZV9zrzrFl47D07x6hGyUPHV
-aZXvuITW8t1o5MMHkCy3pmJ2KgfDvdUxrBvLfgPMICA4c6zA0mWquee43syEW9NY
-g3q61iPlQwD1J1kX1wlimLCdAdgEQ7dh0AEEANAwa63zlQbuy1Meliy8otwiOa+a
-mH6pxxUgUNggjyjO5qx+rl25mMjvGIRX4/L1QwIBXJBVi3SgvJW1COZxZqBYqj9U
-8HVT07mWKFEDf0rZLeUE2jTm16cF9fcW4DQhW+sfYm+hi2sY3HeMuwlUBK9KHfW2
-+bGeDzVZ4pqfUEudABEBAAEAA/0bemib+wxub9IyVFUp7nPobjQC83qxLSNzrGI/
-RHzgu/5CQi4tfLOnwbcQsLELfker2hYnjsLrT9PURqK4F7udrWEoZ1I1LymOtLG/
-4tNZ7Mnul3wRC2tCn7FKx8sGJwGh/3li8vZ6ALVJAyOia5TZ/buX0+QZzt6+hPKk
-7MU1WQIA4bUBjtrsqDwro94DvPj3/jBnMZbXr6WZIItLNeVDUcM8oHL807Am97K1
-ueO/f6v1sGAHG6lVPTmtekqPSTWBfwIA7CGFvEyvSALfB8NUa6jtk27NCiw0csql
-kuhCmwXGMVOiryKEfegkIahf2bAd/gnWHPrpWp7bUE20v8YoW22I4wIAhnm5Wr5Q
-Sy7EHDUxmJm5TzadFp9gq08qNzHBpXSYXXJ3JuWcL1/awUqp3tE1I6zZ0hZ38Ia6
-SdBMN88idnhDPqPoiKUEGAECAA8FAkO3YdACGyAFCQHhM4AACgkQQZUwSa4UDezm
-vQP/ZhK+2ly9oI2z7ZcNC/BJRch0/ybQ3haahII8pXXmOThpZohr/LUgoWgCZdXg
-vP6yiszNk2tIs8KphCAw7Lw/qzDC2hEORjWO4f46qk73RAgSqG/GyzI4ltWiDhqn
-vnQCFl3+QFSe4zinqykHnLwGPMXv428d/ZjkIc2ju8dRsn4=
-=CR5w
------END PGP PRIVATE KEY BLOCK-----
-" | openpgp2ssh 4129E89D17C1D591 >/dev/null 2>/dev/null
-
-}
-
 # remove all lines with specified string from specified file
 remove_line() {
     local file
@@ -420,12 +353,15 @@ remove_monkeysphere_lines() {
 
     file="$1"
 
-    if [ -z "$file" ] ; then
+    # return error if file does not exist
+    if [ ! -e "$file" ] ; then
        return 1
     fi
 
-    if [ ! -e "$file" ] ; then
-       return 1
+    # just return ok if the file is empty, since there aren't any
+    # lines to remove
+    if [ ! -s "$file" ] ; then
+       return 0
     fi
 
     tempfile=$(mktemp "${file}.XXXXXXX") || \
@@ -493,18 +429,21 @@ check_key_file_permissions() {
 
     # return 1 if path has invalid owner
     if [ "$owner" != "$uname" -a "$owner" != 'root' ] ; then
-       log error "improper ownership on path '$path'."
+       log error "improper ownership on path '$path':"
+       log error " $owner != ($uname|root)"
        return 1
     fi
 
     # return 2 if path has group or other writability
     if is_write "$gAccess" || is_write "$oAccess" ; then
-       log error "improper group or other writability on path '$path'."
+       log error "improper group or other writability on path '$path':"
+       log error " group: $gAccess, other: $oAcess"
        return 2
     fi
 
     # return zero if all clear, or go to next path
     if [ "$path" = '/' ] ; then
+       log debug "path ok."
        return 0
     else
        check_key_file_permissions "$uname" $(dirname "$path")
@@ -732,14 +671,14 @@ process_user_id() {
                if [ "$keyOK" -a "$uidOK" -a "$lastKeyOK" ] ; then
                    log verbose "  * acceptable primary key."
                    if [ -z "$sshKey" ] ; then
-                       log error "    ! primary key could not be translated (not RSA or DSA?)."
+                       log error "    ! primary key could not be translated (not RSA?)."
                    else
                        echo "0:${sshKey}"
                    fi
                else
                    log debug "  - unacceptable primary key."
                    if [ -z "$sshKey" ] ; then
-                       log debug "    ! primary key could not be translated (not RSA or DSA?)."
+                       log debug "    ! primary key could not be translated (not RSA?)."
                    else
                        echo "1:${sshKey}"
                    fi
@@ -790,14 +729,14 @@ process_user_id() {
                if [ "$keyOK" -a "$uidOK" -a "$lastKeyOK" ] ; then
                    log verbose "  * acceptable sub key."
                    if [ -z "$sshKey" ] ; then
-                       log error "    ! sub key could not be translated (not RSA or DSA?)."
+                       log error "    ! sub key could not be translated (not RSA?)."
                    else
                        echo "0:${sshKey}"
                    fi
                else
                    log debug "  - unacceptable sub key."
                    if [ -z "$sshKey" ] ; then
-                       log debug "    ! sub key could not be translated (not RSA or DSA?)."
+                       log debug "    ! sub key could not be translated (not RSA?)."
                    else
                        echo "1:${sshKey}"
                    fi
@@ -909,7 +848,7 @@ update_known_hosts() {
     (umask 0022 && touch "$KNOWN_HOSTS")
 
     # check permissions on the known_hosts file path
-    check_key_file_permissions "$USER" "$KNOWN_HOSTS" || failure
+    check_key_file_permissions $(whoami) "$KNOWN_HOSTS" || failure
 
     # create a lockfile on known_hosts:
     lock create "$KNOWN_HOSTS"
@@ -970,7 +909,8 @@ process_known_hosts() {
        failure "known_hosts file '$KNOWN_HOSTS' does not exist."
     fi
 
-    log debug "processing known_hosts file..."
+    log debug "processing known_hosts file:"
+    log debug " $KNOWN_HOSTS"
 
     hosts=$(meat "$KNOWN_HOSTS" | cut -d ' ' -f 1 | grep -v '^|.*$' | tr , ' ' | tr '\n' ' ')
 
@@ -1058,8 +998,11 @@ update_authorized_keys() {
     nIDsOK=0
     nIDsBAD=0
 
+    log debug "updating authorized_keys file:"
+    log debug " $AUTHORIZED_KEYS"
+
     # check permissions on the authorized_keys file path
-    check_key_file_permissions "$USER" "$AUTHORIZED_KEYS" || failure
+    check_key_file_permissions $(whoami) "$AUTHORIZED_KEYS" || failure
 
     # create a lockfile on authorized_keys
     lock create "$AUTHORIZED_KEYS"
@@ -1131,10 +1074,11 @@ process_authorized_user_ids() {
        failure "authorized_user_ids file '$authorizedUserIDs' does not exist."
     fi
 
-    # check permissions on the authorized_user_ids file path
-    check_key_file_permissions "$USER" "$authorizedUserIDs" || failure
+    log debug "processing authorized_user_ids file:"
+    log debug " $authorizedUserIDs"
 
-    log debug "processing authorized_user_ids file..."
+    # check permissions on the authorized_user_ids file path
+    check_key_file_permissions $(whoami) "$authorizedUserIDs" || failure
 
     if ! meat "$authorizedUserIDs" > /dev/null ; then
        log debug " no user IDs to process."
diff --git a/src/share/defaultenv b/src/share/defaultenv
new file mode 100644 (file)
index 0000000..b54a518
--- /dev/null
@@ -0,0 +1,29 @@
+# -*-shell-script-*-
+# This should be sourced by bash (though we welcome changes to make it POSIX sh compliant)
+
+# Shared sh variables for the monkeysphere
+#
+# Written by
+# Jameson Rollins <jrollins@finestructure.net>
+#
+# Copyright 2009, released under the GPL, version 3 or later
+
+# managed directories
+SYSCONFIGDIR=${MONKEYSPHERE_SYSCONFIGDIR:-"/etc/monkeysphere"}
+export SYSCONFIGDIR
+
+# default log level
+LOG_LEVEL="INFO"
+
+# default keyserver
+KEYSERVER="pool.sks-keyservers.net"
+
+# whether or not to check keyservers by defaul
+CHECK_KEYSERVER="true"
+
+# default monkeysphere user
+MONKEYSPHERE_USER="monkeysphere"
+
+# default about whether or not to prompt
+PROMPT="true"
+
diff --git a/src/share/keytrans b/src/share/keytrans
new file mode 100755 (executable)
index 0000000..8b2e2ea
--- /dev/null
@@ -0,0 +1,802 @@
+#!/usr/bin/perl -w -T
+
+# keytrans: this is an RSA key translation utility; it is capable of
+# transforming RSA keys (both public keys and secret keys) between
+# several popular representations, including OpenPGP, PEM-encoded
+# PKCS#1 DER, and OpenSSH-style public key lines.
+
+# How it behaves depends on the name under which it is invoked.  The
+# two implementations currently are: pem2openpgp and openpgp2ssh.
+
+
+
+# pem2openpgp: take a PEM-encoded RSA private-key on standard input, a
+# User ID as the first argument, and generate an OpenPGP secret key
+# and certificate from it.
+
+# WARNING: the secret key material *will* appear on stdout (albeit in
+# OpenPGP form) -- if you redirect stdout to a file, make sure the
+# permissions on that file are appropriately locked down!
+
+# Usage:
+
+# pem2openpgp 'ssh://'$(hostname -f) < /etc/ssh/ssh_host_rsa_key | gpg --import
+
+
+
+
+# openpgp2ssh: take a stream of OpenPGP packets containing public or
+# secret key material on standard input, and a Key ID (or fingerprint)
+# as the first argument.  Find the matching key in the input stream,
+# and emit it on stdout in an OpenSSH-compatible format.  If the input
+# key is an OpenPGP public key (either primary or subkey), the output
+# will be an OpenSSH single-line public key.  If the input key is an
+# OpenPGP secret key, the output will be a PEM-encoded RSA key.
+
+# Example usage:
+
+# gpg --export-secret-subkeys --export-options export-reset-subkey-passwd $KEYID | \
+#  openpgp2ssh $KEYID | ssh-add /dev/stdin
+
+
+# Authors:
+#  Jameson Rollins <jrollins@finestructure.net>
+#  Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+
+# Started on: 2009-01-07 02:01:19-0500
+
+# License: GPL v3 or later (we may need to adjust this given that this
+# connects to OpenSSL via perl)
+
+use strict;
+use warnings;
+use File::Basename;
+use Crypt::OpenSSL::RSA;
+use Crypt::OpenSSL::Bignum;
+use Crypt::OpenSSL::Bignum::CTX;
+use Digest::SHA1;
+use MIME::Base64;
+use POSIX;
+
+## make sure all length() and substr() calls use bytes only:
+use bytes;
+
+my $old_format_packet_lengths = { one => 0,
+                                 two => 1,
+                                 four => 2,
+                                 indeterminate => 3,
+};
+
+# see RFC 4880 section 9.1 (ignoring deprecated algorithms for now)
+my $asym_algos = { rsa => 1,
+                  elgamal => 16,
+                  dsa => 17,
+                  };
+
+# see RFC 4880 section 9.2
+my $ciphers = { plaintext => 0,
+               idea => 1,
+               tripledes => 2,
+               cast5 => 3,
+               blowfish => 4,
+               aes128 => 7,
+               aes192 => 8,
+               aes256 => 9,
+               twofish => 10,
+             };
+
+# see RFC 4880 section 9.3
+my $zips = { uncompressed => 0,
+            zip => 1,
+            zlib => 2,
+            bzip2 => 3,
+          };
+
+# see RFC 4880 section 9.4
+my $digests = { md5 => 1,
+               sha1 => 2,
+               ripemd160 => 3,
+               sha256 => 8,
+               sha384 => 9,
+               sha512 => 10,
+               sha224 => 11,
+             };
+
+# see RFC 4880 section 5.2.3.21
+my $usage_flags = { certify => 0x01,
+                   sign => 0x02,
+                   encrypt_comms => 0x04,
+                   encrypt_storage => 0x08,
+                   encrypt => 0x0c, ## both comms and storage
+                   split => 0x10, # the private key is split via secret sharing
+                   authenticate => 0x20,
+                   shared => 0x80, # more than one person holds the entire private key
+                 };
+
+# see RFC 4880 section 4.3
+my $packet_types = { pubkey_enc_session => 1,
+                    sig => 2,
+                    symkey_enc_session => 3,
+                    onepass_sig => 4,
+                    seckey => 5,
+                    pubkey => 6,
+                    sec_subkey => 7,
+                    compressed_data => 8,
+                    symenc_data => 9,
+                    marker => 10,
+                    literal => 11,
+                    trust => 12,
+                    uid => 13,
+                    pub_subkey => 14,
+                    uat => 17,
+                    symenc_w_integrity => 18,
+                    mdc => 19,
+                  };
+
+# see RFC 4880 section 5.2.1
+my $sig_types = { binary_doc => 0x00,
+                 text_doc => 0x01,
+                 standalone => 0x02,
+                 generic_certification => 0x10,
+                 persona_certification => 0x11,
+                 casual_certification => 0x12,
+                 positive_certification => 0x13,
+                 subkey_binding => 0x18,
+                 primary_key_binding => 0x19,
+                 key_signature => 0x1f,
+                 key_revocation => 0x20,
+                 subkey_revocation => 0x28,
+                 certification_revocation => 0x30,
+                 timestamp => 0x40,
+                 thirdparty => 0x50,
+               };
+
+
+# see RFC 4880 section 5.2.3.1
+my $subpacket_types = { sig_creation_time => 2,
+                       sig_expiration_time => 3,
+                       exportable => 4,
+                       trust_sig => 5,
+                       regex => 6,
+                       revocable => 7,
+                       key_expiration_time => 9,
+                       preferred_cipher => 11,
+                       revocation_key => 12,
+                       issuer => 16,
+                       notation => 20,
+                       preferred_digest => 21,
+                       preferred_compression => 22,
+                       keyserver_prefs => 23,
+                       preferred_keyserver => 24,
+                       primary_uid => 25,
+                       policy_uri => 26,
+                       usage_flags => 27,
+                       signers_uid => 28,
+                       revocation_reason => 29,
+                       features => 30,
+                       signature_target => 31,
+                       embedded_signature => 32,
+                      };
+
+# bitstring (see RFC 4880 section 5.2.3.24)
+my $features = { mdc => 0x01
+              };
+
+# bitstring (see RFC 4880 5.2.3.17)
+my $keyserver_prefs = { nomodify => 0x80
+                     };
+
+###### end lookup tables ######
+
+# FIXME: if we want to be able to interpret openpgp data as well as
+# produce it, we need to produce key/value-swapped lookup tables as well.
+
+
+########### Math/Utility Functions ##############
+
+
+# see the bottom of page 43 of RFC 4880
+sub simple_checksum {
+  my $bytes = shift;
+
+  return unpack("%32W*",$bytes) % 65536;
+}
+
+# calculate the multiplicative inverse of a mod b this is euclid's
+# extended algorithm.  For more information see:
+# http://en.wikipedia.org/wiki/Extended_Euclidean_algorithm the
+# arguments here should be Crypt::OpenSSL::Bignum objects.  $a should
+# be the larger of the two values, and the two values should be
+# coprime.
+
+sub modular_multi_inverse {
+  my $a = shift;
+  my $b = shift;
+
+
+  my $origdivisor = $b->copy();
+
+  my $ctx = Crypt::OpenSSL::Bignum::CTX->new();
+  my $x = Crypt::OpenSSL::Bignum->zero();
+  my $y = Crypt::OpenSSL::Bignum->one();
+  my $lastx = Crypt::OpenSSL::Bignum->one();
+  my $lasty = Crypt::OpenSSL::Bignum->zero();
+
+  my $finalquotient;
+  my $finalremainder;
+
+  while (! $b->is_zero()) {
+    my ($quotient, $remainder) = $a->div($b, $ctx);
+
+    $a = $b;
+    $b = $remainder;
+
+    my $temp = $x;
+    $x = $lastx->sub($quotient->mul($x, $ctx));
+    $lastx = $temp;
+
+    $temp = $y;
+    $y = $lasty->sub($quotient->mul($y, $ctx));
+    $lasty = $temp;
+  }
+
+  if (!$a->is_one()) {
+    die "did this math wrong.\n";
+  }
+
+  # let's make sure that we return a positive value because RFC 4880,
+  # section 3.2 only allows unsigned values:
+
+  ($finalquotient, $finalremainder) = $lastx->add($origdivisor)->div($origdivisor, $ctx);
+
+  return $finalremainder;
+}
+
+
+############ OpenPGP formatting functions ############
+
+# make an old-style packet out of the given packet type and body.
+# old-style  (see RFC 4880 section 4.2)
+sub make_packet {
+  my $type = shift;
+  my $body = shift;
+  my $options = shift;
+
+  my $len = length($body);
+  my $pseudolen = $len;
+
+  # if the caller wants to use at least N octets of packet length,
+  # pretend that we're using that many.
+  if (defined $options && defined $options->{'packet_length'}) {
+      $pseudolen = 2**($options->{'packet_length'} * 8) - 1;
+  }
+  if ($pseudolen < $len) {
+      $pseudolen = $len;
+  }
+
+  my $lenbytes;
+  my $lencode;
+
+  if ($pseudolen < 2**8) {
+    $lenbytes = $old_format_packet_lengths->{one};
+    $lencode = 'C';
+  } elsif ($pseudolen < 2**16) {
+    $lenbytes = $old_format_packet_lengths->{two};
+    $lencode = 'n';
+  } elsif ($pseudolen < 2**31) {
+    ## not testing against full 32 bits because i don't want to deal
+    ## with potential overflow.
+    $lenbytes = $old_format_packet_lengths->{four};
+    $lencode = 'N';
+  } else {
+    ## what the hell do we do here?
+    $lenbytes = $old_format_packet_lengths->{indeterminate};
+    $lencode = '';
+  }
+
+  return pack('C'.$lencode, 0x80 + ($type * 4) + $lenbytes, $len).
+    $body;
+}
+
+
+# takes a Crypt::OpenSSL::Bignum, returns it formatted as OpenPGP MPI
+# (RFC 4880 section 3.2)
+sub mpi_pack {
+  my $num = shift;
+
+  my $val = $num->to_bin();
+  my $mpilen = length($val)*8;
+
+# this is a kludgy way to get the number of significant bits in the
+# first byte:
+  my $bitsinfirstbyte = length(sprintf("%b", ord($val)));
+
+  $mpilen -= (8 - $bitsinfirstbyte);
+
+  return pack('n', $mpilen).$val;
+}
+
+# takes a Crypt::OpenSSL::Bignum, returns an MPI packed in preparation
+# for an OpenSSH-style public key format.  see:
+# http://marc.info/?l=openssh-unix-dev&m=121866301718839&w=2
+sub openssh_mpi_pack {
+  my $num = shift;
+
+  my $val = $num->to_bin();
+  my $mpilen = length($val);
+
+  my $ret = pack('N', $mpilen);
+
+  # if the first bit of the leading byte is high, we should include a
+  # 0 byte:
+  if (ord($val) & 0x80) {
+    $ret = pack('NC', $mpilen+1, 0);
+  }
+
+  return $ret.$val;
+}
+
+sub openssh_pubkey_pack {
+  my $key = shift;
+
+  my ($modulus, $exponent) = $key->get_key_parameters();
+
+  return openssh_mpi_pack(Crypt::OpenSSL::Bignum->new_from_bin("ssh-rsa")).
+      openssh_mpi_pack($exponent).
+       openssh_mpi_pack($modulus);
+}
+
+# pull an OpenPGP-specified MPI off of a given stream, returning it as
+# a Crypt::OpenSSL::Bignum.
+sub read_mpi {
+  my $instr = shift;
+  my $readtally = shift;
+
+  my $bitlen;
+  read($instr, $bitlen, 2) or die "could not read MPI length.\n";
+  $bitlen = unpack('n', $bitlen);
+  $$readtally += 2;
+
+  my $bytestoread = POSIX::floor(($bitlen + 7)/8);
+  my $ret;
+  read($instr, $ret, $bytestoread) or die "could not read MPI body.\n";
+  $$readtally += $bytestoread;
+  return Crypt::OpenSSL::Bignum->new_from_bin($ret);
+}
+
+
+# FIXME: genericize these to accept either RSA or DSA keys:
+sub make_rsa_pub_key_body {
+  my $key = shift;
+  my $timestamp = shift;
+
+  my ($n, $e) = $key->get_key_parameters();
+
+  return
+    pack('CN', 4, $timestamp).
+      pack('C', $asym_algos->{rsa}).
+       mpi_pack($n).
+         mpi_pack($e);
+}
+
+sub make_rsa_sec_key_body {
+  my $key = shift;
+  my $timestamp = shift;
+
+  # we're not using $a and $b, but we need them to get to $c.
+  my ($n, $e, $d, $p, $q) = $key->get_key_parameters();
+
+  my $c3 = modular_multi_inverse($p, $q);
+
+  my $secret_material = mpi_pack($d).
+    mpi_pack($p).
+      mpi_pack($q).
+       mpi_pack($c3);
+
+  # according to Crypt::OpenSSL::RSA, the closest value we can get out
+  # of get_key_parameters is 1/q mod p; but according to sec 5.5.3 of
+  # RFC 4880, we're actually looking for u, the multiplicative inverse
+  # of p, mod q.  This is why we're calculating the value directly
+  # with modular_multi_inverse.
+
+  return
+    pack('CN', 4, $timestamp).
+      pack('C', $asym_algos->{rsa}).
+       mpi_pack($n).
+         mpi_pack($e).
+           pack('C', 0). # seckey material is not encrypted -- see RFC 4880 sec 5.5.3
+             $secret_material.
+               pack('n', simple_checksum($secret_material));
+}
+
+# expects an RSA key (public or private) and a timestamp
+sub fingerprint {
+  my $key = shift;
+  my $timestamp = shift;
+
+  my $rsabody = make_rsa_pub_key_body($key, $timestamp);
+
+  return Digest::SHA1::sha1(pack('Cn', 0x99, length($rsabody)).$rsabody);
+}
+
+
+# FIXME: handle DSA keys as well!
+sub pem2openpgp {
+  my $rsa = shift;
+  my $uid = shift;
+  my $args = shift;
+
+  $rsa->use_sha1_hash();
+
+  # see page 22 of RFC 4880 for why i think this is the right padding
+  # choice to use:
+  $rsa->use_pkcs1_padding();
+
+  if (! $rsa->check_key()) {
+    die "key does not check";
+  }
+
+  my $version = pack('C', 4);
+  # strong assertion of identity:
+  my $sigtype = pack('C', $sig_types->{positive_certification});
+  # RSA
+  my $pubkey_algo = pack('C', $asym_algos->{rsa});
+  # SHA1
+  my $hash_algo = pack('C', $digests->{sha1});
+
+  # FIXME: i'm worried about generating a bazillion new OpenPGP
+  # certificates from the same key, which could easily happen if you run
+  # this script more than once against the same key (because the
+  # timestamps will differ).  How can we prevent this?
+
+  # this environment variable (if set) overrides the current time, to
+  # be able to create a standard key?  If we read the key from a file
+  # instead of stdin, should we use the creation time on the file?
+  my $timestamp = 0;
+  if (defined $args->{timestamp}) {
+    $timestamp = ($args->{timestamp} + 0);
+  } else {
+    $timestamp = time();
+  }
+
+  my $creation_time_packet = pack('CCN', 5, $subpacket_types->{sig_creation_time}, $timestamp);
+
+
+  my $flags = 0;
+  if (! defined $args->{usage_flags}) {
+    $flags = $usage_flags->{certify};
+  } else {
+    my @ff = split(",", $args->{usage_flags});
+    foreach my $f (@ff) {
+      if (! defined $usage_flags->{$f}) {
+       die "No such flag $f";
+      }
+      $flags |= $usage_flags->{$f};
+    }
+  }
+
+  my $usage_packet = pack('CCC', 2, $subpacket_types->{usage_flags}, $flags);
+
+
+  # how should we determine how far off to set the expiration date?
+  # default is no expiration.  Specify the timestamp in seconds from the
+  # key creation.
+  my $expiration_packet = '';
+  if (defined $args->{expiration}) {
+    my $expires_in = $args->{expiration} + 0;
+    $expiration_packet = pack('CCN', 5, $subpacket_types->{key_expiration_time}, $expires_in);
+  }
+
+
+  # prefer AES-256, AES-192, AES-128, CAST5, 3DES:
+  my $pref_sym_algos = pack('CCCCCCC', 6, $subpacket_types->{preferred_cipher},
+                           $ciphers->{aes256},
+                           $ciphers->{aes192},
+                           $ciphers->{aes128},
+                           $ciphers->{cast5},
+                           $ciphers->{tripledes}
+                          );
+
+  # prefer SHA-1, SHA-256, RIPE-MD/160
+  my $pref_hash_algos = pack('CCCCC', 4, $subpacket_types->{preferred_digest},
+                            $digests->{sha1},
+                            $digests->{sha256},
+                            $digests->{ripemd160}
+                           );
+
+  # prefer ZLIB, BZip2, ZIP
+  my $pref_zip_algos = pack('CCCCC', 4, $subpacket_types->{preferred_compression},
+                           $zips->{zlib},
+                           $zips->{bzip2},
+                           $zips->{zip}
+                          );
+
+  # we support the MDC feature:
+  my $feature_subpacket = pack('CCC', 2, $subpacket_types->{features},
+                              $features->{mdc});
+
+  # keyserver preference: only owner modify (???):
+  my $keyserver_pref = pack('CCC', 2, $subpacket_types->{keyserver_prefs},
+                           $keyserver_prefs->{nomodify});
+
+  my $subpackets_to_be_hashed =
+    $creation_time_packet.
+      $usage_packet.
+       $expiration_packet.
+         $pref_sym_algos.
+           $pref_hash_algos.
+             $pref_zip_algos.
+               $feature_subpacket.
+                 $keyserver_pref;
+
+  my $subpacket_octets = pack('n', length($subpackets_to_be_hashed));
+
+  my $sig_data_to_be_hashed =
+    $version.
+      $sigtype.
+       $pubkey_algo.
+         $hash_algo.
+           $subpacket_octets.
+             $subpackets_to_be_hashed;
+
+  my $pubkey = make_rsa_pub_key_body($rsa, $timestamp);
+  my $seckey = make_rsa_sec_key_body($rsa, $timestamp);
+
+  # this is for signing.  it needs to be an old-style header with a
+  # 2-packet octet count.
+
+  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, $timestamp), 20 - 8, 8);
+
+  # the v4 signature trailer is:
+
+  # version number, literal 0xff, and then a 4-byte count of the
+  # signature data itself.
+  my $trailer = pack('CCN', 4, 0xff, length($sig_data_to_be_hashed));
+
+  my $uid_data =
+    pack('CN', 0xb4, length($uid)).
+      $uid;
+
+  my $datatosign =
+    $key_data.
+      $uid_data.
+       $sig_data_to_be_hashed.
+         $trailer;
+
+  my $data_hash = Digest::SHA1::sha1_hex($datatosign);
+
+  my $issuer_packet = pack('CCa8', 9, $subpacket_types->{issuer}, $keyid);
+
+  my $sig = Crypt::OpenSSL::Bignum->new_from_bin($rsa->sign($datatosign));
+
+  my $sig_body =
+    $sig_data_to_be_hashed.
+      pack('n', length($issuer_packet)).
+       $issuer_packet.
+         pack('n', hex(substr($data_hash, 0, 4))).
+           mpi_pack($sig);
+
+  return
+    make_packet($packet_types->{seckey}, $seckey).
+      make_packet($packet_types->{uid}, $uid).
+       make_packet($packet_types->{sig}, $sig_body);
+}
+
+
+sub openpgp2ssh {
+  my $instr = shift;
+  my $fpr = shift;
+
+  if (defined $fpr) {
+    if (length($fpr) < 8) {
+      die "We need at least 8 hex digits of fingerprint.\n";
+    }
+    $fpr = uc($fpr);
+  }
+
+  my $packettag;
+  my $dummy;
+  my $tag;
+
+  my $key;
+
+  while (! eof($instr)) {
+    read($instr, $packettag, 1);
+    $packettag = ord($packettag);
+
+    my $packetlen;
+    if ( ! (0x80 & $packettag)) {
+      die "This is not an OpenPGP packet\n";
+    }
+    if (0x40 & $packettag) {
+      $tag = (0x3f & $packettag);
+      my $nextlen = 0;
+      read($instr, $nextlen, 1);
+      $nextlen = ord($nextlen);
+      if ($nextlen < 192) {
+       $packetlen = $nextlen;
+      } elsif ($nextlen < 224) {
+       my $newoct;
+       read($instr, $newoct, 1);
+       $newoct = ord($newoct);
+       $packetlen = (($nextlen - 192) << 8) + ($newoct) + 192;
+      } elsif ($nextlen == 255) {
+       read($instr, $nextlen, 4);
+       $packetlen = unpack('N', $nextlen);
+      } else {
+       # packet length is undefined.
+      }
+    } else {
+      my $lentype;
+      $lentype = 0x03 & $packettag;
+      $tag = ( 0x3c & $packettag ) >> 2;
+      if ($lentype == 0) {
+       read($instr, $packetlen, 1) or die "could not read packet length\n";
+       $packetlen = unpack('C', $packetlen);
+      } elsif ($lentype == 1) {
+       read($instr, $packetlen, 2) or die "could not read packet length\n";
+       $packetlen = unpack('n', $packetlen);
+      } elsif ($lentype == 2) {
+       read($instr, $packetlen, 4) or die "could not read packet length\n";
+       $packetlen = unpack('N', $packetlen);
+      } else {
+       # packet length is undefined.
+      }
+    }
+
+    if (! defined($packetlen)) {
+      die "Undefined packet lengths are not supported.\n";
+    }
+
+    if ($tag == $packet_types->{pubkey} ||
+       $tag == $packet_types->{pub_subkey} ||
+       $tag == $packet_types->{seckey} ||
+       $tag == $packet_types->{sec_subkey}) {
+      my $ver;
+      my $readbytes = 0;
+      read($instr, $ver, 1) or die "could not read key version\n";
+      $readbytes += 1;
+      $ver = ord($ver);
+
+      if ($ver != 4) {
+       printf(STDERR "We only work with version 4 keys.  This key appears to be version %s.\n", $ver);
+       read($instr, $dummy, $packetlen - $readbytes) or die "Could not skip past this packet.\n";
+      } else {
+
+       my $timestamp;
+       read($instr, $timestamp, 4) or die "could not read key timestamp.\n";
+       $readbytes += 4;
+       $timestamp = unpack('N', $timestamp);
+
+       my $algo;
+       read($instr, $algo, 1) or die "could not read key algorithm.\n";
+       $readbytes += 1;
+       $algo = ord($algo);
+       if ($algo != $asym_algos->{rsa}) {
+         printf(STDERR "We only support RSA keys (this key used algorithm %d).\n", $algo);
+         read($instr, $dummy, $packetlen - $readbytes) or die "Could not skip past this packet.\n";
+       } else {
+         ## we have an RSA key.
+         my $modulus = read_mpi($instr, \$readbytes);
+         my $exponent = read_mpi($instr, \$readbytes);
+
+         my $pubkey = Crypt::OpenSSL::RSA->new_key_from_parameters($modulus, $exponent);
+         my $foundfpr = fingerprint($pubkey, $timestamp);
+
+         my $foundfprstr = Crypt::OpenSSL::Bignum->new_from_bin($foundfpr)->to_hex();
+
+         # is this a match?
+         if ((!defined($fpr)) ||
+             (substr($foundfprstr, -1 * length($fpr)) eq $fpr)) {
+           if (defined($key)) {
+             die "Found two matching keys.\n";
+           }
+           $key = $pubkey;
+         }
+
+         if ($tag == $packet_types->{seckey} ||
+             $tag == $packet_types->{sec_subkey}) {
+           if (!defined($key)) { # we don't think the public part of
+                                  # this key matches
+             read($instr, $dummy, $packetlen - $readbytes) or die "Could not skip past this packet.\n";
+           } else {
+             my $s2k;
+             read($instr, $s2k, 1) or die "Could not read S2K octet.\n";
+             $readbytes += 1;
+             $s2k = ord($s2k);
+             if ($s2k == 0) {
+               # secret material is unencrypted
+               # see http://tools.ietf.org/html/rfc4880#section-5.5.3
+               my $d = read_mpi($instr, \$readbytes);
+               my $p = read_mpi($instr, \$readbytes);
+               my $q = read_mpi($instr, \$readbytes);
+               my $u = read_mpi($instr, \$readbytes);
+
+               my $checksum;
+               read($instr, $checksum, 2) or die "Could not read checksum of secret key material.\n";
+               $readbytes += 2;
+               $checksum = unpack('n', $checksum);
+
+               # FIXME: compare with the checksum!  how?  the data is
+               # gone into the Crypt::OpenSSL::Bignum
+
+               $key = Crypt::OpenSSL::RSA->new_key_from_parameters($modulus,
+                                                                   $exponent,
+                                                                   $d,
+                                                                   $p,
+                                                                   $q);
+
+               $key->check_key() or die "Secret key is not a valid RSA key.\n";
+             } else {
+               print(STDERR "We cannot handle encrypted secret keys.  Skipping!\n") ;
+               read($instr, $dummy, $packetlen - $readbytes) or die "Could not skip past this packet.\n";
+             }
+           }
+         }
+
+       }
+      }
+    } else {
+      read($instr, $dummy, $packetlen) or die "Could not skip past this packet!\n";
+    }
+  }
+
+  return $key;
+}
+
+
+for (basename($0)) {
+  if (/^pem2openpgp$/) {
+    my $rsa;
+    my $stdin;
+
+    my $uid = shift;
+    defined($uid) or die "You must specify a user ID string.\n";
+
+    # FIXME: fail if there is no given user ID; or should we default to
+    # hostname_long() from Sys::Hostname::Long ?
+
+
+    if (defined $ENV{PEM2OPENPGP_NEWKEY}) {
+      $rsa = Crypt::OpenSSL::RSA->generate_key($ENV{PEM2OPENPGP_NEWKEY});
+    } else {
+      $stdin = do {
+       local $/; # slurp!
+       <STDIN>;
+      };
+
+      $rsa = Crypt::OpenSSL::RSA->new_private_key($stdin);
+    }
+
+    print pem2openpgp($rsa,
+                     $uid,
+                     { timestamp => $ENV{PEM2OPENPGP_TIMESTAMP},
+                       expiration => $ENV{PEM2OPENPGP_EXPIRATION},
+                       usage_flags => $ENV{PEM2OPENPGP_USAGE_FLAGS},
+                     }
+                    );
+  }
+  elsif (/^openpgp2ssh$/) {
+      my $fpr = shift;
+      my $instream;
+      open($instream,'-');
+      binmode($instream, ":bytes");
+      my $key = openpgp2ssh($instream, $fpr);
+      if (defined($key)) {
+       if ($key->is_private()) {
+         print $key->get_private_key_string();
+       } else {
+         print "ssh-rsa ".encode_base64(openssh_pubkey_pack($key), '')."\n";
+       }
+      } else {
+       die "No matching key found.\n";
+      }
+  }
+  else {
+    die "Unrecognized keytrans call.\n";
+  }
+}
+
index 4ce14f898709a4002de77b075bcde9b27f746457..aa647a628ae9f0e96e04948056f9279cbf5789d2 100644 (file)
@@ -26,14 +26,6 @@ subkey_to_ssh_agent() {
     local publine
     local kname
 
-    if ! test_gnu_dummy_s2k_extension ; then
-       failure "Your version of GnuTLS does not seem capable of using with gpg's exported subkeys.
-You may want to consider patching or upgrading to GnuTLS 2.6 or later.
-
-For more details, see:
- http://lists.gnu.org/archive/html/gnutls-devel/2008-08/msg00005.html"
-    fi
-
     # if there's no agent running, don't bother:
     if [ -z "$SSH_AUTH_SOCK" ] || ! which ssh-add >/dev/null ; then
        failure "No ssh-agent available."
@@ -45,26 +37,34 @@ For more details, see:
     if [ "$sshaddresponse" = "2" ]; then
        failure "Could not connect to ssh-agent"
     fi
-    
-    # get list of secret keys (to work around bug
-    # https://bugs.g10code.com/gnupg/issue945):
-    secretkeys=$(gpg_user --list-secret-keys --with-colons --fixed-list-mode \
-       --fingerprint | \
-       grep '^fpr:' | cut -f10 -d: | awk '{ print "0x" $1 "!" }')
-
-    if [ -z "$secretkeys" ]; then
-       failure "You have no secret keys in your keyring!
+
+    # if the MONKEYSPHERE_SUBKEYS_FOR_AGENT variable is set, use the
+    # keys specified there
+    if [ "$MONKEYSPHERE_SUBKEYS_FOR_AGENT" ] ; then
+       authsubkeys="$MONKEYSPHERE_SUBKEYS_FOR_AGENT"
+
+    # otherwise find all authentication-capable subkeys and use those
+    else
+       # get list of secret keys
+       # (to work around bug https://bugs.g10code.com/gnupg/issue945):
+       secretkeys=$(gpg_user --list-secret-keys --with-colons --fixed-list-mode \
+           --fingerprint | \
+           grep '^fpr:' | cut -f10 -d: | awk '{ print "0x" $1 "!" }')
+
+       if [ -z "$secretkeys" ]; then
+           failure "You have no secret keys in your keyring!
 You might want to run 'gpg --gen-key'."
-    fi
+       fi
     
-    authsubkeys=$(gpg_user --list-secret-keys --with-colons --fixed-list-mode \
-       --fingerprint --fingerprint $secretkeys | \
-       cut -f1,5,10,12 -d: | grep -A1 '^ssb:[^:]*::[^:]*a[^:]*$' | \
-       grep '^fpr::' | cut -f3 -d: | sort -u)
-
-    if [ -z "$authsubkeys" ]; then
-       failure "no authentication-capable subkeys available.
-You might want to 'monkeysphere gen-subkey'"
+       authsubkeys=$(gpg_user --list-secret-keys --with-colons --fixed-list-mode \
+           --fingerprint --fingerprint $secretkeys | \
+           cut -f1,5,10,12 -d: | grep -A1 '^ssb:[^:]*::[^:]*a[^:]*$' | \
+           grep '^fpr::' | cut -f3 -d: | sort -u)
+
+       if [ -z "$authsubkeys" ]; then
+           failure "no authentication-capable subkeys available.
+You might want to run 'monkeysphere gen-subkey'."
+       fi
     fi
 
     workingdir=$(msmktempdir)
@@ -76,7 +76,16 @@ You might want to 'monkeysphere gen-subkey'"
     # through to ssh-add.  should we limit it to known ones?  For
     # example: -d or -c and/or -t <lifetime> 
 
-    for subkey in $authsubkeys; do 
+    for subkey in $authsubkeys; do
+       # test that the subkey has proper capability
+       capability=$(gpg_user --list-secret-keys --with-colons --fixed-list-mode \
+           --fingerprint --fingerprint "0x${subkey}!" \
+           | egrep -B 1 "^fpr:::::::::${subkey}:$" | grep "^ssb:" | cut -d: -f12)
+       if ! check_capability "$capability" 'a' ; then
+           log error "Did not find authentication-capable subkey with key ID '$subkey'."
+           continue
+       fi
+
        # choose a label by which this key will be known in the agent:
        # we are labelling the key by User ID instead of by
        # fingerprint, but filtering out all / characters to make sure
index 6f85ecfb904321906409af414b6c7503ce611e1c..544a3f0d18e635ad0e060a21642186d3c263d9e7 100644 (file)
@@ -108,7 +108,7 @@ if [ -f "$keyID" -o "$keyID" = '-' ] ; then
     fi
 
     # load the key
-    gpg_sphere "--import" <"$keyID" \
+    gpg_sphere "--import" <"$keyID" 2>/dev/null \
        || failure "could not read key from '$keyID'"
 
 # else, get the key from the keyserver
index 8fc4b313815377ca6227c19009b59d5043e4371a..8eca5862fe258a17e3a4dc2f700b0ebd208e2a43 100644 (file)
@@ -103,7 +103,7 @@ fi
 # make sure that at least one identity certifier exists
 echo
 echo "Checking for Identity Certifiers..."
-if ! monkeysphere-authentication list-identity-certifiers | egrep -q '^[A-F0-9]{40}:' then
+if ! ( monkeysphere-authentication list-identity-certifiers | egrep '^[A-F0-9]{40}:' >/dev/null ) ; then
     echo "! No Identity Certifiers found!"
     echo " - Recommendation: once you know who should be able to certify the identities of 
      connecting users, you should add their key, with: 
index e77afff4299795c7a442bccf43e74dea1f2884e3..b453f3cfd34c7ebbdfc5426ff9c573ba78a62425 100644 (file)
@@ -57,7 +57,7 @@ EOF
     if [ -z "$CORE_FPR" ] ; then
        log info "setting up Monkeysphere authentication trust core..."
 
-       local CORE_UID=$(printf "Monkeysphere authentication trust core UID (random string: %s)" $(head -c21 </dev/urandom | base64))
+       local CORE_UID=$(printf "Monkeysphere authentication trust core UID (random string: %s)" $(head -c21 </dev/urandom | perl -MMIME::Base64 -ne 'print encode_base64($_)'))
     
        log debug "generating monkeysphere authentication trust core key ($CORE_KEYLENGTH bits)..."
        PEM2OPENPGP_USAGE_FLAGS=certify \
@@ -82,7 +82,7 @@ EOF
 
     # ensure that the authentication sphere checker has absolute ownertrust on the expected key.
     log debug "setting ultimate owner trust on core key in gpg_sphere..."
-    printf "%s:6:\n" "$CORE_FPR" | gpg_sphere "--import-ownertrust"
+    printf "%s:6:\n" "$CORE_FPR" | gpg_sphere "--import-ownertrust" 2>&1 | log verbose
     gpg_sphere "--export-ownertrust" 2>&1 | log debug
 
     # check the owner trust
@@ -101,7 +101,7 @@ EOF
     # our preferences are reasonable (i.e. 3 marginal OR 1 fully
     # trusted certifications are sufficient to grant full validity.
     log debug "checking trust model for authentication ..."
-    local TRUST_MODEL=$(gpg_sphere "--with-colons --fixed-list-mode --list-keys" \
+    local TRUST_MODEL=$(gpg_sphere "--with-colons --fixed-list-mode --list-keys" 2>/dev/null \
        | head -n1 | grep "^tru:" | cut -d: -f3,6,7)
     log debug "sphere trust model: $TRUST_MODEL"
     if [ "$TRUST_MODEL" != '1:3:1' ] ; then
index bfefc31cdb83b294175131d502136b17520e7ce5..3a5c006e8f560f6ba2a58130bdb59bf47af659d4 100644 (file)
@@ -13,6 +13,7 @@
 
 update_users() {
 
+local returnCode=0
 local unames
 local uname
 local authorizedKeysDir
@@ -26,8 +27,6 @@ else
     unames=$(getent passwd | cut -d: -f1)
 fi
 
-RETURN=0
-
 # set mode
 MODE="authorized_keys"
 
@@ -81,6 +80,7 @@ for uname in $unames ; do
     # translating ssh-style path variables
     authorizedUserIDs=$(translate_ssh_variables "$uname" "$AUTHORIZED_USER_IDS")
     if [ -s "$authorizedUserIDs" ] ; then
+       log debug "authorized_user_ids file found."
        # check permissions on the authorized_user_ids file path
        if check_key_file_permissions "$uname" "$authorizedUserIDs" ; then
             # copy user authorized_user_ids file to temporary
@@ -94,7 +94,7 @@ for uname in $unames ; do
            # process authorized_user_ids file, as monkeysphere user
            su_monkeysphere_user \
                ". ${SYSSHAREDIR}/common; process_authorized_user_ids $TMP_AUTHORIZED_USER_IDS" \
-               || RETURN="$?"
+               || returnCode="$?"
        else
            log debug "not processing authorized_user_ids."
        fi
@@ -141,7 +141,7 @@ for uname in $unames ; do
            log error "Failed to install authorized_keys for '$uname'!"
            rm -f "${authorizedKeysDir}/${uname}"
            # indicate that there has been a failure:
-           RETURN=1
+           returnCode=1
        }
     else
        rm -f "${authorizedKeysDir}/${uname}"
@@ -154,5 +154,5 @@ for uname in $unames ; do
     rm -rf "$TMPLOC"
 done
 
-return $RETURN
+return $returnCode
 }
index 2f65f899f4cfdd7f0e4aad9fe1304ee50bf46ec2..37460203b9056e490089a357d300882d03fdf339 100644 (file)
@@ -63,11 +63,11 @@ else
     if [ "$expire" ]; then
        if (( "$expire"  < "$curdate" )); then
            echo "! Host key is expired."
-           echo " - Recommendation: extend lifetime of key with 'monkeysphere-host extend-key'"
+           echo " - Recommendation: extend lifetime of key with 'monkeysphere-host set-expire'"
            problemsfound=$(($problemsfound+1))
        elif (( "$expire" < "$warndate" )); then
            echo "! Host key expires in less than $warnwindow:" $(advance_date $(( $expire - $curdate )) seconds +%F)
-           echo " - Recommendation: extend lifetime of key with 'monkeysphere-host extend-key'"
+           echo " - Recommendation: extend lifetime of key with 'monkeysphere-host set-expire'"
            problemsfound=$(($problemsfound+1))
        fi
     fi
index f09dfff4489af8a4d5162e43e73552ffa4864e75..3964558801bef699fa0a170ff834786193988ab4 100755 (executable)
@@ -21,6 +21,7 @@
 set -e
 
 SYSDATADIR=${MONKEYSPHERE_SYSDATADIR:-"/var/lib/monkeysphere"}
+SYSCONFIGDIR=${MONKEYSPHERE_SYSCONFIGDIR:-"/etc/monkeysphere"}
 
 MADATADIR="${SYSDATADIR}/authentication"
 MHDATADIR="${SYSDATADIR}/host"
@@ -43,6 +44,13 @@ is_domain_name() {
     printf "%s" "$1" | egrep -q '^[[:alnum:]][[:alnum:]-.]*[[:alnum:]]$'
 }
 
+
+# move the old server conf file to be the authentication conf file
+if [ -f "$SYSCONFIGDIR"/monkeysphere-server.conf -a \
+    ! -f "$SYSCONFIGDIR"/monkeysphere-authentication.conf ] ; then
+    mv "$SYSCONFIGDIR"/monkeysphere-server.conf "$SYSCONFIGDIR"/monkeysphere-authentication.conf
+fi
+
 # run the authentication setup (this is also the first chance to bail
 # if 0.23 is not fully-installed, because m-a did not exist before
 # 0.23)
@@ -63,7 +71,7 @@ if [ -d "$SYSDATADIR"/gnupg-host ] ; then
        # get the old host keygrip (don't know why there would be more
        # than one, but we'll transfer all tsigs made by any key that
        # had been given ultimate ownertrust):
-       for authgrip in $(GNUPGHOME="$SYSDATADIR"/gnupg-host gpg --no-permission-warning --export-ownertrust | \
+       for authgrip in $(GNUPGHOME="$SYSDATADIR"/gnupg-host gpg --quiet --no-tty --no-permission-warning --export-ownertrust | \
            grep ':6:$' | \
            sed -r 's/^[A-F0-9]{24}([A-F0-9]{16}):6:$/\1/') ; do
            
@@ -79,7 +87,7 @@ if [ -d "$SYSDATADIR"/gnupg-host ] ; then
            # one of those certifications (even if later
            # certifications had different parameters).
            
-           GNUPGHOME="$SYSDATADIR"/gnupg-host gpg --no-permission-warning --fingerprint --with-colons --fixed-list-mode --check-sigs | \
+           GNUPGHOME="$SYSDATADIR"/gnupg-host gpg --quiet --no-tty --no-permission-warning --fingerprint --with-colons --fixed-list-mode --check-sigs | \
                cut -f 1,2,5,8,9,10 -d: | \
                egrep '^(fpr:::::|sig:!:'"$authgrip"':[[:digit:]]+ [[:digit:]]+:)' | \
                while IFS=: read -r type validity grip trustparams trustdomain fpr ; do
@@ -121,7 +129,7 @@ if [ -d "$SYSDATADIR"/gnupg-host ] ; then
 
                            CERTKEY=$(mktemp ${TMPDIR:-/tmp}/mstransition.XXXXXXXX)
                            log "Adding identity certifier with fingerprint %s\n" "$keyfpr"
-                           GNUPGHOME="$SYSDATADIR"/gnupg-host gpg --no-permission-warning --export "0x$keyfpr" --export-options export-clean >"$CERTKEY"
+                           GNUPGHOME="$SYSDATADIR"/gnupg-host gpg --quiet --no-tty --no-permission-warning --export "0x$keyfpr" --export-options export-clean >"$CERTKEY"
                            MONKEYSPHERE_PROMPT=false monkeysphere-authentication add-identity-certifier $finaldomain --trust "$truststring" --depth "$trustdepth" "$CERTKEY"
                            rm -f "$CERTKEY"
                            # clear the fingerprint so that we don't
@@ -141,16 +149,39 @@ if [ -d "$SYSDATADIR"/gnupg-host ] ; then
        log "Not transferring host key info because host directory already exists.\n"
     else
        if [ -s "$SYSDATADIR"/ssh_host_rsa_key ] || \
-           GNUPGHOME="$SYSDATADIR"/gnupg-host gpg --no-permission-warning --with-colons --list-secret-keys | grep -q '^sec:' ; then
+           GNUPGHOME="$SYSDATADIR"/gnupg-host gpg --quiet --no-tty --no-permission-warning --with-colons --list-secret-keys | grep -q '^sec:' ; then
+           
+           FPR=$(GNUPGHOME="$SYSDATADIR"/gnupg-host gpg --quiet --no-tty --no-permission-warning --with-colons --fixed-list-mode --list-secret-keys --fingerprint | awk -F: '/^fpr:/{ print $10 }' )
            
        # create host home
-           mkdir -p "${MHDATADIR}"
-           chmod 0700 "${MHDATADIR}"
+           mkdir -p $(dirname "$MHDATADIR")
+           NEWDATADIR=$(mktemp -d "${MHDATADIR}.XXXXXX")
+           chmod 0700 "${NEWDATADIR}"
            
            log "importing host key from old monkeysphere installation\n"
-           GNUPGHOME="$SYSDATADIR"/gnupg-host gpg --no-permission-warning --export-secret-keys | \
-               GNUPGHOME="$MHDATADIR" gpg --quiet --no-tty --import
+
+# export from the pubring as well as the that new (non-expired)
+# self-sigs are available, otherwise the secret key import may fail
+
+# FIXME: turns out the secret key import fails anyway, stupidly :(
+
+# FIXME: if all self-sigs are expired, then the secret key import may
+# fail anyway. How should we deal with that?
            
+           if (GNUPGHOME="$SYSDATADIR"/gnupg-host gpg --quiet --no-tty --no-permission-warning --export-secret-keys && \
+               GNUPGHOME="$SYSDATADIR"/gnupg-host gpg --quiet --no-tty --no-permission-warning --export "$FPR") | \
+               GNUPGHOME="$NEWDATADIR" gpg --quiet --no-tty --import ; then
+               : we are in good shape!
+           else
+               if ! GNUPGHOME="$NEWDATADIR" gpg --quiet --no-tty --list-secret-key >/dev/null ; then
+                   log "The old host key (%s) was not imported properly.\n" "$FPR"
+                   exit 1
+               fi
+           fi
+               
+           # if we get here cleanly, then we're OK to move forward:
+           mv "$NEWDATADIR" "$MHDATADIR"
+
            monkeysphere-host update-gpg-pub-file
        else
            log "No host key found in old monkeysphere install; not importing any host key.\n"
@@ -162,7 +193,7 @@ if [ -d "$SYSDATADIR"/gnupg-host ] ; then
 
     mkdir -p "$STASHDIR"
     chmod 0700 "$STASHDIR"
-    mv "${SYSDATADIR}/gnupg-host" "$STASHDIR"
+    mv "${SYSDATADIR}/gnupg-host" "$STASHDIR"/gnupg-host.$(date '+%F_%T%z')
 fi
 
 
@@ -171,10 +202,12 @@ fi
 # the new authentication keyring.
 if [ -d "${SYSDATADIR}/gnupg-authentication" ] ; then
 
-    GNUPGHOME="${SYSDATADIR}/gnupg-authentication" gpg --no-permission-warning --export | \
-       monkeysphere-authentication gpg-cmd --import
+    GNUPGHOME="${SYSDATADIR}/gnupg-authentication" \
+       gpg --quiet --no-tty --no-permission-warning --export 2>/dev/null | \
+       monkeysphere-authentication gpg-cmd --import 2>/dev/null || \
+       log "No OpenPGP certificates imported into monkeysphere-authentication trust sphere.\n"
 
     mkdir -p "$STASHDIR"
     chmod 0700 "$STASHDIR"
-    mv "${SYSDATADIR}/gnupg-authentication" "$STASHDIR"
+    mv "${SYSDATADIR}/gnupg-authentication" "$STASHDIR"/gnupg-authentication.$(date '+%F_%T%z')
 fi
index 9308e21295115968964753e1825f4a46a3ef90b8..72771687a8040db419fa76b78dc4af8af2a7185f 100755 (executable)
@@ -112,7 +112,7 @@ TEMPDIR=$(mktemp -d "${TMPDIR:-$TESTDIR/tmp}/monkeyspheretest.XXXXXXX")
 
 # Use the local copy of executables first, instead of system ones.
 # This should help us test without installing.
-export PATH="$TESTDIR"/../src:"$TESTDIR"/../src/keytrans:"$PATH"
+export PATH="$TESTDIR"/../src:"$PATH"
 
 export MONKEYSPHERE_SYSDATADIR="$TEMPDIR"
 export MONKEYSPHERE_SYSCONFIGDIR="$TEMPDIR"
@@ -138,22 +138,6 @@ export SOCKET="$TEMPDIR"/ssh-socket
 # *anything* with any running X11 session.
 export DISPLAY=monkeys
 
-## make sure that the version number matches the debian changelog
-## (don't bother if this is being run from the tests).
-
-if [ -f "$TESTDIR"/../packaging/debian/changelog ]; then
-    echo
-    echo "##################################################"
-    echo "### checking version string match..."
-    repver=$(monkeysphere version)
-    debver=$(head -n1 "$TESTDIR"/../packaging/debian/changelog | sed 's/.*(\([^-]*\)-.*/\1/')
-    if [ "$repver" = "$debver" ] ; then
-       echo "Versions match!"
-    else
-       printf "reported version string (%s) does not match debian changelog (%s)\n" "$repver" "$debver"
-       exit 1
-    fi
-fi
 
 ######################################################################
 ### CONFIGURE ENVIRONMENTS
@@ -291,7 +275,6 @@ monkeysphere-authentication update-users $(whoami)
 # FIXME: this is maybe not failing properly for:
 # ms: improper group or other writability on path '/tmp'.
 
-
 ######################################################################
 ### TESTS
 
index 30c6a8214f84fdd3c78ff2a40744bc45f18ab8cb..e53c31ed72e426726353a0ed0b10206e8815e261 100644 (file)
@@ -3,11 +3,13 @@
 failed_cleanup() {
     # FIXME: can we be more verbose here?
     echo 'FAILED!'
-    read -p "press enter to cleanup and remove tmp (or type bash for a subshell to examine): " XX
-    if [ "$XX" = bash ] ; then
-       echo "Entering subshell..."
-       cd "$TEMPDIR"
-       bash
+    if [ "$MONKEYSPHERE_TEST_ALLOW_EXAMINATION" = prompt ] ; then
+       read -p "press enter to cleanup and remove tmp (or type bash for a subshell to examine): " XX
+       if [ "$XX" = bash ] ; then
+           echo "Entering subshell..."
+           cd "$TEMPDIR"
+           bash
+       fi
     fi
 
     cleanup
diff --git a/utils/preparing-release b/utils/preparing-release
new file mode 100644 (file)
index 0000000..dd9d224
--- /dev/null
@@ -0,0 +1,16 @@
+### Notes about preparing a release for the monkeysphere ###
+
+ * make sure that packaging/debian/changelog has a reasonable version
+   number.
+
+ * make tarball
+
+ * make releasenote
+
+ * create upstream version tag: 
+
+    git tag -s -m 'Tagging Monkeysphere $whatever' monkeysphere_$whatever
+
+ * create debian-specific version tag:
+
+    git tag -s -m 'Tagging Monkeysphere $whatever-1' monkeysphere_$whatever-1
index cc050a09de75223c605062375137c3b8f542d538..0a891db58345a349558939cc4f468d294d49b862 100644 (file)
@@ -11,17 +11,15 @@ administrator](/getting-started-admin).
 
 Monkeysphere relies on:
 
- * [GnuTLS](http://gnutls.org/)
-  * version 2.4 or later for general use
-  * [version 2.6 or later](/news/gnutls-2.6-enables-monkeysphere) to use the `monkeysphere subkey-to-ssh-agent` subcommand.
  * [OpenSSH](http://openssh.com/)
  * [GnuPG](http://gnupg.org/)
+ * [Perl](http://www.perl.org/) (including the [Crypt::OpenSSL::RSA](http://search.cpan.org/dist/Crypt-OpenSSL-RSA/) and [Digest::SHA1](http://search.cpan.org/dist/Digest-SHA1/) modules and their dependencies)
 
 ## Debian ##
 
 If you are running a [Debian](http://www.debian.org/) system, the
-[monkeysphere is now available in the unstable
-("sid") distribution](http://packages.debian.org/sid/monkeysphere).
+[monkeysphere is now available in the Debian unstable ("sid")
+distribution](http://packages.debian.org/sid/monkeysphere).
 
 You can also install the Monkeysphere directly from the Monkeysphere
 Debian archive.  You can add this archive to your system by putting
@@ -36,11 +34,6 @@ signing key](/archive-key), key id EB8AF314 (fingerprint: `2E8D D26C
 verify the packages, you'll want to [add this key to your apt
 configuration after verifying its integrity](/archive-key).
 
-To use the `monkeysphere subkey-to-ssh-agent` subcommand, you will
-also need [version 2.6 of
-GnuTLS](/news/gnutls-2.6-enables-monkeysphere), which is available in
-Debian experimental.
-
 ## FreeBSD ##
 
 There is [now a FreeBSD port available](/news/FreeBSD-port-available)
@@ -65,50 +58,44 @@ port with:
     cd /usr/ports/security/monkeysphere
     make && make install
 
-To use the `monkeysphere subkey-to-ssh-agent` subcommand, you will
-also need [version 2.6 of
-GnuTLS](/news/gnutls-2.6-enables-monkeysphere), which is [slated to be
-available after the 7.1 ports slush is
-over](http://www.freebsd.org/cgi/query-pr.cgi?pr=ports/127330).
-
 ## Source ##
 
 For those that would like to download the source directly, [the source
 is available](/community) via [git](http://git.or.cz/).
 
 The [latest
-tarball](http://archive.monkeysphere.info/debian/pool/monkeysphere/m/monkeysphere/monkeysphere_0.23.orig.tar.gz)
+tarball](http://archive.monkeysphere.info/debian/pool/monkeysphere/m/monkeysphere/monkeysphere_0.24.orig.tar.gz)
 is also available, and has these checksums:
 
 <pre>
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1
 
-checksums for the monkeysphere 0.23 release:
+checksums for the monkeysphere 0.24 release:
 
 MD5:
-2c3e985884ecf7a5f53825f9034932a3  monkeysphere_0.23.orig.tar.gz
+8590532f4702fa44027a6a583657c9ef  monkeysphere_0.24.orig.tar.gz
 
 SHA1:
-6f03b9d813d48479c86623c7facf634d72da2cb0  monkeysphere_0.23.orig.tar.gz
+45b26ada094705e56eeff1117a28162e04226cc7  monkeysphere_0.24.orig.tar.gz
 
 SHA256:
-7854d9c358b684c2b292b4f3470780d2c7e069466bd228885d6a246e0bd1abde  monkeysphere_0.23.orig.tar.gz
+2a58cee998ddb1b21b953826fc746a743e17d94e6fa34ac9cbee4262873b5c5f  monkeysphere_0.24.orig.tar.gz
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.9 (GNU/Linux)
 
-iQIVAwUBSaCGXxjmZ/HrivMUAQKIUhAAs/b+2z+cKkcP3bwfD8ItW377rXY3+ZrV
-pomzhzSuSk52gYxa6QBQ7rgYdWac996VRTSxR14yEM8iLyqxaBpvbvOJCgqv0B51
-VHJiosV8nVqjUXdrOa2iRFqPF3+zaINjsIgJSB5aKCjT6d2sxlYoe5OpIU1JD/yN
-E/ypvO8v3xNZ7V2YU858H2UhT0J2kMmnYPrprgoqgebWrVke/tnQLnGew/A9leel
-ZEWVhWaN+RO6n/obxxKbRHT2cAp2CW/qccFGAf80XB//i7yTD5KxlK1Ls0nLT43H
-3MQPZZsOTKFZsMfOD9Y46CN5ZDm/e3SnGhi7UgW2xDP4QhGihUVYputYHr4lvboA
-uoO2g7JT2MltsuyxFMacscf9tx9cgF80ndHTBUxqDtlh/aK1xlC4tPSwSgQwuKwy
-JabvCz3fwiQbZc08OhB/5DhuDPORhQk2CJJ7HGrN1Sc2Cde0x667rQjI/ckrUC0Y
-PIqXUp8trB+p85tQSSuWJEgxVbNRZ4hVftvNvLECKv7fd0bVdNeVvV57H5ieJ8FR
-adPVaASkhF+pL122t3qC/vSbUi956Hk3pKMT9+05vLnfzYM78A6j1jA4pTvlEzaC
-WWdvL2BvARlhw5OUz4gomCpw5ZSxWjsnF6SHte85UmmunZpmE67/udyvcPqMNzjA
-vG61wNXtmqA=
-=JqmC
+iQIVAwUBSa3ushjmZ/HrivMUAQJGvxAAsc3phUKrWOSdItr7uaIsRsXo3BN/MT8Z
+e+ZJXpQo5roehyaTZR2H4hdUVObepqXmpwfrbmxORQ+mZa7WFKUT9hjdDrh5AyDH
+V4UA/b+4N0VQZYqvfDezA22o6V3HRmrdoaz90LY/8Yfe1YSteUdaO1fQhDOsoHTL
+MVOwhy+pcbjxd5cbLv1NcUb4FbAWoKS4zCQvYgC83u7LcB6irOekWU8rL6PR1qoC
+UebWYg2n2dafnPy4WuQ38DAetPwhTFrCG36YwkkNBkV23sPUMCiDJcDVictIWgdK
+emMhOLyC/G8PldLUYzwSqNMGdy8rLhiYf6Xo4e8dVsava14bbgqn1CXGQieibMYs
+IUyEvkPrxVc5ZUKHi0sNJ2yREMJVY5YYQFFirgv795fP6Rf6oGjjffDKPa5l80Ei
+M0mspn0TdnJtJ8BbbsE76tcT1vTB3hu2VOqDYZeo+3SjT8UGXPRlIcnzAhxt3x5+
+huYnNuaQb1b9+LP6dbb+dSWA3gYMbkXPZu6KXcr+ob4mHIdTPQysXFp2sobq4Dyt
+UeVxInuBQ1iEvQb9MxgbrerNf90yi7flMxxFV0HabrnxLSrufDJy4ai8pIbZBhpw
+v5xIHVkplfXB7zb1JcQKtA93LrKDvCpHMc6ZiVmveEgsRlqzw5UV/zcc4ENDR8gN
+NpxJjlFqEsc=
+=7/gS
 -----END PGP SIGNATURE-----
 </pre>
index 4abeea07458f95c78a818cfd48a9b4d300dc9fb8..ba121a24891509bd30546d629f286033e1b9de10 100644 (file)
@@ -1,4 +1,6 @@
 [[meta title="The Monkeysphere Project"]]
+[[meta license="Unless otherwise noted, all content on this web site is licensed under the GPL version 3 or later"]]
+[[meta copyright="All content on this web site is copyright by the author of that content. [Look in the revision control system](community) for details about who authored a particular piece of content."]]
 
 # The Monkeysphere Project #
 
index de0f196b14c0cef9f732d39d1791dcfffc305b64..b2d86c7b0637b3ca52801c16505436a0a7f78132 100644 (file)
@@ -1,3 +1,22 @@
+/* CSS for web.monkeysphere.info
+
+Copyright: 2008,2009
+
+Authors: 
+Dan Scott, 
+Daniel Kahn Gillmor <dkg@fifthhorseman.net>,
+Jameson Graef Rollins <jrollins@finestructure.net>,
+Jamie McClelland <jm@mayfirst.org>
+
+License: This stylesheet is licensed under the GNU GPL, version 3 or
+later (your choice).
+
+The full text of the GPL can be found at:
+
+  http://www.gnu.org/licenses/gpl.html
+
+ */
+
 h1 {
   -moz-border-radius: 4px;
   background-color: #B67B4E;
diff --git a/website/news/release-0.23.1-1.mdwn b/website/news/release-0.23.1-1.mdwn
new file mode 100644 (file)
index 0000000..79b3c05
--- /dev/null
@@ -0,0 +1,12 @@
+[[meta title="Monkeysphere 0.23.1-1 released!"]]
+
+Monkeysphere 0.23.1-1 has been released.  
+
+Notes from the changelog:
+
+<pre>
+  * New Upstrem "Brown Paper Bag" Release:
+   - adjusts internal version numbers
+</pre>
+
+[[Download]] it now!
diff --git a/website/news/release-0.24-1.mdwn b/website/news/release-0.24-1.mdwn
new file mode 100644 (file)
index 0000000..733df25
--- /dev/null
@@ -0,0 +1,26 @@
+[[meta title="Monkeysphere 0.24-1 released!"]]
+
+Monkeysphere 0.24-1 has been released.  
+
+Notes from the changelog:
+
+<pre>
+  * New upstream release:
+    - fixed how version information is stored/retrieved
+    - now uses perl-based keytrans for both pem2openpgp and openpgp2ssh
+    - no longer needs base64 in PATH
+    - added "test" make target
+    - improved transitions/0.23 script so it no longer fails in common
+      circumstances (Closes: #517779)
+    - RSA only: no longer handles DSA keys
+    - added ability to specify subkeys to add to ssh agent with
+      new MONKEYSPHERE_SUBKEYS_FOR_AGENT environment variable
+  * update/cleanup maintainer scripts
+  * remove GnuTLS dependency
+  * remove versioned coreutils | base64 dependency
+  * added Build-Deps for dh_autotest
+  * switch to Architecture: all
+  * added cron to Recommends
+</pre>
+
+[[Download]] it now!