Skip to content
Commits on Source (33)
......@@ -24,7 +24,7 @@ version 3 or later.
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
......@@ -668,7 +668,7 @@ the "copyright" line and a pointer to where the full notice is found.
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
......@@ -687,11 +687,11 @@ might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
<https://www.gnu.org/philosophy/why-not-lgpl.html>.
monkeysphere (0.43) unstable; urgency=medium
* Depend on a modern version of GnuPG (>= 2.1.11) for --export-ssh-key
* Depend on OpenSSH's ssh-keygen directly for most SSH fingerprints
* Depend on OpenSSH >= 6.0 for ed25519 and "sshd -T"
* Use runuser instead of su
* Support Ed25519 authentication-capable subkeys for users
* Use https for all outbound links
* Clean up spelling
* Use 3072 bits for RSA keys everywhere by default
* Provide clearer error message for PEM2OPENPGP_NEWKEY
(Closes: #906755)
* Avoid locking out users unnecessarily
(Closes: #897366)
-- Daniel Kahn Gillmor <dkg@fifthhorseman.net> Wed, 23 Jan 2019 17:42:19 -0500
monkeysphere (0.42) unstable; urgency=medium
* bugfix release:
......@@ -12,7 +29,7 @@ monkeysphere (0.42) unstable; urgency=medium
* use generic compiler (closes: #883015)
* make print_date_from_seconds_since_the_epoch deal better with bad input
-- Daniel Kahn Gillmor <dkg@fifthhorseman.net> Tue, 16 Oct 2018 11:38:39 -0400
-- Daniel Kahn Gillmor <dkg@fifthhorseman.net> Tue, 16 Oct 2018 11:38:39 -0400
monkeysphere (0.41) unstable; urgency=medium
......@@ -57,11 +74,11 @@ monkeysphere (0.38) unstable; urgency=medium
monkeysphere (0.37) unstable; urgency=medium
* Bugfix release with minor improvements and dependency accomodations.
* Bugfix release with minor improvements and dependency accommodations.
* Test openpgp2ssh functionality (closes MS #6524)
* use new GnuPG with-colons output
* accomodate changed behavior of ssh-keygen -F
* accomodate multiple AuthorizedKeysFile directives
* accommodate changed behavior of ssh-keygen -F
* accommodate multiple AuthorizedKeysFile directives
* deal sanely with empty lines in authorized_user_ids (closes MS #6344)
* treat non-standard ports properly (closes MS #3402)
......
......@@ -2,7 +2,7 @@
# Makefile for monkeysphere
# © 2008-2010 Daniel Kahn Gillmor <dkg@fifthhorseman.net>
# © 2008-2019 Daniel Kahn Gillmor <dkg@fifthhorseman.net>
# Licensed under GPL v3 or later
MONKEYSPHERE_VERSION = `head -n1 Changelog | sed 's/.*(\([^-]*\)).*/\1/'`
......@@ -38,10 +38,10 @@ debian-package:
# don't explicitly depend on the tarball, since our tarball
# (re)generation is not idempotent even when no source changes.
freebsd-distinfo:
./utils/build-freebsd-distinfo
./util/build-freebsd-distinfo
macports-portfile:
./utils/build-macports-portfile
./util/build-macports-portfile
clean:
rm -f src/agent-transfer/agent-transfer
......@@ -57,7 +57,7 @@ replaced/%: %
-e 's:__SYSDATADIR_PREFIX__:$(LOCALSTATEDIR):'
replaced/%.gz: replaced/%
gzip -n $<
gzip -f -n $<
# this target is to be called from the tarball, not from the git
# working dir!
......@@ -105,13 +105,16 @@ installman: $(REPLACED_COMPRESSED_MANPAGES)
releasenote:
../monkeysphere-docs/utils/build-releasenote
test: test-keytrans test-basic
test: test-keytrans test-basic test-ed25519
check: test
test-basic: src/agent-transfer/agent-transfer
MONKEYSPHERE_TEST_NO_EXAMINE=true ./tests/basic
test-ed25519: src/agent-transfer/agent-transfer
MONKEYSPHERE_TEST_NO_EXAMINE=true MONKEYSPHERE_TEST_USE_ED25519=true ./tests/basic
test-keytrans: src/agent-transfer/agent-transfer
MONKEYSPHERE_TEST_NO_EXAMINE=true ./tests/keytrans
......
......@@ -13,3 +13,15 @@ but to identify yourself and the servers you administer or connect to
with your OpenPGP keys. OpenPGP keys are tracked via GnuPG, and
monkeysphere manages the known_hosts and authorized_keys files used by
OpenSSH for authentication, checking them for cryptographic validity.
Dependencies
------------
Monkeysphere depends on:
* GnuPG >= 2.1.11
* Perl
* Perl's Crypt::OpenSSL::RSA module
* lockfile-progs or procmail's lockfile
* Bash
* OpenSSH's ssh-keygen utility (ideally >= 6.0)
......@@ -10,6 +10,8 @@
# They are Copyright 2008-2009, and are all released under the GPL, version 3
# or later.
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# update all keys from the key servers
monkeysphere-authentication refresh-keys
......
# example Monkeysphere cron job:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# Hourly: update the per-user authorized_keys in /var based on
# ~/.monkeysphere/authorized_user_ids
......
......@@ -56,7 +56,7 @@ subjectAltName = $SUBJECTALTNAME
PGPExtension = ASN1:SEQUENCE:pgp_sect
[ pgp_sect ]
# see http://www.alvestrand.no/objectid/submissions/1.3.6.1.4.1.3401.8.1.1.html
# see https://www.alvestrand.no/objectid/1.3.6.1.4.1.3401.8.1.1.html
# this is equivalent to:
# Version ::= INTEGER { v1(0) }
version = INTEGER:0
......
.TH AGENT-TRANSFER "1" "May 2016" "monkeysphere" "User Commands"
.TH AGENT-TRANSFER "1" "Jan 2019" "monkeysphere" "User Commands"
.SH NAME
......@@ -68,6 +68,11 @@ the gpg\-agent to help it figure out how to run a sensible pinentry,
including GPG_TTY, TERM, DISPLAY, XAUTHORITY, GTK_IM_MODULE,
DBUS_SESSION_BUS_ADDRESS, and LANG.
.SH BUGS
\fBagent-transfer\fP can only work with RSA and Ed25519 keys. Support
for other key types not yet implemented. Patches welcome!
.SH AUTHOR
Written by:
......
.\" -*- nroff -*-
.Dd $Mdocdate: March 1, 2009 $
.Dd $Mdocdate: Jan 22, 2019 $
.Dt PEM2OPENPGP 1
.Os
.Sh NAME
......@@ -60,7 +60,7 @@ default, no expiration subpacket is included.
.Nm
should ignore stdin, and instead generate a new key internally and
build the certificate based on this new key. Set this variable to the
number of bits for the new key (e.g. 2048). By default (when this is
number of bits for the new RSA key (e.g. 3072). By default (when this is
unset),
.Nm
will read the key from stdin.
......
......@@ -85,6 +85,6 @@ Daniel Kahn Gillmor <dkg@fifthhorseman.net>
.BR openpgp2ssh (1),
.BR pem2openpgp (1),
.BR gpg (1),
.BR http://tools.ietf.org/html/rfc4880,
.BR https://tools.ietf.org/html/rfc4880,
.BR ssh (1),
.BR http://tools.ietf.org/wg/secsh/draft\-ietf\-secsh\-scp\-sftp\-ssh\-uri/
.BR https://tools.ietf.org/wg/secsh/draft\-ietf\-secsh\-scp\-sftp\-ssh\-uri/
......@@ -178,7 +178,7 @@ using standard OpenPGP keysigning techniques. Usually: pull the
host's OpenPGP certificate from the keyserver, verify and sign it, and
then re\-publish your signature. More than one person can certify any
certificate. Please see
http://web.monkeysphere.info/doc/host\-keys/ for more information
https://web.monkeysphere.info/doc/host\-keys/ for more information
and details. Once an admin's signature is published, users accessing
the host can use the certificate to validate the host's key without
having to manually check the host key's fingerprint (in the case of
......
......@@ -15,7 +15,7 @@ long_description SSH key-based authentication is tried-and-true, \
used in both directions: for users to get \
validated host keys, and for hosts to authenticate \
users.
homepage http://web.monkeysphere.info/
homepage https://web.monkeysphere.info/
platforms darwin
depends_run bin:ssh:openssh \
......@@ -24,7 +24,7 @@ depends_run bin:ssh:openssh \
port:p5-digest-sha \
port:procmail
master_sites http://archive.monkeysphere.info/debian/pool/monkeysphere/m/monkeysphere/
master_sites https://archive.monkeysphere.info/debian/pool/monkeysphere/m/monkeysphere/
distname ${name}_${version}
extract.suffix .orig.tar.gz
worksrcdir ${name}-${version}
......
Monkeysphere on Slackware
=========================
Silvio Rhatto has written a SlackBuild script for the monkeysphere.
Silvio Rhatto wrote a SlackBuild script for the monkeysphere, which
was found here:
You can find the SlackBuild here:
https://slack.sarava.org/slackbuilds/net/misc/monkeysphere/
http://slack.sarava.org/slackbuilds/net/misc/monkeysphere/
As of January 2019, it appears to be no longer online, but a copy can
be found at:
This SlackBuild script is generated from a .mkbuild script, published
https://github.com/pyllyukko/monkeysphere.SlackBuild
History
-------
This SlackBuild script was generated from a .mkbuild script, published
separately:
http://slack.sarava.org/mkbuilds/net/misc/monkeysphere/
https://slack.sarava.org/mkbuilds/net/misc/monkeysphere/
You can read more about the mkbuild system here:
http://simplepkg.sarava.org
https://simplepkg.sarava.org
Thanks, rhatto!
......@@ -119,6 +119,11 @@ char* gpg_agent_sockname () {
}
typedef enum { kt_unknown = 0,
kt_rsa,
kt_ed25519
} key_type;
struct exporter {
assuan_context_t ctx;
gcry_cipher_hd_t wrap_cipher;
......@@ -126,6 +131,7 @@ struct exporter {
size_t wrapped_len;
unsigned char *unwrapped_key;
size_t unwrapped_len;
key_type ktype;
gcry_sexp_t sexp;
gcry_mpi_t n;
gcry_mpi_t e;
......@@ -133,17 +139,19 @@ struct exporter {
gcry_mpi_t p;
gcry_mpi_t q;
gcry_mpi_t iqmp;
gcry_mpi_t curve;
gcry_mpi_t flags;
};
/* percent_plus_escape is copyright Free Software Foundation */
/* taken from common/percent.c in gnupg */
/* Create a newly alloced string from STRING with all spaces and
/* Create a newly allocated string from STRING with all spaces and
control characters converted to plus signs or %xx sequences. The
function returns the new string or NULL in case of a malloc
failure.
Note that we also escape the quote character to work around a bug
in the mingw32 runtime which does not correcty handle command line
in the mingw32 runtime which does not correctly handle command line
quoting. We correctly double the quote mark when calling a program
(i.e. gpg-protect-tool), but the pre-main code does not notice the
double quote as an escaped quote. We do this also on POSIX systems
......@@ -200,6 +208,57 @@ gpg_error_t extend_wrapped_key (struct exporter *e, const void *data, size_t dat
return GPG_ERR_NO_ERROR;
}
gpg_error_t unwrap_rsa_key (struct exporter *e) {
gpg_error_t ret;
e->iqmp = gcry_mpi_new(0);
ret = gcry_mpi_invm (e->iqmp, e->q, e->p);
if (!ret) {
fprintf (stderr, "Could not calculate the (inverse of q) mod p\n");
return GPG_ERR_GENERAL;
} else {
e->ktype = kt_rsa;
return GPG_ERR_NO_ERROR;
}
}
gpg_error_t unwrap_ed25519_key (struct exporter *e) {
unsigned int sz;
const char * data;
#define opaque_compare(val, str, err) { \
data = gcry_mpi_get_opaque (val, &sz); \
if ((sz != strlen (str)*8) || !data || \
memcmp (data, str, strlen(str))) \
return gpg_error (err); }
/* verify that curve matches "Ed25519" */
opaque_compare (e->curve, "Ed25519", GPG_ERR_UNKNOWN_CURVE);
/* verify that flags contains "eddsa" */
/* FIXME: what if there are other flags besides eddsa? */
opaque_compare (e->flags, "eddsa", GPG_ERR_UNKNOWN_FLAG);
/* verify that q starts with 0x40 and is 33 octets long */
data = gcry_mpi_get_opaque (e->q, &sz);
if (sz != 33*8 || !data || data[0] != 0x40)
return gpg_error (GPG_ERR_INV_CURVE);
/* verify that d is 32 octets long */
data = gcry_mpi_get_opaque (e->d, &sz);
if (sz < 32*8)
return gpg_error (GPG_ERR_TOO_SHORT);
if (sz > 32*8)
return gpg_error (GPG_ERR_TOO_LARGE);
if (!data)
return gpg_error (GPG_ERR_NO_OBJ);
e->ktype = kt_ed25519;
return GPG_ERR_NO_ERROR;
}
gpg_error_t unwrap_key (struct exporter *e) {
unsigned char *out = NULL;
gpg_error_t ret;
......@@ -241,22 +300,22 @@ gpg_error_t unwrap_key (struct exporter *e) {
ret = gcry_sexp_new(&e->sexp, e->unwrapped_key, e->unwrapped_len, 0);
if (ret)
return ret;
/* RSA has: n, e, d, p, q */
ret = gcry_sexp_extract_param (e->sexp, "private-key!rsa", "nedpq",
&e->n, &e->e, &e->d, &e->p, &e->q, NULL);
if (ret)
return ret;
e->iqmp = gcry_mpi_new(0);
ret = gcry_mpi_invm (e->iqmp, e->q, e->p);
if (!ret) {
fprintf (stderr, "Could not calculate the (inverse of q) mod p\n");
return GPG_ERR_GENERAL;
} else {
return GPG_ERR_NO_ERROR;
if (!ret)
return unwrap_rsa_key (e);
if (gpg_err_code (ret) == GPG_ERR_NOT_FOUND) {
/* check whether it's ed25519 */
/* EdDSA has: curve, flags, q, d */
ret = gcry_sexp_extract_param (e->sexp, "private-key!ecc", "/'curve''flags'qd",
&e->curve, &e->flags, &e->q, &e->d, NULL);
if (!ret)
return unwrap_ed25519_key (e);
}
return ret;
}
gpg_error_t data_cb (void *arg, const void *data, size_t data_sz) {
......@@ -324,24 +383,38 @@ size_t get_ssh_sz (gcry_mpi_t mpi) {
}
int send_to_ssh_agent(struct exporter *e, int fd, unsigned int seconds, int confirm, const char *comment) {
const char *key_type = "ssh-rsa";
const char *key_type;
int ret;
size_t len;
size_t len, mpilen;
off_t offset;
unsigned char *msgbuf = NULL;
uint32_t tmp;
size_t slen;
ssize_t written, bytesread;
unsigned char resp;
if (e->ktype != kt_rsa && e->ktype != kt_ed25519) {
fprintf (stderr, "key is neither RSA nor Ed25519, cannot handle it.\n");
return -1;
}
if (e->ktype == kt_rsa) {
key_type = "ssh-rsa";
mpilen = get_ssh_sz (e->n) +
get_ssh_sz (e->e) +
get_ssh_sz (e->d) +
get_ssh_sz (e->iqmp) +
get_ssh_sz (e->p) +
get_ssh_sz (e->q);
} else if (e->ktype == kt_ed25519) {
key_type = "ssh-ed25519";
mpilen = 4 + 32 + /* ENC(A) */
4 + 64; /* k || ENC(A) */
}
len = 1 + /* request byte */
4 + strlen(key_type) + /* type of key */
get_ssh_sz (e->n) +
get_ssh_sz (e->e) +
get_ssh_sz (e->d) +
get_ssh_sz (e->iqmp) +
get_ssh_sz (e->p) +
get_ssh_sz (e->q) +
mpilen +
4 + (comment ? strlen (comment) : 0) +
(confirm ? 1 : 0) +
(seconds ? 5 : 0);
......@@ -363,12 +436,33 @@ int send_to_ssh_agent(struct exporter *e, int fd, unsigned int seconds, int conf
w32 (len);
wbyte (seconds || confirm ? SSH2_AGENTC_ADD_ID_CONSTRAINED : SSH2_AGENTC_ADD_IDENTITY);
wstr (key_type);
wmpi (e->n);
wmpi (e->e);
wmpi (e->d);
wmpi (e->iqmp);
wmpi (e->p);
wmpi (e->q);
if (e->ktype == kt_rsa) {
wmpi (e->n);
wmpi (e->e);
wmpi (e->d);
wmpi (e->iqmp);
wmpi (e->p);
wmpi (e->q);
} else if (e->ktype == kt_ed25519) {
unsigned int dsz, qsz;
const char *ddata, *qdata;
qdata = gcry_mpi_get_opaque (e->q, &qsz);
ddata = gcry_mpi_get_opaque (e->d, &dsz);
if (qsz != 33*8 || dsz != 32*8 || !qdata || !ddata) {
fprintf (stderr, "Ed25519 key did not have the expected components (q: %d %p, d: %d %p)\n",
qsz, qdata, dsz, ddata);
return -1;
}
/* ENC(A) (aka q)*/
w32 (32);
memcpy (msgbuf + offset, qdata+1, 32); offset += 32;
/* k || ENC(A) (aka d || q) */
w32 (64);
memcpy (msgbuf + offset, ddata, 32); offset += 32;
memcpy (msgbuf + offset, qdata+1, 32); offset += 32;
}
wstr (comment);
if (confirm)
wbyte (SSH_AGENT_CONSTRAIN_CONFIRM);
......@@ -422,6 +516,8 @@ void free_exporter (struct exporter *e) {
gcry_mpi_release(e->p);
gcry_mpi_release(e->q);
gcry_mpi_release(e->iqmp);
gcry_mpi_release(e->curve);
gcry_mpi_release(e->flags);
gcry_sexp_release (e->sexp);
}
......
/* see PROTOCOL.agent in openssh repo */
/* see https://tools.ietf.org/html/draft-miller-ssh-agent */
/* 3.2 Requests from client to agent for protocol 2 key operations */
......@@ -55,5 +55,20 @@ RSA keys may be added with this request:
constraint[] key_constraints
Ed25519 keys may be added with this request:
byte SSH_AGENTC_ADD_IDENTITY or
SSH_AGENTC_ADD_ID_CONSTRAINED
string "ssh-ed25519"
string ENC(A)
string k || ENC(A)
string comment
constraint[] constraints
The first value is the 32 byte Ed25519 public key "ENC(A)". The
second value is a concatenation of the 32 byte private key "k" and 32
byte public "ENC(A)" key. The contents and interpretation of the
"ENC(A)" and "k" values are defined by [I-D.irtf-cfrg-eddsa].
*/
......@@ -8,7 +8,7 @@
# Daniel Kahn Gillmor <dkg@fifthhorseman.net>
# Micah Anderson <micah@riseup.net>
#
# They are Copyright 2008-2009, and are all released under the GPL, version 3
# They are Copyright 2008-2019, and are all released under the GPL, version 3
# or later.
########################################################################
......@@ -52,7 +52,7 @@ subcommands:
keys-for-userid (u) USERID output valid ssh keys for given user id
sshfprs-for-userid USERID output ssh fingerprints for given user id
gen-subkey (g) [KEYID] generate an authentication subkey
--length (-l) BITS key length in bits (2048)
--length (-l) BITS RSA key length in bits (3072)
version (v) show version number
help (h,?) this help
......@@ -68,7 +68,7 @@ gpg_user() {
# output the ssh fingerprint of a gpg key
gpg_ssh_fingerprint() {
keyid="$1"
gpg_user --export "$keyid" --no-armor | "$SYSSHAREDIR/keytrans" openpgp2sshfpr "$keyid"
gpg_user --export-ssh-key "0x${keyid}!" | cut -f1,2 -d' ' | sed 's/$/ ./' | ssh-keygen -l -f -
}
# take a secret key ID and check that only zero or one ID is provided,
......@@ -211,6 +211,10 @@ if [ "$#" -eq 0 ] ; then
failure "Please supply a subcommand."
fi
if ! is_gpg_version_greater_equal 2.1.11 ; then
failure "Monkeysphere needs GnuPG >= 2.1.11"
fi
# get subcommand
COMMAND="$1"
shift
......
......@@ -8,7 +8,7 @@
# Daniel Kahn Gillmor <dkg@fifthhorseman.net>
# Micah Anderson <micah@riseup.net>
#
# They are Copyright 2008-2009, and are all released under the GPL,
# They are Copyright 2008-2019, and are all released under the GPL,
# version 3 or later.
########################################################################
......@@ -81,14 +81,7 @@ gpg_sphere() {
GNUPGHOME="$GNUPGHOME_SPHERE"
export GNUPGHOME
su_monkeysphere_user gpg --fixed-list-mode --no-greeting --quiet --no-tty "$@"
}
check_openpgp2ssh_sanity() {
if [[ `su_monkeysphere_user openpgp2ssh ABC &>/dev/null || echo $?` != "255" ]]; then
echo "openpgp2ssh command gives unexpected return code. This can lead to a scenario where no authorized keys are populated, even though they are otherwise valid. Aborting!"
exit 1
fi;
run_as_monkeysphere_user gpg --fixed-list-mode --no-greeting --quiet --no-tty "$@"
}
# output to stdout the core fingerprint from the gpg core secret
......@@ -134,10 +127,10 @@ STRICT_MODES=${MONKEYSPHERE_STRICT_MODES:=$STRICT_MODES}
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"}
CORE_KEYLENGTH=${MONKEYSPHERE_CORE_KEYLENGTH:="3072"}
LOG_PREFIX=${MONKEYSPHERE_LOG_PREFIX:='ms: '}
# export variables needed in su invocation
# export variables needed for invoking command under monkeysphere user
export DATE
export LOG_LEVEL
export KEYSERVER
......@@ -170,7 +163,6 @@ case $COMMAND in
'update-users'|'update-user'|'update'|'u')
source "${MASHAREDIR}/setup"
setup
check_openpgp2ssh_sanity
source "${MASHAREDIR}/update_users"
OUTPUT_STDOUT= update_users "$@"
;;
......@@ -179,7 +171,6 @@ case $COMMAND in
(( $# > 0 )) || failure "Must specify user."
source "${MASHAREDIR}/setup"
setup
check_openpgp2ssh_sanity
source "${MASHAREDIR}/update_users"
OUTPUT_STDOUT=true update_users "$1"
;;
......
......@@ -8,7 +8,7 @@
# Daniel Kahn Gillmor <dkg@fifthhorseman.net>
# Micah Anderson <micah@riseup.net>
#
# They are Copyright 2008-2010, and are all released under the GPL,
# They are Copyright 2008-2019, and are all released under the GPL,
# version 3 or later.
########################################################################
......@@ -30,6 +30,15 @@ MHSHAREDIR="${SYSSHAREDIR}/mh"
# datadir for host functions
MHDATADIR="${SYSDATADIR}/host"
# temp directory to enable sharing a temporary directory between root
# and monkeysphere users. This is needed because on systems with
# libpam-tmpdir, simply changing ownership/permissions on a directory
# is not enough to share the directory. Parent directories such as
# /tmp/user/0 will be inaccessible to monkeysphere user.
#
# XXX: Reusing monkeysphere-authentication's tmp directory.
MHTMPDIR="${SYSDATADIR}/authentication/tmp"
# host pub key files
HOST_KEY_FILE="${SYSDATADIR}/host_keys.pub.pgp"
......@@ -223,7 +232,7 @@ check_key_userid() {
# match to only "unknown" user IDs (host has no need for ultimate trust)
tmpuidMatch="uid:-:$(echo $userID | gpg_escape)"
# See whether the requsted user ID is present
# See whether the requested user ID is present
gpg_host_list_keys "$keyID" | cut -f1,2,10 -d: | \
grep -q -x -F "$tmpuidMatch" 2>/dev/null
}
......@@ -331,7 +340,7 @@ show_key() {
# list the ssh fingerprint
printf "ssh fingerprint: %s\n" \
"$(gpg --export --no-armor "$fingerprint" 2>/dev/null | "$SYSSHAREDIR/keytrans" openpgp2sshfpr "$fingerprint")"
"$(gpg --export-ssh-key "0x${fingerprint}!" 2>/dev/null | cut -f1,2 -d' ' | sed 's/$/ ./' | ssh-keygen -l -f -)"
# remove the tmp file
trap - EXIT
......@@ -360,7 +369,7 @@ PROMPT=${MONKEYSPHERE_PROMPT:=$PROMPT}
GNUPGHOME_HOST=${MONKEYSPHERE_GNUPGHOME_HOST:="${MHDATADIR}"}
LOG_PREFIX=${MONKEYSPHERE_LOG_PREFIX:='ms: '}
# export variables needed in su invocation
# export variables needed for invoking command under monkeysphere user
export DATE
export LOG_LEVEL
export KEYSERVER
......
......@@ -8,7 +8,7 @@
# Jamie McClelland <jm@mayfirst.org>
# Daniel Kahn Gillmor <dkg@fifthhorseman.net>
#
# Copyright 2008-2009, released under the GPL, version 3 or later
# Copyright 2008-2019, released under the GPL, version 3 or later
# all-caps variables are meant to be user supplied (ie. from config
# file) and are considered global
......@@ -93,20 +93,14 @@ log() {
}
# run command as monkeysphere user
su_monkeysphere_user() {
run_as_monkeysphere_user() {
# our main goal here is to run the given command as the the
# monkeysphere user, but without prompting for any sort of
# authentication. If this is not possible, we should just fail.
# FIXME: our current implementation is overly restrictive, because
# there may be some su PAM configurations that would allow su
# "$MONKEYSPHERE_USER" -c "$@" to Just Work without prompting,
# allowing specific users to invoke commands which make use of
# this user.
# chpst (from runit) would be nice to use, but we don't want to
# introduce an extra dependency just for this. This may be a
# candidate for re-factoring if we switch implementation languages.
#
# A simple command and its arguments are expected. Shell
# expressions are not supported. If they are required, they may
# be executed with 'bash -c "<EXPR>"'.
case $(id -un) in
# if monkeysphere user, run the command as a subshell
......@@ -114,10 +108,14 @@ su_monkeysphere_user() {
( "$@" )
;;
# if root, su command as monkeysphere user
# if root, run command as monkeysphere user
'root')
local -a runuser_args=(--user "$MONKEYSPHERE_USER")
if runuser --help | grep -q -- --pty; then
runuser_args+=(--pty)
fi
# requote arguments using bash builtin feature (see "help printf"):
su "$MONKEYSPHERE_USER" -s "$(which bash)" -c "$(printf "%q " "$@")"
runuser "${runuser_args[@]}" -- "$@"
;;
# otherwise, fail
......@@ -139,12 +137,12 @@ cutline() {
# make a temporary directory
msmktempdir() {
mktemp -d ${TMPDIR:-/tmp}/monkeysphere.XXXXXXXXXX
mktemp -d -- "${TMPDIR:-/tmp}/monkeysphere.XXXXXXXXXX"
}
# make a temporary file
msmktempfile() {
mktemp ${TMPDIR:-/tmp}/monkeysphere.XXXXXXXXXX
mktemp -- "${TMPDIR:-/tmp}/monkeysphere.XXXXXXXXXX"
}
# this is a wrapper for doing lock functions.
......@@ -495,7 +493,7 @@ gpg2ssh() {
keyID="$1"
gpg --export --no-armor "$keyID" | openpgp2ssh "$keyID" 2>/dev/null
gpg --export-ssh-key "0x${keyID}!" 2>/dev/null | cut -f1,2 -d' '
}
# output known_hosts line from ssh key
......
......@@ -204,7 +204,7 @@ my $keyserver_prefs = { nomodify => 0x80
########### Math/Utility Functions ##############
# see the bottom of page 44 of RFC 4880 (http://tools.ietf.org/html/rfc4880#page-44)
# see the bottom of page 44 of RFC 4880 (https://tools.ietf.org/html/rfc4880#page-44)
sub simple_checksum {
my $bytes = shift;
......@@ -232,7 +232,7 @@ sub sshfpr_sha256 {
# 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
# https://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.
......@@ -346,7 +346,7 @@ sub mpi_pack {
# 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
# https://marc.info/?l=openssh-unix-dev&m=121866301718839&w=2
sub openssh_mpi_pack {
my $num = shift;
......@@ -786,7 +786,7 @@ sub findkey {
}
# secret material is unencrypted
# see http://tools.ietf.org/html/rfc4880#section-5.5.3
# see https://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);
......@@ -1094,7 +1094,9 @@ for (basename($0)) {
# hostname_long() from Sys::Hostname::Long ?
if (defined $ENV{PEM2OPENPGP_NEWKEY}) {
$rsa = Crypt::OpenSSL::RSA->generate_key($ENV{PEM2OPENPGP_NEWKEY});
my $rsa_keysize = ($ENV{PEM2OPENPGP_NEWKEY} + 0);
$rsa_keysize >= 2048 or die "Generating new RSA key: PEM2OPENPGP_NEWKEY should be at least 2048\n";
$rsa = Crypt::OpenSSL::RSA->generate_key($rsa_keysize);
} else {
$stdin = do {
local $/; # slurp!
......