diff --git a/openssh-6.0p1-audit4.patch b/openssh-6.0p1-audit4.patch deleted file mode 100644 index 73b8b14..0000000 --- a/openssh-6.0p1-audit4.patch +++ /dev/null @@ -1,672 +0,0 @@ -diff -up openssh-6.0p1/audit-bsm.c.audit4 openssh-6.0p1/audit-bsm.c ---- openssh-6.0p1/audit-bsm.c.audit4 2012-08-06 20:35:56.306789054 +0200 -+++ openssh-6.0p1/audit-bsm.c 2012-08-06 20:35:56.314789022 +0200 -@@ -485,4 +485,10 @@ audit_kex_body(int ctos, char *enc, char - { - /* not implemented */ - } -+ -+void -+audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) -+{ -+ /* not implemented */ -+} - #endif /* BSM */ -diff -up openssh-6.0p1/audit.c.audit4 openssh-6.0p1/audit.c ---- openssh-6.0p1/audit.c.audit4 2012-08-06 20:35:56.307789050 +0200 -+++ openssh-6.0p1/audit.c 2012-08-06 20:35:56.315789018 +0200 -@@ -143,6 +143,12 @@ audit_kex(int ctos, char *enc, char *mac - PRIVSEP(audit_kex_body(ctos, enc, mac, comp, getpid(), getuid())); - } - -+void -+audit_session_key_free(int ctos) -+{ -+ PRIVSEP(audit_session_key_free_body(ctos, getpid(), getuid())); -+} -+ - # ifndef CUSTOM_SSH_AUDIT_EVENTS - /* - * Null implementations of audit functions. -@@ -274,5 +280,15 @@ audit_kex_body(int ctos, char *enc, char - (unsigned)geteuid(), ctos, enc, mac, compress, (long)pid, - (unsigned)uid); - } -+ -+/* -+ * This will be called on succesfull session key discard -+ */ -+void -+audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) -+{ -+ debug("audit session key discard euid %u direction %d from pid %ld uid %u", -+ (unsigned)geteuid(), ctos, (long)pid, (unsigned)uid); -+} - # endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */ - #endif /* SSH_AUDIT_EVENTS */ -diff -up openssh-6.0p1/audit.h.audit4 openssh-6.0p1/audit.h ---- openssh-6.0p1/audit.h.audit4 2012-08-06 20:35:56.308789046 +0200 -+++ openssh-6.0p1/audit.h 2012-08-06 20:35:56.315789018 +0200 -@@ -62,5 +62,7 @@ void audit_unsupported(int); - void audit_kex(int, char *, char *, char *); - void audit_unsupported_body(int); - void audit_kex_body(int, char *, char *, char *, pid_t, uid_t); -+void audit_session_key_free(int ctos); -+void audit_session_key_free_body(int ctos, pid_t, uid_t); - - #endif /* _SSH_AUDIT_H */ -diff -up openssh-6.0p1/audit-linux.c.audit4 openssh-6.0p1/audit-linux.c ---- openssh-6.0p1/audit-linux.c.audit4 2012-08-06 20:35:56.307789050 +0200 -+++ openssh-6.0p1/audit-linux.c 2012-08-06 20:35:56.315789018 +0200 -@@ -294,6 +294,8 @@ audit_unsupported_body(int what) - #endif - } - -+const static char *direction[] = { "from-server", "from-client", "both" }; -+ - void - audit_kex_body(int ctos, char *enc, char *mac, char *compress, pid_t pid, - uid_t uid) -@@ -301,7 +303,6 @@ audit_kex_body(int ctos, char *enc, char - #ifdef AUDIT_CRYPTO_SESSION - char buf[AUDIT_LOG_SIZE]; - int audit_fd, audit_ok; -- const static char *direction[] = { "from-server", "from-client", "both" }; - Cipher *cipher = cipher_by_name(enc); - char *s; - -@@ -327,4 +328,32 @@ audit_kex_body(int ctos, char *enc, char - #endif - } - -+void -+audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) -+{ -+ char buf[AUDIT_LOG_SIZE]; -+ int audit_fd, audit_ok; -+ char *s; -+ -+ snprintf(buf, sizeof(buf), "op=destroy kind=session fp=? direction=%s spid=%jd suid=%jd rport=%d laddr=%s lport=%d ", -+ direction[ctos], (intmax_t)pid, (intmax_t)uid, -+ get_remote_port(), -+ (s = get_local_ipaddr(packet_get_connection_in())), -+ get_local_port()); -+ xfree(s); -+ audit_fd = audit_open(); -+ if (audit_fd < 0) { -+ if (errno != EINVAL && errno != EPROTONOSUPPORT && -+ errno != EAFNOSUPPORT) -+ error("cannot open audit"); -+ return; -+ } -+ audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER, -+ buf, NULL, get_remote_ipaddr(), NULL, 1); -+ audit_close(audit_fd); -+ /* do not abort if the error is EPERM and sshd is run as non root user */ -+ if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0))) -+ error("cannot write into audit"); -+} -+ - #endif /* USE_LINUX_AUDIT */ -diff -up openssh-6.0p1/auditstub.c.audit4 openssh-6.0p1/auditstub.c ---- openssh-6.0p1/auditstub.c.audit4 2012-08-06 20:35:56.308789046 +0200 -+++ openssh-6.0p1/auditstub.c 2012-08-06 20:35:56.316789015 +0200 -@@ -27,6 +27,8 @@ - * Red Hat author: Jan F. Chadima - */ - -+#include -+ - void - audit_unsupported(int n) - { -@@ -37,3 +39,12 @@ audit_kex(int ctos, char *enc, char *mac - { - } - -+void -+audit_session_key_free(int ctos) -+{ -+} -+ -+void -+audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) -+{ -+} -diff -up openssh-6.0p1/kex.c.audit4 openssh-6.0p1/kex.c ---- openssh-6.0p1/kex.c.audit4 2012-08-06 20:35:56.309789042 +0200 -+++ openssh-6.0p1/kex.c 2012-08-06 20:35:56.317789011 +0200 -@@ -624,3 +624,34 @@ dump_digest(char *msg, u_char *digest, i - fprintf(stderr, "\n"); - } - #endif -+ -+static void -+enc_destroy(Enc *enc) -+{ -+ if (enc == NULL) -+ return; -+ -+ if (enc->key) { -+ memset(enc->key, 0, enc->key_len); -+ xfree(enc->key); -+ } -+ -+ if (enc->iv) { -+ memset(enc->iv, 0, enc->block_size); -+ xfree(enc->iv); -+ } -+ -+ memset(enc, 0, sizeof(*enc)); -+} -+ -+void -+newkeys_destroy(Newkeys *newkeys) -+{ -+ if (newkeys == NULL) -+ return; -+ -+ enc_destroy(&newkeys->enc); -+ mac_destroy(&newkeys->mac); -+ memset(&newkeys->comp, 0, sizeof(newkeys->comp)); -+} -+ -diff -up openssh-6.0p1/kex.h.audit4 openssh-6.0p1/kex.h ---- openssh-6.0p1/kex.h.audit4 2010-09-24 14:11:14.000000000 +0200 -+++ openssh-6.0p1/kex.h 2012-08-06 20:35:56.317789011 +0200 -@@ -156,6 +156,8 @@ void kexgex_server(Kex *); - void kexecdh_client(Kex *); - void kexecdh_server(Kex *); - -+void newkeys_destroy(Newkeys *newkeys); -+ - void - kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int, - BIGNUM *, BIGNUM *, BIGNUM *, u_char **, u_int *); -diff -up openssh-6.0p1/mac.c.audit4 openssh-6.0p1/mac.c ---- openssh-6.0p1/mac.c.audit4 2012-01-17 04:03:38.000000000 +0100 -+++ openssh-6.0p1/mac.c 2012-08-06 20:35:56.318789007 +0200 -@@ -171,6 +171,20 @@ mac_clear(Mac *mac) - mac->umac_ctx = NULL; - } - -+void -+mac_destroy(Mac *mac) -+{ -+ if (mac == NULL) -+ return; -+ -+ if (mac->key) { -+ memset(mac->key, 0, mac->key_len); -+ xfree(mac->key); -+ } -+ -+ memset(mac, 0, sizeof(*mac)); -+} -+ - /* XXX copied from ciphers_valid */ - #define MAC_SEP "," - int -diff -up openssh-6.0p1/mac.h.audit4 openssh-6.0p1/mac.h ---- openssh-6.0p1/mac.h.audit4 2007-06-11 06:01:42.000000000 +0200 -+++ openssh-6.0p1/mac.h 2012-08-06 20:35:56.318789007 +0200 -@@ -28,3 +28,4 @@ int mac_setup(Mac *, char *); - int mac_init(Mac *); - u_char *mac_compute(Mac *, u_int32_t, u_char *, int); - void mac_clear(Mac *); -+void mac_destroy(Mac *); -diff -up openssh-6.0p1/monitor.c.audit4 openssh-6.0p1/monitor.c ---- openssh-6.0p1/monitor.c.audit4 2012-08-06 20:35:56.310789038 +0200 -+++ openssh-6.0p1/monitor.c 2012-08-06 20:35:56.319789003 +0200 -@@ -189,6 +189,7 @@ int mm_answer_audit_command(int, Buffer - int mm_answer_audit_end_command(int, Buffer *); - int mm_answer_audit_unsupported_body(int, Buffer *); - int mm_answer_audit_kex_body(int, Buffer *); -+int mm_answer_audit_session_key_free_body(int, Buffer *); - #endif - - static int monitor_read_log(struct monitor *); -@@ -242,6 +243,7 @@ struct mon_table mon_dispatch_proto20[] - {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, - {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body}, - {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body}, -+ {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body}, - #endif - #ifdef BSD_AUTH - {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery}, -@@ -281,6 +283,7 @@ struct mon_table mon_dispatch_postauth20 - {MONITOR_REQ_AUDIT_END_COMMAND, MON_PERMIT, mm_answer_audit_end_command}, - {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body}, - {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body}, -+ {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body}, - #endif - {0, 0, NULL} - }; -@@ -314,6 +317,7 @@ struct mon_table mon_dispatch_proto15[] - {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, - {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body}, - {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body}, -+ {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body}, - #endif - {0, 0, NULL} - }; -@@ -328,6 +332,7 @@ struct mon_table mon_dispatch_postauth15 - {MONITOR_REQ_AUDIT_END_COMMAND, MON_PERMIT, mm_answer_audit_end_command}, - {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body}, - {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body}, -+ {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body}, - #endif - {0, 0, NULL} - }; -@@ -449,10 +454,6 @@ monitor_child_preauth(Authctxt *_authctx - authenticated = 0; - } - -- /* Drain any buffered messages from the child */ -- while (pmonitor->m_log_recvfd >= 0 && monitor_read_log(pmonitor) == 0) -- ; -- - if (!authctxt->valid) - fatal("%s: authenticated invalid user", __func__); - if (strcmp(auth_method, "unknown") == 0) -@@ -1953,11 +1954,13 @@ mm_get_keystate(struct monitor *pmonitor - - blob = buffer_get_string(&m, &bloblen); - current_keys[MODE_OUT] = mm_newkeys_from_blob(blob, bloblen); -+ memset(blob, 0, bloblen); - xfree(blob); - - debug3("%s: Waiting for second key", __func__); - blob = buffer_get_string(&m, &bloblen); - current_keys[MODE_IN] = mm_newkeys_from_blob(blob, bloblen); -+ memset(blob, 0, bloblen); - xfree(blob); - - /* Now get sequence numbers for the packets */ -@@ -2003,6 +2006,21 @@ mm_get_keystate(struct monitor *pmonitor - } - - buffer_free(&m); -+ -+#ifdef SSH_AUDIT_EVENTS -+ if (compat20) { -+ buffer_init(&m); -+ mm_request_receive_expect(pmonitor->m_sendfd, -+ MONITOR_REQ_AUDIT_SESSION_KEY_FREE, &m); -+ mm_answer_audit_session_key_free_body(pmonitor->m_sendfd, &m); -+ buffer_free(&m); -+ } -+#endif -+ -+ /* Drain any buffered messages from the child */ -+ while (pmonitor->m_log_recvfd >= 0 && monitor_read_log(pmonitor) == 0) -+ ; -+ - } - - -@@ -2449,4 +2467,22 @@ mm_answer_audit_kex_body(int sock, Buffe - return 0; - } - -+int -+mm_answer_audit_session_key_free_body(int sock, Buffer *m) -+{ -+ int ctos; -+ pid_t pid; -+ uid_t uid; -+ -+ ctos = buffer_get_int(m); -+ pid = buffer_get_int64(m); -+ uid = buffer_get_int64(m); -+ -+ audit_session_key_free_body(ctos, pid, uid); -+ -+ buffer_clear(m); -+ -+ mm_request_send(sock, MONITOR_ANS_AUDIT_SESSION_KEY_FREE, m); -+ return 0; -+} - #endif /* SSH_AUDIT_EVENTS */ -diff -up openssh-6.0p1/monitor.h.audit4 openssh-6.0p1/monitor.h ---- openssh-6.0p1/monitor.h.audit4 2012-08-06 20:35:56.310789038 +0200 -+++ openssh-6.0p1/monitor.h 2012-08-06 20:35:56.319789003 +0200 -@@ -63,6 +63,7 @@ enum monitor_reqtype { - MONITOR_ANS_AUDIT_COMMAND, MONITOR_REQ_AUDIT_END_COMMAND, - MONITOR_REQ_AUDIT_UNSUPPORTED, MONITOR_ANS_AUDIT_UNSUPPORTED, - MONITOR_REQ_AUDIT_KEX, MONITOR_ANS_AUDIT_KEX, -+ MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MONITOR_ANS_AUDIT_SESSION_KEY_FREE, - MONITOR_REQ_TERM, - MONITOR_REQ_JPAKE_STEP1, MONITOR_ANS_JPAKE_STEP1, - MONITOR_REQ_JPAKE_GET_PWDATA, MONITOR_ANS_JPAKE_GET_PWDATA, -diff -up openssh-6.0p1/monitor_wrap.c.audit4 openssh-6.0p1/monitor_wrap.c ---- openssh-6.0p1/monitor_wrap.c.audit4 2012-08-06 20:35:56.311789034 +0200 -+++ openssh-6.0p1/monitor_wrap.c 2012-08-06 20:35:56.320788999 +0200 -@@ -653,12 +653,14 @@ mm_send_keystate(struct monitor *monitor - fatal("%s: conversion of newkeys failed", __func__); - - buffer_put_string(&m, blob, bloblen); -+ memset(blob, 0, bloblen); - xfree(blob); - - if (!mm_newkeys_to_blob(MODE_IN, &blob, &bloblen)) - fatal("%s: conversion of newkeys failed", __func__); - - buffer_put_string(&m, blob, bloblen); -+ memset(blob, 0, bloblen); - xfree(blob); - - packet_get_state(MODE_OUT, &seqnr, &blocks, &packets, &bytes); -@@ -1522,4 +1524,19 @@ mm_audit_kex_body(int ctos, char *cipher - - buffer_free(&m); - } -+ -+void -+mm_audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) -+{ -+ Buffer m; -+ -+ buffer_init(&m); -+ buffer_put_int(&m, ctos); -+ buffer_put_int64(&m, pid); -+ buffer_put_int64(&m, uid); -+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SESSION_KEY_FREE, &m); -+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_SESSION_KEY_FREE, -+ &m); -+ buffer_free(&m); -+} - #endif /* SSH_AUDIT_EVENTS */ -diff -up openssh-6.0p1/monitor_wrap.h.audit4 openssh-6.0p1/monitor_wrap.h ---- openssh-6.0p1/monitor_wrap.h.audit4 2012-08-06 20:35:56.311789034 +0200 -+++ openssh-6.0p1/monitor_wrap.h 2012-08-06 20:35:56.320788999 +0200 -@@ -79,6 +79,7 @@ int mm_audit_run_command(const char *); - void mm_audit_end_command(int, const char *); - void mm_audit_unsupported_body(int); - void mm_audit_kex_body(int, char *, char *, char *, pid_t, uid_t); -+void mm_audit_session_key_free_body(int, pid_t, uid_t); - #endif - - struct Session; -diff -up openssh-6.0p1/packet.c.audit4 openssh-6.0p1/packet.c ---- openssh-6.0p1/packet.c.audit4 2012-08-06 20:35:56.282789147 +0200 -+++ openssh-6.0p1/packet.c 2012-08-06 20:35:56.321788995 +0200 -@@ -60,6 +60,7 @@ - #include - - #include "xmalloc.h" -+#include "audit.h" - #include "buffer.h" - #include "packet.h" - #include "crc32.h" -@@ -470,6 +471,13 @@ packet_get_connection_out(void) - return active_state->connection_out; - } - -+static int -+packet_state_has_keys (const struct session_state *state) -+{ -+ return state != NULL && -+ (state->newkeys[MODE_IN] != NULL || state->newkeys[MODE_OUT] != NULL); -+} -+ - /* Closes the connection and clears and frees internal data structures. */ - - void -@@ -478,13 +486,6 @@ packet_close(void) - if (!active_state->initialized) - return; - active_state->initialized = 0; -- if (active_state->connection_in == active_state->connection_out) { -- shutdown(active_state->connection_out, SHUT_RDWR); -- close(active_state->connection_out); -- } else { -- close(active_state->connection_in); -- close(active_state->connection_out); -- } - buffer_free(&active_state->input); - buffer_free(&active_state->output); - buffer_free(&active_state->outgoing_packet); -@@ -493,8 +494,18 @@ packet_close(void) - buffer_free(&active_state->compression_buffer); - buffer_compress_uninit(); - } -- cipher_cleanup(&active_state->send_context); -- cipher_cleanup(&active_state->receive_context); -+ if (packet_state_has_keys(active_state)) { -+ cipher_cleanup(&active_state->send_context); -+ cipher_cleanup(&active_state->receive_context); -+ audit_session_key_free(2); -+ } -+ if (active_state->connection_in == active_state->connection_out) { -+ shutdown(active_state->connection_out, SHUT_RDWR); -+ close(active_state->connection_out); -+ } else { -+ close(active_state->connection_in); -+ close(active_state->connection_out); -+ } - } - - /* Sets remote side protocol flags. */ -@@ -729,6 +740,23 @@ packet_send1(void) - */ - } - -+static void -+newkeys_destroy_and_free(Newkeys *newkeys) -+{ -+ if (newkeys == NULL) -+ return; -+ -+ xfree(newkeys->enc.name); -+ -+ mac_clear(&newkeys->mac); -+ xfree(newkeys->mac.name); -+ -+ xfree(newkeys->comp.name); -+ -+ newkeys_destroy(newkeys); -+ xfree(newkeys); -+} -+ - void - set_newkeys(int mode) - { -@@ -754,18 +782,9 @@ set_newkeys(int mode) - } - if (active_state->newkeys[mode] != NULL) { - debug("set_newkeys: rekeying"); -+ audit_session_key_free(mode); - cipher_cleanup(cc); -- enc = &active_state->newkeys[mode]->enc; -- mac = &active_state->newkeys[mode]->mac; -- comp = &active_state->newkeys[mode]->comp; -- mac_clear(mac); -- xfree(enc->name); -- xfree(enc->iv); -- xfree(enc->key); -- xfree(mac->name); -- xfree(mac->key); -- xfree(comp->name); -- xfree(active_state->newkeys[mode]); -+ newkeys_destroy_and_free(active_state->newkeys[mode]); - } - active_state->newkeys[mode] = kex_get_newkeys(mode); - if (active_state->newkeys[mode] == NULL) -@@ -1921,6 +1940,47 @@ packet_get_newkeys(int mode) - return (void *)active_state->newkeys[mode]; - } - -+static void -+packet_destroy_state(struct session_state *state) -+{ -+ if (state == NULL) -+ return; -+ -+ cipher_cleanup(&state->receive_context); -+ cipher_cleanup(&state->send_context); -+ -+ buffer_free(&state->input); -+ buffer_free(&state->output); -+ buffer_free(&state->outgoing_packet); -+ buffer_free(&state->incoming_packet); -+ buffer_free(&state->compression_buffer); -+ newkeys_destroy_and_free(state->newkeys[MODE_IN]); -+ state->newkeys[MODE_IN] = NULL; -+ newkeys_destroy_and_free(state->newkeys[MODE_OUT]); -+ state->newkeys[MODE_OUT] = NULL; -+ mac_destroy(state->packet_discard_mac); -+// TAILQ_HEAD(, packet) outgoing; -+// memset(state, 0, sizeof(state)); -+} -+ -+void -+packet_destroy_all(int audit_it, int privsep) -+{ -+ if (audit_it) -+ audit_it = packet_state_has_keys (active_state) || -+ packet_state_has_keys (backup_state); -+ packet_destroy_state(active_state); -+ packet_destroy_state(backup_state); -+ if (audit_it) { -+#ifdef SSH_AUDIT_EVENTS -+ if (privsep) -+ audit_session_key_free(2); -+ else -+ audit_session_key_free_body(2, getpid(), getuid()); -+#endif -+ } -+} -+ - /* - * Save the state for the real connection, and use a separate state when - * resuming a suspended connection. -@@ -1928,18 +1988,12 @@ packet_get_newkeys(int mode) - void - packet_backup_state(void) - { -- struct session_state *tmp; -- - close(active_state->connection_in); - active_state->connection_in = -1; - close(active_state->connection_out); - active_state->connection_out = -1; -- if (backup_state) -- tmp = backup_state; -- else -- tmp = alloc_session_state(); - backup_state = active_state; -- active_state = tmp; -+ active_state = alloc_session_state(); - } - - /* -@@ -1956,9 +2010,7 @@ packet_restore_state(void) - backup_state = active_state; - active_state = tmp; - active_state->connection_in = backup_state->connection_in; -- backup_state->connection_in = -1; - active_state->connection_out = backup_state->connection_out; -- backup_state->connection_out = -1; - len = buffer_len(&backup_state->input); - if (len > 0) { - buf = buffer_ptr(&backup_state->input); -@@ -1966,4 +2018,10 @@ packet_restore_state(void) - buffer_clear(&backup_state->input); - add_recv_bytes(len); - } -+ backup_state->connection_in = -1; -+ backup_state->connection_out = -1; -+ packet_destroy_state(backup_state); -+ xfree(backup_state); -+ backup_state = NULL; - } -+ -diff -up openssh-6.0p1/packet.h.audit4 openssh-6.0p1/packet.h ---- openssh-6.0p1/packet.h.audit4 2012-02-10 22:19:21.000000000 +0100 -+++ openssh-6.0p1/packet.h 2012-08-06 20:35:56.321788995 +0200 -@@ -123,4 +123,5 @@ void packet_restore_state(void); - void *packet_get_input(void); - void *packet_get_output(void); - -+void packet_destroy_all(int, int); - #endif /* PACKET_H */ -diff -up openssh-6.0p1/session.c.audit4 openssh-6.0p1/session.c ---- openssh-6.0p1/session.c.audit4 2012-08-06 20:35:56.296789093 +0200 -+++ openssh-6.0p1/session.c 2012-08-06 20:35:56.322788991 +0200 -@@ -1634,6 +1634,9 @@ do_child(Session *s, const char *command - - /* remove hostkey from the child's memory */ - destroy_sensitive_data(); -+ /* Don't audit this - both us and the parent would be talking to the -+ monitor over a single socket, with no synchronization. */ -+ packet_destroy_all(0, 1); - - /* Force a password change */ - if (s->authctxt->force_pwchange) { -diff -up openssh-6.0p1/sshd.c.audit4 openssh-6.0p1/sshd.c ---- openssh-6.0p1/sshd.c.audit4 2012-08-06 20:35:56.312789030 +0200 -+++ openssh-6.0p1/sshd.c 2012-08-06 20:35:56.323788987 +0200 -@@ -690,6 +690,8 @@ privsep_preauth(Authctxt *authctxt) - } - } - -+extern Newkeys *current_keys[]; -+ - static void - privsep_postauth(Authctxt *authctxt) - { -@@ -714,6 +716,10 @@ privsep_postauth(Authctxt *authctxt) - else if (pmonitor->m_pid != 0) { - verbose("User child is on pid %ld", (long)pmonitor->m_pid); - buffer_clear(&loginmsg); -+ newkeys_destroy(current_keys[MODE_OUT]); -+ newkeys_destroy(current_keys[MODE_IN]); -+ audit_session_key_free_body(2, getpid(), getuid()); -+ packet_destroy_all(0, 0); - monitor_child_postauth(pmonitor); - - /* NEVERREACHED */ -@@ -2005,6 +2011,7 @@ main(int ac, char **av) - */ - if (use_privsep) { - mm_send_keystate(pmonitor); -+ packet_destroy_all(1, 1); - exit(0); - } - -@@ -2057,6 +2064,8 @@ main(int ac, char **av) - do_authenticated(authctxt); - - /* The connection has been terminated. */ -+ packet_destroy_all(1, 1); -+ - packet_get_state(MODE_IN, NULL, NULL, NULL, &ibytes); - packet_get_state(MODE_OUT, NULL, NULL, NULL, &obytes); - verbose("Transferred: sent %llu, received %llu bytes", -@@ -2374,6 +2383,16 @@ do_ssh2_kex(void) - void - cleanup_exit(int i) - { -+ static int in_cleanup = 0; -+ int is_privsep_child; -+ -+ /* cleanup_exit can be called at the very least from the privsep -+ wrappers used for auditing. Make sure we don't recurse -+ indefinitely. */ -+ if (in_cleanup) -+ _exit(i); -+ in_cleanup = 1; -+ - if (the_authctxt) { - do_cleanup(the_authctxt); - if (use_privsep && privsep_is_preauth && pmonitor->m_pid > 1) { -@@ -2384,6 +2403,8 @@ cleanup_exit(int i) - pmonitor->m_pid, strerror(errno)); - } - } -+ is_privsep_child = use_privsep && pmonitor != NULL && !mm_is_monitor(); -+ packet_destroy_all(1, is_privsep_child); - #ifdef SSH_AUDIT_EVENTS - /* done after do_cleanup so it can cancel the PAM auth 'thread' */ - if ((the_authctxt == NULL || !the_authctxt->authenticated) && diff --git a/openssh-6.0p1-role-mls.patch b/openssh-6.0p1-role-mls.patch deleted file mode 100644 index e23150f..0000000 --- a/openssh-6.0p1-role-mls.patch +++ /dev/null @@ -1,934 +0,0 @@ -diff -up openssh-6.0p1/auth.h.role-mls openssh-6.0p1/auth.h ---- openssh-6.0p1/auth.h.role-mls 2012-06-24 16:57:17.540262700 +0200 -+++ openssh-6.0p1/auth.h 2012-06-24 16:49:35.802071204 +0200 -@@ -59,6 +59,9 @@ struct Authctxt { - char *service; - struct passwd *pw; /* set if 'valid' */ - char *style; -+#ifdef WITH_SELINUX -+ char *role; -+#endif - void *kbdintctxt; - void *jpake_ctx; - #ifdef BSD_AUTH -diff -up openssh-6.0p1/auth-pam.c.role-mls openssh-6.0p1/auth-pam.c ---- openssh-6.0p1/auth-pam.c.role-mls 2012-06-24 16:57:17.532262382 +0200 -+++ openssh-6.0p1/auth-pam.c 2012-06-24 16:49:35.803071166 +0200 -@@ -1074,7 +1074,7 @@ is_pam_session_open(void) - * during the ssh authentication process. - */ - int --do_pam_putenv(char *name, char *value) -+do_pam_putenv(char *name, const char *value) - { - int ret = 1; - #ifdef HAVE_PAM_PUTENV -diff -up openssh-6.0p1/auth-pam.h.role-mls openssh-6.0p1/auth-pam.h ---- openssh-6.0p1/auth-pam.h.role-mls 2012-06-24 16:57:17.515261702 +0200 -+++ openssh-6.0p1/auth-pam.h 2012-06-24 16:49:35.804071128 +0200 -@@ -38,7 +38,7 @@ void do_pam_session(void); - void do_pam_set_tty(const char *); - void do_pam_setcred(int ); - void do_pam_chauthtok(void); --int do_pam_putenv(char *, char *); -+int do_pam_putenv(char *, const char *); - char ** fetch_pam_environment(void); - char ** fetch_pam_child_environment(void); - void free_pam_environment(char **); -diff -up openssh-6.0p1/auth1.c.role-mls openssh-6.0p1/auth1.c ---- openssh-6.0p1/auth1.c.role-mls 2012-06-24 16:57:17.505261305 +0200 -+++ openssh-6.0p1/auth1.c 2012-06-24 16:49:35.805071090 +0200 -@@ -468,6 +468,9 @@ do_authentication(Authctxt *authctxt) - { - u_int ulen; - char *user, *style = NULL; -+#ifdef WITH_SELINUX -+ char *role=NULL; -+#endif - - /* Get the name of the user that we wish to log in as. */ - packet_read_expect(SSH_CMSG_USER); -@@ -476,11 +479,24 @@ do_authentication(Authctxt *authctxt) - user = packet_get_cstring(&ulen); - packet_check_eom(); - -+#ifdef WITH_SELINUX -+ if ((role = strchr(user, '/')) != NULL) -+ *role++ = '\0'; -+#endif -+ - if ((style = strchr(user, ':')) != NULL) - *style++ = '\0'; -+#ifdef WITH_SELINUX -+ else -+ if (role && (style = strchr(role, ':')) != NULL) -+ *style++ = '\0'; -+#endif - - authctxt->user = user; - authctxt->style = style; -+#ifdef WITH_SELINUX -+ authctxt->role = role; -+#endif - - /* Verify that the user is a valid user. */ - if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL) -diff -up openssh-6.0p1/auth2.c.role-mls openssh-6.0p1/auth2.c ---- openssh-6.0p1/auth2.c.role-mls 2012-06-24 16:57:17.507261384 +0200 -+++ openssh-6.0p1/auth2.c 2012-06-24 16:49:35.806071052 +0200 -@@ -216,6 +216,9 @@ input_userauth_request(int type, u_int32 - Authctxt *authctxt = ctxt; - Authmethod *m = NULL; - char *user, *service, *method, *active_methods, *style = NULL; -+#ifdef WITH_SELINUX -+ char *role = NULL; -+#endif - int authenticated = 0; - - if (authctxt == NULL) -@@ -227,6 +230,11 @@ input_userauth_request(int type, u_int32 - debug("userauth-request for user %s service %s method %s", user, service, method); - debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); - -+#ifdef WITH_SELINUX -+ if ((role = strchr(user, '/')) != NULL) -+ *role++ = 0; -+#endif -+ - if ((style = strchr(user, ':')) != NULL) - *style++ = 0; - -@@ -249,8 +257,15 @@ input_userauth_request(int type, u_int32 - use_privsep ? " [net]" : ""); - authctxt->service = xstrdup(service); - authctxt->style = style ? xstrdup(style) : NULL; -- if (use_privsep) -+#ifdef WITH_SELINUX -+ authctxt->role = role ? xstrdup(role) : NULL; -+#endif -+ if (use_privsep) { - mm_inform_authserv(service, style); -+#ifdef WITH_SELINUX -+ mm_inform_authrole(role); -+#endif -+ } - userauth_banner(); - } else if (strcmp(user, authctxt->user) != 0 || - strcmp(service, authctxt->service) != 0) { -diff -up openssh-6.0p1/auth2-gss.c.role-mls openssh-6.0p1/auth2-gss.c ---- openssh-6.0p1/auth2-gss.c.role-mls 2012-06-24 16:57:17.522261982 +0200 -+++ openssh-6.0p1/auth2-gss.c 2012-06-24 16:49:35.806071052 +0200 -@@ -260,6 +260,7 @@ input_gssapi_mic(int type, u_int32_t ple - Authctxt *authctxt = ctxt; - Gssctxt *gssctxt; - int authenticated = 0; -+ char *micuser; - Buffer b; - gss_buffer_desc mic, gssbuf; - u_int len; -@@ -272,7 +273,13 @@ input_gssapi_mic(int type, u_int32_t ple - mic.value = packet_get_string(&len); - mic.length = len; - -- ssh_gssapi_buildmic(&b, authctxt->user, authctxt->service, -+#ifdef WITH_SELINUX -+ if (authctxt->role && (strlen(authctxt->role) > 0)) -+ xasprintf(&micuser, "%s/%s", authctxt->user, authctxt->role); -+ else -+#endif -+ micuser = authctxt->user; -+ ssh_gssapi_buildmic(&b, micuser, authctxt->service, - "gssapi-with-mic"); - - gssbuf.value = buffer_ptr(&b); -@@ -284,6 +291,8 @@ input_gssapi_mic(int type, u_int32_t ple - logit("GSSAPI MIC check failed"); - - buffer_free(&b); -+ if (micuser != authctxt->user) -+ xfree(micuser); - xfree(mic.value); - - authctxt->postponed = 0; -diff -up openssh-6.0p1/auth2-hostbased.c.role-mls openssh-6.0p1/auth2-hostbased.c ---- openssh-6.0p1/auth2-hostbased.c.role-mls 2012-06-24 16:57:17.535262501 +0200 -+++ openssh-6.0p1/auth2-hostbased.c 2012-06-24 16:49:35.807071014 +0200 -@@ -106,7 +106,15 @@ userauth_hostbased(Authctxt *authctxt) - buffer_put_string(&b, session_id2, session_id2_len); - /* reconstruct packet */ - buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); -- buffer_put_cstring(&b, authctxt->user); -+#ifdef WITH_SELINUX -+ if (authctxt->role) { -+ buffer_put_int(&b, strlen(authctxt->user)+strlen(authctxt->role)+1); -+ buffer_append(&b, authctxt->user, strlen(authctxt->user)); -+ buffer_put_char(&b, '/'); -+ buffer_append(&b, authctxt->role, strlen(authctxt->role)); -+ } else -+#endif -+ buffer_put_cstring(&b, authctxt->user); - buffer_put_cstring(&b, service); - buffer_put_cstring(&b, "hostbased"); - buffer_put_string(&b, pkalg, alen); -diff -up openssh-6.0p1/auth2-pubkey.c.role-mls openssh-6.0p1/auth2-pubkey.c ---- openssh-6.0p1/auth2-pubkey.c.role-mls 2012-06-24 16:57:17.517261782 +0200 -+++ openssh-6.0p1/auth2-pubkey.c 2012-06-24 16:49:35.807071014 +0200 -@@ -121,7 +121,15 @@ userauth_pubkey(Authctxt *authctxt) - } - /* reconstruct packet */ - buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); -- buffer_put_cstring(&b, authctxt->user); -+#ifdef WITH_SELINUX -+ if (authctxt->role) { -+ buffer_put_int(&b, strlen(authctxt->user)+strlen(authctxt->role)+1); -+ buffer_append(&b, authctxt->user, strlen(authctxt->user)); -+ buffer_put_char(&b, '/'); -+ buffer_append(&b, authctxt->role, strlen(authctxt->role)); -+ } else -+#endif -+ buffer_put_cstring(&b, authctxt->user); - buffer_put_cstring(&b, - datafellows & SSH_BUG_PKSERVICE ? - "ssh-userauth" : -diff -up openssh-6.0p1/misc.c.role-mls openssh-6.0p1/misc.c ---- openssh-6.0p1/misc.c.role-mls 2012-06-24 17:02:27.116348979 +0200 -+++ openssh-6.0p1/misc.c 2012-06-24 16:58:09.631883672 +0200 -@@ -427,6 +427,7 @@ char * - colon(char *cp) - { - int flag = 0; -+ int start = 1; - - if (*cp == ':') /* Leading colon is part of file name. */ - return NULL; -@@ -442,6 +443,13 @@ colon(char *cp) - return (cp); - if (*cp == '/') - return NULL; -+ if (start) { -+ /* Slash on beginning or after dots only denotes file name. */ -+ if (*cp == '/') -+ return (0); -+ if (*cp != '.') -+ start = 0; -+ } - } - return NULL; - } -diff -up openssh-6.0p1/monitor.c.role-mls openssh-6.0p1/monitor.c ---- openssh-6.0p1/monitor.c.role-mls 2012-06-24 16:57:17.510261504 +0200 -+++ openssh-6.0p1/monitor.c 2012-06-24 16:49:35.809070938 +0200 -@@ -148,6 +148,9 @@ int mm_answer_sign(int, Buffer *); - int mm_answer_pwnamallow(int, Buffer *); - int mm_answer_auth2_read_banner(int, Buffer *); - int mm_answer_authserv(int, Buffer *); -+#ifdef WITH_SELINUX -+int mm_answer_authrole(int, Buffer *); -+#endif - int mm_answer_authpassword(int, Buffer *); - int mm_answer_bsdauthquery(int, Buffer *); - int mm_answer_bsdauthrespond(int, Buffer *); -@@ -232,6 +235,9 @@ struct mon_table mon_dispatch_proto20[] - {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, - {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, - {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, -+#ifdef WITH_SELINUX -+ {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole}, -+#endif - {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, - {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, - #ifdef USE_PAM -@@ -835,6 +841,9 @@ mm_answer_pwnamallow(int sock, Buffer *m - else { - /* Allow service/style information on the auth context */ - monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); -+#ifdef WITH_SELINUX -+ monitor_permit(mon_dispatch, MONITOR_REQ_AUTHROLE, 1); -+#endif - monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); - } - #ifdef USE_PAM -@@ -878,6 +887,25 @@ mm_answer_authserv(int sock, Buffer *m) - return (0); - } - -+#ifdef WITH_SELINUX -+int -+mm_answer_authrole(int sock, Buffer *m) -+{ -+ monitor_permit_authentications(1); -+ -+ authctxt->role = buffer_get_string(m, NULL); -+ debug3("%s: role=%s", -+ __func__, authctxt->role); -+ -+ if (strlen(authctxt->role) == 0) { -+ xfree(authctxt->role); -+ authctxt->role = NULL; -+ } -+ -+ return (0); -+} -+#endif -+ - int - mm_answer_authpassword(int sock, Buffer *m) - { -@@ -1254,7 +1282,7 @@ static int - monitor_valid_userblob(u_char *data, u_int datalen) - { - Buffer b; -- char *p; -+ char *p, *r; - u_int len; - int fail = 0; - -@@ -1280,6 +1308,8 @@ monitor_valid_userblob(u_char *data, u_i - if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) - fail++; - p = buffer_get_string(&b, NULL); -+ if ((r = strchr(p, '/')) != NULL) -+ *r = '\0'; - if (strcmp(authctxt->user, p) != 0) { - logit("wrong user name passed to monitor: expected %s != %.100s", - authctxt->user, p); -@@ -1311,7 +1341,7 @@ monitor_valid_hostbasedblob(u_char *data - char *chost) - { - Buffer b; -- char *p; -+ char *p, *r; - u_int len; - int fail = 0; - -@@ -1328,6 +1358,8 @@ monitor_valid_hostbasedblob(u_char *data - if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) - fail++; - p = buffer_get_string(&b, NULL); -+ if ((r = strchr(p, '/')) != NULL) -+ *r = '\0'; - if (strcmp(authctxt->user, p) != 0) { - logit("wrong user name passed to monitor: expected %s != %.100s", - authctxt->user, p); -diff -up openssh-6.0p1/monitor.h.role-mls openssh-6.0p1/monitor.h ---- openssh-6.0p1/monitor.h.role-mls 2012-06-24 16:57:17.520261902 +0200 -+++ openssh-6.0p1/monitor.h 2012-06-24 16:49:35.809070938 +0200 -@@ -31,6 +31,9 @@ - enum monitor_reqtype { - MONITOR_REQ_MODULI, MONITOR_ANS_MODULI, - MONITOR_REQ_FREE, MONITOR_REQ_AUTHSERV, -+#ifdef WITH_SELINUX -+ MONITOR_REQ_AUTHROLE, -+#endif - MONITOR_REQ_SIGN, MONITOR_ANS_SIGN, - MONITOR_REQ_PWNAM, MONITOR_ANS_PWNAM, - MONITOR_REQ_AUTH2_READ_BANNER, MONITOR_ANS_AUTH2_READ_BANNER, -diff -up openssh-6.0p1/monitor_wrap.c.role-mls openssh-6.0p1/monitor_wrap.c ---- openssh-6.0p1/monitor_wrap.c.role-mls 2012-06-24 16:57:17.537262580 +0200 -+++ openssh-6.0p1/monitor_wrap.c 2012-06-24 16:49:35.810070900 +0200 -@@ -336,6 +336,25 @@ mm_inform_authserv(char *service, char * - buffer_free(&m); - } - -+/* Inform the privileged process about role */ -+ -+#ifdef WITH_SELINUX -+void -+mm_inform_authrole(char *role) -+{ -+ Buffer m; -+ -+ debug3("%s entering", __func__); -+ -+ buffer_init(&m); -+ buffer_put_cstring(&m, role ? role : ""); -+ -+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHROLE, &m); -+ -+ buffer_free(&m); -+} -+#endif -+ - /* Do the password authentication */ - int - mm_auth_password(Authctxt *authctxt, char *password) -diff -up openssh-6.0p1/monitor_wrap.h.role-mls openssh-6.0p1/monitor_wrap.h ---- openssh-6.0p1/monitor_wrap.h.role-mls 2012-06-24 16:57:17.513261623 +0200 -+++ openssh-6.0p1/monitor_wrap.h 2012-06-24 16:49:35.811070862 +0200 -@@ -42,6 +42,9 @@ int mm_is_monitor(void); - DH *mm_choose_dh(int, int, int); - int mm_key_sign(Key *, u_char **, u_int *, u_char *, u_int); - void mm_inform_authserv(char *, char *); -+#ifdef WITH_SELINUX -+void mm_inform_authrole(char *); -+#endif - struct passwd *mm_getpwnamallow(const char *); - char *mm_auth2_read_banner(void); - int mm_auth_password(struct Authctxt *, char *); -diff -up openssh-6.0p1/openbsd-compat/Makefile.in.role-mls openssh-6.0p1/openbsd-compat/Makefile.in ---- openssh-6.0p1/openbsd-compat/Makefile.in.role-mls 2012-06-24 16:57:17.525262102 +0200 -+++ openssh-6.0p1/openbsd-compat/Makefile.in 2012-06-24 16:51:38.087889399 +0200 -@@ -20,7 +20,7 @@ OPENBSD=base64.o basename.o bindresvport - - COMPAT=bsd-arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o - --PORTS=port-aix.o port-irix.o port-linux.o port-solaris.o port-tun.o port-uw.o -+PORTS=port-aix.o port-irix.o port-linux.o port-linux_part_2.o port-solaris.o port-tun.o port-uw.o - - .c.o: - $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -diff -up openssh-6.0p1/openbsd-compat/port-linux.c.role-mls openssh-6.0p1/openbsd-compat/port-linux.c ---- openssh-6.0p1/openbsd-compat/port-linux.c.role-mls 2012-06-24 16:57:17.527262182 +0200 -+++ openssh-6.0p1/openbsd-compat/port-linux.c 2012-06-24 17:00:55.621978528 +0200 -@@ -31,68 +31,271 @@ - - #include "log.h" - #include "xmalloc.h" -+#include "servconf.h" - #include "port-linux.h" -+#include "key.h" -+#include "hostfile.h" -+#include "auth.h" - - #ifdef WITH_SELINUX - #include - #include -+#include - #include -+#include -+#include -+ -+#ifdef HAVE_LINUX_AUDIT -+#include -+#include -+#endif - - #ifndef SSH_SELINUX_UNCONFINED_TYPE - # define SSH_SELINUX_UNCONFINED_TYPE ":unconfined_t:" - #endif - --/* Wrapper around is_selinux_enabled() to log its return value once only */ --int --ssh_selinux_enabled(void) -+extern ServerOptions options; -+extern Authctxt *the_authctxt; -+extern int inetd_flag; -+extern int rexeced_flag; -+ -+/* Send audit message */ -+static int -+send_audit_message(int success, security_context_t default_context, -+ security_context_t selected_context) -+{ -+ int rc=0; -+#ifdef HAVE_LINUX_AUDIT -+ char *msg = NULL; -+ int audit_fd = audit_open(); -+ security_context_t default_raw=NULL; -+ security_context_t selected_raw=NULL; -+ rc = -1; -+ if (audit_fd < 0) { -+ if (errno == EINVAL || errno == EPROTONOSUPPORT || -+ errno == EAFNOSUPPORT) -+ return 0; /* No audit support in kernel */ -+ error("Error connecting to audit system."); -+ return rc; -+ } -+ if (selinux_trans_to_raw_context(default_context, &default_raw) < 0) { -+ error("Error translating default context."); -+ default_raw = NULL; -+ } -+ if (selinux_trans_to_raw_context(selected_context, &selected_raw) < 0) { -+ error("Error translating selected context."); -+ selected_raw = NULL; -+ } -+ if (asprintf(&msg, "sshd: default-context=%s selected-context=%s", -+ default_raw ? default_raw : (default_context ? default_context: "?"), -+ selected_context ? selected_raw : (selected_context ? selected_context :"?")) < 0) { -+ error("Error allocating memory."); -+ goto out; -+ } -+ if (audit_log_user_message(audit_fd, AUDIT_USER_ROLE_CHANGE, -+ msg, NULL, NULL, NULL, success) <= 0) { -+ error("Error sending audit message."); -+ goto out; -+ } -+ rc = 0; -+ out: -+ free(msg); -+ freecon(default_raw); -+ freecon(selected_raw); -+ close(audit_fd); -+#endif -+ return rc; -+} -+ -+static int -+mls_range_allowed(security_context_t src, security_context_t dst) - { -- static int enabled = -1; -+ struct av_decision avd; -+ int retval; -+ unsigned int bit = CONTEXT__CONTAINS; -+ -+ debug("%s: src:%s dst:%s", __func__, src, dst); -+ retval = security_compute_av(src, dst, SECCLASS_CONTEXT, bit, &avd); -+ if (retval || ((bit & avd.allowed) != bit)) -+ return 0; -+ -+ return 1; -+} -+ -+static int -+get_user_context(const char *sename, const char *role, const char *lvl, -+ security_context_t *sc) { -+#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL -+ if (lvl == NULL || lvl[0] == '\0' || get_default_context_with_level(sename, lvl, NULL, sc) != 0) { -+ /* User may have requested a level completely outside of his -+ allowed range. We get a context just for auditing as the -+ range check below will certainly fail for default context. */ -+#endif -+ if (get_default_context(sename, NULL, sc) != 0) { -+ *sc = NULL; -+ return -1; -+ } -+#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL -+ } -+#endif -+ if (role != NULL && role[0]) { -+ context_t con; -+ char *type=NULL; -+ if (get_default_type(role, &type) != 0) { -+ error("get_default_type: failed to get default type for '%s'", -+ role); -+ goto out; -+ } -+ con = context_new(*sc); -+ if (!con) { -+ goto out; -+ } -+ context_role_set(con, role); -+ context_type_set(con, type); -+ freecon(*sc); -+ *sc = strdup(context_str(con)); -+ context_free(con); -+ if (!*sc) -+ return -1; -+ } -+#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL -+ if (lvl != NULL && lvl[0]) { -+ /* verify that the requested range is obtained */ -+ context_t con; -+ security_context_t obtained_raw; -+ security_context_t requested_raw; -+ con = context_new(*sc); -+ if (!con) { -+ goto out; -+ } -+ context_range_set(con, lvl); -+ if (selinux_trans_to_raw_context(*sc, &obtained_raw) < 0) { -+ context_free(con); -+ goto out; -+ } -+ if (selinux_trans_to_raw_context(context_str(con), &requested_raw) < 0) { -+ freecon(obtained_raw); -+ context_free(con); -+ goto out; -+ } - -- if (enabled == -1) { -- enabled = (is_selinux_enabled() == 1); -- debug("SELinux support %s", enabled ? "enabled" : "disabled"); -+ debug("get_user_context: obtained context '%s' requested context '%s'", -+ obtained_raw, requested_raw); -+ if (strcmp(obtained_raw, requested_raw)) { -+ /* set the context to the real requested one but fail */ -+ freecon(requested_raw); -+ freecon(obtained_raw); -+ freecon(*sc); -+ *sc = strdup(context_str(con)); -+ context_free(con); -+ return -1; -+ } -+ freecon(requested_raw); -+ freecon(obtained_raw); -+ context_free(con); - } -+#endif -+ return 0; -+ out: -+ freecon(*sc); -+ *sc = NULL; -+ return -1; -+} - -- return (enabled); -+static void -+ssh_selinux_get_role_level(char **role, const char **level) -+{ -+ *role = NULL; -+ *level = NULL; -+ if (the_authctxt) { -+ if (the_authctxt->role != NULL) { -+ char *slash; -+ *role = xstrdup(the_authctxt->role); -+ if ((slash = strchr(*role, '/')) != NULL) { -+ *slash = '\0'; -+ *level = slash + 1; -+ } -+ } -+ } - } - - /* Return the default security context for the given username */ - static security_context_t --ssh_selinux_getctxbyname(char *pwname) -+ssh_selinux_getctxbyname(char *pwname, -+ security_context_t *default_sc, security_context_t *user_sc) - { -- security_context_t sc = NULL; -- char *sename = NULL, *lvl = NULL; -- int r; -+ char *sename, *lvl; -+ char *role; -+ const char *reqlvl; -+ int r = 0; -+ context_t con = NULL; -+ -+ ssh_selinux_get_role_level(&role, &reqlvl); - - #ifdef HAVE_GETSEUSERBYNAME -- if (getseuserbyname(pwname, &sename, &lvl) != 0) -- return NULL; -+ if ((r=getseuserbyname(pwname, &sename, &lvl)) != 0) { -+ sename = NULL; -+ lvl = NULL; -+ } - #else - sename = pwname; -- lvl = NULL; -+ lvl = ""; - #endif - -+ if (r == 0) { - #ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL -- r = get_default_context_with_level(sename, lvl, NULL, &sc); -+ r = get_default_context_with_level(sename, lvl, NULL, default_sc); - #else -- r = get_default_context(sename, NULL, &sc); -+ r = get_default_context(sename, NULL, default_sc); - #endif -+ } -+ -+ if (r == 0) { -+ /* If launched from xinetd, we must use current level */ -+ if (inetd_flag && !rexeced_flag) { -+ security_context_t sshdsc=NULL; -+ -+ if (getcon_raw(&sshdsc) < 0) -+ fatal("failed to allocate security context"); -+ -+ if ((con=context_new(sshdsc)) == NULL) -+ fatal("failed to allocate selinux context"); -+ reqlvl = context_range_get(con); -+ freecon(sshdsc); -+ if (reqlvl !=NULL && lvl != NULL && strcmp(reqlvl, lvl) == 0) -+ /* we actually don't change level */ -+ reqlvl = ""; -+ -+ debug("%s: current connection level '%s'", __func__, reqlvl); - -- if (r != 0) { -- switch (security_getenforce()) { -- case -1: -- fatal("%s: ssh_selinux_getctxbyname: " -- "security_getenforce() failed", __func__); -- case 0: -- error("%s: Failed to get default SELinux security " -- "context for %s", __func__, pwname); -- sc = NULL; -- break; -- default: -- fatal("%s: Failed to get default SELinux security " -- "context for %s (in enforcing mode)", -- __func__, pwname); - } -+ -+ if ((reqlvl != NULL && reqlvl[0]) || (role != NULL && role[0])) { -+ r = get_user_context(sename, role, reqlvl, user_sc); -+ -+ if (r == 0 && reqlvl != NULL && reqlvl[0]) { -+ security_context_t default_level_sc = *default_sc; -+ if (role != NULL && role[0]) { -+ if (get_user_context(sename, role, lvl, &default_level_sc) < 0) -+ default_level_sc = *default_sc; -+ } -+ /* verify that the requested range is contained in the user range */ -+ if (mls_range_allowed(default_level_sc, *user_sc)) { -+ logit("permit MLS level %s (user range %s)", reqlvl, lvl); -+ } else { -+ r = -1; -+ error("deny MLS level %s (user range %s)", reqlvl, lvl); -+ } -+ if (default_level_sc != *default_sc) -+ freecon(default_level_sc); -+ } -+ } else { -+ *user_sc = *default_sc; -+ } -+ } -+ if (r != 0) { -+ error("%s: Failed to get default SELinux security " -+ "context for %s", __func__, pwname); - } - - #ifdef HAVE_GETSEUSERBYNAME -@@ -102,7 +305,42 @@ ssh_selinux_getctxbyname(char *pwname) - xfree(lvl); - #endif - -- return sc; -+ if (role != NULL) -+ xfree(role); -+ if (con) -+ context_free(con); -+ -+ return (r); -+} -+ -+/* Setup environment variables for pam_selinux */ -+static int -+ssh_selinux_setup_pam_variables(void) -+{ -+ const char *reqlvl; -+ char *role; -+ char *use_current; -+ int rv; -+ -+ debug3("%s: setting execution context", __func__); -+ -+ ssh_selinux_get_role_level(&role, &reqlvl); -+ -+ rv = do_pam_putenv("SELINUX_ROLE_REQUESTED", role ? role : ""); -+ -+ if (inetd_flag && !rexeced_flag) { -+ use_current = "1"; -+ } else { -+ use_current = ""; -+ rv = rv || do_pam_putenv("SELINUX_LEVEL_REQUESTED", reqlvl ? reqlvl: ""); -+ } -+ -+ rv = rv || do_pam_putenv("SELINUX_USE_CURRENT_RANGE", use_current); -+ -+ if (role != NULL) -+ xfree(role); -+ -+ return rv; - } - - /* Set the execution context to the default for the specified user */ -@@ -110,28 +348,71 @@ void - ssh_selinux_setup_exec_context(char *pwname) - { - security_context_t user_ctx = NULL; -+ int r = 0; -+ security_context_t default_ctx = NULL; - - if (!ssh_selinux_enabled()) - return; - -+ if (options.use_pam) { -+ /* do not compute context, just setup environment for pam_selinux */ -+ if (ssh_selinux_setup_pam_variables()) { -+ switch (security_getenforce()) { -+ case -1: -+ fatal("%s: security_getenforce() failed", __func__); -+ case 0: -+ error("%s: SELinux PAM variable setup failure. Continuing in permissive mode.", -+ __func__); -+ break; -+ default: -+ fatal("%s: SELinux PAM variable setup failure. Aborting connection.", -+ __func__); -+ } -+ } -+ return; -+ } -+ - debug3("%s: setting execution context", __func__); - -- user_ctx = ssh_selinux_getctxbyname(pwname); -- if (setexeccon(user_ctx) != 0) { -+ r = ssh_selinux_getctxbyname(pwname, &default_ctx, &user_ctx); -+ if (r >= 0) { -+ r = setexeccon(user_ctx); -+ if (r < 0) { -+ error("%s: Failed to set SELinux execution context %s for %s", -+ __func__, user_ctx, pwname); -+ } -+#ifdef HAVE_SETKEYCREATECON -+ else if (setkeycreatecon(user_ctx) < 0) { -+ error("%s: Failed to set SELinux keyring creation context %s for %s", -+ __func__, user_ctx, pwname); -+ } -+#endif -+ } -+ if (user_ctx == NULL) { -+ user_ctx = default_ctx; -+ } -+ if (r < 0 || user_ctx != default_ctx) { -+ /* audit just the case when user changed a role or there was -+ a failure */ -+ send_audit_message(r >= 0, default_ctx, user_ctx); -+ } -+ if (r < 0) { - switch (security_getenforce()) { - case -1: - fatal("%s: security_getenforce() failed", __func__); - case 0: -- error("%s: Failed to set SELinux execution " -- "context for %s", __func__, pwname); -+ error("%s: SELinux failure. Continuing in permissive mode.", -+ __func__); - break; - default: -- fatal("%s: Failed to set SELinux execution context " -- "for %s (in enforcing mode)", __func__, pwname); -+ fatal("%s: SELinux failure. Aborting connection.", -+ __func__); - } - } -- if (user_ctx != NULL) -+ if (user_ctx != NULL && user_ctx != default_ctx) - freecon(user_ctx); -+ if (default_ctx != NULL) -+ freecon(default_ctx); - - debug3("%s: done", __func__); - } -@@ -149,7 +430,10 @@ ssh_selinux_setup_pty(char *pwname, cons - - debug3("%s: setting TTY context on %s", __func__, tty); - -- user_ctx = ssh_selinux_getctxbyname(pwname); -+ if (getexeccon(&user_ctx) < 0) { -+ error("%s: getexeccon: %s", __func__, strerror(errno)); -+ goto out; -+ } - - /* XXX: should these calls fatal() upon failure in enforcing mode? */ - -@@ -221,21 +505,6 @@ ssh_selinux_change_context(const char *n - xfree(newctx); - } - --void --ssh_selinux_setfscreatecon(const char *path) --{ -- security_context_t context; -- -- if (!ssh_selinux_enabled()) -- return; -- if (path == NULL) { -- setfscreatecon(NULL); -- return; -- } -- if (matchpathcon(path, 0700, &context) == 0) -- setfscreatecon(context); --} -- - #endif /* WITH_SELINUX */ - - #ifdef LINUX_OOM_ADJUST -diff -up openssh-6.0p1/openbsd-compat/port-linux_part_2.c.role-mls openssh-6.0p1/openbsd-compat/port-linux_part_2.c ---- openssh-6.0p1/openbsd-compat/port-linux_part_2.c.role-mls 2012-06-24 16:57:17.530262302 +0200 -+++ openssh-6.0p1/openbsd-compat/port-linux_part_2.c 2012-06-24 16:49:35.813070786 +0200 -@@ -0,0 +1,75 @@ -+/* $Id: port-linux.c,v 1.11.4.2 2011/02/04 00:43:08 djm Exp $ */ -+ -+/* -+ * Copyright (c) 2005 Daniel Walsh -+ * Copyright (c) 2006 Damien Miller -+ * -+ * Permission to use, copy, modify, and distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+/* -+ * Linux-specific portability code - just SELinux support at present -+ */ -+ -+#include "includes.h" -+ -+#if defined(WITH_SELINUX) || defined(LINUX_OOM_ADJUST) -+#include -+#include -+#include -+#include -+ -+#include "log.h" -+#include "xmalloc.h" -+#include "port-linux.h" -+#include "key.h" -+#include "hostfile.h" -+#include "auth.h" -+ -+#ifdef WITH_SELINUX -+#include -+#include -+#include -+ -+/* Wrapper around is_selinux_enabled() to log its return value once only */ -+int -+ssh_selinux_enabled(void) -+{ -+ static int enabled = -1; -+ -+ if (enabled == -1) { -+ enabled = (is_selinux_enabled() == 1); -+ debug("SELinux support %s", enabled ? "enabled" : "disabled"); -+ } -+ -+ return (enabled); -+} -+ -+void -+ssh_selinux_setfscreatecon(const char *path) -+{ -+ security_context_t context; -+ -+ if (!ssh_selinux_enabled()) -+ return; -+ if (path == NULL) { -+ setfscreatecon(NULL); -+ return; -+ } -+ if (matchpathcon(path, 0700, &context) == 0) -+ setfscreatecon(context); -+} -+ -+#endif /* WITH_SELINUX */ -+ -+#endif /* WITH_SELINUX || LINUX_OOM_ADJUST */ -diff -up openssh-6.0p1/sshd.c.role-mls openssh-6.0p1/sshd.c ---- openssh-6.0p1/sshd.c.role-mls 2012-06-24 17:02:56.543257378 +0200 -+++ openssh-6.0p1/sshd.c 2012-06-24 16:58:09.634883844 +0200 -@@ -2090,6 +2090,9 @@ main(int ac, char **av) - restore_uid(); - } - #endif -+#ifdef WITH_SELINUX -+ ssh_selinux_setup_exec_context(authctxt->pw->pw_name); -+#endif - #ifdef USE_PAM - if (options.use_pam) { - do_pam_setcred(1); diff --git a/openssh-6.1p1-akc.patch b/openssh-6.1p1-akc.patch index bf7a313..0401ba0 100644 --- a/openssh-6.1p1-akc.patch +++ b/openssh-6.1p1-akc.patch @@ -1,110 +1,6 @@ -diff -up openssh-6.1p1/auth.c.akc openssh-6.1p1/auth.c ---- openssh-6.1p1/auth.c.akc 2012-11-02 14:00:49.181077248 +0100 -+++ openssh-6.1p1/auth.c 2012-11-02 14:00:49.253077860 +0100 -@@ -413,39 +413,41 @@ check_key_in_hostfiles(struct passwd *pw - - - /* -- * Check a given file for security. This is defined as all components -+ * Check a given path for security. This is defined as all components - * of the path to the file must be owned by either the owner of - * of the file or root and no directories must be group or world writable. - * - * XXX Should any specific check be done for sym links ? - * -- * Takes an open file descriptor, the file name, a uid and and -+ * Takes an the file name, its stat information (preferably from fstat() to -+ * avoid races), the uid of the expected owner, their home directory and an - * error buffer plus max size as arguments. - * - * Returns 0 on success and -1 on failure - */ --static int --secure_filename(FILE *f, const char *file, struct passwd *pw, -- char *err, size_t errlen) -+int -+auth_secure_path(const char *name, struct stat *stp, const char *pw_dir, -+ uid_t uid, char *err, size_t errlen) - { -- uid_t uid = pw->pw_uid; - char buf[MAXPATHLEN], homedir[MAXPATHLEN]; - char *cp; - int comparehome = 0; - struct stat st; - -- if (realpath(file, buf) == NULL) { -- snprintf(err, errlen, "realpath %s failed: %s", file, -+ if (realpath(name, buf) == NULL) { -+ snprintf(err, errlen, "realpath %s failed: %s", name, - strerror(errno)); - return -1; - } -- if (realpath(pw->pw_dir, homedir) != NULL) -+ if (pw_dir != NULL && realpath(pw_dir, homedir) != NULL) - comparehome = 1; - -- /* check the open file to avoid races */ -- if (fstat(fileno(f), &st) < 0 || -- (st.st_uid != 0 && st.st_uid != uid) || -- (st.st_mode & 022) != 0) { -+ if (!S_ISREG(stp->st_mode)) { -+ snprintf(err, errlen, "%s is not a regular file", buf); -+ return -1; -+ } -+ if ((stp->st_uid != 0 && stp->st_uid != uid) || -+ (stp->st_mode & 022) != 0) { - snprintf(err, errlen, "bad ownership or modes for file %s", - buf); - return -1; -@@ -481,6 +483,31 @@ secure_filename(FILE *f, const char *fil - return 0; - } - -+/* -+ * Version of secure_path() that accepts an open file descriptor to -+ * avoid races. -+ * -+ * Returns 0 on success and -1 on failure -+ */ -+static int -+secure_filename(FILE *f, const char *file, struct passwd *pw, -+ char *err, size_t errlen) -+{ -+ uid_t uid = pw->pw_uid; -+ char buf[MAXPATHLEN], homedir[MAXPATHLEN]; -+ char *cp; -+ int comparehome = 0; -+ struct stat st; -+ -+ /* check the open file to avoid races */ -+ if (fstat(fileno(f), &st) < 0) { -+ snprintf(err, errlen, "cannot stat file %s: %s", -+ buf, strerror(errno)); -+ return -1; -+ } -+ return auth_secure_path(file, &st, pw->pw_dir, pw->pw_uid, err, errlen); -+} -+ - static FILE * - auth_openfile(const char *file, struct passwd *pw, int strict_modes, - int log_missing, char *file_type) -diff -up openssh-6.1p1/auth.h.akc openssh-6.1p1/auth.h ---- openssh-6.1p1/auth.h.akc 2012-11-02 14:00:49.239077742 +0100 -+++ openssh-6.1p1/auth.h 2012-11-02 14:00:49.253077860 +0100 -@@ -123,6 +123,10 @@ int auth_rhosts_rsa_key_allowed(struct - int hostbased_key_allowed(struct passwd *, const char *, char *, Key *); - int user_key_allowed(struct passwd *, Key *); - -+struct stat; -+int auth_secure_path(const char *, struct stat *, const char *, uid_t, -+ char *, size_t); -+ - #ifdef KRB5 - int auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *); - int auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt); diff -up openssh-6.1p1/auth2-pubkey.c.akc openssh-6.1p1/auth2-pubkey.c ---- openssh-6.1p1/auth2-pubkey.c.akc 2012-11-02 14:00:49.241077758 +0100 -+++ openssh-6.1p1/auth2-pubkey.c 2012-11-02 14:00:49.252077852 +0100 +--- openssh-6.1p1/auth2-pubkey.c.akc 2012-11-28 17:12:43.238524384 +0100 ++++ openssh-6.1p1/auth2-pubkey.c 2012-11-28 17:12:43.263524297 +0100 @@ -27,9 +27,13 @@ #include @@ -361,10 +257,114 @@ diff -up openssh-6.1p1/auth2-pubkey.c.akc openssh-6.1p1/auth2-pubkey.c for (i = 0; !success && i < options.num_authkeys_files; i++) { file = expand_authorized_keys( options.authorized_keys_files[i], pw); +diff -up openssh-6.1p1/auth.c.akc openssh-6.1p1/auth.c +--- openssh-6.1p1/auth.c.akc 2012-11-28 17:12:43.187524558 +0100 ++++ openssh-6.1p1/auth.c 2012-11-28 17:12:43.263524297 +0100 +@@ -411,39 +411,41 @@ check_key_in_hostfiles(struct passwd *pw + + + /* +- * Check a given file for security. This is defined as all components ++ * Check a given path for security. This is defined as all components + * of the path to the file must be owned by either the owner of + * of the file or root and no directories must be group or world writable. + * + * XXX Should any specific check be done for sym links ? + * +- * Takes an open file descriptor, the file name, a uid and and ++ * Takes an the file name, its stat information (preferably from fstat() to ++ * avoid races), the uid of the expected owner, their home directory and an + * error buffer plus max size as arguments. + * + * Returns 0 on success and -1 on failure + */ +-static int +-secure_filename(FILE *f, const char *file, struct passwd *pw, +- char *err, size_t errlen) ++int ++auth_secure_path(const char *name, struct stat *stp, const char *pw_dir, ++ uid_t uid, char *err, size_t errlen) + { +- uid_t uid = pw->pw_uid; + char buf[MAXPATHLEN], homedir[MAXPATHLEN]; + char *cp; + int comparehome = 0; + struct stat st; + +- if (realpath(file, buf) == NULL) { +- snprintf(err, errlen, "realpath %s failed: %s", file, ++ if (realpath(name, buf) == NULL) { ++ snprintf(err, errlen, "realpath %s failed: %s", name, + strerror(errno)); + return -1; + } +- if (realpath(pw->pw_dir, homedir) != NULL) ++ if (pw_dir != NULL && realpath(pw_dir, homedir) != NULL) + comparehome = 1; + +- /* check the open file to avoid races */ +- if (fstat(fileno(f), &st) < 0 || +- (st.st_uid != 0 && st.st_uid != uid) || +- (st.st_mode & 022) != 0) { ++ if (!S_ISREG(stp->st_mode)) { ++ snprintf(err, errlen, "%s is not a regular file", buf); ++ return -1; ++ } ++ if ((stp->st_uid != 0 && stp->st_uid != uid) || ++ (stp->st_mode & 022) != 0) { + snprintf(err, errlen, "bad ownership or modes for file %s", + buf); + return -1; +@@ -479,6 +481,31 @@ secure_filename(FILE *f, const char *fil + return 0; + } + ++/* ++ * Version of secure_path() that accepts an open file descriptor to ++ * avoid races. ++ * ++ * Returns 0 on success and -1 on failure ++ */ ++static int ++secure_filename(FILE *f, const char *file, struct passwd *pw, ++ char *err, size_t errlen) ++{ ++ uid_t uid = pw->pw_uid; ++ char buf[MAXPATHLEN], homedir[MAXPATHLEN]; ++ char *cp; ++ int comparehome = 0; ++ struct stat st; ++ ++ /* check the open file to avoid races */ ++ if (fstat(fileno(f), &st) < 0) { ++ snprintf(err, errlen, "cannot stat file %s: %s", ++ buf, strerror(errno)); ++ return -1; ++ } ++ return auth_secure_path(file, &st, pw->pw_dir, pw->pw_uid, err, errlen); ++} ++ + static FILE * + auth_openfile(const char *file, struct passwd *pw, int strict_modes, + int log_missing, char *file_type) +diff -up openssh-6.1p1/auth.h.akc openssh-6.1p1/auth.h +--- openssh-6.1p1/auth.h.akc 2012-11-28 17:12:43.239524381 +0100 ++++ openssh-6.1p1/auth.h 2012-11-28 17:12:43.263524297 +0100 +@@ -125,6 +125,10 @@ int auth_rhosts_rsa_key_allowed(struct + int hostbased_key_allowed(struct passwd *, const char *, char *, Key *); + int user_key_allowed(struct passwd *, Key *); + ++struct stat; ++int auth_secure_path(const char *, struct stat *, const char *, uid_t, ++ char *, size_t); ++ + #ifdef KRB5 + int auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *); + int auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt); diff -up openssh-6.1p1/servconf.c.akc openssh-6.1p1/servconf.c ---- openssh-6.1p1/servconf.c.akc 2012-11-02 14:00:49.186077290 +0100 -+++ openssh-6.1p1/servconf.c 2012-11-02 14:26:32.086138017 +0100 -@@ -139,6 +139,8 @@ initialize_server_options(ServerOptions +--- openssh-6.1p1/servconf.c.akc 2012-11-28 17:12:43.198524521 +0100 ++++ openssh-6.1p1/servconf.c 2012-11-28 17:14:50.314005026 +0100 +@@ -137,6 +137,8 @@ initialize_server_options(ServerOptions options->num_permitted_opens = -1; options->adm_forced_command = NULL; options->chroot_directory = NULL; @@ -373,25 +373,25 @@ diff -up openssh-6.1p1/servconf.c.akc openssh-6.1p1/servconf.c options->zero_knowledge_password_authentication = -1; options->revoked_keys_file = NULL; options->trusted_user_ca_keys = NULL; -@@ -334,6 +336,7 @@ typedef enum { +@@ -331,6 +333,7 @@ typedef enum { sZeroKnowledgePasswordAuthentication, sHostCertificate, sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, sKexAlgorithms, sIPQoS, sVersionAddendum, + sAuthorizedKeysCommand, sAuthorizedKeysCommandUser, + sAuthenticationMethods, sDeprecated, sUnsupported } ServerOpCodes; - -@@ -460,6 +463,9 @@ static struct { - { "requiredauthentications1", sRequiredAuthentications1, SSHCFG_ALL }, - { "requiredauthentications2", sRequiredAuthentications2, SSHCFG_ALL }, +@@ -457,6 +460,9 @@ static struct { + { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, { "ipqos", sIPQoS, SSHCFG_ALL }, + { "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL }, + { "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL }, + { "authorizedkeyscommandrunas", sAuthorizedKeysCommandUser, SSHCFG_ALL }, + { "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL }, - { "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL }, + { "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL }, { NULL, sBadOption, 0 } }; -@@ -1532,6 +1538,26 @@ process_server_config_line(ServerOptions +@@ -1520,6 +1526,26 @@ process_server_config_line(ServerOptions } return 0; @@ -418,7 +418,7 @@ diff -up openssh-6.1p1/servconf.c.akc openssh-6.1p1/servconf.c case sDeprecated: logit("%s line %d: Deprecated option %s", filename, linenum, arg); -@@ -1682,6 +1708,8 @@ copy_set_server_options(ServerOptions *d +@@ -1670,6 +1696,8 @@ copy_set_server_options(ServerOptions *d M_CP_INTOPT(hostbased_uses_name_from_packet_only); M_CP_INTOPT(kbd_interactive_authentication); M_CP_INTOPT(zero_knowledge_password_authentication); @@ -427,7 +427,7 @@ diff -up openssh-6.1p1/servconf.c.akc openssh-6.1p1/servconf.c M_CP_INTOPT(permit_root_login); M_CP_INTOPT(permit_empty_passwd); -@@ -1942,6 +1970,8 @@ dump_config(ServerOptions *o) +@@ -1930,6 +1958,8 @@ dump_config(ServerOptions *o) dump_cfg_string(sAuthorizedPrincipalsFile, o->authorized_principals_file); dump_cfg_string(sVersionAddendum, o->version_addendum); @@ -437,9 +437,9 @@ diff -up openssh-6.1p1/servconf.c.akc openssh-6.1p1/servconf.c /* string arguments requiring a lookup */ dump_cfg_string(sLogLevel, log_level_name(o->log_level)); diff -up openssh-6.1p1/servconf.h.akc openssh-6.1p1/servconf.h ---- openssh-6.1p1/servconf.h.akc 2012-11-02 14:00:49.186077290 +0100 -+++ openssh-6.1p1/servconf.h 2012-11-02 14:00:49.254077869 +0100 -@@ -169,6 +169,8 @@ typedef struct { +--- openssh-6.1p1/servconf.h.akc 2012-11-28 17:12:43.000000000 +0100 ++++ openssh-6.1p1/servconf.h 2012-11-28 17:18:41.217055157 +0100 +@@ -167,6 +167,8 @@ typedef struct { char *revoked_keys_file; char *trusted_user_ca_keys; char *authorized_principals_file; @@ -447,10 +447,10 @@ diff -up openssh-6.1p1/servconf.h.akc openssh-6.1p1/servconf.h + char *authorized_keys_command_user; char *version_addendum; /* Appended to SSH banner */ - } ServerOptions; + diff -up openssh-6.1p1/sshd.c.akc openssh-6.1p1/sshd.c ---- openssh-6.1p1/sshd.c.akc 2012-11-02 14:00:49.249077826 +0100 -+++ openssh-6.1p1/sshd.c 2012-11-02 14:00:49.254077869 +0100 +--- openssh-6.1p1/sshd.c.akc 2012-11-28 17:12:43.245524360 +0100 ++++ openssh-6.1p1/sshd.c 2012-11-28 17:12:43.265524291 +0100 @@ -366,9 +366,20 @@ main_sigchld_handler(int sig) static void grace_alarm_handler(int sig) @@ -472,22 +472,9 @@ diff -up openssh-6.1p1/sshd.c.akc openssh-6.1p1/sshd.c /* Log error and exit. */ sigdie("Timeout before authentication for %s", get_remote_ipaddr()); } -diff -up openssh-6.1p1/sshd_config.akc openssh-6.1p1/sshd_config ---- openssh-6.1p1/sshd_config.akc 2012-07-31 04:21:34.000000000 +0200 -+++ openssh-6.1p1/sshd_config 2012-11-02 14:00:49.255077878 +0100 -@@ -49,6 +49,9 @@ - # but this is overridden so installations will only check .ssh/authorized_keys - AuthorizedKeysFile .ssh/authorized_keys - -+#AuthorizedKeysCommand none -+#AuthorizedKeysCommandUser nobody -+ - #AuthorizedPrincipalsFile none - - # For this to work you will also need host keys in /etc/ssh/ssh_known_hosts diff -up openssh-6.1p1/sshd_config.0.akc openssh-6.1p1/sshd_config.0 --- openssh-6.1p1/sshd_config.0.akc 2012-08-29 02:53:04.000000000 +0200 -+++ openssh-6.1p1/sshd_config.0 2012-11-02 14:00:49.255077878 +0100 ++++ openssh-6.1p1/sshd_config.0 2012-11-28 17:12:43.265524291 +0100 @@ -71,6 +71,23 @@ DESCRIPTION See PATTERNS in ssh_config(5) for more information on patterns. @@ -523,12 +510,12 @@ diff -up openssh-6.1p1/sshd_config.0.akc openssh-6.1p1/sshd_config.0 GatewayPorts, GSSAPIAuthentication, HostbasedAuthentication, HostbasedUsesNameFromPacketOnly, KbdInteractiveAuthentication, diff -up openssh-6.1p1/sshd_config.5.akc openssh-6.1p1/sshd_config.5 ---- openssh-6.1p1/sshd_config.5.akc 2012-11-02 14:00:49.187077299 +0100 -+++ openssh-6.1p1/sshd_config.5 2012-11-02 14:00:49.255077878 +0100 -@@ -151,6 +151,20 @@ See - in - .Xr ssh_config 5 - for more information on patterns. +--- openssh-6.1p1/sshd_config.5.akc 2012-11-28 17:12:43.199524517 +0100 ++++ openssh-6.1p1/sshd_config.5 2012-11-28 17:16:23.736624980 +0100 +@@ -173,6 +173,20 @@ Note that each authentication method lis + in the configuration. + The default is not to require multiple authentication; successful completion + of a single authentication method is sufficient. +.It Cm AuthorizedKeysCommand +Specifies a program to be used for lookup of the user's public keys. +The program will be invoked with a single argument of the username @@ -546,16 +533,16 @@ diff -up openssh-6.1p1/sshd_config.5.akc openssh-6.1p1/sshd_config.5 .It Cm AuthorizedKeysFile Specifies the file that contains the public keys that can be used for user authentication. -@@ -712,6 +726,8 @@ Available keywords are +@@ -734,6 +748,8 @@ Available keywords are .Cm AllowTcpForwarding , .Cm AllowUsers , - .Cm AuthorizedKeysFile , + .Cm AuthenticationMethods , +.Cm AuthorizedKeysCommand , +.Cm AuthorizedKeysCommandUser , + .Cm AuthorizedKeysFile , .Cm AuthorizedPrincipalsFile , .Cm Banner , - .Cm ChrootDirectory , -@@ -726,6 +742,7 @@ Available keywords are +@@ -749,6 +765,7 @@ Available keywords are .Cm KerberosAuthentication , .Cm MaxAuthTries , .Cm MaxSessions , @@ -563,3 +550,16 @@ diff -up openssh-6.1p1/sshd_config.5.akc openssh-6.1p1/sshd_config.5 .Cm PasswordAuthentication , .Cm PermitEmptyPasswords , .Cm PermitOpen , +diff -up openssh-6.1p1/sshd_config.akc openssh-6.1p1/sshd_config +--- openssh-6.1p1/sshd_config.akc 2012-07-31 04:21:34.000000000 +0200 ++++ openssh-6.1p1/sshd_config 2012-11-28 17:12:43.265524291 +0100 +@@ -49,6 +49,9 @@ + # but this is overridden so installations will only check .ssh/authorized_keys + AuthorizedKeysFile .ssh/authorized_keys + ++#AuthorizedKeysCommand none ++#AuthorizedKeysCommandUser nobody ++ + #AuthorizedPrincipalsFile none + + # For this to work you will also need host keys in /etc/ssh/ssh_known_hosts diff --git a/openssh-6.1p1-audit4.patch b/openssh-6.1p1-audit4.patch new file mode 100644 index 0000000..4f7abac --- /dev/null +++ b/openssh-6.1p1-audit4.patch @@ -0,0 +1,672 @@ +diff -up openssh-6.1p1/audit-bsm.c.audit4 openssh-6.1p1/audit-bsm.c +--- openssh-6.1p1/audit-bsm.c.audit4 2012-11-28 14:20:38.990185823 +0100 ++++ openssh-6.1p1/audit-bsm.c 2012-11-28 14:20:38.995185800 +0100 +@@ -485,4 +485,10 @@ audit_kex_body(int ctos, char *enc, char + { + /* not implemented */ + } ++ ++void ++audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) ++{ ++ /* not implemented */ ++} + #endif /* BSM */ +diff -up openssh-6.1p1/audit.c.audit4 openssh-6.1p1/audit.c +--- openssh-6.1p1/audit.c.audit4 2012-11-28 14:20:38.990185823 +0100 ++++ openssh-6.1p1/audit.c 2012-11-28 14:20:38.995185800 +0100 +@@ -143,6 +143,12 @@ audit_kex(int ctos, char *enc, char *mac + PRIVSEP(audit_kex_body(ctos, enc, mac, comp, getpid(), getuid())); + } + ++void ++audit_session_key_free(int ctos) ++{ ++ PRIVSEP(audit_session_key_free_body(ctos, getpid(), getuid())); ++} ++ + # ifndef CUSTOM_SSH_AUDIT_EVENTS + /* + * Null implementations of audit functions. +@@ -274,5 +280,15 @@ audit_kex_body(int ctos, char *enc, char + (unsigned)geteuid(), ctos, enc, mac, compress, (long)pid, + (unsigned)uid); + } ++ ++/* ++ * This will be called on succesfull session key discard ++ */ ++void ++audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) ++{ ++ debug("audit session key discard euid %u direction %d from pid %ld uid %u", ++ (unsigned)geteuid(), ctos, (long)pid, (unsigned)uid); ++} + # endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */ + #endif /* SSH_AUDIT_EVENTS */ +diff -up openssh-6.1p1/audit.h.audit4 openssh-6.1p1/audit.h +--- openssh-6.1p1/audit.h.audit4 2012-11-28 14:20:38.990185823 +0100 ++++ openssh-6.1p1/audit.h 2012-11-28 14:20:38.995185800 +0100 +@@ -62,5 +62,7 @@ void audit_unsupported(int); + void audit_kex(int, char *, char *, char *); + void audit_unsupported_body(int); + void audit_kex_body(int, char *, char *, char *, pid_t, uid_t); ++void audit_session_key_free(int ctos); ++void audit_session_key_free_body(int ctos, pid_t, uid_t); + + #endif /* _SSH_AUDIT_H */ +diff -up openssh-6.1p1/audit-linux.c.audit4 openssh-6.1p1/audit-linux.c +--- openssh-6.1p1/audit-linux.c.audit4 2012-11-28 14:20:38.990185823 +0100 ++++ openssh-6.1p1/audit-linux.c 2012-11-28 14:20:38.995185800 +0100 +@@ -294,6 +294,8 @@ audit_unsupported_body(int what) + #endif + } + ++const static char *direction[] = { "from-server", "from-client", "both" }; ++ + void + audit_kex_body(int ctos, char *enc, char *mac, char *compress, pid_t pid, + uid_t uid) +@@ -301,7 +303,6 @@ audit_kex_body(int ctos, char *enc, char + #ifdef AUDIT_CRYPTO_SESSION + char buf[AUDIT_LOG_SIZE]; + int audit_fd, audit_ok; +- const static char *direction[] = { "from-server", "from-client", "both" }; + Cipher *cipher = cipher_by_name(enc); + char *s; + +@@ -327,4 +328,32 @@ audit_kex_body(int ctos, char *enc, char + #endif + } + ++void ++audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) ++{ ++ char buf[AUDIT_LOG_SIZE]; ++ int audit_fd, audit_ok; ++ char *s; ++ ++ snprintf(buf, sizeof(buf), "op=destroy kind=session fp=? direction=%s spid=%jd suid=%jd rport=%d laddr=%s lport=%d ", ++ direction[ctos], (intmax_t)pid, (intmax_t)uid, ++ get_remote_port(), ++ (s = get_local_ipaddr(packet_get_connection_in())), ++ get_local_port()); ++ xfree(s); ++ audit_fd = audit_open(); ++ if (audit_fd < 0) { ++ if (errno != EINVAL && errno != EPROTONOSUPPORT && ++ errno != EAFNOSUPPORT) ++ error("cannot open audit"); ++ return; ++ } ++ audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER, ++ buf, NULL, get_remote_ipaddr(), NULL, 1); ++ audit_close(audit_fd); ++ /* do not abort if the error is EPERM and sshd is run as non root user */ ++ if ((audit_ok < 0) && ((audit_ok != -1) || (getuid() == 0))) ++ error("cannot write into audit"); ++} ++ + #endif /* USE_LINUX_AUDIT */ +diff -up openssh-6.1p1/auditstub.c.audit4 openssh-6.1p1/auditstub.c +--- openssh-6.1p1/auditstub.c.audit4 2012-11-28 14:20:38.990185823 +0100 ++++ openssh-6.1p1/auditstub.c 2012-11-28 14:20:38.995185800 +0100 +@@ -27,6 +27,8 @@ + * Red Hat author: Jan F. Chadima + */ + ++#include ++ + void + audit_unsupported(int n) + { +@@ -37,3 +39,12 @@ audit_kex(int ctos, char *enc, char *mac + { + } + ++void ++audit_session_key_free(int ctos) ++{ ++} ++ ++void ++audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) ++{ ++} +diff -up openssh-6.1p1/kex.c.audit4 openssh-6.1p1/kex.c +--- openssh-6.1p1/kex.c.audit4 2012-11-28 14:20:38.991185818 +0100 ++++ openssh-6.1p1/kex.c 2012-11-28 14:20:38.995185800 +0100 +@@ -624,3 +624,34 @@ dump_digest(char *msg, u_char *digest, i + fprintf(stderr, "\n"); + } + #endif ++ ++static void ++enc_destroy(Enc *enc) ++{ ++ if (enc == NULL) ++ return; ++ ++ if (enc->key) { ++ memset(enc->key, 0, enc->key_len); ++ xfree(enc->key); ++ } ++ ++ if (enc->iv) { ++ memset(enc->iv, 0, enc->block_size); ++ xfree(enc->iv); ++ } ++ ++ memset(enc, 0, sizeof(*enc)); ++} ++ ++void ++newkeys_destroy(Newkeys *newkeys) ++{ ++ if (newkeys == NULL) ++ return; ++ ++ enc_destroy(&newkeys->enc); ++ mac_destroy(&newkeys->mac); ++ memset(&newkeys->comp, 0, sizeof(newkeys->comp)); ++} ++ +diff -up openssh-6.1p1/kex.h.audit4 openssh-6.1p1/kex.h +--- openssh-6.1p1/kex.h.audit4 2010-09-24 14:11:14.000000000 +0200 ++++ openssh-6.1p1/kex.h 2012-11-28 14:20:38.996185795 +0100 +@@ -156,6 +156,8 @@ void kexgex_server(Kex *); + void kexecdh_client(Kex *); + void kexecdh_server(Kex *); + ++void newkeys_destroy(Newkeys *newkeys); ++ + void + kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int, + BIGNUM *, BIGNUM *, BIGNUM *, u_char **, u_int *); +diff -up openssh-6.1p1/mac.c.audit4 openssh-6.1p1/mac.c +--- openssh-6.1p1/mac.c.audit4 2012-06-30 00:34:59.000000000 +0200 ++++ openssh-6.1p1/mac.c 2012-11-28 14:20:38.996185795 +0100 +@@ -169,6 +169,20 @@ mac_clear(Mac *mac) + mac->umac_ctx = NULL; + } + ++void ++mac_destroy(Mac *mac) ++{ ++ if (mac == NULL) ++ return; ++ ++ if (mac->key) { ++ memset(mac->key, 0, mac->key_len); ++ xfree(mac->key); ++ } ++ ++ memset(mac, 0, sizeof(*mac)); ++} ++ + /* XXX copied from ciphers_valid */ + #define MAC_SEP "," + int +diff -up openssh-6.1p1/mac.h.audit4 openssh-6.1p1/mac.h +--- openssh-6.1p1/mac.h.audit4 2007-06-11 06:01:42.000000000 +0200 ++++ openssh-6.1p1/mac.h 2012-11-28 14:20:38.996185795 +0100 +@@ -28,3 +28,4 @@ int mac_setup(Mac *, char *); + int mac_init(Mac *); + u_char *mac_compute(Mac *, u_int32_t, u_char *, int); + void mac_clear(Mac *); ++void mac_destroy(Mac *); +diff -up openssh-6.1p1/monitor.c.audit4 openssh-6.1p1/monitor.c +--- openssh-6.1p1/monitor.c.audit4 2012-11-28 14:20:38.992185813 +0100 ++++ openssh-6.1p1/monitor.c 2012-11-28 17:02:17.677045093 +0100 +@@ -189,6 +189,7 @@ int mm_answer_audit_command(int, Buffer + int mm_answer_audit_end_command(int, Buffer *); + int mm_answer_audit_unsupported_body(int, Buffer *); + int mm_answer_audit_kex_body(int, Buffer *); ++int mm_answer_audit_session_key_free_body(int, Buffer *); + #endif + + static int monitor_read_log(struct monitor *); +@@ -241,6 +242,7 @@ struct mon_table mon_dispatch_proto20[] + {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, + {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body}, + {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body}, ++ {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body}, + #endif + #ifdef BSD_AUTH + {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery}, +@@ -280,6 +282,7 @@ struct mon_table mon_dispatch_postauth20 + {MONITOR_REQ_AUDIT_END_COMMAND, MON_PERMIT, mm_answer_audit_end_command}, + {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body}, + {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body}, ++ {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body}, + #endif + {0, 0, NULL} + }; +@@ -313,6 +316,7 @@ struct mon_table mon_dispatch_proto15[] + {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, + {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body}, + {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body}, ++ {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body}, + #endif + {0, 0, NULL} + }; +@@ -327,6 +331,7 @@ struct mon_table mon_dispatch_postauth15 + {MONITOR_REQ_AUDIT_END_COMMAND, MON_PERMIT, mm_answer_audit_end_command}, + {MONITOR_REQ_AUDIT_UNSUPPORTED, MON_PERMIT, mm_answer_audit_unsupported_body}, + {MONITOR_REQ_AUDIT_KEX, MON_PERMIT, mm_answer_audit_kex_body}, ++ {MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MON_PERMIT, mm_answer_audit_session_key_free_body}, + #endif + {0, 0, NULL} + }; +@@ -448,10 +453,6 @@ monitor_child_preauth(Authctxt *_authctx + #endif + } + +- /* Drain any buffered messages from the child */ +- while (pmonitor->m_log_recvfd >= 0 && monitor_read_log(pmonitor) == 0) +- ; +- + if (!authctxt->valid) + fatal("%s: authenticated invalid user", __func__); + if (strcmp(auth_method, "unknown") == 0) +@@ -1950,11 +1951,13 @@ mm_get_keystate(struct monitor *pmonitor + + blob = buffer_get_string(&m, &bloblen); + current_keys[MODE_OUT] = mm_newkeys_from_blob(blob, bloblen); ++ memset(blob, 0, bloblen); + xfree(blob); + + debug3("%s: Waiting for second key", __func__); + blob = buffer_get_string(&m, &bloblen); + current_keys[MODE_IN] = mm_newkeys_from_blob(blob, bloblen); ++ memset(blob, 0, bloblen); + xfree(blob); + + /* Now get sequence numbers for the packets */ +@@ -2000,6 +2003,21 @@ mm_get_keystate(struct monitor *pmonitor + } + + buffer_free(&m); ++ ++#ifdef SSH_AUDIT_EVENTS ++ if (compat20) { ++ buffer_init(&m); ++ mm_request_receive_expect(pmonitor->m_sendfd, ++ MONITOR_REQ_AUDIT_SESSION_KEY_FREE, &m); ++ mm_answer_audit_session_key_free_body(pmonitor->m_sendfd, &m); ++ buffer_free(&m); ++ } ++#endif ++ ++ /* Drain any buffered messages from the child */ ++ while (pmonitor->m_log_recvfd >= 0 && monitor_read_log(pmonitor) == 0) ++ ; ++ + } + + +@@ -2444,4 +2462,22 @@ mm_answer_audit_kex_body(int sock, Buffe + return 0; + } + ++int ++mm_answer_audit_session_key_free_body(int sock, Buffer *m) ++{ ++ int ctos; ++ pid_t pid; ++ uid_t uid; ++ ++ ctos = buffer_get_int(m); ++ pid = buffer_get_int64(m); ++ uid = buffer_get_int64(m); ++ ++ audit_session_key_free_body(ctos, pid, uid); ++ ++ buffer_clear(m); ++ ++ mm_request_send(sock, MONITOR_ANS_AUDIT_SESSION_KEY_FREE, m); ++ return 0; ++} + #endif /* SSH_AUDIT_EVENTS */ +diff -up openssh-6.1p1/monitor.h.audit4 openssh-6.1p1/monitor.h +--- openssh-6.1p1/monitor.h.audit4 2012-11-28 14:20:38.992185813 +0100 ++++ openssh-6.1p1/monitor.h 2012-11-28 14:20:38.997185790 +0100 +@@ -63,6 +63,7 @@ enum monitor_reqtype { + MONITOR_ANS_AUDIT_COMMAND, MONITOR_REQ_AUDIT_END_COMMAND, + MONITOR_REQ_AUDIT_UNSUPPORTED, MONITOR_ANS_AUDIT_UNSUPPORTED, + MONITOR_REQ_AUDIT_KEX, MONITOR_ANS_AUDIT_KEX, ++ MONITOR_REQ_AUDIT_SESSION_KEY_FREE, MONITOR_ANS_AUDIT_SESSION_KEY_FREE, + MONITOR_REQ_TERM, + MONITOR_REQ_JPAKE_STEP1, MONITOR_ANS_JPAKE_STEP1, + MONITOR_REQ_JPAKE_GET_PWDATA, MONITOR_ANS_JPAKE_GET_PWDATA, +diff -up openssh-6.1p1/monitor_wrap.c.audit4 openssh-6.1p1/monitor_wrap.c +--- openssh-6.1p1/monitor_wrap.c.audit4 2012-11-28 14:20:38.992185813 +0100 ++++ openssh-6.1p1/monitor_wrap.c 2012-11-28 14:20:38.997185790 +0100 +@@ -653,12 +653,14 @@ mm_send_keystate(struct monitor *monitor + fatal("%s: conversion of newkeys failed", __func__); + + buffer_put_string(&m, blob, bloblen); ++ memset(blob, 0, bloblen); + xfree(blob); + + if (!mm_newkeys_to_blob(MODE_IN, &blob, &bloblen)) + fatal("%s: conversion of newkeys failed", __func__); + + buffer_put_string(&m, blob, bloblen); ++ memset(blob, 0, bloblen); + xfree(blob); + + packet_get_state(MODE_OUT, &seqnr, &blocks, &packets, &bytes); +@@ -1522,4 +1524,19 @@ mm_audit_kex_body(int ctos, char *cipher + + buffer_free(&m); + } ++ ++void ++mm_audit_session_key_free_body(int ctos, pid_t pid, uid_t uid) ++{ ++ Buffer m; ++ ++ buffer_init(&m); ++ buffer_put_int(&m, ctos); ++ buffer_put_int64(&m, pid); ++ buffer_put_int64(&m, uid); ++ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SESSION_KEY_FREE, &m); ++ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_SESSION_KEY_FREE, ++ &m); ++ buffer_free(&m); ++} + #endif /* SSH_AUDIT_EVENTS */ +diff -up openssh-6.1p1/monitor_wrap.h.audit4 openssh-6.1p1/monitor_wrap.h +--- openssh-6.1p1/monitor_wrap.h.audit4 2012-11-28 14:20:38.992185813 +0100 ++++ openssh-6.1p1/monitor_wrap.h 2012-11-28 14:20:38.997185790 +0100 +@@ -79,6 +79,7 @@ int mm_audit_run_command(const char *); + void mm_audit_end_command(int, const char *); + void mm_audit_unsupported_body(int); + void mm_audit_kex_body(int, char *, char *, char *, pid_t, uid_t); ++void mm_audit_session_key_free_body(int, pid_t, uid_t); + #endif + + struct Session; +diff -up openssh-6.1p1/packet.c.audit4 openssh-6.1p1/packet.c +--- openssh-6.1p1/packet.c.audit4 2012-11-28 14:20:38.973185902 +0100 ++++ openssh-6.1p1/packet.c 2012-11-28 14:20:38.998185785 +0100 +@@ -60,6 +60,7 @@ + #include + + #include "xmalloc.h" ++#include "audit.h" + #include "buffer.h" + #include "packet.h" + #include "crc32.h" +@@ -470,6 +471,13 @@ packet_get_connection_out(void) + return active_state->connection_out; + } + ++static int ++packet_state_has_keys (const struct session_state *state) ++{ ++ return state != NULL && ++ (state->newkeys[MODE_IN] != NULL || state->newkeys[MODE_OUT] != NULL); ++} ++ + /* Closes the connection and clears and frees internal data structures. */ + + void +@@ -478,13 +486,6 @@ packet_close(void) + if (!active_state->initialized) + return; + active_state->initialized = 0; +- if (active_state->connection_in == active_state->connection_out) { +- shutdown(active_state->connection_out, SHUT_RDWR); +- close(active_state->connection_out); +- } else { +- close(active_state->connection_in); +- close(active_state->connection_out); +- } + buffer_free(&active_state->input); + buffer_free(&active_state->output); + buffer_free(&active_state->outgoing_packet); +@@ -493,8 +494,18 @@ packet_close(void) + buffer_free(&active_state->compression_buffer); + buffer_compress_uninit(); + } +- cipher_cleanup(&active_state->send_context); +- cipher_cleanup(&active_state->receive_context); ++ if (packet_state_has_keys(active_state)) { ++ cipher_cleanup(&active_state->send_context); ++ cipher_cleanup(&active_state->receive_context); ++ audit_session_key_free(2); ++ } ++ if (active_state->connection_in == active_state->connection_out) { ++ shutdown(active_state->connection_out, SHUT_RDWR); ++ close(active_state->connection_out); ++ } else { ++ close(active_state->connection_in); ++ close(active_state->connection_out); ++ } + } + + /* Sets remote side protocol flags. */ +@@ -729,6 +740,23 @@ packet_send1(void) + */ + } + ++static void ++newkeys_destroy_and_free(Newkeys *newkeys) ++{ ++ if (newkeys == NULL) ++ return; ++ ++ xfree(newkeys->enc.name); ++ ++ mac_clear(&newkeys->mac); ++ xfree(newkeys->mac.name); ++ ++ xfree(newkeys->comp.name); ++ ++ newkeys_destroy(newkeys); ++ xfree(newkeys); ++} ++ + void + set_newkeys(int mode) + { +@@ -754,18 +782,9 @@ set_newkeys(int mode) + } + if (active_state->newkeys[mode] != NULL) { + debug("set_newkeys: rekeying"); ++ audit_session_key_free(mode); + cipher_cleanup(cc); +- enc = &active_state->newkeys[mode]->enc; +- mac = &active_state->newkeys[mode]->mac; +- comp = &active_state->newkeys[mode]->comp; +- mac_clear(mac); +- xfree(enc->name); +- xfree(enc->iv); +- xfree(enc->key); +- xfree(mac->name); +- xfree(mac->key); +- xfree(comp->name); +- xfree(active_state->newkeys[mode]); ++ newkeys_destroy_and_free(active_state->newkeys[mode]); + } + active_state->newkeys[mode] = kex_get_newkeys(mode); + if (active_state->newkeys[mode] == NULL) +@@ -1921,6 +1940,47 @@ packet_get_newkeys(int mode) + return (void *)active_state->newkeys[mode]; + } + ++static void ++packet_destroy_state(struct session_state *state) ++{ ++ if (state == NULL) ++ return; ++ ++ cipher_cleanup(&state->receive_context); ++ cipher_cleanup(&state->send_context); ++ ++ buffer_free(&state->input); ++ buffer_free(&state->output); ++ buffer_free(&state->outgoing_packet); ++ buffer_free(&state->incoming_packet); ++ buffer_free(&state->compression_buffer); ++ newkeys_destroy_and_free(state->newkeys[MODE_IN]); ++ state->newkeys[MODE_IN] = NULL; ++ newkeys_destroy_and_free(state->newkeys[MODE_OUT]); ++ state->newkeys[MODE_OUT] = NULL; ++ mac_destroy(state->packet_discard_mac); ++// TAILQ_HEAD(, packet) outgoing; ++// memset(state, 0, sizeof(state)); ++} ++ ++void ++packet_destroy_all(int audit_it, int privsep) ++{ ++ if (audit_it) ++ audit_it = packet_state_has_keys (active_state) || ++ packet_state_has_keys (backup_state); ++ packet_destroy_state(active_state); ++ packet_destroy_state(backup_state); ++ if (audit_it) { ++#ifdef SSH_AUDIT_EVENTS ++ if (privsep) ++ audit_session_key_free(2); ++ else ++ audit_session_key_free_body(2, getpid(), getuid()); ++#endif ++ } ++} ++ + /* + * Save the state for the real connection, and use a separate state when + * resuming a suspended connection. +@@ -1928,18 +1988,12 @@ packet_get_newkeys(int mode) + void + packet_backup_state(void) + { +- struct session_state *tmp; +- + close(active_state->connection_in); + active_state->connection_in = -1; + close(active_state->connection_out); + active_state->connection_out = -1; +- if (backup_state) +- tmp = backup_state; +- else +- tmp = alloc_session_state(); + backup_state = active_state; +- active_state = tmp; ++ active_state = alloc_session_state(); + } + + /* +@@ -1956,9 +2010,7 @@ packet_restore_state(void) + backup_state = active_state; + active_state = tmp; + active_state->connection_in = backup_state->connection_in; +- backup_state->connection_in = -1; + active_state->connection_out = backup_state->connection_out; +- backup_state->connection_out = -1; + len = buffer_len(&backup_state->input); + if (len > 0) { + buf = buffer_ptr(&backup_state->input); +@@ -1966,4 +2018,10 @@ packet_restore_state(void) + buffer_clear(&backup_state->input); + add_recv_bytes(len); + } ++ backup_state->connection_in = -1; ++ backup_state->connection_out = -1; ++ packet_destroy_state(backup_state); ++ xfree(backup_state); ++ backup_state = NULL; + } ++ +diff -up openssh-6.1p1/packet.h.audit4 openssh-6.1p1/packet.h +--- openssh-6.1p1/packet.h.audit4 2012-02-10 22:19:21.000000000 +0100 ++++ openssh-6.1p1/packet.h 2012-11-28 14:20:38.998185785 +0100 +@@ -123,4 +123,5 @@ void packet_restore_state(void); + void *packet_get_input(void); + void *packet_get_output(void); + ++void packet_destroy_all(int, int); + #endif /* PACKET_H */ +diff -up openssh-6.1p1/session.c.audit4 openssh-6.1p1/session.c +--- openssh-6.1p1/session.c.audit4 2012-11-28 14:20:38.983185855 +0100 ++++ openssh-6.1p1/session.c 2012-11-28 14:20:38.998185785 +0100 +@@ -1634,6 +1634,9 @@ do_child(Session *s, const char *command + + /* remove hostkey from the child's memory */ + destroy_sensitive_data(); ++ /* Don't audit this - both us and the parent would be talking to the ++ monitor over a single socket, with no synchronization. */ ++ packet_destroy_all(0, 1); + + /* Force a password change */ + if (s->authctxt->force_pwchange) { +diff -up openssh-6.1p1/sshd.c.audit4 openssh-6.1p1/sshd.c +--- openssh-6.1p1/sshd.c.audit4 2012-11-28 14:20:38.993185808 +0100 ++++ openssh-6.1p1/sshd.c 2012-11-28 14:20:38.999185780 +0100 +@@ -692,6 +692,8 @@ privsep_preauth(Authctxt *authctxt) + } + } + ++extern Newkeys *current_keys[]; ++ + static void + privsep_postauth(Authctxt *authctxt) + { +@@ -716,6 +718,10 @@ privsep_postauth(Authctxt *authctxt) + else if (pmonitor->m_pid != 0) { + verbose("User child is on pid %ld", (long)pmonitor->m_pid); + buffer_clear(&loginmsg); ++ newkeys_destroy(current_keys[MODE_OUT]); ++ newkeys_destroy(current_keys[MODE_IN]); ++ audit_session_key_free_body(2, getpid(), getuid()); ++ packet_destroy_all(0, 0); + monitor_child_postauth(pmonitor); + + /* NEVERREACHED */ +@@ -2016,6 +2022,7 @@ main(int ac, char **av) + */ + if (use_privsep) { + mm_send_keystate(pmonitor); ++ packet_destroy_all(1, 1); + exit(0); + } + +@@ -2068,6 +2075,8 @@ main(int ac, char **av) + do_authenticated(authctxt); + + /* The connection has been terminated. */ ++ packet_destroy_all(1, 1); ++ + packet_get_state(MODE_IN, NULL, NULL, NULL, &ibytes); + packet_get_state(MODE_OUT, NULL, NULL, NULL, &obytes); + verbose("Transferred: sent %llu, received %llu bytes", +@@ -2385,6 +2394,16 @@ do_ssh2_kex(void) + void + cleanup_exit(int i) + { ++ static int in_cleanup = 0; ++ int is_privsep_child; ++ ++ /* cleanup_exit can be called at the very least from the privsep ++ wrappers used for auditing. Make sure we don't recurse ++ indefinitely. */ ++ if (in_cleanup) ++ _exit(i); ++ in_cleanup = 1; ++ + if (the_authctxt) { + do_cleanup(the_authctxt); + if (use_privsep && privsep_is_preauth && pmonitor->m_pid > 1) { +@@ -2395,6 +2414,8 @@ cleanup_exit(int i) + pmonitor->m_pid, strerror(errno)); + } + } ++ is_privsep_child = use_privsep && pmonitor != NULL && !mm_is_monitor(); ++ packet_destroy_all(1, is_privsep_child); + #ifdef SSH_AUDIT_EVENTS + /* done after do_cleanup so it can cancel the PAM auth 'thread' */ + if ((the_authctxt == NULL || !the_authctxt->authenticated) && diff --git a/openssh-6.1p1-gsskex.patch b/openssh-6.1p1-gsskex.patch index b580a6d..9b0bad9 100644 --- a/openssh-6.1p1-gsskex.patch +++ b/openssh-6.1p1-gsskex.patch @@ -1,6 +1,102 @@ +diff -up openssh-6.1p1/auth2.c.gsskex openssh-6.1p1/auth2.c +--- openssh-6.1p1/auth2.c.gsskex 2012-11-30 13:58:08.871298935 +0100 ++++ openssh-6.1p1/auth2.c 2012-11-30 13:58:08.946298649 +0100 +@@ -69,6 +69,7 @@ extern Authmethod method_passwd; + extern Authmethod method_kbdint; + extern Authmethod method_hostbased; + #ifdef GSSAPI ++extern Authmethod method_gsskeyex; + extern Authmethod method_gssapi; + #endif + #ifdef JPAKE +@@ -79,6 +80,7 @@ Authmethod *authmethods[] = { + &method_none, + &method_pubkey, + #ifdef GSSAPI ++ &method_gsskeyex, + &method_gssapi, + #endif + #ifdef JPAKE +diff -up openssh-6.1p1/auth2-gss.c.gsskex openssh-6.1p1/auth2-gss.c +--- openssh-6.1p1/auth2-gss.c.gsskex 2012-11-30 13:58:08.871298935 +0100 ++++ openssh-6.1p1/auth2-gss.c 2012-11-30 13:59:19.622985133 +0100 +@@ -52,6 +52,40 @@ static void input_gssapi_mic(int type, u + static void input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt); + static void input_gssapi_errtok(int, u_int32_t, void *); + ++/* ++ * The 'gssapi_keyex' userauth mechanism. ++ */ ++static int ++userauth_gsskeyex(Authctxt *authctxt) ++{ ++ int authenticated = 0; ++ Buffer b; ++ gss_buffer_desc mic, gssbuf; ++ u_int len; ++ ++ mic.value = packet_get_string(&len); ++ mic.length = len; ++ ++ packet_check_eom(); ++ ++ ssh_gssapi_buildmic(&b, authctxt->user, authctxt->service, ++ "gssapi-keyex"); ++ ++ gssbuf.value = buffer_ptr(&b); ++ gssbuf.length = buffer_len(&b); ++ ++ /* gss_kex_context is NULL with privsep, so we can't check it here */ ++ if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gss_kex_context, ++ &gssbuf, &mic)))) ++ authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, ++ authctxt->pw)); ++ ++ buffer_free(&b); ++ xfree(mic.value); ++ ++ return (authenticated); ++} ++ + /* + * We only support those mechanisms that we know about (ie ones that we know + * how to check local user kuserok and the like) +@@ -244,7 +278,8 @@ input_gssapi_exchange_complete(int type, + + packet_check_eom(); + +- authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); ++ authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, ++ authctxt->pw)); + + authctxt->postponed = 0; + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); +@@ -286,7 +321,8 @@ input_gssapi_mic(int type, u_int32_t ple + gssbuf.length = buffer_len(&b); + + if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))) +- authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); ++ authenticated = ++ PRIVSEP(ssh_gssapi_userok(authctxt->user, authctxt->pw)); + else + logit("GSSAPI MIC check failed"); + +@@ -303,6 +339,12 @@ input_gssapi_mic(int type, u_int32_t ple + userauth_finish(authctxt, authenticated, "gssapi-with-mic", NULL); + } + ++Authmethod method_gsskeyex = { ++ "gssapi-keyex", ++ userauth_gsskeyex, ++ &options.gss_authentication ++}; ++ + Authmethod method_gssapi = { + "gssapi-with-mic", + userauth_gssapi, diff -up openssh-6.1p1/auth-krb5.c.gsskex openssh-6.1p1/auth-krb5.c --- openssh-6.1p1/auth-krb5.c.gsskex 2012-04-26 01:52:15.000000000 +0200 -+++ openssh-6.1p1/auth-krb5.c 2012-09-14 21:07:19.695203206 +0200 ++++ openssh-6.1p1/auth-krb5.c 2012-11-30 13:58:08.947298647 +0100 @@ -50,6 +50,7 @@ #include #include @@ -107,105 +203,126 @@ diff -up openssh-6.1p1/auth-krb5.c.gsskex openssh-6.1p1/auth-krb5.c return (krb5_cc_resolve(ctx, ccname, ccache)); } -diff -up openssh-6.1p1/auth2.c.gsskex openssh-6.1p1/auth2.c ---- openssh-6.1p1/auth2.c.gsskex 2012-09-14 20:57:55.291263269 +0200 -+++ openssh-6.1p1/auth2.c 2012-09-14 20:57:55.853266860 +0200 -@@ -69,6 +69,7 @@ extern Authmethod method_passwd; - extern Authmethod method_kbdint; - extern Authmethod method_hostbased; - #ifdef GSSAPI -+extern Authmethod method_gsskeyex; - extern Authmethod method_gssapi; - #endif - #ifdef JPAKE -@@ -79,6 +80,7 @@ Authmethod *authmethods[] = { - &method_none, - &method_pubkey, - #ifdef GSSAPI -+ &method_gsskeyex, - &method_gssapi, - #endif - #ifdef JPAKE -diff -up openssh-6.1p1/auth2-gss.c.gsskex openssh-6.1p1/auth2-gss.c ---- openssh-6.1p1/auth2-gss.c.gsskex 2012-09-14 20:57:55.292263276 +0200 -+++ openssh-6.1p1/auth2-gss.c 2012-09-14 20:57:55.855266873 +0200 -@@ -52,6 +52,40 @@ static void input_gssapi_mic(int type, u - static void input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt); - static void input_gssapi_errtok(int, u_int32_t, void *); - -+/* -+ * The 'gssapi_keyex' userauth mechanism. -+ */ -+static int -+userauth_gsskeyex(Authctxt *authctxt) -+{ -+ int authenticated = 0; -+ Buffer b; -+ gss_buffer_desc mic, gssbuf; -+ u_int len; +diff -up openssh-6.1p1/ChangeLog.gssapi.gsskex openssh-6.1p1/ChangeLog.gssapi +--- openssh-6.1p1/ChangeLog.gssapi.gsskex 2012-11-30 13:58:08.947298647 +0100 ++++ openssh-6.1p1/ChangeLog.gssapi 2012-11-30 13:58:08.947298647 +0100 +@@ -0,0 +1,113 @@ ++20110101 ++ - Finally update for OpenSSH 5.6p1 ++ - Add GSSAPIServerIdentity option from Jim Basney ++ ++20100308 ++ - [ Makefile.in, key.c, key.h ] ++ Updates for OpenSSH 5.4p1 ++ - [ servconf.c ] ++ Include GSSAPI options in the sshd -T configuration dump, and flag ++ some older configuration options as being unsupported. Thanks to Colin ++ Watson. ++ - + -+ mic.value = packet_get_string(&len); -+ mic.length = len; ++20100124 ++ - [ sshconnect2.c ] ++ Adapt to deal with additional element in Authmethod structure. Thanks to ++ Colin Watson + -+ packet_check_eom(); ++20090615 ++ - [ gss-genr.c gss-serv.c kexgssc.c kexgsss.c monitor.c sshconnect2.c ++ sshd.c ] ++ Fix issues identified by Greg Hudson following a code review ++ Check return value of gss_indicate_mechs ++ Protect GSSAPI calls in monitor, so they can only be used if enabled ++ Check return values of bignum functions in key exchange ++ Use BN_clear_free to clear other side's DH value ++ Make ssh_gssapi_id_kex more robust ++ Only configure kex table pointers if GSSAPI is enabled ++ Don't leak mechanism list, or gss mechanism list ++ Cast data.length before printing ++ If serverkey isn't provided, use an empty string, rather than NULL + -+ ssh_gssapi_buildmic(&b, authctxt->user, authctxt->service, -+ "gssapi-keyex"); ++20090201 ++ - [ gss-genr.c gss-serv.c kex.h kexgssc.c readconf.c readconf.h ssh-gss.h ++ ssh_config.5 sshconnet2.c ] ++ Add support for the GSSAPIClientIdentity option, which allows the user ++ to specify which GSSAPI identity to use to contact a given server + -+ gssbuf.value = buffer_ptr(&b); -+ gssbuf.length = buffer_len(&b); ++20080404 ++ - [ gss-serv.c ] ++ Add code to actually implement GSSAPIStrictAcceptCheck, which had somehow ++ been omitted from a previous version of this patch. Reported by Borislav ++ Stoichkov + -+ /* gss_kex_context is NULL with privsep, so we can't check it here */ -+ if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gss_kex_context, -+ &gssbuf, &mic)))) -+ authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, -+ authctxt->pw)); -+ -+ buffer_free(&b); -+ xfree(mic.value); ++20070317 ++ - [ gss-serv-krb5.c ] ++ Remove C99ism, where new_ccname was being declared in the middle of a ++ function + -+ return (authenticated); -+} ++20061220 ++ - [ servconf.c ] ++ Make default for GSSAPIStrictAcceptorCheck be Yes, to match previous, and ++ documented, behaviour. Reported by Dan Watson. + - /* - * We only support those mechanisms that we know about (ie ones that we know - * how to check local user kuserok and the like) -@@ -244,7 +278,8 @@ input_gssapi_exchange_complete(int type, - - packet_check_eom(); - -- authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); -+ authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, -+ authctxt->pw)); - - authctxt->postponed = 0; - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); -@@ -286,7 +321,8 @@ input_gssapi_mic(int type, u_int32_t ple - gssbuf.length = buffer_len(&b); - - if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))) -- authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); -+ authenticated = -+ PRIVSEP(ssh_gssapi_userok(authctxt->user, authctxt->pw)); - else - logit("GSSAPI MIC check failed"); - -@@ -303,6 +339,12 @@ input_gssapi_mic(int type, u_int32_t ple - userauth_finish(authctxt, authenticated, "gssapi-with-mic", NULL); - } - -+Authmethod method_gsskeyex = { -+ "gssapi-keyex", -+ userauth_gsskeyex, -+ &options.gss_authentication -+}; ++20060910 ++ - [ gss-genr.c kexgssc.c kexgsss.c kex.h monitor.c sshconnect2.c sshd.c ++ ssh-gss.h ] ++ add support for gss-group14-sha1 key exchange mechanisms ++ - [ gss-serv.c servconf.c servconf.h sshd_config sshd_config.5 ] ++ Add GSSAPIStrictAcceptorCheck option to allow the disabling of ++ acceptor principal checking on multi-homed machines. ++ ++ - [ sshd_config ssh_config ] ++ Add settings for GSSAPIKeyExchange and GSSAPITrustDNS to the sample ++ configuration files ++ - [ kexgss.c kegsss.c sshconnect2.c sshd.c ] ++ Code cleanup. Replace strlen/xmalloc/snprintf sequences with xasprintf() ++ Limit length of error messages displayed by client + - Authmethod method_gssapi = { - "gssapi-with-mic", - userauth_gssapi, ++20060909 ++ - [ gss-genr.c gss-serv.c ] ++ move ssh_gssapi_acquire_cred() and ssh_gssapi_server_ctx to be server ++ only, where they belong ++ ++ ++20060829 ++ - [ gss-serv-krb5.c ] ++ Fix CCAPI credentials cache name when creating KRB5CCNAME environment ++ variable ++ ++20060828 ++ - [ gss-genr.c ] ++ Avoid Heimdal context freeing problem ++ ++ ++20060818 ++ - [ gss-genr.c ssh-gss.h sshconnect2.c ] ++ Make sure that SPENGO is disabled ++ ++ ++20060421 ++ - [ gssgenr.c, sshconnect2.c ] ++ a few type changes (signed versus unsigned, int versus size_t) to ++ fix compiler errors/warnings ++ (from jbasney AT ncsa.uiuc.edu) ++ - [ kexgssc.c, sshconnect2.c ] ++ fix uninitialized variable warnings ++ (from jbasney AT ncsa.uiuc.edu) ++ - [ gssgenr.c ] ++ pass oid to gss_display_status (helpful when using GSSAPI mechglue) ++ (from jbasney AT ncsa.uiuc.edu) ++ ++ - [ gss-serv-krb5.c ] ++ #ifdef HAVE_GSSAPI_KRB5 should be #ifdef HAVE_GSSAPI_KRB5_H ++ (from jbasney AT ncsa.uiuc.edu) ++ ++ - [ readconf.c, readconf.h, ssh_config.5, sshconnect2.c ++ add client-side GssapiKeyExchange option ++ (from jbasney AT ncsa.uiuc.edu) ++ - [ sshconnect2.c ] ++ add support for GssapiTrustDns option for gssapi-with-mic ++ (from jbasney AT ncsa.uiuc.edu) ++ diff -up openssh-6.1p1/clientloop.c.gsskex openssh-6.1p1/clientloop.c ---- openssh-6.1p1/clientloop.c.gsskex 2012-09-14 20:57:54.862260529 +0200 -+++ openssh-6.1p1/clientloop.c 2012-09-14 20:57:55.861266911 +0200 +--- openssh-6.1p1/clientloop.c.gsskex 2012-11-30 13:58:08.781299279 +0100 ++++ openssh-6.1p1/clientloop.c 2012-11-30 13:58:08.948298644 +0100 @@ -111,6 +111,10 @@ #include "msg.h" #include "roaming.h" @@ -234,8 +351,8 @@ diff -up openssh-6.1p1/clientloop.c.gsskex openssh-6.1p1/clientloop.c debug("need rekeying"); xxx_kex->done = 0; diff -up openssh-6.1p1/configure.ac.gsskex openssh-6.1p1/configure.ac ---- openssh-6.1p1/configure.ac.gsskex 2012-09-14 20:57:55.756266240 +0200 -+++ openssh-6.1p1/configure.ac 2012-09-14 20:57:55.865266937 +0200 +--- openssh-6.1p1/configure.ac.gsskex 2012-11-30 13:58:08.934298697 +0100 ++++ openssh-6.1p1/configure.ac 2012-11-30 13:58:08.949298640 +0100 @@ -545,6 +545,30 @@ main() { if (NSVersionOfRunTimeLibrary(" [Use tunnel device compatibility to OpenBSD]) AC_DEFINE([SSH_TUN_PREPEND_AF], [1], @@ -269,7 +386,7 @@ diff -up openssh-6.1p1/configure.ac.gsskex openssh-6.1p1/configure.ac AC_DEFINE([AU_IPv4], [0], [System only supports IPv4 audit records]) diff -up openssh-6.1p1/gss-genr.c.gsskex openssh-6.1p1/gss-genr.c --- openssh-6.1p1/gss-genr.c.gsskex 2009-06-22 08:11:07.000000000 +0200 -+++ openssh-6.1p1/gss-genr.c 2012-09-14 20:57:55.867266949 +0200 ++++ openssh-6.1p1/gss-genr.c 2012-11-30 13:58:08.949298640 +0100 @@ -1,7 +1,7 @@ /* $OpenBSD: gss-genr.c,v 1.20 2009/06/22 05:39:28 dtucker Exp $ */ @@ -619,7 +736,7 @@ diff -up openssh-6.1p1/gss-genr.c.gsskex openssh-6.1p1/gss-genr.c #endif /* GSSAPI */ diff -up openssh-6.1p1/gss-serv.c.gsskex openssh-6.1p1/gss-serv.c --- openssh-6.1p1/gss-serv.c.gsskex 2011-08-05 22:16:46.000000000 +0200 -+++ openssh-6.1p1/gss-serv.c 2012-09-14 20:57:55.870266969 +0200 ++++ openssh-6.1p1/gss-serv.c 2012-11-30 13:58:08.949298640 +0100 @@ -45,15 +45,20 @@ #include "channels.h" #include "session.h" @@ -960,7 +1077,7 @@ diff -up openssh-6.1p1/gss-serv.c.gsskex openssh-6.1p1/gss-serv.c #endif diff -up openssh-6.1p1/gss-serv-krb5.c.gsskex openssh-6.1p1/gss-serv-krb5.c --- openssh-6.1p1/gss-serv-krb5.c.gsskex 2006-09-01 07:38:36.000000000 +0200 -+++ openssh-6.1p1/gss-serv-krb5.c 2012-09-14 20:57:55.872266981 +0200 ++++ openssh-6.1p1/gss-serv-krb5.c 2012-11-30 13:58:08.949298640 +0100 @@ -1,7 +1,7 @@ /* $OpenBSD: gss-serv-krb5.c,v 1.7 2006/08/03 03:34:42 deraadt Exp $ */ @@ -1083,126 +1200,9 @@ diff -up openssh-6.1p1/gss-serv-krb5.c.gsskex openssh-6.1p1/gss-serv-krb5.c }; #endif /* KRB5 */ -diff -up openssh-6.1p1/ChangeLog.gssapi.gsskex openssh-6.1p1/ChangeLog.gssapi ---- openssh-6.1p1/ChangeLog.gssapi.gsskex 2012-09-14 20:57:55.858266892 +0200 -+++ openssh-6.1p1/ChangeLog.gssapi 2012-09-14 20:57:55.859266899 +0200 -@@ -0,0 +1,113 @@ -+20110101 -+ - Finally update for OpenSSH 5.6p1 -+ - Add GSSAPIServerIdentity option from Jim Basney -+ -+20100308 -+ - [ Makefile.in, key.c, key.h ] -+ Updates for OpenSSH 5.4p1 -+ - [ servconf.c ] -+ Include GSSAPI options in the sshd -T configuration dump, and flag -+ some older configuration options as being unsupported. Thanks to Colin -+ Watson. -+ - -+ -+20100124 -+ - [ sshconnect2.c ] -+ Adapt to deal with additional element in Authmethod structure. Thanks to -+ Colin Watson -+ -+20090615 -+ - [ gss-genr.c gss-serv.c kexgssc.c kexgsss.c monitor.c sshconnect2.c -+ sshd.c ] -+ Fix issues identified by Greg Hudson following a code review -+ Check return value of gss_indicate_mechs -+ Protect GSSAPI calls in monitor, so they can only be used if enabled -+ Check return values of bignum functions in key exchange -+ Use BN_clear_free to clear other side's DH value -+ Make ssh_gssapi_id_kex more robust -+ Only configure kex table pointers if GSSAPI is enabled -+ Don't leak mechanism list, or gss mechanism list -+ Cast data.length before printing -+ If serverkey isn't provided, use an empty string, rather than NULL -+ -+20090201 -+ - [ gss-genr.c gss-serv.c kex.h kexgssc.c readconf.c readconf.h ssh-gss.h -+ ssh_config.5 sshconnet2.c ] -+ Add support for the GSSAPIClientIdentity option, which allows the user -+ to specify which GSSAPI identity to use to contact a given server -+ -+20080404 -+ - [ gss-serv.c ] -+ Add code to actually implement GSSAPIStrictAcceptCheck, which had somehow -+ been omitted from a previous version of this patch. Reported by Borislav -+ Stoichkov -+ -+20070317 -+ - [ gss-serv-krb5.c ] -+ Remove C99ism, where new_ccname was being declared in the middle of a -+ function -+ -+20061220 -+ - [ servconf.c ] -+ Make default for GSSAPIStrictAcceptorCheck be Yes, to match previous, and -+ documented, behaviour. Reported by Dan Watson. -+ -+20060910 -+ - [ gss-genr.c kexgssc.c kexgsss.c kex.h monitor.c sshconnect2.c sshd.c -+ ssh-gss.h ] -+ add support for gss-group14-sha1 key exchange mechanisms -+ - [ gss-serv.c servconf.c servconf.h sshd_config sshd_config.5 ] -+ Add GSSAPIStrictAcceptorCheck option to allow the disabling of -+ acceptor principal checking on multi-homed machines. -+ -+ - [ sshd_config ssh_config ] -+ Add settings for GSSAPIKeyExchange and GSSAPITrustDNS to the sample -+ configuration files -+ - [ kexgss.c kegsss.c sshconnect2.c sshd.c ] -+ Code cleanup. Replace strlen/xmalloc/snprintf sequences with xasprintf() -+ Limit length of error messages displayed by client -+ -+20060909 -+ - [ gss-genr.c gss-serv.c ] -+ move ssh_gssapi_acquire_cred() and ssh_gssapi_server_ctx to be server -+ only, where they belong -+ -+ -+20060829 -+ - [ gss-serv-krb5.c ] -+ Fix CCAPI credentials cache name when creating KRB5CCNAME environment -+ variable -+ -+20060828 -+ - [ gss-genr.c ] -+ Avoid Heimdal context freeing problem -+ -+ -+20060818 -+ - [ gss-genr.c ssh-gss.h sshconnect2.c ] -+ Make sure that SPENGO is disabled -+ -+ -+20060421 -+ - [ gssgenr.c, sshconnect2.c ] -+ a few type changes (signed versus unsigned, int versus size_t) to -+ fix compiler errors/warnings -+ (from jbasney AT ncsa.uiuc.edu) -+ - [ kexgssc.c, sshconnect2.c ] -+ fix uninitialized variable warnings -+ (from jbasney AT ncsa.uiuc.edu) -+ - [ gssgenr.c ] -+ pass oid to gss_display_status (helpful when using GSSAPI mechglue) -+ (from jbasney AT ncsa.uiuc.edu) -+ -+ - [ gss-serv-krb5.c ] -+ #ifdef HAVE_GSSAPI_KRB5 should be #ifdef HAVE_GSSAPI_KRB5_H -+ (from jbasney AT ncsa.uiuc.edu) -+ -+ - [ readconf.c, readconf.h, ssh_config.5, sshconnect2.c -+ add client-side GssapiKeyExchange option -+ (from jbasney AT ncsa.uiuc.edu) -+ - [ sshconnect2.c ] -+ add support for GssapiTrustDns option for gssapi-with-mic -+ (from jbasney AT ncsa.uiuc.edu) -+ diff -up openssh-6.1p1/kex.c.gsskex openssh-6.1p1/kex.c ---- openssh-6.1p1/kex.c.gsskex 2012-09-14 20:57:55.139262298 +0200 -+++ openssh-6.1p1/kex.c 2012-09-14 20:57:55.874266995 +0200 +--- openssh-6.1p1/kex.c.gsskex 2012-11-30 13:58:08.820299131 +0100 ++++ openssh-6.1p1/kex.c 2012-11-30 13:58:08.950298635 +0100 @@ -51,6 +51,10 @@ #include "roaming.h" #include "audit.h" @@ -1236,8 +1236,8 @@ diff -up openssh-6.1p1/kex.c.gsskex openssh-6.1p1/kex.c fatal("bad kex alg %s", k->name); } diff -up openssh-6.1p1/kexgssc.c.gsskex openssh-6.1p1/kexgssc.c ---- openssh-6.1p1/kexgssc.c.gsskex 2012-09-14 20:57:55.875267001 +0200 -+++ openssh-6.1p1/kexgssc.c 2012-09-14 20:57:55.875267001 +0200 +--- openssh-6.1p1/kexgssc.c.gsskex 2012-11-30 13:58:08.950298635 +0100 ++++ openssh-6.1p1/kexgssc.c 2012-11-30 13:58:08.950298635 +0100 @@ -0,0 +1,334 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. @@ -1574,8 +1574,8 @@ diff -up openssh-6.1p1/kexgssc.c.gsskex openssh-6.1p1/kexgssc.c + +#endif /* GSSAPI */ diff -up openssh-6.1p1/kexgsss.c.gsskex openssh-6.1p1/kexgsss.c ---- openssh-6.1p1/kexgsss.c.gsskex 2012-09-14 20:57:55.876267007 +0200 -+++ openssh-6.1p1/kexgsss.c 2012-09-14 20:57:55.876267007 +0200 +--- openssh-6.1p1/kexgsss.c.gsskex 2012-11-30 13:58:08.950298635 +0100 ++++ openssh-6.1p1/kexgsss.c 2012-11-30 13:58:08.950298635 +0100 @@ -0,0 +1,288 @@ +/* + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. @@ -1866,8 +1866,8 @@ diff -up openssh-6.1p1/kexgsss.c.gsskex openssh-6.1p1/kexgsss.c +} +#endif /* GSSAPI */ diff -up openssh-6.1p1/kex.h.gsskex openssh-6.1p1/kex.h ---- openssh-6.1p1/kex.h.gsskex 2012-09-14 20:57:55.141262312 +0200 -+++ openssh-6.1p1/kex.h 2012-09-14 20:57:55.878267019 +0200 +--- openssh-6.1p1/kex.h.gsskex 2012-11-30 13:58:08.820299131 +0100 ++++ openssh-6.1p1/kex.h 2012-11-30 13:58:08.950298635 +0100 @@ -73,6 +73,9 @@ enum kex_exchange { KEX_DH_GEX_SHA1, KEX_DH_GEX_SHA256, @@ -1904,8 +1904,8 @@ diff -up openssh-6.1p1/kex.h.gsskex openssh-6.1p1/kex.h void diff -up openssh-6.1p1/key.c.gsskex openssh-6.1p1/key.c ---- openssh-6.1p1/key.c.gsskex 2012-09-14 20:57:55.593265199 +0200 -+++ openssh-6.1p1/key.c 2012-09-14 20:57:55.881267039 +0200 +--- openssh-6.1p1/key.c.gsskex 2012-11-30 13:58:08.912298779 +0100 ++++ openssh-6.1p1/key.c 2012-11-30 13:58:08.951298630 +0100 @@ -1011,6 +1011,8 @@ key_ssh_name_from_type_nid(int type, int } break; @@ -1925,8 +1925,8 @@ diff -up openssh-6.1p1/key.c.gsskex openssh-6.1p1/key.c debug2("key_type_from_name: unknown key type '%s'", name); diff -up openssh-6.1p1/key.h.gsskex openssh-6.1p1/key.h ---- openssh-6.1p1/key.h.gsskex 2012-09-14 20:57:55.184262586 +0200 -+++ openssh-6.1p1/key.h 2012-09-14 20:57:55.882267045 +0200 +--- openssh-6.1p1/key.h.gsskex 2012-11-30 13:58:08.827299104 +0100 ++++ openssh-6.1p1/key.h 2012-11-30 13:58:08.951298630 +0100 @@ -44,6 +44,7 @@ enum types { KEY_ECDSA_CERT, KEY_RSA_CERT_V00, @@ -1936,8 +1936,8 @@ diff -up openssh-6.1p1/key.h.gsskex openssh-6.1p1/key.h }; enum fp_type { diff -up openssh-6.1p1/Makefile.in.gsskex openssh-6.1p1/Makefile.in ---- openssh-6.1p1/Makefile.in.gsskex 2012-09-14 20:57:55.832266726 +0200 -+++ openssh-6.1p1/Makefile.in 2012-09-14 20:57:55.884267058 +0200 +--- openssh-6.1p1/Makefile.in.gsskex 2012-11-30 13:58:08.945298652 +0100 ++++ openssh-6.1p1/Makefile.in 2012-11-30 13:58:08.951298630 +0100 @@ -75,6 +75,7 @@ LIBSSH_OBJS=acss.o authfd.o authfile.o b atomicio.o key.o dispatch.o kex.o mac.o uidswap.o uuencode.o misc.o \ monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \ @@ -1956,8 +1956,8 @@ diff -up openssh-6.1p1/Makefile.in.gsskex openssh-6.1p1/Makefile.in sftp-server.o sftp-common.o \ roaming_common.o roaming_serv.o \ diff -up openssh-6.1p1/monitor.c.gsskex openssh-6.1p1/monitor.c ---- openssh-6.1p1/monitor.c.gsskex 2012-09-14 20:57:55.299263321 +0200 -+++ openssh-6.1p1/monitor.c 2012-09-14 20:57:55.888267083 +0200 +--- openssh-6.1p1/monitor.c.gsskex 2012-11-30 13:58:08.873298927 +0100 ++++ openssh-6.1p1/monitor.c 2012-11-30 13:58:08.952298626 +0100 @@ -186,6 +186,8 @@ int mm_answer_gss_setup_ctx(int, Buffer int mm_answer_gss_accept_ctx(int, Buffer *); int mm_answer_gss_userok(int, Buffer *); @@ -1988,7 +1988,7 @@ diff -up openssh-6.1p1/monitor.c.gsskex openssh-6.1p1/monitor.c {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, {MONITOR_REQ_SIGN, 0, mm_answer_sign}, {MONITOR_REQ_PTY, 0, mm_answer_pty}, -@@ -406,6 +415,10 @@ monitor_child_preauth(Authctxt *_authctx +@@ -404,6 +413,10 @@ monitor_child_preauth(Authctxt *_authctx /* Permit requests for moduli and signatures */ monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); @@ -1998,8 +1998,8 @@ diff -up openssh-6.1p1/monitor.c.gsskex openssh-6.1p1/monitor.c +#endif } else { mon_dispatch = mon_dispatch_proto15; - req_auth = &options.required_auth1; -@@ -512,6 +525,10 @@ monitor_child_postauth(struct monitor *p + +@@ -516,6 +529,10 @@ monitor_child_postauth(struct monitor *p monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); @@ -2010,7 +2010,7 @@ diff -up openssh-6.1p1/monitor.c.gsskex openssh-6.1p1/monitor.c } else { mon_dispatch = mon_dispatch_postauth15; monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); -@@ -1939,6 +1956,13 @@ mm_get_kex(Buffer *m) +@@ -1948,6 +1965,13 @@ mm_get_kex(Buffer *m) kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; kex->kex[KEX_ECDH_SHA2] = kexecdh_server; @@ -2024,7 +2024,7 @@ diff -up openssh-6.1p1/monitor.c.gsskex openssh-6.1p1/monitor.c kex->server = 1; kex->hostkey_type = buffer_get_int(m); kex->kex_type = buffer_get_int(m); -@@ -2162,6 +2186,9 @@ mm_answer_gss_setup_ctx(int sock, Buffer +@@ -2171,6 +2195,9 @@ mm_answer_gss_setup_ctx(int sock, Buffer OM_uint32 major; u_int len; @@ -2034,7 +2034,7 @@ diff -up openssh-6.1p1/monitor.c.gsskex openssh-6.1p1/monitor.c goid.elements = buffer_get_string(m, &len); goid.length = len; -@@ -2189,6 +2216,9 @@ mm_answer_gss_accept_ctx(int sock, Buffe +@@ -2198,6 +2225,9 @@ mm_answer_gss_accept_ctx(int sock, Buffe OM_uint32 flags = 0; /* GSI needs this */ u_int len; @@ -2044,7 +2044,7 @@ diff -up openssh-6.1p1/monitor.c.gsskex openssh-6.1p1/monitor.c in.value = buffer_get_string(m, &len); in.length = len; major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags); -@@ -2206,6 +2236,7 @@ mm_answer_gss_accept_ctx(int sock, Buffe +@@ -2215,6 +2245,7 @@ mm_answer_gss_accept_ctx(int sock, Buffe monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); @@ -2052,7 +2052,7 @@ diff -up openssh-6.1p1/monitor.c.gsskex openssh-6.1p1/monitor.c } return (0); } -@@ -2217,6 +2248,9 @@ mm_answer_gss_checkmic(int sock, Buffer +@@ -2226,6 +2257,9 @@ mm_answer_gss_checkmic(int sock, Buffer OM_uint32 ret; u_int len; @@ -2062,7 +2062,7 @@ diff -up openssh-6.1p1/monitor.c.gsskex openssh-6.1p1/monitor.c gssbuf.value = buffer_get_string(m, &len); gssbuf.length = len; mic.value = buffer_get_string(m, &len); -@@ -2243,7 +2277,11 @@ mm_answer_gss_userok(int sock, Buffer *m +@@ -2252,7 +2286,11 @@ mm_answer_gss_userok(int sock, Buffer *m { int authenticated; @@ -2075,7 +2075,7 @@ diff -up openssh-6.1p1/monitor.c.gsskex openssh-6.1p1/monitor.c buffer_clear(m); buffer_put_int(m, authenticated); -@@ -2257,6 +2295,74 @@ mm_answer_gss_userok(int sock, Buffer *m +@@ -2265,6 +2303,74 @@ mm_answer_gss_userok(int sock, Buffer *m /* Monitor loop will terminate if authenticated */ return (authenticated); } @@ -2151,8 +2151,8 @@ diff -up openssh-6.1p1/monitor.c.gsskex openssh-6.1p1/monitor.c #ifdef JPAKE diff -up openssh-6.1p1/monitor.h.gsskex openssh-6.1p1/monitor.h ---- openssh-6.1p1/monitor.h.gsskex 2012-09-14 20:57:55.300263327 +0200 -+++ openssh-6.1p1/monitor.h 2012-09-14 20:57:55.889267090 +0200 +--- openssh-6.1p1/monitor.h.gsskex 2012-11-30 13:58:08.873298927 +0100 ++++ openssh-6.1p1/monitor.h 2012-11-30 13:58:08.952298626 +0100 @@ -56,6 +56,8 @@ enum monitor_reqtype { MONITOR_REQ_GSSSTEP, MONITOR_ANS_GSSSTEP, MONITOR_REQ_GSSUSEROK, MONITOR_ANS_GSSUSEROK, @@ -2163,8 +2163,8 @@ diff -up openssh-6.1p1/monitor.h.gsskex openssh-6.1p1/monitor.h MONITOR_REQ_PAM_ACCOUNT, MONITOR_ANS_PAM_ACCOUNT, MONITOR_REQ_PAM_INIT_CTX, MONITOR_ANS_PAM_INIT_CTX, diff -up openssh-6.1p1/monitor_wrap.c.gsskex openssh-6.1p1/monitor_wrap.c ---- openssh-6.1p1/monitor_wrap.c.gsskex 2012-09-14 20:57:55.302263340 +0200 -+++ openssh-6.1p1/monitor_wrap.c 2012-09-14 20:57:55.892267109 +0200 +--- openssh-6.1p1/monitor_wrap.c.gsskex 2012-11-30 13:58:08.873298927 +0100 ++++ openssh-6.1p1/monitor_wrap.c 2012-11-30 13:58:08.952298626 +0100 @@ -1326,7 +1326,7 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss } @@ -2227,8 +2227,8 @@ diff -up openssh-6.1p1/monitor_wrap.c.gsskex openssh-6.1p1/monitor_wrap.c #ifdef JPAKE diff -up openssh-6.1p1/monitor_wrap.h.gsskex openssh-6.1p1/monitor_wrap.h ---- openssh-6.1p1/monitor_wrap.h.gsskex 2012-09-14 20:57:55.304263353 +0200 -+++ openssh-6.1p1/monitor_wrap.h 2012-09-14 20:57:55.893267116 +0200 +--- openssh-6.1p1/monitor_wrap.h.gsskex 2012-11-30 13:58:08.874298923 +0100 ++++ openssh-6.1p1/monitor_wrap.h 2012-11-30 13:58:08.953298623 +0100 @@ -62,8 +62,10 @@ BIGNUM *mm_auth_rsa_generate_challenge(K OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, @@ -2243,7 +2243,7 @@ diff -up openssh-6.1p1/monitor_wrap.h.gsskex openssh-6.1p1/monitor_wrap.h #ifdef USE_PAM diff -up openssh-6.1p1/readconf.c.gsskex openssh-6.1p1/readconf.c --- openssh-6.1p1/readconf.c.gsskex 2011-10-02 09:59:03.000000000 +0200 -+++ openssh-6.1p1/readconf.c 2012-09-14 20:57:55.896267134 +0200 ++++ openssh-6.1p1/readconf.c 2012-11-30 13:58:08.953298623 +0100 @@ -129,6 +129,8 @@ typedef enum { oClearAllForwardings, oNoHostAuthenticationForLocalhost, oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, @@ -2334,7 +2334,7 @@ diff -up openssh-6.1p1/readconf.c.gsskex openssh-6.1p1/readconf.c if (options->kbd_interactive_authentication == -1) diff -up openssh-6.1p1/readconf.h.gsskex openssh-6.1p1/readconf.h --- openssh-6.1p1/readconf.h.gsskex 2011-10-02 09:59:03.000000000 +0200 -+++ openssh-6.1p1/readconf.h 2012-09-14 20:57:55.897267141 +0200 ++++ openssh-6.1p1/readconf.h 2012-11-30 13:58:08.953298623 +0100 @@ -48,7 +48,12 @@ typedef struct { int challenge_response_authentication; /* Try S/Key or TIS, authentication. */ @@ -2349,8 +2349,8 @@ diff -up openssh-6.1p1/readconf.h.gsskex openssh-6.1p1/readconf.h * authentication. */ int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ diff -up openssh-6.1p1/servconf.c.gsskex openssh-6.1p1/servconf.c ---- openssh-6.1p1/servconf.c.gsskex 2012-09-14 20:57:55.760266266 +0200 -+++ openssh-6.1p1/servconf.c 2012-09-14 20:57:55.900267160 +0200 +--- openssh-6.1p1/servconf.c.gsskex 2012-11-30 13:58:08.935298693 +0100 ++++ openssh-6.1p1/servconf.c 2012-11-30 13:58:08.954298621 +0100 @@ -102,7 +102,10 @@ initialize_server_options(ServerOptions options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; @@ -2362,7 +2362,7 @@ diff -up openssh-6.1p1/servconf.c.gsskex openssh-6.1p1/servconf.c options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->challenge_response_authentication = -1; -@@ -236,8 +239,14 @@ fill_default_server_options(ServerOption +@@ -234,8 +237,14 @@ fill_default_server_options(ServerOption options->kerberos_get_afs_token = 0; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -2377,7 +2377,7 @@ diff -up openssh-6.1p1/servconf.c.gsskex openssh-6.1p1/servconf.c if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -333,7 +342,9 @@ typedef enum { +@@ -331,7 +340,9 @@ typedef enum { sBanner, sShowPatchLevel, sUseDNS, sHostbasedAuthentication, sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, @@ -2385,10 +2385,10 @@ diff -up openssh-6.1p1/servconf.c.gsskex openssh-6.1p1/servconf.c + sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, + sGssKeyEx, sGssStoreRekey, + sAcceptEnv, sPermitTunnel, - sRequiredAuthentications1, sRequiredAuthentications2, sMatch, sPermitOpen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, -@@ -399,10 +410,20 @@ static struct { + sZeroKnowledgePasswordAuthentication, sHostCertificate, +@@ -397,10 +408,20 @@ static struct { #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, @@ -2409,7 +2409,7 @@ diff -up openssh-6.1p1/servconf.c.gsskex openssh-6.1p1/servconf.c { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, -@@ -1054,10 +1075,22 @@ process_server_config_line(ServerOptions +@@ -1046,10 +1067,22 @@ process_server_config_line(ServerOptions intptr = &options->gss_authentication; goto parse_flag; @@ -2432,7 +2432,7 @@ diff -up openssh-6.1p1/servconf.c.gsskex openssh-6.1p1/servconf.c case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -1944,6 +1977,9 @@ dump_config(ServerOptions *o) +@@ -1929,6 +1962,9 @@ dump_config(ServerOptions *o) #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); @@ -2443,9 +2443,9 @@ diff -up openssh-6.1p1/servconf.c.gsskex openssh-6.1p1/servconf.c #ifdef JPAKE dump_cfg_fmtint(sZeroKnowledgePasswordAuthentication, diff -up openssh-6.1p1/servconf.h.gsskex openssh-6.1p1/servconf.h ---- openssh-6.1p1/servconf.h.gsskex 2012-09-14 20:57:55.762266278 +0200 -+++ openssh-6.1p1/servconf.h 2012-09-14 20:57:55.902267173 +0200 -@@ -103,7 +103,10 @@ typedef struct { +--- openssh-6.1p1/servconf.h.gsskex 2012-11-30 13:58:08.935298693 +0100 ++++ openssh-6.1p1/servconf.h 2012-11-30 13:58:08.954298621 +0100 +@@ -104,7 +104,10 @@ typedef struct { int kerberos_get_afs_token; /* If true, try to get AFS token if * authenticated with Kerberos. */ int gss_authentication; /* If true, permit GSSAPI authentication */ @@ -2456,21 +2456,9 @@ diff -up openssh-6.1p1/servconf.h.gsskex openssh-6.1p1/servconf.h int password_authentication; /* If true, permit password * authentication. */ int kbd_interactive_authentication; /* If true, permit */ -diff -up openssh-6.1p1/ssh_config.gsskex openssh-6.1p1/ssh_config ---- openssh-6.1p1/ssh_config.gsskex 2012-09-14 20:57:55.707265928 +0200 -+++ openssh-6.1p1/ssh_config 2012-09-14 20:57:55.906267198 +0200 -@@ -26,6 +26,8 @@ - # HostbasedAuthentication no - # GSSAPIAuthentication no - # GSSAPIDelegateCredentials no -+# GSSAPIKeyExchange no -+# GSSAPITrustDNS no - # BatchMode no - # CheckHostIP yes - # AddressFamily any diff -up openssh-6.1p1/ssh_config.5.gsskex openssh-6.1p1/ssh_config.5 --- openssh-6.1p1/ssh_config.5.gsskex 2012-07-02 10:53:38.000000000 +0200 -+++ openssh-6.1p1/ssh_config.5 2012-09-14 20:57:55.904267186 +0200 ++++ openssh-6.1p1/ssh_config.5 2012-11-30 13:58:08.954298621 +0100 @@ -527,11 +527,43 @@ Specifies whether user authentication ba The default is .Dq no . @@ -2516,9 +2504,21 @@ diff -up openssh-6.1p1/ssh_config.5.gsskex openssh-6.1p1/ssh_config.5 .It Cm HashKnownHosts Indicates that .Xr ssh 1 +diff -up openssh-6.1p1/ssh_config.gsskex openssh-6.1p1/ssh_config +--- openssh-6.1p1/ssh_config.gsskex 2012-11-30 13:58:08.927298724 +0100 ++++ openssh-6.1p1/ssh_config 2012-11-30 13:58:08.954298621 +0100 +@@ -26,6 +26,8 @@ + # HostbasedAuthentication no + # GSSAPIAuthentication no + # GSSAPIDelegateCredentials no ++# GSSAPIKeyExchange no ++# GSSAPITrustDNS no + # BatchMode no + # CheckHostIP yes + # AddressFamily any diff -up openssh-6.1p1/sshconnect2.c.gsskex openssh-6.1p1/sshconnect2.c ---- openssh-6.1p1/sshconnect2.c.gsskex 2012-09-14 20:57:55.605265275 +0200 -+++ openssh-6.1p1/sshconnect2.c 2012-09-14 20:57:55.909267218 +0200 +--- openssh-6.1p1/sshconnect2.c.gsskex 2012-11-30 13:58:08.913298775 +0100 ++++ openssh-6.1p1/sshconnect2.c 2012-11-30 13:58:08.955298617 +0100 @@ -162,9 +162,34 @@ ssh_kex2(char *host, struct sockaddr *ho { Kex *kex; @@ -2718,8 +2718,8 @@ diff -up openssh-6.1p1/sshconnect2.c.gsskex openssh-6.1p1/sshconnect2.c int diff -up openssh-6.1p1/sshd.c.gsskex openssh-6.1p1/sshd.c ---- openssh-6.1p1/sshd.c.gsskex 2012-09-14 20:57:55.799266515 +0200 -+++ openssh-6.1p1/sshd.c 2012-09-14 20:57:55.912267237 +0200 +--- openssh-6.1p1/sshd.c.gsskex 2012-11-30 13:58:08.940298674 +0100 ++++ openssh-6.1p1/sshd.c 2012-11-30 13:58:08.955298617 +0100 @@ -124,6 +124,10 @@ #include "ssh-sandbox.h" #include "version.h" @@ -2731,7 +2731,7 @@ diff -up openssh-6.1p1/sshd.c.gsskex openssh-6.1p1/sshd.c #ifdef LIBWRAP #include #include -@@ -1692,10 +1696,13 @@ main(int ac, char **av) +@@ -1723,10 +1727,13 @@ main(int ac, char **av) logit("Disabling protocol version 1. Could not load host key"); options.protocol &= ~SSH_PROTO_1; } @@ -2745,7 +2745,7 @@ diff -up openssh-6.1p1/sshd.c.gsskex openssh-6.1p1/sshd.c if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) { logit("sshd: no hostkeys available -- exiting."); exit(1); -@@ -2027,6 +2034,60 @@ main(int ac, char **av) +@@ -2058,6 +2065,60 @@ main(int ac, char **av) /* Log the connection. */ verbose("Connection from %.500s port %d", remote_ip, remote_port); @@ -2806,7 +2806,7 @@ diff -up openssh-6.1p1/sshd.c.gsskex openssh-6.1p1/sshd.c /* * We don't want to listen forever unless the other side * successfully authenticates itself. So we set up an alarm which is -@@ -2425,6 +2486,48 @@ do_ssh2_kex(void) +@@ -2456,6 +2517,48 @@ do_ssh2_kex(void) myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types(); @@ -2855,7 +2855,7 @@ diff -up openssh-6.1p1/sshd.c.gsskex openssh-6.1p1/sshd.c /* start key exchange */ kex = kex_setup(myproposal); kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; -@@ -2432,6 +2535,13 @@ do_ssh2_kex(void) +@@ -2463,6 +2566,13 @@ do_ssh2_kex(void) kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; kex->kex[KEX_ECDH_SHA2] = kexecdh_server; @@ -2869,22 +2869,10 @@ diff -up openssh-6.1p1/sshd.c.gsskex openssh-6.1p1/sshd.c kex->server = 1; kex->client_version_string=client_version_string; kex->server_version_string=server_version_string; -diff -up openssh-6.1p1/sshd_config.gsskex openssh-6.1p1/sshd_config ---- openssh-6.1p1/sshd_config.gsskex 2012-09-14 20:57:55.801266528 +0200 -+++ openssh-6.1p1/sshd_config 2012-09-14 20:57:55.916267263 +0200 -@@ -85,6 +85,8 @@ ChallengeResponseAuthentication no - GSSAPIAuthentication yes - #GSSAPICleanupCredentials yes - GSSAPICleanupCredentials yes -+#GSSAPIStrictAcceptorCheck yes -+#GSSAPIKeyExchange no - - # Set this to 'yes' to enable PAM authentication, account processing, - # and session processing. If this is enabled, PAM authentication will diff -up openssh-6.1p1/sshd_config.5.gsskex openssh-6.1p1/sshd_config.5 ---- openssh-6.1p1/sshd_config.5.gsskex 2012-09-14 20:57:55.767266310 +0200 -+++ openssh-6.1p1/sshd_config.5 2012-09-14 20:57:55.915267256 +0200 -@@ -439,12 +439,40 @@ Specifies whether user authentication ba +--- openssh-6.1p1/sshd_config.5.gsskex 2012-11-30 13:58:08.935298693 +0100 ++++ openssh-6.1p1/sshd_config.5 2012-11-30 13:58:08.956298613 +0100 +@@ -462,12 +462,40 @@ Specifies whether user authentication ba The default is .Dq no . Note that this option applies to protocol version 2 only. @@ -2925,9 +2913,21 @@ diff -up openssh-6.1p1/sshd_config.5.gsskex openssh-6.1p1/sshd_config.5 .It Cm HostbasedAuthentication Specifies whether rhosts or /etc/hosts.equiv authentication together with successful public key client host authentication is allowed +diff -up openssh-6.1p1/sshd_config.gsskex openssh-6.1p1/sshd_config +--- openssh-6.1p1/sshd_config.gsskex 2012-11-30 13:58:08.940298674 +0100 ++++ openssh-6.1p1/sshd_config 2012-11-30 13:58:08.956298613 +0100 +@@ -89,6 +89,8 @@ ChallengeResponseAuthentication no + GSSAPIAuthentication yes + #GSSAPICleanupCredentials yes + GSSAPICleanupCredentials yes ++#GSSAPIStrictAcceptorCheck yes ++#GSSAPIKeyExchange no + + # Set this to 'yes' to enable PAM authentication, account processing, + # and session processing. If this is enabled, PAM authentication will diff -up openssh-6.1p1/ssh-gss.h.gsskex openssh-6.1p1/ssh-gss.h --- openssh-6.1p1/ssh-gss.h.gsskex 2007-06-12 15:40:39.000000000 +0200 -+++ openssh-6.1p1/ssh-gss.h 2012-09-14 20:57:55.918267275 +0200 ++++ openssh-6.1p1/ssh-gss.h 2012-11-30 13:58:08.956298613 +0100 @@ -1,6 +1,6 @@ /* $OpenBSD: ssh-gss.h,v 1.10 2007/06/12 08:20:00 djm Exp $ */ /* diff --git a/openssh-6.1p1-role-mls.patch b/openssh-6.1p1-role-mls.patch new file mode 100644 index 0000000..4de3dae --- /dev/null +++ b/openssh-6.1p1-role-mls.patch @@ -0,0 +1,934 @@ +diff -up openssh-6.1p1/auth1.c.role-mls openssh-6.1p1/auth1.c +--- openssh-6.1p1/auth1.c.role-mls 2012-11-28 17:06:43.657990103 +0100 ++++ openssh-6.1p1/auth1.c 2012-11-28 17:06:43.699989959 +0100 +@@ -384,6 +384,9 @@ do_authentication(Authctxt *authctxt) + { + u_int ulen; + char *user, *style = NULL; ++#ifdef WITH_SELINUX ++ char *role=NULL; ++#endif + + /* Get the name of the user that we wish to log in as. */ + packet_read_expect(SSH_CMSG_USER); +@@ -392,11 +395,24 @@ do_authentication(Authctxt *authctxt) + user = packet_get_cstring(&ulen); + packet_check_eom(); + ++#ifdef WITH_SELINUX ++ if ((role = strchr(user, '/')) != NULL) ++ *role++ = '\0'; ++#endif ++ + if ((style = strchr(user, ':')) != NULL) + *style++ = '\0'; ++#ifdef WITH_SELINUX ++ else ++ if (role && (style = strchr(role, ':')) != NULL) ++ *style++ = '\0'; ++#endif + + authctxt->user = user; + authctxt->style = style; ++#ifdef WITH_SELINUX ++ authctxt->role = role; ++#endif + + /* Verify that the user is a valid user. */ + if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL) +diff -up openssh-6.1p1/auth2.c.role-mls openssh-6.1p1/auth2.c +--- openssh-6.1p1/auth2.c.role-mls 2012-11-28 17:06:43.661990089 +0100 ++++ openssh-6.1p1/auth2.c 2012-11-28 17:11:09.058916613 +0100 +@@ -218,6 +218,9 @@ input_userauth_request(int type, u_int32 + Authctxt *authctxt = ctxt; + Authmethod *m = NULL; + char *user, *service, *method, *style = NULL; ++#ifdef WITH_SELINUX ++ char *role = NULL; ++#endif + int authenticated = 0; + + if (authctxt == NULL) +@@ -229,6 +232,11 @@ input_userauth_request(int type, u_int32 + debug("userauth-request for user %s service %s method %s", user, service, method); + debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); + ++#ifdef WITH_SELINUX ++ if ((role = strchr(user, '/')) != NULL) ++ *role++ = 0; ++#endif ++ + if ((style = strchr(user, ':')) != NULL) + *style++ = 0; + +@@ -251,8 +259,15 @@ input_userauth_request(int type, u_int32 + use_privsep ? " [net]" : ""); + authctxt->service = xstrdup(service); + authctxt->style = style ? xstrdup(style) : NULL; +- if (use_privsep) ++#ifdef WITH_SELINUX ++ authctxt->role = role ? xstrdup(role) : NULL; ++#endif ++ if (use_privsep) { + mm_inform_authserv(service, style); ++#ifdef WITH_SELINUX ++ mm_inform_authrole(role); ++#endif ++ } + userauth_banner(); + if (auth2_setup_methods_lists(authctxt) != 0) + packet_disconnect("no authentication methods enabled"); +diff -up openssh-6.1p1/auth2-gss.c.role-mls openssh-6.1p1/auth2-gss.c +--- openssh-6.1p1/auth2-gss.c.role-mls 2011-05-05 06:04:11.000000000 +0200 ++++ openssh-6.1p1/auth2-gss.c 2012-11-28 17:06:43.700989956 +0100 +@@ -260,6 +260,7 @@ input_gssapi_mic(int type, u_int32_t ple + Authctxt *authctxt = ctxt; + Gssctxt *gssctxt; + int authenticated = 0; ++ char *micuser; + Buffer b; + gss_buffer_desc mic, gssbuf; + u_int len; +@@ -272,7 +273,13 @@ input_gssapi_mic(int type, u_int32_t ple + mic.value = packet_get_string(&len); + mic.length = len; + +- ssh_gssapi_buildmic(&b, authctxt->user, authctxt->service, ++#ifdef WITH_SELINUX ++ if (authctxt->role && (strlen(authctxt->role) > 0)) ++ xasprintf(&micuser, "%s/%s", authctxt->user, authctxt->role); ++ else ++#endif ++ micuser = authctxt->user; ++ ssh_gssapi_buildmic(&b, micuser, authctxt->service, + "gssapi-with-mic"); + + gssbuf.value = buffer_ptr(&b); +@@ -284,6 +291,8 @@ input_gssapi_mic(int type, u_int32_t ple + logit("GSSAPI MIC check failed"); + + buffer_free(&b); ++ if (micuser != authctxt->user) ++ xfree(micuser); + xfree(mic.value); + + authctxt->postponed = 0; +diff -up openssh-6.1p1/auth2-hostbased.c.role-mls openssh-6.1p1/auth2-hostbased.c +--- openssh-6.1p1/auth2-hostbased.c.role-mls 2012-11-28 17:06:43.669990062 +0100 ++++ openssh-6.1p1/auth2-hostbased.c 2012-11-28 17:06:43.700989956 +0100 +@@ -106,7 +106,15 @@ userauth_hostbased(Authctxt *authctxt) + buffer_put_string(&b, session_id2, session_id2_len); + /* reconstruct packet */ + buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); +- buffer_put_cstring(&b, authctxt->user); ++#ifdef WITH_SELINUX ++ if (authctxt->role) { ++ buffer_put_int(&b, strlen(authctxt->user)+strlen(authctxt->role)+1); ++ buffer_append(&b, authctxt->user, strlen(authctxt->user)); ++ buffer_put_char(&b, '/'); ++ buffer_append(&b, authctxt->role, strlen(authctxt->role)); ++ } else ++#endif ++ buffer_put_cstring(&b, authctxt->user); + buffer_put_cstring(&b, service); + buffer_put_cstring(&b, "hostbased"); + buffer_put_string(&b, pkalg, alen); +diff -up openssh-6.1p1/auth2-pubkey.c.role-mls openssh-6.1p1/auth2-pubkey.c +--- openssh-6.1p1/auth2-pubkey.c.role-mls 2012-11-28 17:06:43.669990062 +0100 ++++ openssh-6.1p1/auth2-pubkey.c 2012-11-28 17:06:43.700989956 +0100 +@@ -121,7 +121,15 @@ userauth_pubkey(Authctxt *authctxt) + } + /* reconstruct packet */ + buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); +- buffer_put_cstring(&b, authctxt->user); ++#ifdef WITH_SELINUX ++ if (authctxt->role) { ++ buffer_put_int(&b, strlen(authctxt->user)+strlen(authctxt->role)+1); ++ buffer_append(&b, authctxt->user, strlen(authctxt->user)); ++ buffer_put_char(&b, '/'); ++ buffer_append(&b, authctxt->role, strlen(authctxt->role)); ++ } else ++#endif ++ buffer_put_cstring(&b, authctxt->user); + buffer_put_cstring(&b, + datafellows & SSH_BUG_PKSERVICE ? + "ssh-userauth" : +diff -up openssh-6.1p1/auth.h.role-mls openssh-6.1p1/auth.h +--- openssh-6.1p1/auth.h.role-mls 2012-11-28 17:06:43.669990062 +0100 ++++ openssh-6.1p1/auth.h 2012-11-28 17:06:43.699989959 +0100 +@@ -59,6 +59,9 @@ struct Authctxt { + char *service; + struct passwd *pw; /* set if 'valid' */ + char *style; ++#ifdef WITH_SELINUX ++ char *role; ++#endif + void *kbdintctxt; + void *jpake_ctx; + #ifdef BSD_AUTH +diff -up openssh-6.1p1/auth-pam.c.role-mls openssh-6.1p1/auth-pam.c +--- openssh-6.1p1/auth-pam.c.role-mls 2012-11-28 17:06:43.638990168 +0100 ++++ openssh-6.1p1/auth-pam.c 2012-11-28 17:06:43.699989959 +0100 +@@ -1074,7 +1074,7 @@ is_pam_session_open(void) + * during the ssh authentication process. + */ + int +-do_pam_putenv(char *name, char *value) ++do_pam_putenv(char *name, const char *value) + { + int ret = 1; + #ifdef HAVE_PAM_PUTENV +diff -up openssh-6.1p1/auth-pam.h.role-mls openssh-6.1p1/auth-pam.h +--- openssh-6.1p1/auth-pam.h.role-mls 2004-09-11 14:17:26.000000000 +0200 ++++ openssh-6.1p1/auth-pam.h 2012-11-28 17:06:43.699989959 +0100 +@@ -38,7 +38,7 @@ void do_pam_session(void); + void do_pam_set_tty(const char *); + void do_pam_setcred(int ); + void do_pam_chauthtok(void); +-int do_pam_putenv(char *, char *); ++int do_pam_putenv(char *, const char *); + char ** fetch_pam_environment(void); + char ** fetch_pam_child_environment(void); + void free_pam_environment(char **); +diff -up openssh-6.1p1/misc.c.role-mls openssh-6.1p1/misc.c +--- openssh-6.1p1/misc.c.role-mls 2011-09-22 13:34:36.000000000 +0200 ++++ openssh-6.1p1/misc.c 2012-11-28 17:06:43.701989952 +0100 +@@ -427,6 +427,7 @@ char * + colon(char *cp) + { + int flag = 0; ++ int start = 1; + + if (*cp == ':') /* Leading colon is part of file name. */ + return NULL; +@@ -442,6 +443,13 @@ colon(char *cp) + return (cp); + if (*cp == '/') + return NULL; ++ if (start) { ++ /* Slash on beginning or after dots only denotes file name. */ ++ if (*cp == '/') ++ return (0); ++ if (*cp != '.') ++ start = 0; ++ } + } + return NULL; + } +diff -up openssh-6.1p1/monitor.c.role-mls openssh-6.1p1/monitor.c +--- openssh-6.1p1/monitor.c.role-mls 2012-11-28 17:06:43.686990004 +0100 ++++ openssh-6.1p1/monitor.c 2012-11-28 17:06:43.701989952 +0100 +@@ -148,6 +148,9 @@ int mm_answer_sign(int, Buffer *); + int mm_answer_pwnamallow(int, Buffer *); + int mm_answer_auth2_read_banner(int, Buffer *); + int mm_answer_authserv(int, Buffer *); ++#ifdef WITH_SELINUX ++int mm_answer_authrole(int, Buffer *); ++#endif + int mm_answer_authpassword(int, Buffer *); + int mm_answer_bsdauthquery(int, Buffer *); + int mm_answer_bsdauthrespond(int, Buffer *); +@@ -231,6 +234,9 @@ struct mon_table mon_dispatch_proto20[] + {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, + {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, + {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, ++#ifdef WITH_SELINUX ++ {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole}, ++#endif + {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, + {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, + #ifdef USE_PAM +@@ -838,6 +844,9 @@ mm_answer_pwnamallow(int sock, Buffer *m + else { + /* Allow service/style information on the auth context */ + monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); ++#ifdef WITH_SELINUX ++ monitor_permit(mon_dispatch, MONITOR_REQ_AUTHROLE, 1); ++#endif + monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); + } + #ifdef USE_PAM +@@ -881,6 +890,25 @@ mm_answer_authserv(int sock, Buffer *m) + return (0); + } + ++#ifdef WITH_SELINUX ++int ++mm_answer_authrole(int sock, Buffer *m) ++{ ++ monitor_permit_authentications(1); ++ ++ authctxt->role = buffer_get_string(m, NULL); ++ debug3("%s: role=%s", ++ __func__, authctxt->role); ++ ++ if (strlen(authctxt->role) == 0) { ++ xfree(authctxt->role); ++ authctxt->role = NULL; ++ } ++ ++ return (0); ++} ++#endif ++ + int + mm_answer_authpassword(int sock, Buffer *m) + { +@@ -1251,7 +1279,7 @@ static int + monitor_valid_userblob(u_char *data, u_int datalen) + { + Buffer b; +- char *p; ++ char *p, *r; + u_int len; + int fail = 0; + +@@ -1277,6 +1305,8 @@ monitor_valid_userblob(u_char *data, u_i + if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) + fail++; + p = buffer_get_string(&b, NULL); ++ if ((r = strchr(p, '/')) != NULL) ++ *r = '\0'; + if (strcmp(authctxt->user, p) != 0) { + logit("wrong user name passed to monitor: expected %s != %.100s", + authctxt->user, p); +@@ -1308,7 +1338,7 @@ monitor_valid_hostbasedblob(u_char *data + char *chost) + { + Buffer b; +- char *p; ++ char *p, *r; + u_int len; + int fail = 0; + +@@ -1325,6 +1355,8 @@ monitor_valid_hostbasedblob(u_char *data + if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) + fail++; + p = buffer_get_string(&b, NULL); ++ if ((r = strchr(p, '/')) != NULL) ++ *r = '\0'; + if (strcmp(authctxt->user, p) != 0) { + logit("wrong user name passed to monitor: expected %s != %.100s", + authctxt->user, p); +diff -up openssh-6.1p1/monitor.h.role-mls openssh-6.1p1/monitor.h +--- openssh-6.1p1/monitor.h.role-mls 2012-11-28 17:06:43.686990004 +0100 ++++ openssh-6.1p1/monitor.h 2012-11-28 17:06:43.701989952 +0100 +@@ -31,6 +31,9 @@ + enum monitor_reqtype { + MONITOR_REQ_MODULI, MONITOR_ANS_MODULI, + MONITOR_REQ_FREE, MONITOR_REQ_AUTHSERV, ++#ifdef WITH_SELINUX ++ MONITOR_REQ_AUTHROLE, ++#endif + MONITOR_REQ_SIGN, MONITOR_ANS_SIGN, + MONITOR_REQ_PWNAM, MONITOR_ANS_PWNAM, + MONITOR_REQ_AUTH2_READ_BANNER, MONITOR_ANS_AUTH2_READ_BANNER, +diff -up openssh-6.1p1/monitor_wrap.c.role-mls openssh-6.1p1/monitor_wrap.c +--- openssh-6.1p1/monitor_wrap.c.role-mls 2012-11-28 17:06:43.686990004 +0100 ++++ openssh-6.1p1/monitor_wrap.c 2012-11-28 17:06:43.702989948 +0100 +@@ -336,6 +336,25 @@ mm_inform_authserv(char *service, char * + buffer_free(&m); + } + ++/* Inform the privileged process about role */ ++ ++#ifdef WITH_SELINUX ++void ++mm_inform_authrole(char *role) ++{ ++ Buffer m; ++ ++ debug3("%s entering", __func__); ++ ++ buffer_init(&m); ++ buffer_put_cstring(&m, role ? role : ""); ++ ++ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHROLE, &m); ++ ++ buffer_free(&m); ++} ++#endif ++ + /* Do the password authentication */ + int + mm_auth_password(Authctxt *authctxt, char *password) +diff -up openssh-6.1p1/monitor_wrap.h.role-mls openssh-6.1p1/monitor_wrap.h +--- openssh-6.1p1/monitor_wrap.h.role-mls 2012-11-28 17:06:43.686990004 +0100 ++++ openssh-6.1p1/monitor_wrap.h 2012-11-28 17:06:43.702989948 +0100 +@@ -42,6 +42,9 @@ int mm_is_monitor(void); + DH *mm_choose_dh(int, int, int); + int mm_key_sign(Key *, u_char **, u_int *, u_char *, u_int); + void mm_inform_authserv(char *, char *); ++#ifdef WITH_SELINUX ++void mm_inform_authrole(char *); ++#endif + struct passwd *mm_getpwnamallow(const char *); + char *mm_auth2_read_banner(void); + int mm_auth_password(struct Authctxt *, char *); +diff -up openssh-6.1p1/openbsd-compat/Makefile.in.role-mls openssh-6.1p1/openbsd-compat/Makefile.in +--- openssh-6.1p1/openbsd-compat/Makefile.in.role-mls 2011-11-04 01:25:25.000000000 +0100 ++++ openssh-6.1p1/openbsd-compat/Makefile.in 2012-11-28 17:06:43.702989948 +0100 +@@ -20,7 +20,7 @@ OPENBSD=base64.o basename.o bindresvport + + COMPAT=bsd-arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o + +-PORTS=port-aix.o port-irix.o port-linux.o port-solaris.o port-tun.o port-uw.o ++PORTS=port-aix.o port-irix.o port-linux.o port-linux_part_2.o port-solaris.o port-tun.o port-uw.o + + .c.o: + $(CC) $(CFLAGS) $(CPPFLAGS) -c $< +diff -up openssh-6.1p1/openbsd-compat/port-linux.c.role-mls openssh-6.1p1/openbsd-compat/port-linux.c +--- openssh-6.1p1/openbsd-compat/port-linux.c.role-mls 2012-03-09 00:25:18.000000000 +0100 ++++ openssh-6.1p1/openbsd-compat/port-linux.c 2012-11-28 17:06:43.702989948 +0100 +@@ -31,68 +31,271 @@ + + #include "log.h" + #include "xmalloc.h" ++#include "servconf.h" + #include "port-linux.h" ++#include "key.h" ++#include "hostfile.h" ++#include "auth.h" + + #ifdef WITH_SELINUX + #include + #include ++#include + #include ++#include ++#include ++ ++#ifdef HAVE_LINUX_AUDIT ++#include ++#include ++#endif + + #ifndef SSH_SELINUX_UNCONFINED_TYPE + # define SSH_SELINUX_UNCONFINED_TYPE ":unconfined_t:" + #endif + +-/* Wrapper around is_selinux_enabled() to log its return value once only */ +-int +-ssh_selinux_enabled(void) ++extern ServerOptions options; ++extern Authctxt *the_authctxt; ++extern int inetd_flag; ++extern int rexeced_flag; ++ ++/* Send audit message */ ++static int ++send_audit_message(int success, security_context_t default_context, ++ security_context_t selected_context) ++{ ++ int rc=0; ++#ifdef HAVE_LINUX_AUDIT ++ char *msg = NULL; ++ int audit_fd = audit_open(); ++ security_context_t default_raw=NULL; ++ security_context_t selected_raw=NULL; ++ rc = -1; ++ if (audit_fd < 0) { ++ if (errno == EINVAL || errno == EPROTONOSUPPORT || ++ errno == EAFNOSUPPORT) ++ return 0; /* No audit support in kernel */ ++ error("Error connecting to audit system."); ++ return rc; ++ } ++ if (selinux_trans_to_raw_context(default_context, &default_raw) < 0) { ++ error("Error translating default context."); ++ default_raw = NULL; ++ } ++ if (selinux_trans_to_raw_context(selected_context, &selected_raw) < 0) { ++ error("Error translating selected context."); ++ selected_raw = NULL; ++ } ++ if (asprintf(&msg, "sshd: default-context=%s selected-context=%s", ++ default_raw ? default_raw : (default_context ? default_context: "?"), ++ selected_context ? selected_raw : (selected_context ? selected_context :"?")) < 0) { ++ error("Error allocating memory."); ++ goto out; ++ } ++ if (audit_log_user_message(audit_fd, AUDIT_USER_ROLE_CHANGE, ++ msg, NULL, NULL, NULL, success) <= 0) { ++ error("Error sending audit message."); ++ goto out; ++ } ++ rc = 0; ++ out: ++ free(msg); ++ freecon(default_raw); ++ freecon(selected_raw); ++ close(audit_fd); ++#endif ++ return rc; ++} ++ ++static int ++mls_range_allowed(security_context_t src, security_context_t dst) + { +- static int enabled = -1; ++ struct av_decision avd; ++ int retval; ++ unsigned int bit = CONTEXT__CONTAINS; ++ ++ debug("%s: src:%s dst:%s", __func__, src, dst); ++ retval = security_compute_av(src, dst, SECCLASS_CONTEXT, bit, &avd); ++ if (retval || ((bit & avd.allowed) != bit)) ++ return 0; ++ ++ return 1; ++} ++ ++static int ++get_user_context(const char *sename, const char *role, const char *lvl, ++ security_context_t *sc) { ++#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL ++ if (lvl == NULL || lvl[0] == '\0' || get_default_context_with_level(sename, lvl, NULL, sc) != 0) { ++ /* User may have requested a level completely outside of his ++ allowed range. We get a context just for auditing as the ++ range check below will certainly fail for default context. */ ++#endif ++ if (get_default_context(sename, NULL, sc) != 0) { ++ *sc = NULL; ++ return -1; ++ } ++#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL ++ } ++#endif ++ if (role != NULL && role[0]) { ++ context_t con; ++ char *type=NULL; ++ if (get_default_type(role, &type) != 0) { ++ error("get_default_type: failed to get default type for '%s'", ++ role); ++ goto out; ++ } ++ con = context_new(*sc); ++ if (!con) { ++ goto out; ++ } ++ context_role_set(con, role); ++ context_type_set(con, type); ++ freecon(*sc); ++ *sc = strdup(context_str(con)); ++ context_free(con); ++ if (!*sc) ++ return -1; ++ } ++#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL ++ if (lvl != NULL && lvl[0]) { ++ /* verify that the requested range is obtained */ ++ context_t con; ++ security_context_t obtained_raw; ++ security_context_t requested_raw; ++ con = context_new(*sc); ++ if (!con) { ++ goto out; ++ } ++ context_range_set(con, lvl); ++ if (selinux_trans_to_raw_context(*sc, &obtained_raw) < 0) { ++ context_free(con); ++ goto out; ++ } ++ if (selinux_trans_to_raw_context(context_str(con), &requested_raw) < 0) { ++ freecon(obtained_raw); ++ context_free(con); ++ goto out; ++ } + +- if (enabled == -1) { +- enabled = (is_selinux_enabled() == 1); +- debug("SELinux support %s", enabled ? "enabled" : "disabled"); ++ debug("get_user_context: obtained context '%s' requested context '%s'", ++ obtained_raw, requested_raw); ++ if (strcmp(obtained_raw, requested_raw)) { ++ /* set the context to the real requested one but fail */ ++ freecon(requested_raw); ++ freecon(obtained_raw); ++ freecon(*sc); ++ *sc = strdup(context_str(con)); ++ context_free(con); ++ return -1; ++ } ++ freecon(requested_raw); ++ freecon(obtained_raw); ++ context_free(con); + } ++#endif ++ return 0; ++ out: ++ freecon(*sc); ++ *sc = NULL; ++ return -1; ++} + +- return (enabled); ++static void ++ssh_selinux_get_role_level(char **role, const char **level) ++{ ++ *role = NULL; ++ *level = NULL; ++ if (the_authctxt) { ++ if (the_authctxt->role != NULL) { ++ char *slash; ++ *role = xstrdup(the_authctxt->role); ++ if ((slash = strchr(*role, '/')) != NULL) { ++ *slash = '\0'; ++ *level = slash + 1; ++ } ++ } ++ } + } + + /* Return the default security context for the given username */ + static security_context_t +-ssh_selinux_getctxbyname(char *pwname) ++ssh_selinux_getctxbyname(char *pwname, ++ security_context_t *default_sc, security_context_t *user_sc) + { +- security_context_t sc = NULL; +- char *sename = NULL, *lvl = NULL; +- int r; ++ char *sename, *lvl; ++ char *role; ++ const char *reqlvl; ++ int r = 0; ++ context_t con = NULL; ++ ++ ssh_selinux_get_role_level(&role, &reqlvl); + + #ifdef HAVE_GETSEUSERBYNAME +- if (getseuserbyname(pwname, &sename, &lvl) != 0) +- return NULL; ++ if ((r=getseuserbyname(pwname, &sename, &lvl)) != 0) { ++ sename = NULL; ++ lvl = NULL; ++ } + #else + sename = pwname; +- lvl = NULL; ++ lvl = ""; + #endif + ++ if (r == 0) { + #ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL +- r = get_default_context_with_level(sename, lvl, NULL, &sc); ++ r = get_default_context_with_level(sename, lvl, NULL, default_sc); + #else +- r = get_default_context(sename, NULL, &sc); ++ r = get_default_context(sename, NULL, default_sc); + #endif ++ } ++ ++ if (r == 0) { ++ /* If launched from xinetd, we must use current level */ ++ if (inetd_flag && !rexeced_flag) { ++ security_context_t sshdsc=NULL; ++ ++ if (getcon_raw(&sshdsc) < 0) ++ fatal("failed to allocate security context"); ++ ++ if ((con=context_new(sshdsc)) == NULL) ++ fatal("failed to allocate selinux context"); ++ reqlvl = context_range_get(con); ++ freecon(sshdsc); ++ if (reqlvl !=NULL && lvl != NULL && strcmp(reqlvl, lvl) == 0) ++ /* we actually don't change level */ ++ reqlvl = ""; ++ ++ debug("%s: current connection level '%s'", __func__, reqlvl); + +- if (r != 0) { +- switch (security_getenforce()) { +- case -1: +- fatal("%s: ssh_selinux_getctxbyname: " +- "security_getenforce() failed", __func__); +- case 0: +- error("%s: Failed to get default SELinux security " +- "context for %s", __func__, pwname); +- sc = NULL; +- break; +- default: +- fatal("%s: Failed to get default SELinux security " +- "context for %s (in enforcing mode)", +- __func__, pwname); + } ++ ++ if ((reqlvl != NULL && reqlvl[0]) || (role != NULL && role[0])) { ++ r = get_user_context(sename, role, reqlvl, user_sc); ++ ++ if (r == 0 && reqlvl != NULL && reqlvl[0]) { ++ security_context_t default_level_sc = *default_sc; ++ if (role != NULL && role[0]) { ++ if (get_user_context(sename, role, lvl, &default_level_sc) < 0) ++ default_level_sc = *default_sc; ++ } ++ /* verify that the requested range is contained in the user range */ ++ if (mls_range_allowed(default_level_sc, *user_sc)) { ++ logit("permit MLS level %s (user range %s)", reqlvl, lvl); ++ } else { ++ r = -1; ++ error("deny MLS level %s (user range %s)", reqlvl, lvl); ++ } ++ if (default_level_sc != *default_sc) ++ freecon(default_level_sc); ++ } ++ } else { ++ *user_sc = *default_sc; ++ } ++ } ++ if (r != 0) { ++ error("%s: Failed to get default SELinux security " ++ "context for %s", __func__, pwname); + } + + #ifdef HAVE_GETSEUSERBYNAME +@@ -102,7 +305,42 @@ ssh_selinux_getctxbyname(char *pwname) + xfree(lvl); + #endif + +- return sc; ++ if (role != NULL) ++ xfree(role); ++ if (con) ++ context_free(con); ++ ++ return (r); ++} ++ ++/* Setup environment variables for pam_selinux */ ++static int ++ssh_selinux_setup_pam_variables(void) ++{ ++ const char *reqlvl; ++ char *role; ++ char *use_current; ++ int rv; ++ ++ debug3("%s: setting execution context", __func__); ++ ++ ssh_selinux_get_role_level(&role, &reqlvl); ++ ++ rv = do_pam_putenv("SELINUX_ROLE_REQUESTED", role ? role : ""); ++ ++ if (inetd_flag && !rexeced_flag) { ++ use_current = "1"; ++ } else { ++ use_current = ""; ++ rv = rv || do_pam_putenv("SELINUX_LEVEL_REQUESTED", reqlvl ? reqlvl: ""); ++ } ++ ++ rv = rv || do_pam_putenv("SELINUX_USE_CURRENT_RANGE", use_current); ++ ++ if (role != NULL) ++ xfree(role); ++ ++ return rv; + } + + /* Set the execution context to the default for the specified user */ +@@ -110,28 +348,71 @@ void + ssh_selinux_setup_exec_context(char *pwname) + { + security_context_t user_ctx = NULL; ++ int r = 0; ++ security_context_t default_ctx = NULL; + + if (!ssh_selinux_enabled()) + return; + ++ if (options.use_pam) { ++ /* do not compute context, just setup environment for pam_selinux */ ++ if (ssh_selinux_setup_pam_variables()) { ++ switch (security_getenforce()) { ++ case -1: ++ fatal("%s: security_getenforce() failed", __func__); ++ case 0: ++ error("%s: SELinux PAM variable setup failure. Continuing in permissive mode.", ++ __func__); ++ break; ++ default: ++ fatal("%s: SELinux PAM variable setup failure. Aborting connection.", ++ __func__); ++ } ++ } ++ return; ++ } ++ + debug3("%s: setting execution context", __func__); + +- user_ctx = ssh_selinux_getctxbyname(pwname); +- if (setexeccon(user_ctx) != 0) { ++ r = ssh_selinux_getctxbyname(pwname, &default_ctx, &user_ctx); ++ if (r >= 0) { ++ r = setexeccon(user_ctx); ++ if (r < 0) { ++ error("%s: Failed to set SELinux execution context %s for %s", ++ __func__, user_ctx, pwname); ++ } ++#ifdef HAVE_SETKEYCREATECON ++ else if (setkeycreatecon(user_ctx) < 0) { ++ error("%s: Failed to set SELinux keyring creation context %s for %s", ++ __func__, user_ctx, pwname); ++ } ++#endif ++ } ++ if (user_ctx == NULL) { ++ user_ctx = default_ctx; ++ } ++ if (r < 0 || user_ctx != default_ctx) { ++ /* audit just the case when user changed a role or there was ++ a failure */ ++ send_audit_message(r >= 0, default_ctx, user_ctx); ++ } ++ if (r < 0) { + switch (security_getenforce()) { + case -1: + fatal("%s: security_getenforce() failed", __func__); + case 0: +- error("%s: Failed to set SELinux execution " +- "context for %s", __func__, pwname); ++ error("%s: SELinux failure. Continuing in permissive mode.", ++ __func__); + break; + default: +- fatal("%s: Failed to set SELinux execution context " +- "for %s (in enforcing mode)", __func__, pwname); ++ fatal("%s: SELinux failure. Aborting connection.", ++ __func__); + } + } +- if (user_ctx != NULL) ++ if (user_ctx != NULL && user_ctx != default_ctx) + freecon(user_ctx); ++ if (default_ctx != NULL) ++ freecon(default_ctx); + + debug3("%s: done", __func__); + } +@@ -149,7 +430,10 @@ ssh_selinux_setup_pty(char *pwname, cons + + debug3("%s: setting TTY context on %s", __func__, tty); + +- user_ctx = ssh_selinux_getctxbyname(pwname); ++ if (getexeccon(&user_ctx) < 0) { ++ error("%s: getexeccon: %s", __func__, strerror(errno)); ++ goto out; ++ } + + /* XXX: should these calls fatal() upon failure in enforcing mode? */ + +@@ -221,21 +505,6 @@ ssh_selinux_change_context(const char *n + xfree(newctx); + } + +-void +-ssh_selinux_setfscreatecon(const char *path) +-{ +- security_context_t context; +- +- if (!ssh_selinux_enabled()) +- return; +- if (path == NULL) { +- setfscreatecon(NULL); +- return; +- } +- if (matchpathcon(path, 0700, &context) == 0) +- setfscreatecon(context); +-} +- + #endif /* WITH_SELINUX */ + + #ifdef LINUX_OOM_ADJUST +diff -up openssh-6.1p1/openbsd-compat/port-linux_part_2.c.role-mls openssh-6.1p1/openbsd-compat/port-linux_part_2.c +--- openssh-6.1p1/openbsd-compat/port-linux_part_2.c.role-mls 2012-11-28 17:06:43.703989944 +0100 ++++ openssh-6.1p1/openbsd-compat/port-linux_part_2.c 2012-11-28 17:06:43.703989944 +0100 +@@ -0,0 +1,75 @@ ++/* $Id: port-linux.c,v 1.11.4.2 2011/02/04 00:43:08 djm Exp $ */ ++ ++/* ++ * Copyright (c) 2005 Daniel Walsh ++ * Copyright (c) 2006 Damien Miller ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++/* ++ * Linux-specific portability code - just SELinux support at present ++ */ ++ ++#include "includes.h" ++ ++#if defined(WITH_SELINUX) || defined(LINUX_OOM_ADJUST) ++#include ++#include ++#include ++#include ++ ++#include "log.h" ++#include "xmalloc.h" ++#include "port-linux.h" ++#include "key.h" ++#include "hostfile.h" ++#include "auth.h" ++ ++#ifdef WITH_SELINUX ++#include ++#include ++#include ++ ++/* Wrapper around is_selinux_enabled() to log its return value once only */ ++int ++ssh_selinux_enabled(void) ++{ ++ static int enabled = -1; ++ ++ if (enabled == -1) { ++ enabled = (is_selinux_enabled() == 1); ++ debug("SELinux support %s", enabled ? "enabled" : "disabled"); ++ } ++ ++ return (enabled); ++} ++ ++void ++ssh_selinux_setfscreatecon(const char *path) ++{ ++ security_context_t context; ++ ++ if (!ssh_selinux_enabled()) ++ return; ++ if (path == NULL) { ++ setfscreatecon(NULL); ++ return; ++ } ++ if (matchpathcon(path, 0700, &context) == 0) ++ setfscreatecon(context); ++} ++ ++#endif /* WITH_SELINUX */ ++ ++#endif /* WITH_SELINUX || LINUX_OOM_ADJUST */ +diff -up openssh-6.1p1/sshd.c.role-mls openssh-6.1p1/sshd.c +--- openssh-6.1p1/sshd.c.role-mls 2012-11-28 17:06:43.688989996 +0100 ++++ openssh-6.1p1/sshd.c 2012-11-28 17:06:43.703989944 +0100 +@@ -2101,6 +2101,9 @@ main(int ac, char **av) + restore_uid(); + } + #endif ++#ifdef WITH_SELINUX ++ ssh_selinux_setup_exec_context(authctxt->pw->pw_name); ++#endif + #ifdef USE_PAM + if (options.use_pam) { + do_pam_setcred(1); diff --git a/openssh.spec b/openssh.spec index 737c89d..18dbfaf 100644 --- a/openssh.spec +++ b/openssh.spec @@ -120,7 +120,7 @@ Patch202: openssh-5.9p1-audit2.patch # -"- Patch203: openssh-5.9p1-audit3.patch # -"- -Patch204: openssh-6.0p1-audit4.patch +Patch204: openssh-6.1p1-audit4.patch # -"- Patch205: openssh-6.0p1-audit5.patch @@ -132,7 +132,7 @@ Patch301: pam_ssh_agent_auth-0.9.2-seteuid.patch # explicitly make pam callbacks visible Patch302: pam_ssh_agent_auth-0.9.2-visibility.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1641 (WONTFIX) -Patch400: openssh-6.0p1-role-mls.patch +Patch400: openssh-6.1p1-role-mls.patch #? #Patch402: openssh-5.9p1-sftp-chroot.patch #https://bugzilla.mindrot.org/show_bug.cgi?id=1940