-# function to interact with the host gnupg keyring
-gpg_host() {
- local returnCode
-
- GNUPGHOME="$GNUPGHOME_HOST"
- export GNUPGHOME
-
- # NOTE: we supress this warning because we need the monkeysphere
- # user to be able to read the host pubring. we realize this might
- # be problematic, but it's the simplest solution, without too much
- # loss of security.
- gpg --no-permission-warning "$@"
- returnCode="$?"
-
- # always reset the permissions on the host pubring so that the
- # monkeysphere user can read the trust signatures
- chgrp "$MONKEYSPHERE_USER" "${GNUPGHOME_HOST}/pubring.gpg"
- chmod g+r "${GNUPGHOME_HOST}/pubring.gpg"
+# edit key scripts, takes scripts on stdin, and keyID as first input
+gpg_host_edit() {
+ gpg_host --command-fd 0 --edit-key "$@"
+}
+
+# export the monkeysphere OpenPGP pub key file
+update_pgp_pub_file() {
+ log debug "updating openpgp public key file '$HOST_KEY_FILE'..."
+ gpg_host --export --armor --export-options export-minimal \
+ $(gpg_host --list-secret-keys --with-colons --fingerprint | grep ^fpr | cut -f10 -d:) \
+ > "$HOST_KEY_FILE"
+}
+
+# check that the service name is well formed. we assume that the
+# service name refers to a host; DNS labels for host names are limited
+# to a very small range of characters (see RFC 1912, section 2.1).
+
+# FIXME: i'm failing to check here for label components that are
+# all-number (e.g. ssh://666.666), which are technically not allowed
+# (though some exist on the 'net, apparently)
+
+# FIXME: this will probably misbehave if raw IP addresses are provided,
+# either IPv4 or IPv6 using the bracket notation.
+
+# FIXME: this doesn't address the use of hashed User IDs.
+
+check_service_name() {
+ local name="$1"
+ local errs=""
+ local scheme
+ local port
+ local assigned_ports
+
+ [ -n "$name" ] || \
+ failure "You must supply a service name to check"
+
+ printf '%s' "$name" | perl -n -e '($str = $_) =~ s/\s//g ; exit !(lc($str) eq $_);' || \
+ failure "Not a valid service name: '$name'
+
+Service names should be canonicalized to all lower-case,
+with no whitespace"
+
+ [[ "$name" =~ ^[a-z0-9./:-]+$ ]] || \
+ failure "Not a valid service name: '$name'
+
+Service names should contain only lower-case ASCII letters
+numbers, dots (.), hyphens (-), slashes (/), and a colon (:).
+If you are using non-ASCII characters (e.g. IDN), you should
+use the canonicalized ASCII (NAMEPREP -> Punycode) representation
+(see RFC 3490)."
+
+ [[ "$name" =~ \. ]] || \
+ failure "Not a valid service name: '$name'
+
+Service names should use fully-qualified domain names (FQDN), but the
+domain name you chose appears to only have the local part. For
+example: don't use 'ssh://foo' ; use 'ssh://foo.example.com' instead."
+
+ [[ "$name" =~ ^[a-z0-9]([a-z0-9-]*[a-z0-9])?://[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.|((\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+))(:[1-9][0-9]{0,4})?$ ]] || \
+ failure "Not a valid service name: '$name'
+
+Service names look like <scheme>://full.example.com[:<portnumber>],
+where <scheme> is something like ssh or https, and <portnumber> is
+a decimal number (supplied only if the service is on a non-standard
+port)."
+
+ scheme=$(cut -f1 -d: <<<"$name")
+ port=$(cut -f3 -d: <<<"$name")