summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS6
-rw-r--r--docs/remctld.pod6
-rw-r--r--server/generic.c7
-rw-r--r--server/internal.h1
-rw-r--r--server/process.c6
-rwxr-xr-xtests/data/cmd-env1
-rw-r--r--tests/server/env-t.c8
7 files changed, 32 insertions, 3 deletions
diff --git a/NEWS b/NEWS
index b2aed34..7072c2e 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,12 @@
remctl 3.10 (unreleased)
+ The remctld server now sets the REMOTE_EXPIRES environment variable to
+ the time (in seconds since UNIX epoch) when the authenticated session
+ used to run a command will expire. This will generally be the
+ expiration time of the Kerberos ticket used to authenticate to the
+ server.
+
Simplify the Python RemctlError exception class. The code in the
exception class just duplicated the behavior of the parent Exception
class and was unnecessary, and it interfered with pickling the
diff --git a/docs/remctld.pod b/docs/remctld.pod
index dc68e17..3dcd5e9 100644
--- a/docs/remctld.pod
+++ b/docs/remctld.pod
@@ -506,6 +506,12 @@ the authenticated client.
[2.1] The IP address of the remote host. This may be IPv4 or IPv6.
+=item REMOTE_EXPIRES
+
+[3.10] The time (in seconds since UNIX epoch) when the authenticated
+remote session will expire. This will normally be the expiration time of
+the Kerberos ticket used to authenticate to the server.
+
=item REMOTE_HOST
[2.1] The hostname of the remote host, if it was available. If reverse
diff --git a/server/generic.c b/server/generic.c
index 74134b5..cc0f0e3 100644
--- a/server/generic.c
+++ b/server/generic.c
@@ -19,6 +19,8 @@
#include <portable/system.h>
#include <portable/uio.h>
+#include <time.h>
+
#include <server/internal.h>
#include <util/messages.h>
#include <util/protocol.h>
@@ -45,7 +47,7 @@ server_new_client(int fd, gss_cred_id_t creds)
gss_OID doid;
OM_uint32 major = 0;
OM_uint32 minor = 0;
- OM_uint32 acc_minor;
+ OM_uint32 acc_minor, time_rec;
int flags, status;
static const OM_uint32 req_gss_flags
= (GSS_C_MUTUAL_FLAG | GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG);
@@ -116,7 +118,7 @@ server_new_client(int fd, gss_cred_id_t creds)
(unsigned long) recv_tok.length);
major = gss_accept_sec_context(&acc_minor, &client->context, creds,
&recv_tok, GSS_C_NO_CHANNEL_BINDINGS, &name, &doid,
- &send_tok, &client->flags, NULL, NULL);
+ &send_tok, &client->flags, &time_rec, NULL);
free(recv_tok.value);
/* Send back a token if we need to. */
@@ -160,6 +162,7 @@ server_new_client(int fd, gss_cred_id_t creds)
}
gss_release_name(&minor, &name);
client->user = xstrndup(name_buf.value, name_buf.length);
+ client->expires = time(NULL) + time_rec;
gss_release_buffer(&minor, &name_buf);
return client;
diff --git a/server/internal.h b/server/internal.h
index 622fc8d..49741bc 100644
--- a/server/internal.h
+++ b/server/internal.h
@@ -52,6 +52,7 @@ struct client {
gss_ctx_id_t context; /* GSS-API context. */
char *user; /* Name of the client as a string. */
OM_uint32 flags; /* Connection flags. */
+ time_t expires; /* Expiration time of GSS-API session. */
bool keepalive; /* Whether keep-alive was set. */
bool fatal; /* Whether a fatal error has occurred. */
};
diff --git a/server/process.c b/server/process.c
index 4a96b17..c1b68f5 100644
--- a/server/process.c
+++ b/server/process.c
@@ -27,6 +27,7 @@
#include <util/macros.h>
#include <util/messages.h>
#include <util/protocol.h>
+#include <util/xmalloc.h>
/*
* We would like to use event_base_loopbreak and event_base_got_break, but the
@@ -226,6 +227,7 @@ start(evutil_socket_t junk UNUSED, short what UNUSED, void *data)
socket_type stderr_fds[2] = { INVALID_SOCKET, INVALID_SOCKET };
socket_type fd;
struct sigaction sa;
+ char *expires;
/*
* Socket pairs are used for communication with the child process that
@@ -335,6 +337,10 @@ start(evutil_socket_t junk UNUSED, short what UNUSED, void *data)
sysdie("cannot set REMOTE_HOST in environment");
if (setenv("REMCTL_COMMAND", process->command, 1) < 0)
sysdie("cannot set REMCTL_COMMAND in environment");
+ xasprintf(&expires, "%lu", (unsigned long) client->expires);
+ if (setenv("REMOTE_EXPIRES", expires, 1) < 0)
+ sysdie("cannot set REMOTE_EXPIRES in environment");
+ free(expires);
/* Drop privileges if requested. */
if (process->rule->user != NULL && process->rule->uid > 0) {
diff --git a/tests/data/cmd-env b/tests/data/cmd-env
index d6c6b62..cc1927b 100755
--- a/tests/data/cmd-env
+++ b/tests/data/cmd-env
@@ -4,6 +4,7 @@ REMUSER) echo "$REMUSER" ;;
REMOTE_USER) echo "$REMOTE_USER" ;;
REMOTE_HOST) echo "$REMOTE_HOST" ;;
REMOTE_ADDR) echo "$REMOTE_ADDR" ;;
+REMOTE_EXPIRES) echo "$REMOTE_EXPIRES" ;;
*)
echo "Unknown environment variable $2" >&2
exit 1
diff --git a/tests/server/env-t.c b/tests/server/env-t.c
index 831bfec..af16034 100644
--- a/tests/server/env-t.c
+++ b/tests/server/env-t.c
@@ -2,6 +2,7 @@
* Test suite for environment variables set by the server.
*
* Written by Russ Allbery <eagle@eyrie.org>
+ * Copyright 2015 Russ Allbery <eagle@eyrie.org>
* Copyright 2006, 2009, 2010, 2012, 2013, 2014
* The Board of Trustees of the Leland Stanford Junior University
*
@@ -71,12 +72,13 @@ main(void)
struct kerberos_config *config;
char *expected, *value;
struct remctl *r;
+ time_t expires;
/* Unless we have Kerberos available, we can't really do anything. */
config = kerberos_setup(TAP_KRB_NEEDS_KEYTAB);
remctld_start(config, "data/conf-simple", NULL);
- plan(4);
+ plan(5);
/* Run the tests. */
r = remctl_new();
@@ -98,7 +100,11 @@ main(void)
value = test_env(r, "REMOTE_HOST");
ok(strcmp(value, "\n") == 0 || strstr(value, "localhost") != NULL,
"value for REMOTE_HOST");
+ value = test_env(r, "REMOTE_EXPIRES");
+ expires = strtol(value, NULL, 10);
free(value);
+ ok(expires > time(NULL), "REMOTE_EXPIRES is in the future (%lu)",
+ (unsigned long) expires);
remctl_close(r);
free(expected);