sshsvc-mkauthkeys: A new script joins the collection.
authorMark Wooding <mdw@distorted.org.uk>
Thu, 23 Apr 2015 14:57:33 +0000 (15:57 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Fri, 24 Apr 2015 09:23:08 +0000 (10:23 +0100)
Makefile.am
debian/control
debian/inst
sshsvc-mkauthkeys [new file with mode: 0755]
sshsvc-mkauthkeys.1 [new file with mode: 0644]

index 2e70051..c896216 100644 (file)
@@ -181,6 +181,9 @@ hush.1: hush.1.in Makefile
 dist_bin_SCRIPTS       += with-umask
 dist_man_MANS          += with-umask.1
 
+dist_bin_SCRIPTS       += sshsvc-mkauthkeys
+dist_man_MANS          += sshsvc-mkauthkeys.1
+
 ## bash scripts.
 if HAVE_BASH
 
index e8f226e..fa05cca 100644 (file)
@@ -29,7 +29,8 @@ Depends:
        space,
        getpass,
        hush,
-       with-umask
+       with-umask,
+       sshsvc-mkauthkeys
 Description: Dummy package for convenience.
 
 Package: mdwopt-perl
@@ -167,3 +168,12 @@ Description: Run a command, hiding its output in a logfile unless it fails
  where you get spammed with uninteresting success reports.  hush runs a
  command, logging its output, but, unless the command actually fails, it
  produces no output of its own.
+
+Package: sshsvc-mkauthkeys
+Architecture: all
+Section: utils
+Description: Construct .ssh/authorized_keys files for SSH services.
+ SSH is a fine way to provide services to external users.  It conveniently
+ takes care of details like authenticating users and encrypting
+ communications.  Unfortunately, managing the key files is rather painful.
+ This simple script does a lot of the heavy lifting.
index 5e26960..7a46492 100644 (file)
@@ -52,3 +52,5 @@ hush hush /usr/bin
 hush.1 hush /usr/share/man/man1
 with-umask with-umask /usr/bin
 with-umask.1 with-umask /usr/share/man/man1
+sshsvc-mkauthkeys sshsvc-mkauthkeys /usr/bin
+sshsvc-mkauthkeys.1 sshsvc-mkauthkeys /usr/share/man/man1
diff --git a/sshsvc-mkauthkeys b/sshsvc-mkauthkeys
new file mode 100755 (executable)
index 0000000..a8a370a
--- /dev/null
@@ -0,0 +1,123 @@
+#! /bin/sh
+###
+### Generate .ssh/authorized_keys files for SSH services
+###
+### (c) 2015 Mark Wooding
+###
+
+###----- Licensing notice ---------------------------------------------------
+###
+### This program is free software; you can redistribute it and/or modify
+### it under the terms of the GNU General Public License as published by
+### the Free Software Foundation; either version 2 of the License, or
+### (at your option) any later version.
+###
+### This program is distributed in the hope that it will be useful,
+### but WITHOUT ANY WARRANTY; without even the implied warranty of
+### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+### 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, write to the Free Software
+### Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+set -e
+
+## Initial setup.
+allow_agent_forwarding=no
+allow_x11_forwarding=no
+allow_port_forwarding=no
+allow_pty=no
+env="SSHSVC_USER=@user"
+cmd="bin/sshsvc"
+
+## Hook functions.
+make_key_line () {
+  user=$1
+  e=$env
+  while :; do
+    progressp=t
+    case "$e" in
+      *@user*) e=${e%%@user*}$user${e#*@user} ;;
+      *) progressp=nil ;;
+    esac
+    case $progressp in nil) break ;; esac
+  done
+  line="environment=\"$e\""
+  echo "$line"
+}
+
+make_full_key_line () {
+  user=$1
+  line=$(make_key_line "$user")
+  case "${cmd+t},$line" in
+    ,* | *,command=*) ;;
+    t,*) line="command=\"$cmd\",$line" ;;
+  esac
+  case "$allow_port_forwarding" in
+    yes) ;; *) line="no-port-forwarding,$line" ;;
+  esac
+  case "$allow_x11_forwarding" in
+    yes) ;; *) line="no-X11-forwarding,$line" ;;
+  esac
+  case "$allow_agent_forwarding" in
+    yes) ;; *) line="no-agent-forwarding,$line" ;;
+  esac
+  case "$allow_pty" in
+    yes) ;; *) line="no-pty,$line" ;;
+  esac
+  echo "$line"
+}
+
+## Scan the command line.
+prog=${0##*/} bogusp=nil
+conf=sshsvc.conf out=authorized_keys keysdir=keys
+head=sshsvc-authkeys.head tail=sshsvc-authkeys.tail
+usage () {
+  echo "usage: $prog [-c CONF] [-k DIR] [-o OUTPUT] [-H HEAD] [-T TAIL]"
+}
+while getopts hc:k:o:H:T: opt; do
+  case $opt in
+    h) usage; exit 0 ;;
+    c) conf=$OPTARG ;;
+    k) keysdir=$OPTARG ;;
+    o) out=$OPTARG ;;
+    H) head=$OPTARG ;;
+    T) tail=$OPTARG ;;
+    *) bogusp=t ;;
+  esac
+done
+shift $(( $OPTIND - 1 ))
+case $# in 0) ;; *) bogusp=t ;; esac
+case $bogusp in t) usage >&2; exit 1 ;; esac
+
+## Read the configuration.
+case $conf in /*) ;; *) conf=./$conf ;; esac
+. "$conf"
+
+## Do the thing.
+case $out in
+  -) exec 3>&1 ;;
+  *) exec 3>"$out.new" ;;
+esac
+
+echo >&3 "### GENERATED by $prog"
+
+if [ -r "$head" ]; then cat "$head" >&3; fi
+
+for i in "$keysdir"/*.pub; do
+  u=${i#*/}; u=${u%.*}; u=${u%%!*}
+  l=$(make_full_key_line "$u")
+  k=$(cat "$i")
+  echo >&3 "$l $k"
+done
+
+if [ -r "$tail" ]; then cat "$tail" >&3; fi
+
+echo >&3 "### GENERATED by $prog"
+
+exec 3>&-
+case $out in
+  -) ;;
+  *) mv "$out.new" "$out" ;;
+esac
diff --git a/sshsvc-mkauthkeys.1 b/sshsvc-mkauthkeys.1
new file mode 100644 (file)
index 0000000..958e41c
--- /dev/null
@@ -0,0 +1,281 @@
+.de hP
+.IP
+\h'-\w'\fB\\$1\ \fP'u'\fB\\$1\ \fP\c
+..
+.ie t .ds o \(bu
+.el .ds o o
+.
+.TH sshsvc-mkauthkeys 1 "23 April 2015" "distorted.org.uk" "Utilities"
+.SH NAME
+sshsvc-mkauthkeys \- build authorized_keys files for SSH services
+.SH SYNOPSIS
+.B sshsvc-mkauthkeys
+.RB [ \-c
+.IR config ]
+.RB [ \-k
+.IR keysdir ]
+.RB [ \-o
+.IR output ]
+.br
+\&\h'8n'
+.RB [ \-H
+.IR head ]
+.RB [ \-T
+.IR tail ]
+.SH DESCRIPTION
+The
+.B sshsvc-mkauthkeys
+script constructs an OpenSSH
+.B authorized_keys
+file
+from a collection of SSH public keys
+and some configuration in the form of shell variable and function
+definitions.
+The script expects to be run from a makefile
+within a
+.B .ssh/
+directory
+and reads and writes files with fixed relative pathnames by default.
+These can be overridden using command-line options.
+.SS "Command line options"
+.TP
+.BI \-c " config"
+Source configuration from
+.I config
+instead of the default
+.BR sshsvc.conf .
+.TP
+.BI \-k " keysdir"
+Collect user keys from
+.I keysdir
+instead of the default
+.BR keys/ .
+.TP
+.BI \-o " output"
+Write the output to
+.I output
+instead of the default
+.BR authorized_keys .
+.TP
+.BI \-H " head"
+Read initial raw entries from
+.I head
+(if it exists)
+instead of the default
+.BR sshsvc-authkeys.head .
+.TP
+.BI \-T " tail"
+Read final raw entries from
+.I tail
+(if it exists)
+instead of the default
+.BR sshsvc-authkeys.tail .
+.SS "Overall operation"
+The
+.I output
+file
+.RB ( authorized_keys
+by default)
+is constructed as follows.
+.hP 0.
+A comment is written to
+the very top of
+the output file
+explaining that it was generated by
+.BR sshsvc-mkauthkeys .
+.hP 1.
+If the
+.I head
+file
+.RB ( sshsvc-authkeys.head
+by default)
+exists then its contents are written unchanged to the output.
+.hP 2.
+Each of the files
+.IB keysdir / user\fR[ ! label\fR] .pub
+is processed in turn
+(see below)
+in ascending lexicographic order
+to make a single-line entry
+in the output file.
+The default
+.I keysdir
+is
+.BR keys/ .
+.hP 3.
+If the
+.I tail
+file
+.RB ( sshsvc-authkeys.tail
+by default)
+exists then its contents are written unchanged to the output.
+.hP 4.
+A commend is written to
+the very bottom of
+the output file
+explaining that it was generated by
+.BR sshsvc-mkauthkeys .
+.SS "Configuration"
+The configuration
+for a particular SSH service
+is read from
+.BR sshsvc.conf .
+This file must exist
+in the current working directory,
+though it needn't have any content
+since all configurable parameters have sensible
+(though not necessarily useful)
+defaults.
+.SS "The make_full_key_line function"
+The most general configuration hook
+(and therefore the one requiring most effort from the user)
+is the
+.B make_full_key_line
+function.
+It is given the key file's
+.I user
+name as an argument and
+expected to write
+the
+.I options
+portion of an
+.B authorized_keys
+entry to standard output.
+.PP
+The default implementation is likely to be suitable
+for almost all services.  It calls
+.B make_key_line
+(see below)
+to construct
+environment variable settings
+and other per-user configuration settings,
+and attaches general policy settings.
+.PP
+It uses the following variables.
+.TP
+.B allow_port_forwarding
+If not
+.B yes
+then forbid port forwarding
+(include
+.B no-port-forwarding
+in the line).
+The default is
+.BR no .
+.TP
+.B allow_x11_forwarding
+If not
+.B yes
+then forbid X11 connection forwarding
+(include
+.B no-X11-forwarding
+in the line).
+The default is
+.BR no .
+.TP
+.B allow_agent_forwarding
+If not
+.B yes
+then forbid SSH agent forwarding
+(include
+.B no-agent-forwarding
+in the line).
+The default is
+.BR no .
+It's probably not a good idea to enable this.
+.TP
+.B allow_pty
+If not
+.B yes
+then forbid pty allocation
+(include
+.B no-pty
+in the line).
+The default is
+.BR no .
+This is usually what you want
+unless your service needs an interactive terminal
+(e.g., a console for a virtual machine).
+.TP
+.B cmd
+If set to any value
+and the line from
+.B make_key_line
+doesn't already contain a
+.RB ` command= ...'
+option,
+then always run
+.I cmd
+(with the service user's shell)
+rather than using the client's requested command line,
+which is left in
+.B SSH_ORIGINAL_COMMAND
+(include
+.BI command="" cmd ""
+in the line).
+The default is
+.BR bin/sshsvc .
+.SS "The make_key_line function"
+The
+.B make_key_line
+function is called with
+the key file's
+.I user
+name as its only argument,
+and is expected to write any per-user
+(and unusual)
+options to standard output.
+Mostly it will be sufficient to generate an
+.RB ` environment= ...'
+option
+and leave the rest to
+.BR make_full_key_line .
+.PP
+The default
+.B make_key_line
+function is suitable for simple cases.
+It examines the
+.B env
+variable,
+replacing
+.B @user
+placeholders with the key's
+.I user
+name,
+and emits the line
+.BI environment= env\fR.
+The default value of
+.B env
+is
+.B SSHSVC_USER=@user
+which may be good enough for services
+explicitly written to work with it.
+.SH FILES
+.TP
+.BR sshsvc.conf
+Read for configuration
+(shell variable and function definitions).
+.TP
+.BI keys/ user\fR[ ! label\fR] .pub
+Input public keys to process.
+.TP
+.B sshsvc-authkeys.head
+Pre-cooked
+.B authorized_keys
+entries to write at the top of the output.
+.TP
+.B sshsvc-authkeys.tail
+Pre-cooked
+.B authorized_keys
+entries to write at the bottom of the output.
+.TP
+.B authorized_keys
+Output file.
+.SH BUGS
+Perfection guaranteed.
+Satisfaction, or your money back.
+.SH "SEE ALSO"
+.BR ssh (1),
+.BR sshd (8).
+.SH AUTHOR
+Mark Wooding, <mdw@distorted.org.uk>