430 lines
12 KiB
Diff
430 lines
12 KiB
Diff
diff -up openssh-5.8p1/audit-bsm.c.audit1a openssh-5.8p1/audit-bsm.c
|
|
--- openssh-5.8p1/audit-bsm.c.audit1a 2011-03-02 09:37:14.000000000 +0100
|
|
+++ openssh-5.8p1/audit-bsm.c 2011-03-02 09:37:14.000000000 +0100
|
|
@@ -298,19 +298,26 @@ audit_connection_from(const char *host,
|
|
#endif
|
|
}
|
|
|
|
-void
|
|
+int
|
|
audit_run_command(const char *command)
|
|
{
|
|
/* not implemented */
|
|
+ return 0;
|
|
}
|
|
|
|
void
|
|
-audit_end_command(const char *command)
|
|
+audit_end_command(int handle, const char *command)
|
|
{
|
|
/* not implemented */
|
|
}
|
|
|
|
void
|
|
+audit_count_session_open(void)
|
|
+{
|
|
+ /* not necessary */
|
|
+}
|
|
+
|
|
+void
|
|
audit_session_open(struct logininfo *li)
|
|
{
|
|
/* not implemented */
|
|
diff -up openssh-5.8p1/audit.c.audit1a openssh-5.8p1/audit.c
|
|
--- openssh-5.8p1/audit.c.audit1a 2011-03-02 09:37:14.000000000 +0100
|
|
+++ openssh-5.8p1/audit.c 2011-03-02 09:37:14.000000000 +0100
|
|
@@ -140,6 +140,17 @@ audit_event(ssh_audit_event_t event)
|
|
}
|
|
|
|
/*
|
|
+ * Called when a child process has called, or will soon call,
|
|
+ * audit_session_open.
|
|
+ */
|
|
+void
|
|
+audit_count_session_open(void)
|
|
+{
|
|
+ debug("audit count session open euid %d user %s", geteuid(),
|
|
+ audit_username());
|
|
+}
|
|
+
|
|
+/*
|
|
* Called when a user session is started. Argument is the tty allocated to
|
|
* the session, or NULL if no tty was allocated.
|
|
*
|
|
@@ -174,22 +185,25 @@ audit_session_close(struct logininfo *li
|
|
/*
|
|
* This will be called when a user runs a non-interactive command. Note that
|
|
* it may be called multiple times for a single connection since SSH2 allows
|
|
- * multiple sessions within a single connection.
|
|
+ * multiple sessions within a single connection. Returns a "handle" for
|
|
+ * audit_end_command.
|
|
*/
|
|
-void
|
|
+int
|
|
audit_run_command(const char *command)
|
|
{
|
|
debug("audit run command euid %d user %s command '%.200s'", geteuid(),
|
|
audit_username(), command);
|
|
+ return 0;
|
|
}
|
|
|
|
/*
|
|
* This will be called when the non-interactive command finishes. Note that
|
|
* it may be called multiple times for a single connection since SSH2 allows
|
|
- * multiple sessions within a single connection.
|
|
+ * multiple sessions within a single connection. "handle" should come from
|
|
+ * the corresponding audit_run_command.
|
|
*/
|
|
void
|
|
-audit_end_command(const char *command)
|
|
+audit_end_command(int handle, const char *command)
|
|
{
|
|
debug("audit end nopty exec euid %d user %s command '%.200s'", geteuid(),
|
|
audit_username(), command);
|
|
diff -up openssh-5.8p1/audit.h.audit1a openssh-5.8p1/audit.h
|
|
--- openssh-5.8p1/audit.h.audit1a 2011-03-02 09:37:14.000000000 +0100
|
|
+++ openssh-5.8p1/audit.h 2011-03-02 09:37:14.000000000 +0100
|
|
@@ -49,10 +49,11 @@ typedef enum ssh_audit_event_type ssh_au
|
|
|
|
void audit_connection_from(const char *, int);
|
|
void audit_event(ssh_audit_event_t);
|
|
+void audit_count_session_open(void);
|
|
void audit_session_open(struct logininfo *);
|
|
void audit_session_close(struct logininfo *);
|
|
-void audit_run_command(const char *);
|
|
-void audit_end_command(const char *);
|
|
+int audit_run_command(const char *);
|
|
+void audit_end_command(int, const char *);
|
|
ssh_audit_event_t audit_classify_auth(const char *);
|
|
|
|
#endif /* _SSH_AUDIT_H */
|
|
diff -up openssh-5.8p1/audit-linux.c.audit1a openssh-5.8p1/audit-linux.c
|
|
--- openssh-5.8p1/audit-linux.c.audit1a 2011-03-02 09:37:14.000000000 +0100
|
|
+++ openssh-5.8p1/audit-linux.c 2011-03-02 09:37:14.000000000 +0100
|
|
@@ -140,7 +140,7 @@ audit_connection_from(const char *host,
|
|
/* not implemented */
|
|
}
|
|
|
|
-void
|
|
+int
|
|
audit_run_command(const char *command)
|
|
{
|
|
if (!user_login_count++)
|
|
@@ -148,10 +148,11 @@ audit_run_command(const char *command)
|
|
NULL, "ssh", 1, AUDIT_USER_LOGIN);
|
|
linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns),
|
|
NULL, "ssh", 1, AUDIT_USER_START);
|
|
+ return 0;
|
|
}
|
|
|
|
void
|
|
-audit_end_command(const char *command)
|
|
+audit_end_command(int handle, const char *command)
|
|
{
|
|
linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns),
|
|
NULL, "ssh", 1, AUDIT_USER_END);
|
|
@@ -161,6 +162,12 @@ audit_end_command(const char *command)
|
|
}
|
|
|
|
void
|
|
+audit_count_session_open(void)
|
|
+{
|
|
+ user_login_count++;
|
|
+}
|
|
+
|
|
+void
|
|
audit_session_open(struct logininfo *li)
|
|
{
|
|
if (!user_login_count++)
|
|
diff -up openssh-5.8p1/monitor.c.audit1a openssh-5.8p1/monitor.c
|
|
--- openssh-5.8p1/monitor.c.audit1a 2011-03-02 09:37:14.000000000 +0100
|
|
+++ openssh-5.8p1/monitor.c 2011-03-02 09:37:14.000000000 +0100
|
|
@@ -1291,6 +1291,12 @@ mm_session_close(Session *s)
|
|
debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd);
|
|
session_pty_cleanup2(s);
|
|
}
|
|
+#ifdef SSH_AUDIT_EVENTS
|
|
+ if (s->command != NULL) {
|
|
+ debug3("%s: command %d", __func__, s->command_handle);
|
|
+ session_end_command2(s);
|
|
+ }
|
|
+#endif
|
|
session_unused(s->self);
|
|
}
|
|
|
|
@@ -1613,25 +1619,44 @@ mm_answer_audit_command(int socket, Buff
|
|
{
|
|
u_int len;
|
|
char *cmd;
|
|
+ Session *s;
|
|
|
|
debug3("%s entering", __func__);
|
|
cmd = buffer_get_string(m, &len);
|
|
+
|
|
/* sanity check command, if so how? */
|
|
- audit_run_command(cmd);
|
|
- xfree(cmd);
|
|
+ s = session_new();
|
|
+ if (s == NULL)
|
|
+ fatal("%s: error allocating a session", __func__);
|
|
+ s->command = cmd;
|
|
+ s->command_handle = audit_run_command(cmd);
|
|
+
|
|
+ buffer_clear(m);
|
|
+ buffer_put_int(m, s->self);
|
|
+
|
|
+ mm_request_send(socket, MONITOR_ANS_AUDIT_COMMAND, m);
|
|
+
|
|
return (0);
|
|
}
|
|
|
|
int
|
|
mm_answer_audit_end_command(int socket, Buffer *m)
|
|
{
|
|
+ int handle;
|
|
u_int len;
|
|
char *cmd;
|
|
+ Session *s;
|
|
|
|
debug3("%s entering", __func__);
|
|
+ handle = buffer_get_int(m);
|
|
cmd = buffer_get_string(m, &len);
|
|
- /* sanity check command, if so how? */
|
|
- audit_end_command(cmd);
|
|
+
|
|
+ s = session_by_id(handle);
|
|
+ if (s == NULL || s->ttyfd != -1 || s->command == NULL ||
|
|
+ strcmp(s->command, cmd) != 0)
|
|
+ fatal("%s: invalid handle", __func__);
|
|
+ mm_session_close(s);
|
|
+
|
|
xfree(cmd);
|
|
return (0);
|
|
}
|
|
diff -up openssh-5.8p1/monitor.h.audit1a openssh-5.8p1/monitor.h
|
|
--- openssh-5.8p1/monitor.h.audit1a 2011-03-02 09:37:14.000000000 +0100
|
|
+++ openssh-5.8p1/monitor.h 2011-03-02 09:37:15.000000000 +0100
|
|
@@ -60,7 +60,7 @@ enum monitor_reqtype {
|
|
MONITOR_REQ_PAM_RESPOND, MONITOR_ANS_PAM_RESPOND,
|
|
MONITOR_REQ_PAM_FREE_CTX, MONITOR_ANS_PAM_FREE_CTX,
|
|
MONITOR_REQ_AUDIT_EVENT, MONITOR_REQ_AUDIT_COMMAND,
|
|
- MONITOR_REQ_AUDIT_END_COMMAND,
|
|
+ MONITOR_ANS_AUDIT_COMMAND, MONITOR_REQ_AUDIT_END_COMMAND,
|
|
MONITOR_REQ_TERM,
|
|
MONITOR_REQ_JPAKE_STEP1, MONITOR_ANS_JPAKE_STEP1,
|
|
MONITOR_REQ_JPAKE_GET_PWDATA, MONITOR_ANS_JPAKE_GET_PWDATA,
|
|
diff -up openssh-5.8p1/monitor_wrap.c.audit1a openssh-5.8p1/monitor_wrap.c
|
|
--- openssh-5.8p1/monitor_wrap.c.audit1a 2011-03-02 09:37:14.000000000 +0100
|
|
+++ openssh-5.8p1/monitor_wrap.c 2011-03-02 09:37:15.000000000 +0100
|
|
@@ -1150,10 +1150,11 @@ mm_audit_event(ssh_audit_event_t event)
|
|
buffer_free(&m);
|
|
}
|
|
|
|
-void
|
|
+int
|
|
mm_audit_run_command(const char *command)
|
|
{
|
|
Buffer m;
|
|
+ int handle;
|
|
|
|
debug3("%s entering command %s", __func__, command);
|
|
|
|
@@ -1161,17 +1162,23 @@ mm_audit_run_command(const char *command
|
|
buffer_put_cstring(&m, command);
|
|
|
|
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, &m);
|
|
+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_COMMAND, &m);
|
|
+
|
|
+ handle = buffer_get_int(&m);
|
|
buffer_free(&m);
|
|
+
|
|
+ return (handle);
|
|
}
|
|
|
|
void
|
|
-mm_audit_end_command(const char *command)
|
|
+mm_audit_end_command(int handle, const char *command)
|
|
{
|
|
Buffer m;
|
|
|
|
debug3("%s entering command %s", __func__, command);
|
|
|
|
buffer_init(&m);
|
|
+ buffer_put_int(&m, handle);
|
|
buffer_put_cstring(&m, command);
|
|
|
|
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_END_COMMAND, &m);
|
|
diff -up openssh-5.8p1/monitor_wrap.h.audit1a openssh-5.8p1/monitor_wrap.h
|
|
--- openssh-5.8p1/monitor_wrap.h.audit1a 2011-03-02 09:41:17.000000000 +0100
|
|
+++ openssh-5.8p1/monitor_wrap.h 2011-03-02 09:44:35.000000000 +0100
|
|
@@ -73,8 +73,8 @@ void mm_sshpam_free_ctx(void *);
|
|
#ifdef SSH_AUDIT_EVENTS
|
|
#include "audit.h"
|
|
void mm_audit_event(ssh_audit_event_t);
|
|
-void mm_audit_run_command(const char *);
|
|
-void mm_audit_end_command(const char *);
|
|
+int mm_audit_run_command(const char *);
|
|
+void mm_audit_end_command(int, const char *);
|
|
#endif
|
|
|
|
struct Session;
|
|
diff -up openssh-5.8p1/session.c.audit1a openssh-5.8p1/session.c
|
|
--- openssh-5.8p1/session.c.audit1a 2011-03-02 09:37:14.000000000 +0100
|
|
+++ openssh-5.8p1/session.c 2011-03-02 09:37:15.000000000 +0100
|
|
@@ -738,6 +738,14 @@ do_exec_pty(Session *s, const char *comm
|
|
/* Parent. Close the slave side of the pseudo tty. */
|
|
close(ttyfd);
|
|
|
|
+#ifndef HAVE_OSF_SIA
|
|
+ /* do_login in the child did not affect state in this process,
|
|
+ compensate. From an architectural standpoint, this is extremely
|
|
+ ugly. */
|
|
+ if (!(options.use_login && command == NULL))
|
|
+ audit_count_session_open();
|
|
+#endif
|
|
+
|
|
/* Enter interactive session. */
|
|
s->ptymaster = ptymaster;
|
|
packet_set_interactive(1,
|
|
@@ -809,17 +817,19 @@ do_exec(Session *s, const char *command)
|
|
}
|
|
|
|
#ifdef SSH_AUDIT_EVENTS
|
|
- if (command != NULL) {
|
|
- PRIVSEP(audit_run_command(command));
|
|
+ if (s->command != NULL || s->command_handle != -1)
|
|
+ fatal("do_exec: command already set");
|
|
+ if (command != NULL)
|
|
s->command = xstrdup(command);
|
|
- } else if (s->ttyfd == -1) {
|
|
+ else if (s->ttyfd == -1) {
|
|
char *shell = s->pw->pw_shell;
|
|
|
|
if (shell[0] == '\0') /* empty shell means /bin/sh */
|
|
shell =_PATH_BSHELL;
|
|
- PRIVSEP(audit_run_command(shell));
|
|
s->command = xstrdup(shell);
|
|
}
|
|
+ if (s->command != NULL)
|
|
+ s->command_handle = PRIVSEP(audit_run_command(s->command));
|
|
#endif
|
|
if (s->ttyfd != -1)
|
|
ret = do_exec_pty(s, command);
|
|
@@ -1843,6 +1853,7 @@ session_unused(int id)
|
|
sessions[id].ttyfd = -1;
|
|
sessions[id].ptymaster = -1;
|
|
sessions[id].x11_chanids = NULL;
|
|
+ sessions[id].command_handle = -1;
|
|
sessions[id].next_unused = sessions_first_unused;
|
|
sessions_first_unused = id;
|
|
}
|
|
@@ -1925,6 +1936,19 @@ session_open(Authctxt *authctxt, int cha
|
|
}
|
|
|
|
Session *
|
|
+session_by_id(int id)
|
|
+{
|
|
+ if (id >= 0 && id < sessions_nalloc) {
|
|
+ Session *s = &sessions[id];
|
|
+ if (s->used)
|
|
+ return s;
|
|
+ }
|
|
+ debug("session_by_id: unknown id %d", id);
|
|
+ session_dump();
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
+Session *
|
|
session_by_tty(char *tty)
|
|
{
|
|
int i;
|
|
@@ -2450,6 +2474,30 @@ session_exit_message(Session *s, int sta
|
|
chan_write_failed(c);
|
|
}
|
|
|
|
+#ifdef SSH_AUDIT_EVENTS
|
|
+void
|
|
+session_end_command2(Session *s)
|
|
+{
|
|
+ if (s->command != NULL) {
|
|
+ audit_end_command(s->command_handle, s->command);
|
|
+ xfree(s->command);
|
|
+ s->command = NULL;
|
|
+ s->command_handle = -1;
|
|
+ }
|
|
+}
|
|
+
|
|
+static void
|
|
+session_end_command(Session *s)
|
|
+{
|
|
+ if (s->command != NULL) {
|
|
+ PRIVSEP(audit_end_command(s->command_handle, s->command));
|
|
+ xfree(s->command);
|
|
+ s->command = NULL;
|
|
+ s->command_handle = -1;
|
|
+ }
|
|
+}
|
|
+#endif
|
|
+
|
|
void
|
|
session_close(Session *s)
|
|
{
|
|
@@ -2459,10 +2507,8 @@ session_close(Session *s)
|
|
if (s->ttyfd != -1)
|
|
session_pty_cleanup(s);
|
|
#ifdef SSH_AUDIT_EVENTS
|
|
- if (s->command) {
|
|
- PRIVSEP(audit_end_command(s->command));
|
|
- xfree(s->command);
|
|
- }
|
|
+ if (s->command)
|
|
+ session_end_command(s);
|
|
#endif
|
|
if (s->term)
|
|
xfree(s->term);
|
|
@@ -2683,6 +2729,15 @@ do_authenticated2(Authctxt *authctxt)
|
|
server_loop2(authctxt);
|
|
}
|
|
|
|
+static void
|
|
+do_cleanup_one_session(Session *s)
|
|
+{
|
|
+ session_pty_cleanup2(s);
|
|
+#ifdef SSH_AUDIT_EVENTS
|
|
+ session_end_command2(s);
|
|
+#endif
|
|
+}
|
|
+
|
|
void
|
|
do_cleanup(Authctxt *authctxt)
|
|
{
|
|
@@ -2731,5 +2786,5 @@ do_cleanup(Authctxt *authctxt)
|
|
* or if running in monitor.
|
|
*/
|
|
if (!use_privsep || mm_is_monitor())
|
|
- session_destroy_all(session_pty_cleanup2);
|
|
+ session_destroy_all(do_cleanup_one_session);
|
|
}
|
|
diff -up openssh-5.8p1/session.h.audit1a openssh-5.8p1/session.h
|
|
--- openssh-5.8p1/session.h.audit1a 2011-03-02 09:37:14.000000000 +0100
|
|
+++ openssh-5.8p1/session.h 2011-03-02 09:37:15.000000000 +0100
|
|
@@ -63,6 +63,7 @@ struct Session {
|
|
|
|
/* exec */
|
|
#ifdef SSH_AUDIT_EVENTS
|
|
+ int command_handle;
|
|
char *command;
|
|
#endif
|
|
};
|
|
@@ -77,8 +78,10 @@ void session_close_by_pid(pid_t, int);
|
|
void session_close_by_channel(int, void *);
|
|
void session_destroy_all(void (*)(Session *));
|
|
void session_pty_cleanup2(Session *);
|
|
+void session_end_command2(Session *);
|
|
|
|
Session *session_new(void);
|
|
+Session *session_by_id(int);
|
|
Session *session_by_tty(char *);
|
|
void session_close(Session *);
|
|
void do_setusercontext(struct passwd *);
|