diff options
-rw-r--r-- | docs/remctl-shell.pod | 30 | ||||
-rw-r--r-- | docs/remctld.pod | 23 | ||||
-rw-r--r-- | server/server-ssh.c | 21 | ||||
-rwxr-xr-x | tests/server/shell-misc-t | 18 |
4 files changed, 71 insertions, 21 deletions
diff --git a/docs/remctl-shell.pod b/docs/remctl-shell.pod index 3e7ac35..af3cfc7 100644 --- a/docs/remctl-shell.pod +++ b/docs/remctl-shell.pod @@ -202,13 +202,11 @@ noted in each description. =over 4 -=item REMOTE_USER - -=item REMUSER +=item REMCTL_COMMAND -[3.12] Set to the value of REMCTL_CLIENT as set in the environment of -B<remctl-shell>. This should be set security via F<authorized_keys> as -discussed above. +[3.12] The command string that caused this command to be run. This +variable will contain only the command, not the subcommand or any +additional arguments (which are passed as command arguments). =item REMOTE_ADDR @@ -223,11 +221,23 @@ meaningful concept for ssh authentication via public key, and regardless is not communicated by B<sshd> to the shell. It is therefore always set to C<0> by B<remctl-shell>. -=item REMCTL_COMMAND +=item REMOTE_HOST -[3.12] The command string that caused this command to be run. This -variable will contain only the command, not the subcommand or any -additional arguments (which are passed as command arguments). +[3.12] The hostname of the remote host, if it was available. If reverse +name resolution failed, this environment variable will not be set. + +This is determined via a simple reverse DNS lookup and should be +considered under the control of the client. remctl commands should treat +it with skepticism and not use it for anything other than logging +purposes. + +=item REMOTE_USER + +=item REMUSER + +[3.12] Set to the value of REMCTL_CLIENT as set in the environment of +B<remctl-shell>. This should be set security via F<authorized_keys> as +discussed above. =back diff --git a/docs/remctld.pod b/docs/remctld.pod index c601043..f10d245 100644 --- a/docs/remctld.pod +++ b/docs/remctld.pod @@ -523,12 +523,11 @@ B<remctld> (annotated with the version at which they were added): =over 4 -=item REMOTE_USER - -=item REMUSER +=item REMCTL_COMMAND -[1.0 for REMUSER, 2.1 for REMOTE_USER] Set to the Kerberos principal of -the authenticated client. +[2.16] The command string that caused this command to be run. This +variable will contain only the command, not the subcommand or any +additional arguments (which are passed as command arguments). =item REMOTE_ADDR @@ -545,11 +544,17 @@ the Kerberos ticket used to authenticate to the server. [2.1] The hostname of the remote host, if it was available. If reverse name resolution failed, this environment variable will not be set. -=item REMCTL_COMMAND +This is determined via a simple reverse DNS lookup and should be +considered under the control of the client. remctl commands should treat +it with skepticism and not use it for anything other than logging +purposes. -[2.16] The command string that caused this command to be run. This -variable will contain only the command, not the subcommand or any -additional arguments (which are passed as command arguments). +=item REMOTE_USER + +=item REMUSER + +[1.0 for REMUSER, 2.1 for REMOTE_USER] Set to the Kerberos principal of +the authenticated client. =back diff --git a/server/server-ssh.c b/server/server-ssh.c index e7b2faa..1b48447 100644 --- a/server/server-ssh.c +++ b/server/server-ssh.c @@ -13,6 +13,7 @@ #include <config.h> #include <portable/event.h> +#include <portable/socket.h> #include <portable/system.h> #include <ctype.h> @@ -233,6 +234,10 @@ server_ssh_new_client(void) struct client *client; const char *ssh_client, *user; struct vector *client_info; + struct addrinfo hints; + struct addrinfo *result; + char *buffer; + int status; /* Parse client identity from ssh environment variables. */ user = getenv("REMCTL_USER"); @@ -251,6 +256,22 @@ server_ssh_new_client(void) client->protocol = 3; client->user = xstrdup(user); + /* Get the remote hostname. */ + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + status = getaddrinfo(client->ipaddress, NULL, &hints, &result); + if (status == 0) { + buffer = xmalloc(NI_MAXHOST); + status = getnameinfo(result->ai_addr, result->ai_addrlen, buffer, + NI_MAXHOST, NULL, 0, NI_NAMEREQD); + if (status == 0) + client->hostname = buffer; + else + free(buffer); + freeaddrinfo(result); + } + /* Add ssh protocol callbacks. */ client->setup = command_setup; client->finish = command_finish; diff --git a/tests/server/shell-misc-t b/tests/server/shell-misc-t index a907d6b..5788c6d 100755 --- a/tests/server/shell-misc-t +++ b/tests/server/shell-misc-t @@ -33,13 +33,27 @@ ok_program 'value for REMUSER' 0 "$REMCTL_USER" \ "$shell" -qSf "${C_TAP_BUILD}/data/conf-simple" -c 'test env REMUSER' ok_program 'value for REMOTE_USER' 0 "$REMCTL_USER" \ "$shell" -qSf "${C_TAP_BUILD}/data/conf-simple" -c 'test env REMOTE_USER' -ok_program 'value for REMOTE_HOST' 0 '' \ - "$shell" -qSf "${C_TAP_BUILD}/data/conf-simple" -c 'test env REMOTE_HOST' ok_program 'value for REMOTE_ADDR' 0 '127.0.0.1' \ "$shell" -qSf "${C_TAP_BUILD}/data/conf-simple" -c 'test env REMOTE_ADDR' ok_program 'value for REMOTE_EXPIRES' 0 '0' \ "$shell" -qSf "${C_TAP_BUILD}/data/conf-simple" -c 'test env REMOTE_EXPIRES' +# Remote host requires a bit more effort, since it can be one of a number of +# values. Don't bother with all the ok_program checks, and just check the +# output. +command='test env REMOTE_HOST' +hostname=`"$shell" -qSf "${C_TAP_BUILD}/data/conf-simple" -c "$command" 2>&1` +status=$? +ok 'return status for REMOTE_HOST' [ $status -eq 0 ] +if [ -z "$hostname" ]; then + ok 'value for REMOTE_HOST' true +elif echo "$hostname" | grep -q localhost; then + ok 'value for REMOTE_HOST' true +else + diag "env REMOTE_HOST: $hostname" + ok 'value for REMOTE_HOST' false +fi + # Test some of the general server properties. This code is mostly also tested # by the regular server tests, but it's good verification that the shell # implementation works the same. |