summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/remctl-shell.pod30
-rw-r--r--docs/remctld.pod23
-rw-r--r--server/server-ssh.c21
-rwxr-xr-xtests/server/shell-misc-t18
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.