ignore SIGPIPE in ssh keyscan
This commit is contained in:
parent
19d4c790a8
commit
69dd72f6ef
1
.gitignore
vendored
1
.gitignore
vendored
@ -4,3 +4,4 @@ pam_ssh_agent_auth-0.9.2.tar.bz2
|
||||
/pam_ssh_agent_auth-0.9.2.tar.bz2
|
||||
/openssh-5.8p1-noacss.tar.bz2
|
||||
/openssh-5.8p2-noacss.tar.bz2
|
||||
/openssh-5.9p1-noacss.tar.bz2
|
||||
|
446
openssh-5.9p1-2auth.patch
Normal file
446
openssh-5.9p1-2auth.patch
Normal file
@ -0,0 +1,446 @@
|
||||
diff -up openssh-5.9p0/auth.h.2auth openssh-5.9p0/auth.h
|
||||
--- openssh-5.9p0/auth.h.2auth 2011-05-29 13:39:38.000000000 +0200
|
||||
+++ openssh-5.9p0/auth.h 2011-09-05 13:16:00.550626991 +0200
|
||||
@@ -149,6 +149,8 @@ int auth_root_allowed(char *);
|
||||
|
||||
char *auth2_read_banner(void);
|
||||
|
||||
+void userauth_restart(const char *);
|
||||
+
|
||||
void privsep_challenge_enable(void);
|
||||
|
||||
int auth2_challenge(Authctxt *, char *);
|
||||
diff -up openssh-5.9p0/auth2.c.2auth openssh-5.9p0/auth2.c
|
||||
--- openssh-5.9p0/auth2.c.2auth 2011-05-05 06:04:11.000000000 +0200
|
||||
+++ openssh-5.9p0/auth2.c 2011-09-05 13:16:00.640626827 +0200
|
||||
@@ -290,6 +290,23 @@ input_userauth_request(int type, u_int32
|
||||
}
|
||||
|
||||
void
|
||||
+userauth_restart(const char *method)
|
||||
+{
|
||||
+ options.two_factor_authentication = 0;
|
||||
+
|
||||
+ options.pubkey_authentication = options.second_pubkey_authentication && strcmp(method, method_pubkey.name);
|
||||
+#ifdef GSSAPI
|
||||
+ options.gss_authentication = options.second_gss_authentication && strcmp(method, method_gssapi.name);
|
||||
+#endif
|
||||
+#ifdef JPAKE
|
||||
+ options.zero_knowledge_password_authentication = options.second_zero_knowledge_password_authentication && strcmp(method, method_jpake.name);
|
||||
+#endif
|
||||
+ options.password_authentication = options.second_password_authentication && strcmp(method, method_passwd.name);
|
||||
+ options.kbd_interactive_authentication = options.second_kbd_interactive_authentication && strcmp(method, method_kbdint.name);
|
||||
+ options.hostbased_authentication = options.second_hostbased_authentication && strcmp(method, method_hostbased.name);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
userauth_finish(Authctxt *authctxt, int authenticated, char *method)
|
||||
{
|
||||
char *methods;
|
||||
@@ -337,6 +354,15 @@ userauth_finish(Authctxt *authctxt, int
|
||||
|
||||
/* XXX todo: check if multiple auth methods are needed */
|
||||
if (authenticated == 1) {
|
||||
+ if (options.two_factor_authentication) {
|
||||
+ userauth_restart(method);
|
||||
+ if (use_privsep)
|
||||
+ PRIVSEP(userauth_restart(method));
|
||||
+
|
||||
+ debug("1st factor authentication done go to 2nd factor");
|
||||
+ goto ask_methods;
|
||||
+ }
|
||||
+
|
||||
/* turn off userauth */
|
||||
dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore);
|
||||
packet_start(SSH2_MSG_USERAUTH_SUCCESS);
|
||||
@@ -356,6 +382,7 @@ userauth_finish(Authctxt *authctxt, int
|
||||
#endif
|
||||
packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
|
||||
}
|
||||
+ask_methods:
|
||||
methods = authmethods_get();
|
||||
packet_start(SSH2_MSG_USERAUTH_FAILURE);
|
||||
packet_put_cstring(methods);
|
||||
diff -up openssh-5.9p0/monitor.c.2auth openssh-5.9p0/monitor.c
|
||||
--- openssh-5.9p0/monitor.c.2auth 2011-08-05 22:15:18.000000000 +0200
|
||||
+++ openssh-5.9p0/monitor.c 2011-09-05 13:37:35.468502112 +0200
|
||||
@@ -165,6 +165,7 @@ int mm_answer_jpake_step1(int, Buffer *)
|
||||
int mm_answer_jpake_step2(int, Buffer *);
|
||||
int mm_answer_jpake_key_confirm(int, Buffer *);
|
||||
int mm_answer_jpake_check_confirm(int, Buffer *);
|
||||
+int mm_answer_userauth_restart(int, Buffer *);
|
||||
|
||||
#ifdef USE_PAM
|
||||
int mm_answer_pam_start(int, Buffer *);
|
||||
@@ -259,6 +260,7 @@ struct mon_table mon_dispatch_proto20[]
|
||||
{MONITOR_REQ_JPAKE_KEY_CONFIRM, MON_ONCE, mm_answer_jpake_key_confirm},
|
||||
{MONITOR_REQ_JPAKE_CHECK_CONFIRM, MON_AUTH, mm_answer_jpake_check_confirm},
|
||||
#endif
|
||||
+ {MONITOR_REQ_USERAUTH_RESTART, MON_PERMIT, mm_answer_userauth_restart},
|
||||
{0, 0, NULL}
|
||||
};
|
||||
|
||||
@@ -378,9 +380,9 @@ monitor_child_preauth(Authctxt *_authctx
|
||||
}
|
||||
|
||||
/* The first few requests do not require asynchronous access */
|
||||
- while (!authenticated) {
|
||||
+ while (!authenticated || options.two_factor_authentication) {
|
||||
auth_method = "unknown";
|
||||
authenticated = (monitor_read(pmonitor, mon_dispatch, &ent) == 1);
|
||||
if (authenticated) {
|
||||
if (!(ent->flags & MON_AUTHDECIDE))
|
||||
fatal("%s: unexpected authentication from %d",
|
||||
@@ -390,7 +393,7 @@ monitor_child_preauth(Authctxt *_authctx
|
||||
authenticated = 0;
|
||||
#ifdef USE_PAM
|
||||
/* PAM needs to perform account checks after auth */
|
||||
- if (options.use_pam && authenticated) {
|
||||
+ if (options.use_pam && authenticated && !options.two_factor_authentication) {
|
||||
Buffer m;
|
||||
|
||||
buffer_init(&m);
|
||||
@@ -2000,6 +2006,19 @@ monitor_reinit(struct monitor *mon)
|
||||
monitor_openfds(mon, 0);
|
||||
}
|
||||
|
||||
+int
|
||||
+mm_answer_userauth_restart(int sock, Buffer *m)
|
||||
+{
|
||||
+ char *method;
|
||||
+ u_int method_len;
|
||||
+
|
||||
+ method = buffer_get_string(m, &method_len);
|
||||
+
|
||||
+ userauth_restart(method);
|
||||
+
|
||||
+ mm_request_send(sock, MONITOR_ANS_USERAUTH_RESTART, m);
|
||||
+}
|
||||
+
|
||||
#ifdef GSSAPI
|
||||
int
|
||||
mm_answer_gss_setup_ctx(int sock, Buffer *m)
|
||||
diff -up openssh-5.9p0/monitor.h.2auth openssh-5.9p0/monitor.h
|
||||
--- openssh-5.9p0/monitor.h.2auth 2011-06-20 06:42:23.000000000 +0200
|
||||
+++ openssh-5.9p0/monitor.h 2011-09-05 13:16:00.855502353 +0200
|
||||
@@ -66,6 +66,7 @@ enum monitor_reqtype {
|
||||
MONITOR_REQ_JPAKE_STEP2, MONITOR_ANS_JPAKE_STEP2,
|
||||
MONITOR_REQ_JPAKE_KEY_CONFIRM, MONITOR_ANS_JPAKE_KEY_CONFIRM,
|
||||
MONITOR_REQ_JPAKE_CHECK_CONFIRM, MONITOR_ANS_JPAKE_CHECK_CONFIRM,
|
||||
+ MONITOR_REQ_USERAUTH_RESTART, MONITOR_ANS_USERAUTH_RESTART,
|
||||
};
|
||||
|
||||
struct mm_master;
|
||||
diff -up openssh-5.9p0/monitor_wrap.c.2auth openssh-5.9p0/monitor_wrap.c
|
||||
--- openssh-5.9p0/monitor_wrap.c.2auth 2011-06-20 06:42:23.000000000 +0200
|
||||
+++ openssh-5.9p0/monitor_wrap.c 2011-09-05 13:16:00.968503257 +0200
|
||||
@@ -1173,6 +1173,26 @@ mm_auth_rsa_verify_response(Key *key, BI
|
||||
return (success);
|
||||
}
|
||||
|
||||
+void
|
||||
+mm_userauth_restart(const char *monitor)
|
||||
+{
|
||||
+ Buffer m;
|
||||
+
|
||||
+ debug3("%s entering", __func__);
|
||||
+
|
||||
+ buffer_init(&m);
|
||||
+
|
||||
+ buffer_put_cstring(&m, monitor);
|
||||
+
|
||||
+ mm_request_send(pmonitor->m_recvfd,
|
||||
+ MONITOR_REQ_USERAUTH_RESTART, &m);
|
||||
+ debug3("%s: waiting for MONITOR_ANS_USERAUTH_RESTART", __func__);
|
||||
+ mm_request_receive_expect(pmonitor->m_recvfd,
|
||||
+ MONITOR_ANS_USERAUTH_RESTART, &m);
|
||||
+
|
||||
+ buffer_free(&m);
|
||||
+}
|
||||
+
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
void
|
||||
mm_audit_event(ssh_audit_event_t event)
|
||||
diff -up openssh-5.9p0/monitor_wrap.h.2auth openssh-5.9p0/monitor_wrap.h
|
||||
--- openssh-5.9p0/monitor_wrap.h.2auth 2011-06-20 06:42:23.000000000 +0200
|
||||
+++ openssh-5.9p0/monitor_wrap.h 2011-09-05 13:16:01.074502211 +0200
|
||||
@@ -53,6 +53,7 @@ int mm_key_verify(Key *, u_char *, u_int
|
||||
int mm_auth_rsa_key_allowed(struct passwd *, BIGNUM *, Key **);
|
||||
int mm_auth_rsa_verify_response(Key *, BIGNUM *, u_char *);
|
||||
BIGNUM *mm_auth_rsa_generate_challenge(Key *);
|
||||
+void mm_userauth_restart(const char *);
|
||||
|
||||
#ifdef GSSAPI
|
||||
OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID);
|
||||
diff -up openssh-5.9p0/servconf.c.2auth openssh-5.9p0/servconf.c
|
||||
--- openssh-5.9p0/servconf.c.2auth 2011-06-23 00:30:03.000000000 +0200
|
||||
+++ openssh-5.9p0/servconf.c 2011-09-05 13:16:01.223441110 +0200
|
||||
@@ -92,6 +92,13 @@ initialize_server_options(ServerOptions
|
||||
options->hostbased_uses_name_from_packet_only = -1;
|
||||
options->rsa_authentication = -1;
|
||||
options->pubkey_authentication = -1;
|
||||
+ options->two_factor_authentication = -1;
|
||||
+ options->second_pubkey_authentication = -1;
|
||||
+ options->second_gss_authentication = -1;
|
||||
+ options->second_password_authentication = -1;
|
||||
+ options->second_kbd_interactive_authentication = -1;
|
||||
+ options->second_zero_knowledge_password_authentication = -1;
|
||||
+ options->second_hostbased_authentication = -1;
|
||||
options->kerberos_authentication = -1;
|
||||
options->kerberos_or_local_passwd = -1;
|
||||
options->kerberos_ticket_cleanup = -1;
|
||||
@@ -237,6 +244,20 @@ fill_default_server_options(ServerOption
|
||||
options->permit_empty_passwd = 0;
|
||||
if (options->permit_user_env == -1)
|
||||
options->permit_user_env = 0;
|
||||
+ if (options->two_factor_authentication == -1)
|
||||
+ options->two_factor_authentication = 0;
|
||||
+ if (options->second_pubkey_authentication == -1)
|
||||
+ options->second_pubkey_authentication = 1;
|
||||
+ if (options->second_gss_authentication == -1)
|
||||
+ options->second_gss_authentication = 0;
|
||||
+ if (options->second_password_authentication == -1)
|
||||
+ options->second_password_authentication = 1;
|
||||
+ if (options->second_kbd_interactive_authentication == -1)
|
||||
+ options->second_kbd_interactive_authentication = 0;
|
||||
+ if (options->second_zero_knowledge_password_authentication == -1)
|
||||
+ options->second_zero_knowledge_password_authentication = 0;
|
||||
+ if (options->second_hostbased_authentication == -1)
|
||||
+ options->second_hostbased_authentication = 0;
|
||||
if (options->use_login == -1)
|
||||
options->use_login = 0;
|
||||
if (options->compression == -1)
|
||||
@@ -316,8 +337,11 @@ typedef enum {
|
||||
sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
|
||||
sMaxStartups, sMaxAuthTries, sMaxSessions,
|
||||
sBanner, sUseDNS, sHostbasedAuthentication,
|
||||
- sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
|
||||
- sClientAliveCountMax, sAuthorizedKeysFile,
|
||||
+ sHostbasedUsesNameFromPacketOnly, sTwoFactorAuthentication,
|
||||
+ sSecondPubkeyAuthentication, sSecondGssAuthentication,
|
||||
+ sSecondPasswordAuthentication, sSecondKbdInteractiveAuthentication,
|
||||
+ sSecondZeroKnowledgePasswordAuthentication, sSecondHostbasedAuthentication,
|
||||
+ sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
|
||||
sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
|
||||
sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
|
||||
sUsePrivilegeSeparation, sAllowAgentForwarding,
|
||||
@@ -395,6 +419,21 @@ static struct {
|
||||
#else
|
||||
{ "zeroknowledgepasswordauthentication", sUnsupported, SSHCFG_ALL },
|
||||
#endif
|
||||
+ { "twofactorauthentication", sTwoFactorAuthentication, SSHCFG_ALL },
|
||||
+ { "secondpubkeyauthentication", sSecondPubkeyAuthentication, SSHCFG_ALL },
|
||||
+#ifdef GSSAPI
|
||||
+ { "secondgssapiauthentication", sSecondGssAuthentication, SSHCFG_ALL },
|
||||
+#else
|
||||
+ { "secondgssapiauthentication", sUnsupported, SSHCFG_ALL },
|
||||
+#endif
|
||||
+ { "secondpasswordauthentication", sSecondPasswordAuthentication, SSHCFG_ALL },
|
||||
+ { "secondkbdinteractiveauthentication", sSecondKbdInteractiveAuthentication, SSHCFG_ALL },
|
||||
+#ifdef JPAKE
|
||||
+ { "secondzeroknowledgepasswordauthentication", sSecondZeroKnowledgePasswordAuthentication, SSHCFG_ALL },
|
||||
+#else
|
||||
+ { "secondzeroknowledgepasswordauthentication", sUnsupported, SSHCFG_ALL },
|
||||
+#endif
|
||||
+ { "secondhostbasedauthentication", sSecondHostbasedAuthentication, SSHCFG_ALL },
|
||||
{ "checkmail", sDeprecated, SSHCFG_GLOBAL },
|
||||
{ "listenaddress", sListenAddress, SSHCFG_GLOBAL },
|
||||
{ "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
|
||||
@@ -982,6 +1021,34 @@ process_server_config_line(ServerOptions
|
||||
intptr = &options->challenge_response_authentication;
|
||||
goto parse_flag;
|
||||
|
||||
+ case sTwoFactorAuthentication:
|
||||
+ intptr = &options->two_factor_authentication;
|
||||
+ goto parse_flag;
|
||||
+
|
||||
+ case sSecondPubkeyAuthentication:
|
||||
+ intptr = &options->second_pubkey_authentication;
|
||||
+ goto parse_flag;
|
||||
+
|
||||
+ case sSecondGssAuthentication:
|
||||
+ intptr = &options->second_gss_authentication;
|
||||
+ goto parse_flag;
|
||||
+
|
||||
+ case sSecondPasswordAuthentication:
|
||||
+ intptr = &options->second_password_authentication;
|
||||
+ goto parse_flag;
|
||||
+
|
||||
+ case sSecondKbdInteractiveAuthentication:
|
||||
+ intptr = &options->second_kbd_interactive_authentication;
|
||||
+ goto parse_flag;
|
||||
+
|
||||
+ case sSecondZeroKnowledgePasswordAuthentication:
|
||||
+ intptr = &options->second_zero_knowledge_password_authentication;
|
||||
+ goto parse_flag;
|
||||
+
|
||||
+ case sSecondHostbasedAuthentication:
|
||||
+ intptr = &options->second_hostbased_authentication;
|
||||
+ goto parse_flag;
|
||||
+
|
||||
case sPrintMotd:
|
||||
intptr = &options->print_motd;
|
||||
goto parse_flag;
|
||||
@@ -1491,14 +1558,21 @@ void
|
||||
copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
|
||||
{
|
||||
M_CP_INTOPT(password_authentication);
|
||||
+ M_CP_INTOPT(second_password_authentication);
|
||||
M_CP_INTOPT(gss_authentication);
|
||||
+ M_CP_INTOPT(second_gss_authentication);
|
||||
M_CP_INTOPT(rsa_authentication);
|
||||
M_CP_INTOPT(pubkey_authentication);
|
||||
+ M_CP_INTOPT(second_pubkey_authentication);
|
||||
M_CP_INTOPT(kerberos_authentication);
|
||||
M_CP_INTOPT(hostbased_authentication);
|
||||
+ M_CP_INTOPT(second_hostbased_authentication);
|
||||
M_CP_INTOPT(hostbased_uses_name_from_packet_only);
|
||||
M_CP_INTOPT(kbd_interactive_authentication);
|
||||
+ M_CP_INTOPT(second_kbd_interactive_authentication);
|
||||
M_CP_INTOPT(zero_knowledge_password_authentication);
|
||||
+ M_CP_INTOPT(second_zero_knowledge_password_authentication);
|
||||
+ M_CP_INTOPT(two_factor_authentication);
|
||||
M_CP_INTOPT(permit_root_login);
|
||||
M_CP_INTOPT(permit_empty_passwd);
|
||||
|
||||
@@ -1720,17 +1794,24 @@ dump_config(ServerOptions *o)
|
||||
#endif
|
||||
#ifdef GSSAPI
|
||||
dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
|
||||
+ dump_cfg_fmtint(sSecondGssAuthentication, o->second_gss_authentication);
|
||||
dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds);
|
||||
#endif
|
||||
#ifdef JPAKE
|
||||
dump_cfg_fmtint(sZeroKnowledgePasswordAuthentication,
|
||||
o->zero_knowledge_password_authentication);
|
||||
+ dump_cfg_fmtint(sSecondZeroKnowledgePasswordAuthentication,
|
||||
+ o->second_zero_knowledge_password_authentication);
|
||||
#endif
|
||||
dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
|
||||
+ dump_cfg_fmtint(sSecondPasswordAuthentication, o->second_password_authentication);
|
||||
dump_cfg_fmtint(sKbdInteractiveAuthentication,
|
||||
o->kbd_interactive_authentication);
|
||||
+ dump_cfg_fmtint(sSecondKbdInteractiveAuthentication,
|
||||
+ o->second_kbd_interactive_authentication);
|
||||
dump_cfg_fmtint(sChallengeResponseAuthentication,
|
||||
o->challenge_response_authentication);
|
||||
+ dump_cfg_fmtint(sTwoFactorAuthentication, o->two_factor_authentication);
|
||||
dump_cfg_fmtint(sPrintMotd, o->print_motd);
|
||||
dump_cfg_fmtint(sPrintLastLog, o->print_lastlog);
|
||||
dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding);
|
||||
diff -up openssh-5.9p0/servconf.h.2auth openssh-5.9p0/servconf.h
|
||||
--- openssh-5.9p0/servconf.h.2auth 2011-06-23 00:30:03.000000000 +0200
|
||||
+++ openssh-5.9p0/servconf.h 2011-09-05 13:16:01.352564530 +0200
|
||||
@@ -112,6 +112,14 @@ typedef struct {
|
||||
/* If true, permit jpake auth */
|
||||
int permit_empty_passwd; /* If false, do not permit empty
|
||||
* passwords. */
|
||||
+ int two_factor_authentication; /* If true, the first sucessful authentication
|
||||
+ * will be followed by the second one from anorher set */
|
||||
+ int second_pubkey_authentication; /* second set of authentications */
|
||||
+ int second_gss_authentication;
|
||||
+ int second_password_authentication;
|
||||
+ int second_kbd_interactive_authentication;
|
||||
+ int second_zero_knowledge_password_authentication;
|
||||
+ int second_hostbased_authentication;
|
||||
int permit_user_env; /* If true, read ~/.ssh/environment */
|
||||
int use_login; /* If true, login(1) is used */
|
||||
int compression; /* If true, compression is allowed */
|
||||
diff -up openssh-5.9p0/sshd_config.2auth openssh-5.9p0/sshd_config
|
||||
--- openssh-5.9p0/sshd_config.2auth 2011-05-29 13:39:39.000000000 +0200
|
||||
+++ openssh-5.9p0/sshd_config 2011-09-05 13:16:01.461565750 +0200
|
||||
@@ -87,6 +87,13 @@ AuthorizedKeysFile .ssh/authorized_keys
|
||||
# and ChallengeResponseAuthentication to 'no'.
|
||||
#UsePAM no
|
||||
|
||||
+#TwoFactorAuthentication no
|
||||
+#SecondPubkeyAuthentication yes
|
||||
+#SecondHostbasedAuthentication no
|
||||
+#SecondPasswordAuthentication yes
|
||||
+#SecondChallengeResponseAuthentication yes
|
||||
+#SecondGSSAPIAuthentication no
|
||||
+
|
||||
#AllowAgentForwarding yes
|
||||
#AllowTcpForwarding yes
|
||||
#GatewayPorts no
|
||||
diff -up openssh-5.9p0/sshd_config.5.2auth openssh-5.9p0/sshd_config.5
|
||||
--- openssh-5.9p0/sshd_config.5.2auth 2011-08-05 22:17:33.000000000 +0200
|
||||
+++ openssh-5.9p0/sshd_config.5 2011-09-05 13:16:01.572564496 +0200
|
||||
@@ -726,6 +726,12 @@ Available keywords are
|
||||
.Cm PubkeyAuthentication ,
|
||||
.Cm RhostsRSAAuthentication ,
|
||||
.Cm RSAAuthentication ,
|
||||
+.Cm SecondGSSAPIAuthentication ,
|
||||
+.Cm SecondHostbasedAuthentication ,
|
||||
+.Cm SecondKbdInteractiveAuthentication ,
|
||||
+.Cm SecondPasswordAuthentication ,
|
||||
+.Cm SecondPubkeyAuthentication ,
|
||||
+.Cm TwoFactorAuthentication ,
|
||||
.Cm X11DisplayOffset ,
|
||||
.Cm X11Forwarding
|
||||
and
|
||||
@@ -931,6 +937,41 @@ Specifies whether pure RSA authenticatio
|
||||
The default is
|
||||
.Dq yes .
|
||||
This option applies to protocol version 1 only.
|
||||
+.It Cm SecondGSSAPIAuthentication
|
||||
+Specifies whether the
|
||||
+.Cm GSSAPIAuthentication
|
||||
+may be used on the second authentication while
|
||||
+.Cm TwoFactorAuthentication
|
||||
+is set.
|
||||
+The argument must be “yes” or “no”. The default is “no”.
|
||||
+.It Cm SecondHostbasedAuthentication
|
||||
+Specifies whether the
|
||||
+.Cm HostbasedAuthentication
|
||||
+may be used on the second authentication while
|
||||
+.Cm TwoFactorAuthentication
|
||||
+is set.
|
||||
+The argument must be “yes” or “no”. The default is “no”.
|
||||
+.It Cm SecondKbdInteractiveAuthentication
|
||||
+Specifies whether the
|
||||
+.Cm KbdInteractiveAuthentication
|
||||
+may be used on the second authentication while
|
||||
+.Cm TwoFactorAuthentication
|
||||
+is set.
|
||||
+The argument must be “yes” or “no”. The default is “no”.
|
||||
+.It Cm SecondPasswordAuthentication
|
||||
+Specifies whether the
|
||||
+.Cm PasswordAuthentication
|
||||
+may be used on the second authentication while
|
||||
+.Cm TwoFactorAuthentication
|
||||
+is set.
|
||||
+The argument must be “yes” or “no”. The default is “yes”.
|
||||
+.It Cm SecondPubkeyAuthentication
|
||||
+Specifies whether the
|
||||
+.Cm PubkeyAuthentication
|
||||
+may be used on the second authentication while
|
||||
+.Cm TwoFactorAuthentication
|
||||
+is set.
|
||||
+The argument must be “yes” or “no”. The default is “yes”.
|
||||
.It Cm ServerKeyBits
|
||||
Defines the number of bits in the ephemeral protocol version 1 server key.
|
||||
The minimum value is 512, and the default is 1024.
|
||||
@@ -1011,6 +1052,22 @@ For more details on certificates, see th
|
||||
.Sx CERTIFICATES
|
||||
section in
|
||||
.Xr ssh-keygen 1 .
|
||||
+.It Cm TwoFactorAuthentication
|
||||
+Specifies whether for a successful login is necessary to meet two independent authentications.
|
||||
+If select the first method is selected from the set of allowed methods from
|
||||
+.Cm GSSAPIAuthentication ,
|
||||
+.Cm HostbasedAuthentication ,
|
||||
+.Cm KbdInteractiveAuthentication ,
|
||||
+.Cm PasswordAuthentication ,
|
||||
+.Cm PubkeyAuthentication .
|
||||
+And the second method is selected from the set of allowed methods from
|
||||
+.Cm SecondGSSAPIAuthentication ,
|
||||
+.Cm SecondHostbasedAuthentication ,
|
||||
+.Cm SecondKbdInteractiveAuthentication ,
|
||||
+.Cm SecondPasswordAuthentication ,
|
||||
+.Cm SecondPubkeyAuthentication
|
||||
+without the method used for the first authentication.
|
||||
+The argument must be “yes” or “no”. The default is “no”.
|
||||
.It Cm UseDNS
|
||||
Specifies whether
|
||||
.Xr sshd 8
|
436
openssh-5.9p1-akc.patch
Normal file
436
openssh-5.9p1-akc.patch
Normal file
@ -0,0 +1,436 @@
|
||||
diff -up openssh-5.9p0/auth2-pubkey.c.akc openssh-5.9p0/auth2-pubkey.c
|
||||
--- openssh-5.9p0/auth2-pubkey.c.akc 2011-09-05 14:26:19.008627855 +0200
|
||||
+++ openssh-5.9p0/auth2-pubkey.c 2011-09-05 14:26:21.125500355 +0200
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
+#include <sys/wait.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <pwd.h>
|
||||
@@ -276,27 +277,15 @@ match_principals_file(char *file, struct
|
||||
|
||||
/* return 1 if user allows given key */
|
||||
static int
|
||||
-user_key_allowed2(struct passwd *pw, Key *key, char *file)
|
||||
+user_search_key_in_file(FILE *f, char *file, Key* key, struct passwd *pw)
|
||||
{
|
||||
char line[SSH_MAX_PUBKEY_BYTES];
|
||||
const char *reason;
|
||||
int found_key = 0;
|
||||
- FILE *f;
|
||||
u_long linenum = 0;
|
||||
Key *found;
|
||||
char *fp;
|
||||
|
||||
- /* Temporarily use the user's uid. */
|
||||
- temporarily_use_uid(pw);
|
||||
-
|
||||
- debug("trying public key file %s", file);
|
||||
- f = auth_openkeyfile(file, pw, options.strict_modes);
|
||||
-
|
||||
- if (!f) {
|
||||
- restore_uid();
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
found_key = 0;
|
||||
found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type);
|
||||
|
||||
@@ -389,8 +378,6 @@ user_key_allowed2(struct passwd *pw, Key
|
||||
break;
|
||||
}
|
||||
}
|
||||
- restore_uid();
|
||||
- fclose(f);
|
||||
key_free(found);
|
||||
if (!found_key)
|
||||
debug2("key not found");
|
||||
@@ -452,7 +439,179 @@ user_cert_trusted_ca(struct passwd *pw,
|
||||
return ret;
|
||||
}
|
||||
|
||||
-/* check whether given key is in .ssh/authorized_keys* */
|
||||
+/* return 1 if user allows given key */
|
||||
+static int
|
||||
+user_key_allowed2(struct passwd *pw, Key *key, char *file)
|
||||
+{
|
||||
+ FILE *f;
|
||||
+ int found_key = 0;
|
||||
+
|
||||
+ /* Temporarily use the user's uid. */
|
||||
+ temporarily_use_uid(pw);
|
||||
+
|
||||
+ debug("trying public key file %s", file);
|
||||
+ f = auth_openkeyfile(file, pw, options.strict_modes);
|
||||
+
|
||||
+ if (f) {
|
||||
+ found_key = user_search_key_in_file (f, file, key, pw);
|
||||
+ fclose(f);
|
||||
+ }
|
||||
+
|
||||
+ restore_uid();
|
||||
+ return found_key;
|
||||
+}
|
||||
+
|
||||
+#ifdef WITH_AUTHORIZED_KEYS_COMMAND
|
||||
+
|
||||
+#define WHITESPACE " \t\r\n"
|
||||
+
|
||||
+/* return 1 if user allows given key */
|
||||
+static int
|
||||
+user_key_via_command_allowed2(struct passwd *pw, Key *key)
|
||||
+{
|
||||
+ FILE *f;
|
||||
+ int found_key = 0;
|
||||
+ char *progname = NULL;
|
||||
+ char *cp;
|
||||
+ struct passwd *runas_pw;
|
||||
+ struct stat st;
|
||||
+ int childdescriptors[2], i;
|
||||
+ pid_t pstat, pid, child;
|
||||
+
|
||||
+ if (options.authorized_keys_command == NULL || options.authorized_keys_command[0] != '/')
|
||||
+ return -1;
|
||||
+
|
||||
+ /* get the run as identity from config */
|
||||
+ runas_pw = (options.authorized_keys_command_runas == NULL)? pw
|
||||
+ : getpwnam (options.authorized_keys_command_runas);
|
||||
+ if (!runas_pw) {
|
||||
+ error("%s: getpwnam(\"%s\"): %s", __func__,
|
||||
+ options.authorized_keys_command_runas, strerror(errno));
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ /* Temporarily use the specified uid. */
|
||||
+ if (runas_pw->pw_uid != 0)
|
||||
+ temporarily_use_uid(runas_pw);
|
||||
+
|
||||
+ progname = xstrdup(options.authorized_keys_command);
|
||||
+
|
||||
+ debug3("%s: checking program '%s'", __func__, progname);
|
||||
+
|
||||
+ if (stat (progname, &st) < 0) {
|
||||
+ error("%s: stat(\"%s\"): %s", __func__,
|
||||
+ progname, strerror(errno));
|
||||
+ goto go_away;
|
||||
+ }
|
||||
+
|
||||
+ if (st.st_uid != 0 || (st.st_mode & 022) != 0) {
|
||||
+ error("bad ownership or modes for AuthorizedKeysCommand \"%s\"",
|
||||
+ progname);
|
||||
+ goto go_away;
|
||||
+ }
|
||||
+
|
||||
+ if (!S_ISREG(st.st_mode)) {
|
||||
+ error("AuthorizedKeysCommand \"%s\" is not a regular file",
|
||||
+ progname);
|
||||
+ goto go_away;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Descend the path, checking that each component is a
|
||||
+ * root-owned directory with strict permissions.
|
||||
+ */
|
||||
+ do {
|
||||
+ if ((cp = strrchr(progname, '/')) == NULL)
|
||||
+ break;
|
||||
+ else
|
||||
+ *cp = '\0';
|
||||
+
|
||||
+ debug3("%s: checking component '%s'", __func__, (*progname == '\0' ? "/" : progname));
|
||||
+
|
||||
+ if (stat((*progname == '\0' ? "/" : progname), &st) != 0) {
|
||||
+ error("%s: stat(\"%s\"): %s", __func__,
|
||||
+ progname, strerror(errno));
|
||||
+ goto go_away;
|
||||
+ }
|
||||
+ if (st.st_uid != 0 || (st.st_mode & 022) != 0) {
|
||||
+ error("bad ownership or modes for AuthorizedKeysCommand path component \"%s\"",
|
||||
+ progname);
|
||||
+ goto go_away;
|
||||
+ }
|
||||
+ if (!S_ISDIR(st.st_mode)) {
|
||||
+ error("AuthorizedKeysCommand path component \"%s\" is not a directory",
|
||||
+ progname);
|
||||
+ goto go_away;
|
||||
+ }
|
||||
+ } while (1);
|
||||
+
|
||||
+ /* open the pipe and read the keys */
|
||||
+ if (pipe(childdescriptors)) {
|
||||
+ error("failed to pipe(2) for AuthorizedKeysCommand: %s",
|
||||
+ strerror(errno));
|
||||
+ goto go_away;
|
||||
+ }
|
||||
+
|
||||
+ child = fork();
|
||||
+ if (child == -1) {
|
||||
+ error("failed to fork(2) for AuthorizedKeysCommand: %s",
|
||||
+ strerror(errno));
|
||||
+ goto go_away;
|
||||
+ } else if (child == 0) {
|
||||
+ /* we're in the child process here -- we should never return from this block. */
|
||||
+ /* permanently drop privs in child process */
|
||||
+ if (runas_pw->pw_uid != 0) {
|
||||
+ restore_uid();
|
||||
+ permanently_set_uid(runas_pw);
|
||||
+ }
|
||||
+
|
||||
+ close(childdescriptors[0]);
|
||||
+ /* put the write end of the pipe on stdout (FD 1) */
|
||||
+ if (dup2(childdescriptors[1], 1) == -1) {
|
||||
+ error("failed to dup2(2) from AuthorizedKeysCommand: %s",
|
||||
+ strerror(errno));
|
||||
+ _exit(127);
|
||||
+ }
|
||||
+
|
||||
+ debug3("about to execl() AuthorizedKeysCommand: \"%s\" \"%s\"", options.authorized_keys_command, pw->pw_name);
|
||||
+ /* see session.c:child_close_fds() */
|
||||
+ for (i = 3; i < 64; ++i) {
|
||||
+ close(i);
|
||||
+ }
|
||||
+
|
||||
+ execl(options.authorized_keys_command, options.authorized_keys_command, pw->pw_name, NULL);
|
||||
+
|
||||
+ /* if we got here, it didn't work */
|
||||
+ error("failed to execl AuthorizedKeysCommand: %s", strerror(errno)); /* this won't work because we closed the fds above */
|
||||
+ _exit(127);
|
||||
+ }
|
||||
+
|
||||
+ close(childdescriptors[1]);
|
||||
+ f = fdopen(childdescriptors[0], "r");
|
||||
+ if (!f) {
|
||||
+ error("%s: could not buffer FDs from AuthorizedKeysCommand (\"%s\", \"r\"): %s", __func__,
|
||||
+ options.authorized_keys_command, strerror (errno));
|
||||
+ goto go_away;
|
||||
+ }
|
||||
+
|
||||
+ found_key = user_search_key_in_file (f, options.authorized_keys_command, key, pw);
|
||||
+ fclose (f);
|
||||
+ do {
|
||||
+ pid = waitpid(child, &pstat, 0);
|
||||
+ } while (pid == -1 && errno == EINTR);
|
||||
+
|
||||
+ /* what about the return value from the child process? */
|
||||
+go_away:
|
||||
+ if (progname)
|
||||
+ xfree (progname);
|
||||
+
|
||||
+ if (runas_pw->pw_uid != 0)
|
||||
+ restore_uid();
|
||||
+ return found_key;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+/* check whether given key is in <AuthorizedKeysCommand or .ssh/authorized_keys* */
|
||||
int
|
||||
user_key_allowed(struct passwd *pw, Key *key)
|
||||
{
|
||||
diff -up openssh-5.9p0/configure.ac.akc openssh-5.9p0/configure.ac
|
||||
--- openssh-5.9p0/configure.ac.akc 2011-08-18 06:48:24.000000000 +0200
|
||||
+++ openssh-5.9p0/configure.ac 2011-09-05 14:26:21.227601590 +0200
|
||||
@@ -1421,6 +1421,18 @@ AC_ARG_WITH([audit],
|
||||
esac ]
|
||||
)
|
||||
|
||||
+# Check whether user wants AuthorizedKeysCommand support
|
||||
+AKC_MSG="no"
|
||||
+AC_ARG_WITH(authorized-keys-command,
|
||||
+ [ --with-authorized-keys-command Enable AuthorizedKeysCommand support],
|
||||
+ [
|
||||
+ if test "x$withval" != "xno" ; then
|
||||
+ AC_DEFINE([WITH_AUTHORIZED_KEYS_COMMAND], 1, [Enable AuthorizedKeysCommand support])
|
||||
+ AKC_MSG="yes"
|
||||
+ fi
|
||||
+ ]
|
||||
+)
|
||||
+
|
||||
dnl Checks for library functions. Please keep in alphabetical order
|
||||
AC_CHECK_FUNCS([ \
|
||||
arc4random \
|
||||
@@ -4235,6 +4247,7 @@ echo " SELinux support
|
||||
echo " Smartcard support: $SCARD_MSG"
|
||||
echo " S/KEY support: $SKEY_MSG"
|
||||
echo " TCP Wrappers support: $TCPW_MSG"
|
||||
+echo " AuthorizedKeysCommand support: $AKC_MSG"
|
||||
echo " MD5 password support: $MD5_MSG"
|
||||
echo " libedit support: $LIBEDIT_MSG"
|
||||
echo " Solaris process contract support: $SPC_MSG"
|
||||
diff -up openssh-5.9p0/servconf.c.akc openssh-5.9p0/servconf.c
|
||||
--- openssh-5.9p0/servconf.c.akc 2011-09-05 14:26:08.430440620 +0200
|
||||
+++ openssh-5.9p0/servconf.c 2011-09-05 14:26:21.386571209 +0200
|
||||
@@ -139,6 +139,8 @@ initialize_server_options(ServerOptions
|
||||
options->num_permitted_opens = -1;
|
||||
options->adm_forced_command = NULL;
|
||||
options->chroot_directory = NULL;
|
||||
+ options->authorized_keys_command = NULL;
|
||||
+ options->authorized_keys_command_runas = NULL;
|
||||
options->zero_knowledge_password_authentication = -1;
|
||||
options->revoked_keys_file = NULL;
|
||||
options->trusted_user_ca_keys = NULL;
|
||||
@@ -348,6 +350,7 @@ typedef enum {
|
||||
sZeroKnowledgePasswordAuthentication, sHostCertificate,
|
||||
sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
|
||||
sKexAlgorithms, sIPQoS,
|
||||
+ sAuthorizedKeysCommand, sAuthorizedKeysCommandRunAs,
|
||||
sDeprecated, sUnsupported
|
||||
} ServerOpCodes;
|
||||
|
||||
@@ -487,6 +490,13 @@ static struct {
|
||||
{ "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL },
|
||||
{ "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL },
|
||||
{ "ipqos", sIPQoS, SSHCFG_ALL },
|
||||
+#ifdef WITH_AUTHORIZED_KEYS_COMMAND
|
||||
+ { "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL },
|
||||
+ { "authorizedkeyscommandrunas", sAuthorizedKeysCommandRunAs, SSHCFG_ALL },
|
||||
+#else
|
||||
+ { "authorizedkeyscommand", sUnsupported, SSHCFG_ALL },
|
||||
+ { "authorizedkeyscommandrunas", sUnsupported, SSHCFG_ALL },
|
||||
+#endif
|
||||
{ NULL, sBadOption, 0 }
|
||||
};
|
||||
|
||||
@@ -1462,6 +1472,20 @@ process_server_config_line(ServerOptions
|
||||
}
|
||||
break;
|
||||
|
||||
+ case sAuthorizedKeysCommand:
|
||||
+ len = strspn(cp, WHITESPACE);
|
||||
+ if (*activep && options->authorized_keys_command == NULL)
|
||||
+ options->authorized_keys_command = xstrdup(cp + len);
|
||||
+ return 0;
|
||||
+
|
||||
+ case sAuthorizedKeysCommandRunAs:
|
||||
+ charptr = &options->authorized_keys_command_runas;
|
||||
+
|
||||
+ arg = strdelim(&cp);
|
||||
+ if (*activep && *charptr == NULL)
|
||||
+ *charptr = xstrdup(arg);
|
||||
+ break;
|
||||
+
|
||||
case sDeprecated:
|
||||
logit("%s line %d: Deprecated option %s",
|
||||
filename, linenum, arg);
|
||||
@@ -1573,6 +1597,8 @@ copy_set_server_options(ServerOptions *d
|
||||
M_CP_INTOPT(zero_knowledge_password_authentication);
|
||||
M_CP_INTOPT(second_zero_knowledge_password_authentication);
|
||||
M_CP_INTOPT(two_factor_authentication);
|
||||
+ M_CP_STROPT(authorized_keys_command);
|
||||
+ M_CP_STROPT(authorized_keys_command_runas);
|
||||
M_CP_INTOPT(permit_root_login);
|
||||
M_CP_INTOPT(permit_empty_passwd);
|
||||
|
||||
@@ -1839,6 +1865,8 @@ dump_config(ServerOptions *o)
|
||||
dump_cfg_string(sRevokedKeys, o->revoked_keys_file);
|
||||
dump_cfg_string(sAuthorizedPrincipalsFile,
|
||||
o->authorized_principals_file);
|
||||
+ dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command);
|
||||
+ dump_cfg_string(sAuthorizedKeysCommandRunAs, o->authorized_keys_command_runas);
|
||||
|
||||
/* string arguments requiring a lookup */
|
||||
dump_cfg_string(sLogLevel, log_level_name(o->log_level));
|
||||
diff -up openssh-5.9p0/servconf.h.akc openssh-5.9p0/servconf.h
|
||||
--- openssh-5.9p0/servconf.h.akc 2011-09-05 14:26:08.536478884 +0200
|
||||
+++ openssh-5.9p0/servconf.h 2011-09-05 14:26:21.513500639 +0200
|
||||
@@ -174,6 +174,8 @@ typedef struct {
|
||||
char *revoked_keys_file;
|
||||
char *trusted_user_ca_keys;
|
||||
char *authorized_principals_file;
|
||||
+ char *authorized_keys_command;
|
||||
+ char *authorized_keys_command_runas;
|
||||
} ServerOptions;
|
||||
|
||||
/*
|
||||
diff -up openssh-5.9p0/sshd_config.0.akc openssh-5.9p0/sshd_config.0
|
||||
--- openssh-5.9p0/sshd_config.0.akc 2011-08-29 16:30:02.000000000 +0200
|
||||
+++ openssh-5.9p0/sshd_config.0 2011-09-05 14:26:21.880500451 +0200
|
||||
@@ -71,6 +71,23 @@ DESCRIPTION
|
||||
|
||||
See PATTERNS in ssh_config(5) for more information on patterns.
|
||||
|
||||
+ AuthorizedKeysCommand
|
||||
+
|
||||
+ Specifies a program to be used for lookup of the user's
|
||||
+ public keys. The program will be invoked with its first
|
||||
+ argument the name of the user being authorized, and should produce
|
||||
+ on standard output AuthorizedKeys lines (see AUTHORIZED_KEYS
|
||||
+ in sshd(8)). By default (or when set to the empty string) there is no
|
||||
+ AuthorizedKeysCommand run. If the AuthorizedKeysCommand does not successfully
|
||||
+ authorize the user, authorization falls through to the
|
||||
+ AuthorizedKeysFile. Note that this option has an effect
|
||||
+ only with PubkeyAuthentication turned on.
|
||||
+
|
||||
+ AuthorizedKeysCommandRunAs
|
||||
+ Specifies the user under whose account the AuthorizedKeysCommand is run.
|
||||
+ Empty string (the default value) means the user being authorized
|
||||
+ is used.
|
||||
+
|
||||
AuthorizedKeysFile
|
||||
Specifies the file that contains the public keys that can be used
|
||||
for user authentication. The format is described in the
|
||||
@@ -401,7 +418,8 @@ DESCRIPTION
|
||||
|
||||
Only a subset of keywords may be used on the lines following a
|
||||
Match keyword. Available keywords are AllowAgentForwarding,
|
||||
- AllowTcpForwarding, AuthorizedKeysFile, AuthorizedPrincipalsFile,
|
||||
+ AllowTcpForwarding, AuthorizedKeysFile, AuthorizedKeysCommand,
|
||||
+ AuthorizedKeysCommandRunAs, AuthorizedPrincipalsFile,
|
||||
Banner, ChrootDirectory, ForceCommand, GatewayPorts,
|
||||
GSSAPIAuthentication, HostbasedAuthentication,
|
||||
HostbasedUsesNameFromPacketOnly, KbdInteractiveAuthentication,
|
||||
diff -up openssh-5.9p0/sshd_config.5.akc openssh-5.9p0/sshd_config.5
|
||||
--- openssh-5.9p0/sshd_config.5.akc 2011-09-05 14:26:08.750503994 +0200
|
||||
+++ openssh-5.9p0/sshd_config.5 2011-09-05 14:26:21.987502513 +0200
|
||||
@@ -706,6 +706,8 @@ Available keywords are
|
||||
.Cm AllowAgentForwarding ,
|
||||
.Cm AllowTcpForwarding ,
|
||||
.Cm AuthorizedKeysFile ,
|
||||
+.Cm AuthorizedKeysCommand ,
|
||||
+.Cm AuthorizedKeysCommandRunAs ,
|
||||
.Cm AuthorizedPrincipalsFile ,
|
||||
.Cm Banner ,
|
||||
.Cm ChrootDirectory ,
|
||||
@@ -718,6 +720,7 @@ Available keywords are
|
||||
.Cm KerberosAuthentication ,
|
||||
.Cm MaxAuthTries ,
|
||||
.Cm MaxSessions ,
|
||||
+.Cm PubkeyAuthentication ,
|
||||
.Cm PasswordAuthentication ,
|
||||
.Cm PermitEmptyPasswords ,
|
||||
.Cm PermitOpen ,
|
||||
@@ -926,6 +929,20 @@ Specifies a list of revoked public keys.
|
||||
Keys listed in this file will be refused for public key authentication.
|
||||
Note that if this file is not readable, then public key authentication will
|
||||
be refused for all users.
|
||||
+.It Cm AuthorizedKeysCommand
|
||||
+Specifies a program to be used for lookup of the user's
|
||||
+public keys. The program will be invoked with its first
|
||||
+argument the name of the user being authorized, and should produce
|
||||
+on standard output AuthorizedKeys lines (see AUTHORIZED_KEYS
|
||||
+in sshd(8)). By default (or when set to the empty string) there is no
|
||||
+AuthorizedKeysCommand run. If the AuthorizedKeysCommand does not successfully
|
||||
+authorize the user, authorization falls through to the
|
||||
+AuthorizedKeysFile. Note that this option has an effect
|
||||
+only with PubkeyAuthentication turned on.
|
||||
+.It Cm AuthorizedKeysCommandRunAs
|
||||
+Specifies the user under whose account the AuthorizedKeysCommand is run. Empty
|
||||
+string (the default value) means the user being authorized is used.
|
||||
+.Dq
|
||||
.It Cm RhostsRSAAuthentication
|
||||
Specifies whether rhosts or /etc/hosts.equiv authentication together
|
||||
with successful RSA host authentication is allowed.
|
||||
diff -up openssh-5.9p0/sshd_config.akc openssh-5.9p0/sshd_config
|
||||
--- openssh-5.9p0/sshd_config.akc 2011-09-05 14:26:08.000000000 +0200
|
||||
+++ openssh-5.9p0/sshd_config 2011-09-05 14:45:21.135479100 +0200
|
||||
@@ -49,6 +49,9 @@
|
||||
# but this is overridden so installations will only check .ssh/authorized_keys
|
||||
AuthorizedKeysFile .ssh/authorized_keys
|
||||
|
||||
+#AuthorizedKeysCommand none
|
||||
+#AuthorizedKeysCommandRunAs nobody
|
||||
+
|
||||
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
|
||||
#RhostsRSAAuthentication no
|
||||
# similar for protocol version 2
|
641
openssh-5.9p1-audit1.patch
Normal file
641
openssh-5.9p1-audit1.patch
Normal file
@ -0,0 +1,641 @@
|
||||
diff -up openssh-5.9p0/audit-bsm.c.audit1 openssh-5.9p0/audit-bsm.c
|
||||
--- openssh-5.9p0/audit-bsm.c.audit1 2011-01-17 11:15:29.000000000 +0100
|
||||
+++ openssh-5.9p0/audit-bsm.c 2011-08-30 10:46:57.704148875 +0200
|
||||
@@ -298,10 +298,23 @@ audit_connection_from(const char *host,
|
||||
#endif
|
||||
}
|
||||
|
||||
-void
|
||||
+int
|
||||
audit_run_command(const char *command)
|
||||
{
|
||||
/* not implemented */
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+audit_end_command(int handle, const char *command)
|
||||
+{
|
||||
+ /* not implemented */
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+audit_count_session_open(void)
|
||||
+{
|
||||
+ /* not necessary */
|
||||
}
|
||||
|
||||
void
|
||||
diff -up openssh-5.9p0/audit-linux.c.audit1 openssh-5.9p0/audit-linux.c
|
||||
--- openssh-5.9p0/audit-linux.c.audit1 2011-01-17 11:15:30.000000000 +0100
|
||||
+++ openssh-5.9p0/audit-linux.c 2011-08-30 10:46:58.059024733 +0200
|
||||
@@ -35,13 +35,20 @@
|
||||
|
||||
#include "log.h"
|
||||
#include "audit.h"
|
||||
+#include "key.h"
|
||||
+#include "hostfile.h"
|
||||
+#include "auth.h"
|
||||
+#include "servconf.h"
|
||||
#include "canohost.h"
|
||||
|
||||
+extern ServerOptions options;
|
||||
+extern Authctxt *the_authctxt;
|
||||
+extern u_int utmp_len;
|
||||
const char* audit_username(void);
|
||||
|
||||
-int
|
||||
-linux_audit_record_event(int uid, const char *username,
|
||||
- const char *hostname, const char *ip, const char *ttyn, int success)
|
||||
+static void
|
||||
+linux_audit_user_logxxx(int uid, const char *username,
|
||||
+ const char *hostname, const char *ip, const char *ttyn, int success, int event)
|
||||
{
|
||||
int audit_fd, rc, saved_errno;
|
||||
|
||||
@@ -49,11 +56,11 @@ linux_audit_record_event(int uid, const
|
||||
if (audit_fd < 0) {
|
||||
if (errno == EINVAL || errno == EPROTONOSUPPORT ||
|
||||
errno == EAFNOSUPPORT)
|
||||
- return 1; /* No audit support in kernel */
|
||||
+ return; /* No audit support in kernel */
|
||||
else
|
||||
- return 0; /* Must prevent login */
|
||||
+ goto fatal_report; /* Must prevent login */
|
||||
}
|
||||
- rc = audit_log_acct_message(audit_fd, AUDIT_USER_LOGIN,
|
||||
+ rc = audit_log_acct_message(audit_fd, event,
|
||||
NULL, "login", username ? username : "(unknown)",
|
||||
username == NULL ? uid : -1, hostname, ip, ttyn, success);
|
||||
saved_errno = errno;
|
||||
@@ -65,35 +72,119 @@ linux_audit_record_event(int uid, const
|
||||
if ((rc == -EPERM) && (geteuid() != 0))
|
||||
rc = 0;
|
||||
errno = saved_errno;
|
||||
- return (rc >= 0);
|
||||
+ if (rc < 0) {
|
||||
+fatal_report:
|
||||
+ fatal("linux_audit_write_entry failed: %s", strerror(errno));
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+linux_audit_user_auth(int uid, const char *username,
|
||||
+ const char *hostname, const char *ip, const char *ttyn, int success, int event)
|
||||
+{
|
||||
+ int audit_fd, rc, saved_errno;
|
||||
+ static const char *event_name[] = {
|
||||
+ "maxtries exceeded",
|
||||
+ "root denied",
|
||||
+ "success",
|
||||
+ "none",
|
||||
+ "password",
|
||||
+ "challenge-response",
|
||||
+ "pubkey",
|
||||
+ "hostbased",
|
||||
+ "gssapi",
|
||||
+ "invalid user",
|
||||
+ "nologin",
|
||||
+ "connection closed",
|
||||
+ "connection abandoned",
|
||||
+ "unknown"
|
||||
+ };
|
||||
+
|
||||
+ audit_fd = audit_open();
|
||||
+ if (audit_fd < 0) {
|
||||
+ if (errno == EINVAL || errno == EPROTONOSUPPORT ||
|
||||
+ errno == EAFNOSUPPORT)
|
||||
+ return; /* No audit support in kernel */
|
||||
+ else
|
||||
+ goto fatal_report; /* Must prevent login */
|
||||
+ }
|
||||
+
|
||||
+ if ((event < 0) || (event > SSH_AUDIT_UNKNOWN))
|
||||
+ event = SSH_AUDIT_UNKNOWN;
|
||||
+
|
||||
+ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH,
|
||||
+ NULL, event_name[event], username ? username : "(unknown)",
|
||||
+ username == NULL ? uid : -1, hostname, ip, ttyn, success);
|
||||
+ saved_errno = errno;
|
||||
+ close(audit_fd);
|
||||
+ /*
|
||||
+ * Do not report error if the error is EPERM and sshd is run as non
|
||||
+ * root user.
|
||||
+ */
|
||||
+ if ((rc == -EPERM) && (geteuid() != 0))
|
||||
+ rc = 0;
|
||||
+ errno = saved_errno;
|
||||
+ if (rc < 0) {
|
||||
+fatal_report:
|
||||
+ fatal("linux_audit_write_entry failed: %s", strerror(errno));
|
||||
+ }
|
||||
}
|
||||
|
||||
+static int user_login_count = 0;
|
||||
+
|
||||
/* Below is the sshd audit API code */
|
||||
|
||||
void
|
||||
audit_connection_from(const char *host, int port)
|
||||
{
|
||||
-}
|
||||
/* not implemented */
|
||||
+}
|
||||
|
||||
-void
|
||||
+int
|
||||
audit_run_command(const char *command)
|
||||
{
|
||||
- /* not implemented */
|
||||
+ if (!user_login_count++)
|
||||
+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns),
|
||||
+ NULL, "ssh", 1, AUDIT_USER_LOGIN);
|
||||
+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns),
|
||||
+ NULL, "ssh", 1, AUDIT_USER_START);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+audit_end_command(int handle, const char *command)
|
||||
+{
|
||||
+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns),
|
||||
+ NULL, "ssh", 1, AUDIT_USER_END);
|
||||
+ if (user_login_count && !--user_login_count)
|
||||
+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns),
|
||||
+ NULL, "ssh", 1, AUDIT_USER_LOGOUT);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+audit_count_session_open(void)
|
||||
+{
|
||||
+ user_login_count++;
|
||||
}
|
||||
|
||||
void
|
||||
audit_session_open(struct logininfo *li)
|
||||
{
|
||||
- if (linux_audit_record_event(li->uid, NULL, li->hostname,
|
||||
- NULL, li->line, 1) == 0)
|
||||
- fatal("linux_audit_write_entry failed: %s", strerror(errno));
|
||||
+ if (!user_login_count++)
|
||||
+ linux_audit_user_logxxx(li->uid, NULL, li->hostname,
|
||||
+ NULL, li->line, 1, AUDIT_USER_LOGIN);
|
||||
+ linux_audit_user_logxxx(li->uid, NULL, li->hostname,
|
||||
+ NULL, li->line, 1, AUDIT_USER_START);
|
||||
}
|
||||
|
||||
void
|
||||
audit_session_close(struct logininfo *li)
|
||||
{
|
||||
- /* not implemented */
|
||||
+ linux_audit_user_logxxx(li->uid, NULL, li->hostname,
|
||||
+ NULL, li->line, 1, AUDIT_USER_END);
|
||||
+ if (user_login_count && !--user_login_count)
|
||||
+ linux_audit_user_logxxx(li->uid, NULL, li->hostname,
|
||||
+ NULL, li->line, 1, AUDIT_USER_LOGOUT);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -101,21 +192,43 @@ audit_event(ssh_audit_event_t event)
|
||||
{
|
||||
switch(event) {
|
||||
case SSH_AUTH_SUCCESS:
|
||||
- case SSH_CONNECTION_CLOSE:
|
||||
+ linux_audit_user_auth(-1, audit_username(), NULL,
|
||||
+ get_remote_ipaddr(), "ssh", 1, event);
|
||||
+ break;
|
||||
+
|
||||
case SSH_NOLOGIN:
|
||||
- case SSH_LOGIN_EXCEED_MAXTRIES:
|
||||
case SSH_LOGIN_ROOT_DENIED:
|
||||
+ linux_audit_user_auth(-1, audit_username(), NULL,
|
||||
+ get_remote_ipaddr(), "ssh", 0, event);
|
||||
+ linux_audit_user_logxxx(-1, audit_username(), NULL,
|
||||
+ get_remote_ipaddr(), "ssh", 0, AUDIT_USER_LOGIN);
|
||||
break;
|
||||
|
||||
+ case SSH_LOGIN_EXCEED_MAXTRIES:
|
||||
case SSH_AUTH_FAIL_NONE:
|
||||
case SSH_AUTH_FAIL_PASSWD:
|
||||
case SSH_AUTH_FAIL_KBDINT:
|
||||
case SSH_AUTH_FAIL_PUBKEY:
|
||||
case SSH_AUTH_FAIL_HOSTBASED:
|
||||
case SSH_AUTH_FAIL_GSSAPI:
|
||||
+ linux_audit_user_auth(-1, audit_username(), NULL,
|
||||
+ get_remote_ipaddr(), "ssh", 0, event);
|
||||
+ break;
|
||||
+
|
||||
+ case SSH_CONNECTION_CLOSE:
|
||||
+ if (user_login_count) {
|
||||
+ while (user_login_count--)
|
||||
+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns),
|
||||
+ NULL, "ssh", 1, AUDIT_USER_END);
|
||||
+ linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL, get_remote_name_or_ip(utmp_len, options.use_dns),
|
||||
+ NULL, "ssh", 1, AUDIT_USER_LOGOUT);
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ case SSH_CONNECTION_ABANDON:
|
||||
case SSH_INVALID_USER:
|
||||
- linux_audit_record_event(-1, audit_username(), NULL,
|
||||
- get_remote_ipaddr(), "sshd", 0);
|
||||
+ linux_audit_user_logxxx(-1, audit_username(), NULL,
|
||||
+ get_remote_ipaddr(), "ssh", 0, AUDIT_USER_LOGIN);
|
||||
break;
|
||||
|
||||
default:
|
||||
diff -up openssh-5.9p0/audit.c.audit1 openssh-5.9p0/audit.c
|
||||
--- openssh-5.9p0/audit.c.audit1 2011-01-17 11:15:30.000000000 +0100
|
||||
+++ openssh-5.9p0/audit.c 2011-08-30 10:46:57.822025769 +0200
|
||||
@@ -140,6 +140,17 @@ audit_event(ssh_audit_event_t event)
|
||||
}
|
||||
|
||||
/*
|
||||
+ * Called when a child process has called, or will soon call,
|
||||
+ * audit_session_open.
|
||||
+ */
|
||||
+void
|
||||
+audit_count_session_open(void)
|
||||
+{
|
||||
+ debug("audit count session open euid %d user %s", geteuid(),
|
||||
+ audit_username());
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
* Called when a user session is started. Argument is the tty allocated to
|
||||
* the session, or NULL if no tty was allocated.
|
||||
*
|
||||
@@ -174,13 +185,29 @@ audit_session_close(struct logininfo *li
|
||||
/*
|
||||
* This will be called when a user runs a non-interactive command. Note that
|
||||
* it may be called multiple times for a single connection since SSH2 allows
|
||||
- * multiple sessions within a single connection.
|
||||
+ * multiple sessions within a single connection. Returns a "handle" for
|
||||
+ * audit_end_command.
|
||||
*/
|
||||
-void
|
||||
+int
|
||||
audit_run_command(const char *command)
|
||||
{
|
||||
debug("audit run command euid %d user %s command '%.200s'", geteuid(),
|
||||
audit_username(), command);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * This will be called when the non-interactive command finishes. Note that
|
||||
+ * it may be called multiple times for a single connection since SSH2 allows
|
||||
+ * multiple sessions within a single connection. "handle" should come from
|
||||
+ * the corresponding audit_run_command.
|
||||
+ */
|
||||
+void
|
||||
+audit_end_command(int handle, const char *command)
|
||||
+{
|
||||
+ debug("audit end nopty exec euid %d user %s command '%.200s'", geteuid(),
|
||||
+ audit_username(), command);
|
||||
}
|
||||
+
|
||||
# endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */
|
||||
#endif /* SSH_AUDIT_EVENTS */
|
||||
diff -up openssh-5.9p0/audit.h.audit1 openssh-5.9p0/audit.h
|
||||
--- openssh-5.9p0/audit.h.audit1 2011-01-17 11:15:30.000000000 +0100
|
||||
+++ openssh-5.9p0/audit.h 2011-08-30 10:46:57.952035525 +0200
|
||||
@@ -49,9 +49,11 @@ typedef enum ssh_audit_event_type ssh_au
|
||||
|
||||
void audit_connection_from(const char *, int);
|
||||
void audit_event(ssh_audit_event_t);
|
||||
+void audit_count_session_open(void);
|
||||
void audit_session_open(struct logininfo *);
|
||||
void audit_session_close(struct logininfo *);
|
||||
-void audit_run_command(const char *);
|
||||
+int audit_run_command(const char *);
|
||||
+void audit_end_command(int, const char *);
|
||||
ssh_audit_event_t audit_classify_auth(const char *);
|
||||
|
||||
#endif /* _SSH_AUDIT_H */
|
||||
diff -up openssh-5.9p0/monitor.c.audit1 openssh-5.9p0/monitor.c
|
||||
--- openssh-5.9p0/monitor.c.audit1 2011-08-05 22:15:18.000000000 +0200
|
||||
+++ openssh-5.9p0/monitor.c 2011-08-30 10:50:47.074038891 +0200
|
||||
@@ -185,6 +185,7 @@ int mm_answer_gss_checkmic(int, Buffer *
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
int mm_answer_audit_event(int, Buffer *);
|
||||
int mm_answer_audit_command(int, Buffer *);
|
||||
+int mm_answer_audit_end_command(int, Buffer *);
|
||||
#endif
|
||||
|
||||
static int monitor_read_log(struct monitor *);
|
||||
@@ -271,6 +272,7 @@ struct mon_table mon_dispatch_postauth20
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
{MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
|
||||
{MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT, mm_answer_audit_command},
|
||||
+ {MONITOR_REQ_AUDIT_END_COMMAND, MON_PERMIT, mm_answer_audit_end_command},
|
||||
#endif
|
||||
{0, 0, NULL}
|
||||
};
|
||||
@@ -313,6 +315,7 @@ struct mon_table mon_dispatch_postauth15
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
{MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
|
||||
{MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT|MON_ONCE, mm_answer_audit_command},
|
||||
+ {MONITOR_REQ_AUDIT_END_COMMAND, MON_PERMIT, mm_answer_audit_end_command},
|
||||
#endif
|
||||
{0, 0, NULL}
|
||||
};
|
||||
@@ -1398,6 +1401,12 @@ mm_session_close(Session *s)
|
||||
debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd);
|
||||
session_pty_cleanup2(s);
|
||||
}
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+ if (s->command != NULL) {
|
||||
+ debug3("%s: command %d", __func__, s->command_handle);
|
||||
+ session_end_command2(s);
|
||||
+ }
|
||||
+#endif
|
||||
session_unused(s->self);
|
||||
}
|
||||
|
||||
@@ -1720,11 +1729,44 @@ mm_answer_audit_command(int socket, Buff
|
||||
{
|
||||
u_int len;
|
||||
char *cmd;
|
||||
+ Session *s;
|
||||
|
||||
debug3("%s entering", __func__);
|
||||
cmd = buffer_get_string(m, &len);
|
||||
+
|
||||
/* sanity check command, if so how? */
|
||||
- audit_run_command(cmd);
|
||||
+ s = session_new();
|
||||
+ if (s == NULL)
|
||||
+ fatal("%s: error allocating a session", __func__);
|
||||
+ s->command = cmd;
|
||||
+ s->command_handle = audit_run_command(cmd);
|
||||
+
|
||||
+ buffer_clear(m);
|
||||
+ buffer_put_int(m, s->self);
|
||||
+
|
||||
+ mm_request_send(socket, MONITOR_ANS_AUDIT_COMMAND, m);
|
||||
+
|
||||
+ return (0);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+mm_answer_audit_end_command(int socket, Buffer *m)
|
||||
+{
|
||||
+ int handle;
|
||||
+ u_int len;
|
||||
+ char *cmd;
|
||||
+ Session *s;
|
||||
+
|
||||
+ debug3("%s entering", __func__);
|
||||
+ handle = buffer_get_int(m);
|
||||
+ cmd = buffer_get_string(m, &len);
|
||||
+
|
||||
+ s = session_by_id(handle);
|
||||
+ if (s == NULL || s->ttyfd != -1 || s->command == NULL ||
|
||||
+ strcmp(s->command, cmd) != 0)
|
||||
+ fatal("%s: invalid handle", __func__);
|
||||
+ mm_session_close(s);
|
||||
+
|
||||
xfree(cmd);
|
||||
return (0);
|
||||
}
|
||||
diff -up openssh-5.9p0/monitor.h.audit1 openssh-5.9p0/monitor.h
|
||||
--- openssh-5.9p0/monitor.h.audit1 2011-06-20 06:42:23.000000000 +0200
|
||||
+++ openssh-5.9p0/monitor.h 2011-08-30 10:46:58.392112520 +0200
|
||||
@@ -60,6 +60,7 @@ enum monitor_reqtype {
|
||||
MONITOR_REQ_PAM_RESPOND, MONITOR_ANS_PAM_RESPOND,
|
||||
MONITOR_REQ_PAM_FREE_CTX, MONITOR_ANS_PAM_FREE_CTX,
|
||||
MONITOR_REQ_AUDIT_EVENT, MONITOR_REQ_AUDIT_COMMAND,
|
||||
+ MONITOR_ANS_AUDIT_COMMAND, MONITOR_REQ_AUDIT_END_COMMAND,
|
||||
MONITOR_REQ_TERM,
|
||||
MONITOR_REQ_JPAKE_STEP1, MONITOR_ANS_JPAKE_STEP1,
|
||||
MONITOR_REQ_JPAKE_GET_PWDATA, MONITOR_ANS_JPAKE_GET_PWDATA,
|
||||
diff -up openssh-5.9p0/monitor_wrap.c.audit1 openssh-5.9p0/monitor_wrap.c
|
||||
--- openssh-5.9p0/monitor_wrap.c.audit1 2011-06-20 06:42:23.000000000 +0200
|
||||
+++ openssh-5.9p0/monitor_wrap.c 2011-08-30 10:46:58.505031574 +0200
|
||||
@@ -1188,10 +1188,11 @@ mm_audit_event(ssh_audit_event_t event)
|
||||
buffer_free(&m);
|
||||
}
|
||||
|
||||
-void
|
||||
+int
|
||||
mm_audit_run_command(const char *command)
|
||||
{
|
||||
Buffer m;
|
||||
+ int handle;
|
||||
|
||||
debug3("%s entering command %s", __func__, command);
|
||||
|
||||
@@ -1199,6 +1200,26 @@ mm_audit_run_command(const char *command
|
||||
buffer_put_cstring(&m, command);
|
||||
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, &m);
|
||||
+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_COMMAND, &m);
|
||||
+
|
||||
+ handle = buffer_get_int(&m);
|
||||
+ buffer_free(&m);
|
||||
+
|
||||
+ return (handle);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+mm_audit_end_command(int handle, const char *command)
|
||||
+{
|
||||
+ Buffer m;
|
||||
+
|
||||
+ debug3("%s entering command %s", __func__, command);
|
||||
+
|
||||
+ buffer_init(&m);
|
||||
+ buffer_put_int(&m, handle);
|
||||
+ buffer_put_cstring(&m, command);
|
||||
+
|
||||
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_END_COMMAND, &m);
|
||||
buffer_free(&m);
|
||||
}
|
||||
#endif /* SSH_AUDIT_EVENTS */
|
||||
diff -up openssh-5.9p0/monitor_wrap.h.audit1 openssh-5.9p0/monitor_wrap.h
|
||||
--- openssh-5.9p0/monitor_wrap.h.audit1 2011-06-20 06:42:23.000000000 +0200
|
||||
+++ openssh-5.9p0/monitor_wrap.h 2011-08-30 10:46:58.616212835 +0200
|
||||
@@ -74,7 +74,8 @@ void mm_sshpam_free_ctx(void *);
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
#include "audit.h"
|
||||
void mm_audit_event(ssh_audit_event_t);
|
||||
-void mm_audit_run_command(const char *);
|
||||
+int mm_audit_run_command(const char *);
|
||||
+void mm_audit_end_command(int, const char *);
|
||||
#endif
|
||||
|
||||
struct Session;
|
||||
diff -up openssh-5.9p0/session.c.audit1 openssh-5.9p0/session.c
|
||||
--- openssh-5.9p0/session.c.audit1 2011-05-20 03:23:10.000000000 +0200
|
||||
+++ openssh-5.9p0/session.c 2011-08-30 10:46:58.756024849 +0200
|
||||
@@ -742,6 +742,14 @@ do_exec_pty(Session *s, const char *comm
|
||||
/* Parent. Close the slave side of the pseudo tty. */
|
||||
close(ttyfd);
|
||||
|
||||
+#ifndef HAVE_OSF_SIA
|
||||
+ /* do_login in the child did not affect state in this process,
|
||||
+ compensate. From an architectural standpoint, this is extremely
|
||||
+ ugly. */
|
||||
+ if (!(options.use_login && command == NULL))
|
||||
+ audit_count_session_open();
|
||||
+#endif
|
||||
+
|
||||
/* Enter interactive session. */
|
||||
s->ptymaster = ptymaster;
|
||||
packet_set_interactive(1,
|
||||
@@ -813,15 +821,19 @@ do_exec(Session *s, const char *command)
|
||||
}
|
||||
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
+ if (s->command != NULL || s->command_handle != -1)
|
||||
+ fatal("do_exec: command already set");
|
||||
if (command != NULL)
|
||||
- PRIVSEP(audit_run_command(command));
|
||||
+ s->command = xstrdup(command);
|
||||
else if (s->ttyfd == -1) {
|
||||
char *shell = s->pw->pw_shell;
|
||||
|
||||
if (shell[0] == '\0') /* empty shell means /bin/sh */
|
||||
shell =_PATH_BSHELL;
|
||||
- PRIVSEP(audit_run_command(shell));
|
||||
+ s->command = xstrdup(shell);
|
||||
}
|
||||
+ if (s->command != NULL)
|
||||
+ s->command_handle = PRIVSEP(audit_run_command(s->command));
|
||||
#endif
|
||||
if (s->ttyfd != -1)
|
||||
ret = do_exec_pty(s, command);
|
||||
@@ -1848,6 +1860,7 @@ session_unused(int id)
|
||||
sessions[id].ttyfd = -1;
|
||||
sessions[id].ptymaster = -1;
|
||||
sessions[id].x11_chanids = NULL;
|
||||
+ sessions[id].command_handle = -1;
|
||||
sessions[id].next_unused = sessions_first_unused;
|
||||
sessions_first_unused = id;
|
||||
}
|
||||
@@ -1930,6 +1943,19 @@ session_open(Authctxt *authctxt, int cha
|
||||
}
|
||||
|
||||
Session *
|
||||
+session_by_id(int id)
|
||||
+{
|
||||
+ if (id >= 0 && id < sessions_nalloc) {
|
||||
+ Session *s = &sessions[id];
|
||||
+ if (s->used)
|
||||
+ return s;
|
||||
+ }
|
||||
+ debug("session_by_id: unknown id %d", id);
|
||||
+ session_dump();
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+Session *
|
||||
session_by_tty(char *tty)
|
||||
{
|
||||
int i;
|
||||
@@ -2455,6 +2481,30 @@ session_exit_message(Session *s, int sta
|
||||
chan_write_failed(c);
|
||||
}
|
||||
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+void
|
||||
+session_end_command2(Session *s)
|
||||
+{
|
||||
+ if (s->command != NULL) {
|
||||
+ audit_end_command(s->command_handle, s->command);
|
||||
+ xfree(s->command);
|
||||
+ s->command = NULL;
|
||||
+ s->command_handle = -1;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+session_end_command(Session *s)
|
||||
+{
|
||||
+ if (s->command != NULL) {
|
||||
+ PRIVSEP(audit_end_command(s->command_handle, s->command));
|
||||
+ xfree(s->command);
|
||||
+ s->command = NULL;
|
||||
+ s->command_handle = -1;
|
||||
+ }
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
void
|
||||
session_close(Session *s)
|
||||
{
|
||||
@@ -2463,6 +2513,10 @@ session_close(Session *s)
|
||||
debug("session_close: session %d pid %ld", s->self, (long)s->pid);
|
||||
if (s->ttyfd != -1)
|
||||
session_pty_cleanup(s);
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+ if (s->command)
|
||||
+ session_end_command(s);
|
||||
+#endif
|
||||
if (s->term)
|
||||
xfree(s->term);
|
||||
if (s->display)
|
||||
@@ -2682,6 +2736,15 @@ do_authenticated2(Authctxt *authctxt)
|
||||
server_loop2(authctxt);
|
||||
}
|
||||
|
||||
+static void
|
||||
+do_cleanup_one_session(Session *s)
|
||||
+{
|
||||
+ session_pty_cleanup2(s);
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+ session_end_command2(s);
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
void
|
||||
do_cleanup(Authctxt *authctxt)
|
||||
{
|
||||
@@ -2730,5 +2793,5 @@ do_cleanup(Authctxt *authctxt)
|
||||
* or if running in monitor.
|
||||
*/
|
||||
if (!use_privsep || mm_is_monitor())
|
||||
- session_destroy_all(session_pty_cleanup2);
|
||||
+ session_destroy_all(do_cleanup_one_session);
|
||||
}
|
||||
diff -up openssh-5.9p0/session.h.audit1 openssh-5.9p0/session.h
|
||||
--- openssh-5.9p0/session.h.audit1 2008-05-19 07:34:50.000000000 +0200
|
||||
+++ openssh-5.9p0/session.h 2011-08-30 10:46:58.884024597 +0200
|
||||
@@ -60,6 +60,12 @@ struct Session {
|
||||
char *name;
|
||||
char *val;
|
||||
} *env;
|
||||
+
|
||||
+ /* exec */
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+ int command_handle;
|
||||
+ char *command;
|
||||
+#endif
|
||||
};
|
||||
|
||||
void do_authenticated(Authctxt *);
|
||||
@@ -72,8 +78,10 @@ void session_close_by_pid(pid_t, int);
|
||||
void session_close_by_channel(int, void *);
|
||||
void session_destroy_all(void (*)(Session *));
|
||||
void session_pty_cleanup2(Session *);
|
||||
+void session_end_command2(Session *);
|
||||
|
||||
Session *session_new(void);
|
||||
+Session *session_by_id(int);
|
||||
Session *session_by_tty(char *);
|
||||
void session_close(Session *);
|
||||
void do_setusercontext(struct passwd *);
|
||||
diff -up openssh-5.9p0/sshd.c.audit1 openssh-5.9p0/sshd.c
|
||||
--- openssh-5.9p0/sshd.c.audit1 2011-06-23 11:45:51.000000000 +0200
|
||||
+++ openssh-5.9p0/sshd.c 2011-08-30 10:46:59.009025421 +0200
|
||||
@@ -2364,7 +2364,8 @@ cleanup_exit(int i)
|
||||
do_cleanup(the_authctxt);
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
/* done after do_cleanup so it can cancel the PAM auth 'thread' */
|
||||
- if (!use_privsep || mm_is_monitor())
|
||||
+ if ((the_authctxt == NULL || !the_authctxt->authenticated) &&
|
||||
+ (!use_privsep || mm_is_monitor()))
|
||||
audit_event(SSH_CONNECTION_ABANDON);
|
||||
#endif
|
||||
_exit(i);
|
353
openssh-5.9p1-audit2.patch
Normal file
353
openssh-5.9p1-audit2.patch
Normal file
@ -0,0 +1,353 @@
|
||||
diff -up openssh-5.9p0/audit-bsm.c.audit2 openssh-5.9p0/audit-bsm.c
|
||||
--- openssh-5.9p0/audit-bsm.c.audit2 2011-08-30 10:55:35.281025258 +0200
|
||||
+++ openssh-5.9p0/audit-bsm.c 2011-08-30 10:55:37.500052231 +0200
|
||||
@@ -329,6 +329,12 @@ audit_session_close(struct logininfo *li
|
||||
/* not implemented */
|
||||
}
|
||||
|
||||
+int
|
||||
+audit_keyusage(int host_user, const char *type, unsigned bits, char *fp, int rv)
|
||||
+{
|
||||
+ /* not implemented */
|
||||
+}
|
||||
+
|
||||
void
|
||||
audit_event(ssh_audit_event_t event)
|
||||
{
|
||||
diff -up openssh-5.9p0/audit-linux.c.audit2 openssh-5.9p0/audit-linux.c
|
||||
--- openssh-5.9p0/audit-linux.c.audit2 2011-08-30 10:55:35.385102905 +0200
|
||||
+++ openssh-5.9p0/audit-linux.c 2011-08-30 10:55:38.009088040 +0200
|
||||
@@ -41,6 +41,8 @@
|
||||
#include "servconf.h"
|
||||
#include "canohost.h"
|
||||
|
||||
+#define AUDIT_LOG_SIZE 128
|
||||
+
|
||||
extern ServerOptions options;
|
||||
extern Authctxt *the_authctxt;
|
||||
extern u_int utmp_len;
|
||||
@@ -130,6 +132,37 @@ fatal_report:
|
||||
}
|
||||
}
|
||||
|
||||
+int
|
||||
+audit_keyusage(int host_user, const char *type, unsigned bits, char *fp, int rv)
|
||||
+{
|
||||
+ char buf[AUDIT_LOG_SIZE];
|
||||
+ int audit_fd, rc, saved_errno;
|
||||
+
|
||||
+ audit_fd = audit_open();
|
||||
+ if (audit_fd < 0) {
|
||||
+ if (errno == EINVAL || errno == EPROTONOSUPPORT ||
|
||||
+ errno == EAFNOSUPPORT)
|
||||
+ return 1; /* No audit support in kernel */
|
||||
+ else
|
||||
+ return 0; /* Must prevent login */
|
||||
+ }
|
||||
+ snprintf(buf, sizeof(buf), "%s_auth rport=%d", host_user ? "pubkey" : "hostbased", get_remote_port());
|
||||
+ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL,
|
||||
+ buf, audit_username(), -1, NULL, get_remote_ipaddr(), NULL, rv);
|
||||
+ if ((rc < 0) && ((rc != -1) || (getuid() == 0)))
|
||||
+ goto out;
|
||||
+ snprintf(buf, sizeof(buf), "key algo=%s size=%d fp=%s%s rport=%d",
|
||||
+ type, bits, key_fingerprint_prefix(), fp, get_remote_port());
|
||||
+ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL,
|
||||
+ buf, audit_username(), -1, NULL, get_remote_ipaddr(), NULL, rv);
|
||||
+out:
|
||||
+ saved_errno = errno;
|
||||
+ audit_close(audit_fd);
|
||||
+ errno = saved_errno;
|
||||
+ /* do not report error if the error is EPERM and sshd is run as non root user */
|
||||
+ return (rc >= 0) || ((rc == -EPERM) && (getuid() != 0));
|
||||
+}
|
||||
+
|
||||
static int user_login_count = 0;
|
||||
|
||||
/* Below is the sshd audit API code */
|
||||
diff -up openssh-5.9p0/audit.c.audit2 openssh-5.9p0/audit.c
|
||||
--- openssh-5.9p0/audit.c.audit2 2011-08-30 10:55:35.523141273 +0200
|
||||
+++ openssh-5.9p0/audit.c 2011-08-30 10:55:37.658024710 +0200
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "key.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
+#include "xmalloc.h"
|
||||
|
||||
/*
|
||||
* Care must be taken when using this since it WILL NOT be initialized when
|
||||
@@ -111,6 +112,22 @@ audit_event_lookup(ssh_audit_event_t ev)
|
||||
return(event_lookup[i].name);
|
||||
}
|
||||
|
||||
+void
|
||||
+audit_key(int host_user, int *rv, const Key *key)
|
||||
+{
|
||||
+ char *fp;
|
||||
+ const char *crypto_name;
|
||||
+
|
||||
+ fp = key_selected_fingerprint(key, SSH_FP_HEX);
|
||||
+ if (key->type == KEY_RSA1)
|
||||
+ crypto_name = "ssh-rsa1";
|
||||
+ else
|
||||
+ crypto_name = key_ssh_name(key);
|
||||
+ if (audit_keyusage(host_user, crypto_name, key_size(key), fp, *rv) == 0)
|
||||
+ *rv = 0;
|
||||
+ xfree(fp);
|
||||
+}
|
||||
+
|
||||
# ifndef CUSTOM_SSH_AUDIT_EVENTS
|
||||
/*
|
||||
* Null implementations of audit functions.
|
||||
@@ -209,5 +226,17 @@ audit_end_command(int handle, const char
|
||||
audit_username(), command);
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * This will be called when user is successfully autherized by the RSA1/RSA/DSA key.
|
||||
+ *
|
||||
+ * Type is the key type, len is the key length(byte) and fp is the fingerprint of the key.
|
||||
+ */
|
||||
+int
|
||||
+audit_keyusage(int host_user, const char *type, unsigned bits, char *fp, int rv)
|
||||
+{
|
||||
+ debug("audit %s key usage euid %d user %s key type %s key length %d fingerprint %s%s, result %d",
|
||||
+ host_user ? "pubkey" : "hostbased", geteuid(), audit_username(), type, bits,
|
||||
+ key_fingerprint_prefix(), fp, rv);
|
||||
+}
|
||||
# endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */
|
||||
#endif /* SSH_AUDIT_EVENTS */
|
||||
diff -up openssh-5.9p0/audit.h.audit2 openssh-5.9p0/audit.h
|
||||
--- openssh-5.9p0/audit.h.audit2 2011-08-30 10:55:35.723122290 +0200
|
||||
+++ openssh-5.9p0/audit.h 2011-08-30 10:55:37.905212176 +0200
|
||||
@@ -28,6 +28,7 @@
|
||||
# define _SSH_AUDIT_H
|
||||
|
||||
#include "loginrec.h"
|
||||
+#include "key.h"
|
||||
|
||||
enum ssh_audit_event_type {
|
||||
SSH_LOGIN_EXCEED_MAXTRIES,
|
||||
@@ -55,5 +56,7 @@ void audit_session_close(struct logininf
|
||||
int audit_run_command(const char *);
|
||||
void audit_end_command(int, const char *);
|
||||
ssh_audit_event_t audit_classify_auth(const char *);
|
||||
+int audit_keyusage(int, const char *, unsigned, char *, int);
|
||||
+void audit_key(int, int *, const Key *);
|
||||
|
||||
#endif /* _SSH_AUDIT_H */
|
||||
diff -up openssh-5.9p0/auth-rsa.c.audit2 openssh-5.9p0/auth-rsa.c
|
||||
--- openssh-5.9p0/auth-rsa.c.audit2 2011-08-30 10:55:33.120097071 +0200
|
||||
+++ openssh-5.9p0/auth-rsa.c 2011-08-30 10:55:38.729025376 +0200
|
||||
@@ -92,7 +92,10 @@ auth_rsa_verify_response(Key *key, BIGNU
|
||||
{
|
||||
u_char buf[32], mdbuf[16];
|
||||
MD5_CTX md;
|
||||
- int len;
|
||||
+ int len, rv;
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+ char *fp;
|
||||
+#endif
|
||||
|
||||
/* don't allow short keys */
|
||||
if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
|
||||
@@ -113,12 +116,18 @@ auth_rsa_verify_response(Key *key, BIGNU
|
||||
MD5_Final(mdbuf, &md);
|
||||
|
||||
/* Verify that the response is the original challenge. */
|
||||
- if (timingsafe_bcmp(response, mdbuf, 16) != 0) {
|
||||
- /* Wrong answer. */
|
||||
- return (0);
|
||||
+ rv = timingsafe_bcmp(response, mdbuf, 16) == 0;
|
||||
+
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+ fp = key_selected_fingerprint(key, SSH_FP_HEX);
|
||||
+ if (audit_keyusage(1, "ssh-rsa1", RSA_size(key->rsa) * 8, fp, rv) == 0) {
|
||||
+ debug("unsuccessful audit");
|
||||
+ rv = 0;
|
||||
}
|
||||
- /* Correct answer. */
|
||||
- return (1);
|
||||
+ xfree(fp);
|
||||
+#endif
|
||||
+
|
||||
+ return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
diff -up openssh-5.9p0/auth.h.audit2 openssh-5.9p0/auth.h
|
||||
--- openssh-5.9p0/auth.h.audit2 2011-05-29 13:39:38.000000000 +0200
|
||||
+++ openssh-5.9p0/auth.h 2011-08-30 10:57:43.238087347 +0200
|
||||
@@ -170,6 +170,7 @@ void abandon_challenge_response(Authctxt
|
||||
|
||||
char *expand_authorized_keys(const char *, struct passwd *pw);
|
||||
char *authorized_principals_file(struct passwd *);
|
||||
+int user_key_verify(const Key *, const u_char *, u_int, const u_char *, u_int);
|
||||
|
||||
FILE *auth_openkeyfile(const char *, struct passwd *, int);
|
||||
FILE *auth_openprincipals(const char *, struct passwd *, int);
|
||||
@@ -185,6 +186,7 @@ Key *get_hostkey_public_by_type(int);
|
||||
Key *get_hostkey_private_by_type(int);
|
||||
int get_hostkey_index(Key *);
|
||||
int ssh1_session_key(BIGNUM *);
|
||||
+int hostbased_key_verify(const Key *, const u_char *, u_int, const u_char *, u_int);
|
||||
|
||||
/* debug messages during authentication */
|
||||
void auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2)));
|
||||
diff -up openssh-5.9p0/auth2-hostbased.c.audit2 openssh-5.9p0/auth2-hostbased.c
|
||||
--- openssh-5.9p0/auth2-hostbased.c.audit2 2011-08-30 10:55:32.696212587 +0200
|
||||
+++ openssh-5.9p0/auth2-hostbased.c 2011-08-30 10:55:38.120068864 +0200
|
||||
@@ -119,7 +119,7 @@ userauth_hostbased(Authctxt *authctxt)
|
||||
/* test for allowed key and correct signature */
|
||||
authenticated = 0;
|
||||
if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) &&
|
||||
- PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
|
||||
+ PRIVSEP(hostbased_key_verify(key, sig, slen, buffer_ptr(&b),
|
||||
buffer_len(&b))) == 1)
|
||||
authenticated = 1;
|
||||
|
||||
@@ -136,6 +136,18 @@ done:
|
||||
return authenticated;
|
||||
}
|
||||
|
||||
+int
|
||||
+hostbased_key_verify(const Key *key, const u_char *sig, u_int slen, const u_char *data, u_int datalen)
|
||||
+{
|
||||
+ int rv;
|
||||
+
|
||||
+ rv = key_verify(key, sig, slen, data, datalen);
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+ audit_key(0, &rv, key);
|
||||
+#endif
|
||||
+ return rv;
|
||||
+}
|
||||
+
|
||||
/* return 1 if given hostkey is allowed */
|
||||
int
|
||||
hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
|
||||
diff -up openssh-5.9p0/auth2-pubkey.c.audit2 openssh-5.9p0/auth2-pubkey.c
|
||||
--- openssh-5.9p0/auth2-pubkey.c.audit2 2011-08-30 10:55:32.803126151 +0200
|
||||
+++ openssh-5.9p0/auth2-pubkey.c 2011-08-30 10:55:38.426108672 +0200
|
||||
@@ -140,7 +140,7 @@ userauth_pubkey(Authctxt *authctxt)
|
||||
/* test for correct signature */
|
||||
authenticated = 0;
|
||||
if (PRIVSEP(user_key_allowed(authctxt->pw, key)) &&
|
||||
- PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
|
||||
+ PRIVSEP(user_key_verify(key, sig, slen, buffer_ptr(&b),
|
||||
buffer_len(&b))) == 1)
|
||||
authenticated = 1;
|
||||
buffer_free(&b);
|
||||
@@ -177,6 +177,18 @@ done:
|
||||
return authenticated;
|
||||
}
|
||||
|
||||
+int
|
||||
+user_key_verify(const Key *key, const u_char *sig, u_int slen, const u_char *data, u_int datalen)
|
||||
+{
|
||||
+ int rv;
|
||||
+
|
||||
+ rv = key_verify(key, sig, slen, data, datalen);
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+ audit_key(1, &rv, key);
|
||||
+#endif
|
||||
+ return rv;
|
||||
+}
|
||||
+
|
||||
static int
|
||||
match_principals_option(const char *principal_list, struct KeyCert *cert)
|
||||
{
|
||||
diff -up openssh-5.9p0/monitor.c.audit2 openssh-5.9p0/monitor.c
|
||||
--- openssh-5.9p0/monitor.c.audit2 2011-08-30 10:55:35.849023496 +0200
|
||||
+++ openssh-5.9p0/monitor.c 2011-08-30 10:55:38.848024600 +0200
|
||||
@@ -1318,9 +1318,11 @@ mm_answer_keyverify(int sock, Buffer *m)
|
||||
Key *key;
|
||||
u_char *signature, *data, *blob;
|
||||
u_int signaturelen, datalen, bloblen;
|
||||
+ int type = 0;
|
||||
int verified = 0;
|
||||
int valid_data = 0;
|
||||
|
||||
+ type = buffer_get_int(m);
|
||||
blob = buffer_get_string(m, &bloblen);
|
||||
signature = buffer_get_string(m, &signaturelen);
|
||||
data = buffer_get_string(m, &datalen);
|
||||
@@ -1328,6 +1330,8 @@ mm_answer_keyverify(int sock, Buffer *m)
|
||||
if (hostbased_cuser == NULL || hostbased_chost == NULL ||
|
||||
!monitor_allowed_key(blob, bloblen))
|
||||
fatal("%s: bad key, not previously allowed", __func__);
|
||||
+ if (type != key_blobtype)
|
||||
+ fatal("%s: bad key type", __func__);
|
||||
|
||||
key = key_from_blob(blob, bloblen);
|
||||
if (key == NULL)
|
||||
@@ -1348,7 +1352,17 @@ mm_answer_keyverify(int sock, Buffer *m)
|
||||
if (!valid_data)
|
||||
fatal("%s: bad signature data blob", __func__);
|
||||
|
||||
- verified = key_verify(key, signature, signaturelen, data, datalen);
|
||||
+ switch (key_blobtype) {
|
||||
+ case MM_USERKEY:
|
||||
+ verified = user_key_verify(key, signature, signaturelen, data, datalen);
|
||||
+ break;
|
||||
+ case MM_HOSTKEY:
|
||||
+ verified = hostbased_key_verify(key, signature, signaturelen, data, datalen);
|
||||
+ break;
|
||||
+ default:
|
||||
+ verified = 0;
|
||||
+ break;
|
||||
+ }
|
||||
debug3("%s: key %p signature %s",
|
||||
__func__, key, (verified == 1) ? "verified" : "unverified");
|
||||
|
||||
diff -up openssh-5.9p0/monitor_wrap.c.audit2 openssh-5.9p0/monitor_wrap.c
|
||||
--- openssh-5.9p0/monitor_wrap.c.audit2 2011-08-30 10:55:36.431043533 +0200
|
||||
+++ openssh-5.9p0/monitor_wrap.c 2011-08-30 10:55:39.074038187 +0200
|
||||
@@ -431,7 +431,7 @@ mm_key_allowed(enum mm_keytype type, cha
|
||||
*/
|
||||
|
||||
int
|
||||
-mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
|
||||
+mm_key_verify(enum mm_keytype type, Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
|
||||
{
|
||||
Buffer m;
|
||||
u_char *blob;
|
||||
@@ -445,6 +445,7 @@ mm_key_verify(Key *key, u_char *sig, u_i
|
||||
return (0);
|
||||
|
||||
buffer_init(&m);
|
||||
+ buffer_put_int(&m, type);
|
||||
buffer_put_string(&m, blob, len);
|
||||
buffer_put_string(&m, sig, siglen);
|
||||
buffer_put_string(&m, data, datalen);
|
||||
@@ -462,6 +463,19 @@ mm_key_verify(Key *key, u_char *sig, u_i
|
||||
return (verified);
|
||||
}
|
||||
|
||||
+int
|
||||
+mm_hostbased_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
|
||||
+{
|
||||
+ return mm_key_verify(MM_HOSTKEY, key, sig, siglen, data, datalen);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+mm_user_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
|
||||
+{
|
||||
+ return mm_key_verify(MM_USERKEY, key, sig, siglen, data, datalen);
|
||||
+}
|
||||
+
|
||||
+
|
||||
/* Export key state after authentication */
|
||||
Newkeys *
|
||||
mm_newkeys_from_blob(u_char *blob, int blen)
|
||||
diff -up openssh-5.9p0/monitor_wrap.h.audit2 openssh-5.9p0/monitor_wrap.h
|
||||
--- openssh-5.9p0/monitor_wrap.h.audit2 2011-08-30 10:55:36.550088263 +0200
|
||||
+++ openssh-5.9p0/monitor_wrap.h 2011-08-30 10:55:39.282151179 +0200
|
||||
@@ -49,7 +49,8 @@ int mm_key_allowed(enum mm_keytype, char
|
||||
int mm_user_key_allowed(struct passwd *, Key *);
|
||||
int mm_hostbased_key_allowed(struct passwd *, char *, char *, Key *);
|
||||
int mm_auth_rhosts_rsa_key_allowed(struct passwd *, char *, char *, Key *);
|
||||
-int mm_key_verify(Key *, u_char *, u_int, u_char *, u_int);
|
||||
+int mm_hostbased_key_verify(Key *, u_char *, u_int, u_char *, u_int);
|
||||
+int mm_user_key_verify(Key *, u_char *, u_int, u_char *, u_int);
|
||||
int mm_auth_rsa_key_allowed(struct passwd *, BIGNUM *, Key **);
|
||||
int mm_auth_rsa_verify_response(Key *, BIGNUM *, u_char *);
|
||||
BIGNUM *mm_auth_rsa_generate_challenge(Key *);
|
521
openssh-5.9p1-audit3.patch
Normal file
521
openssh-5.9p1-audit3.patch
Normal file
@ -0,0 +1,521 @@
|
||||
diff -up openssh-5.9p0/Makefile.in.audit3 openssh-5.9p0/Makefile.in
|
||||
--- openssh-5.9p0/Makefile.in.audit3 2011-08-05 22:15:18.000000000 +0200
|
||||
+++ openssh-5.9p0/Makefile.in 2011-09-03 19:28:53.226036039 +0200
|
||||
@@ -71,7 +71,7 @@ LIBSSH_OBJS=acss.o authfd.o authfile.o b
|
||||
monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \
|
||||
kexdh.o kexgex.o kexdhc.o kexgexc.o bufec.o kexecdh.o kexecdhc.o \
|
||||
msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o jpake.o \
|
||||
- schnorr.o ssh-pkcs11.o
|
||||
+ schnorr.o ssh-pkcs11.o auditstub.o
|
||||
|
||||
SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
|
||||
sshconnect.o sshconnect1.o sshconnect2.o mux.o \
|
||||
diff -up openssh-5.9p0/audit-bsm.c.audit3 openssh-5.9p0/audit-bsm.c
|
||||
--- openssh-5.9p0/audit-bsm.c.audit3 2011-09-03 19:28:51.922034646 +0200
|
||||
+++ openssh-5.9p0/audit-bsm.c 2011-09-03 19:28:53.475151642 +0200
|
||||
@@ -396,4 +396,16 @@ audit_event(ssh_audit_event_t event)
|
||||
debug("%s: unhandled event %d", __func__, event);
|
||||
}
|
||||
}
|
||||
+
|
||||
+void
|
||||
+audit_unsupported_body(int what)
|
||||
+{
|
||||
+ /* not implemented */
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+audit_kex_body(int ctos, char *enc, char *mac, char *compress, pid_t pid, uid_t uid)
|
||||
+{
|
||||
+ /* not implemented */
|
||||
+}
|
||||
#endif /* BSM */
|
||||
diff -up openssh-5.9p0/audit-linux.c.audit3 openssh-5.9p0/audit-linux.c
|
||||
--- openssh-5.9p0/audit-linux.c.audit3 2011-09-03 19:28:52.053030306 +0200
|
||||
+++ openssh-5.9p0/audit-linux.c 2011-09-03 19:28:53.583026470 +0200
|
||||
@@ -40,6 +40,8 @@
|
||||
#include "auth.h"
|
||||
#include "servconf.h"
|
||||
#include "canohost.h"
|
||||
+#include "packet.h"
|
||||
+#include "cipher.h"
|
||||
|
||||
#define AUDIT_LOG_SIZE 128
|
||||
|
||||
@@ -269,4 +271,56 @@ audit_event(ssh_audit_event_t event)
|
||||
}
|
||||
}
|
||||
|
||||
+void
|
||||
+audit_unsupported_body(int what)
|
||||
+{
|
||||
+#ifdef AUDIT_CRYPTO_SESSION
|
||||
+ char buf[AUDIT_LOG_SIZE];
|
||||
+ const static char *name[] = { "cipher", "mac", "comp" };
|
||||
+ int audit_fd;
|
||||
+
|
||||
+ snprintf(buf, sizeof(buf), "op=unsupported-%s direction=? cipher=? ksize=? rport=%d laddr=%s lport=%d ",
|
||||
+ name[what], get_remote_port(), get_local_ipaddr(packet_get_connection_in()),
|
||||
+ get_local_port());
|
||||
+ audit_fd = audit_open();
|
||||
+ if (audit_fd < 0)
|
||||
+ /* no problem, the next instruction will be fatal() */
|
||||
+ return;
|
||||
+ audit_log_user_message(audit_fd, AUDIT_CRYPTO_SESSION,
|
||||
+ buf, NULL, get_remote_ipaddr(), NULL, 0);
|
||||
+ audit_close(audit_fd);
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+audit_kex_body(int ctos, char *enc, char *mac, char *compress, pid_t pid,
|
||||
+ uid_t uid)
|
||||
+{
|
||||
+#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);
|
||||
+
|
||||
+ snprintf(buf, sizeof(buf), "op=start direction=%s cipher=%s ksize=%d spid=%jd suid=%jd rport=%d laddr=%s lport=%d ",
|
||||
+ direction[ctos], enc, cipher ? 8 * cipher->key_len : 0,
|
||||
+ (intmax_t)pid, (intmax_t)uid,
|
||||
+ get_remote_port(), get_local_ipaddr(packet_get_connection_in()), get_local_port());
|
||||
+ audit_fd = audit_open();
|
||||
+ if (audit_fd < 0) {
|
||||
+ if (errno == EINVAL || errno == EPROTONOSUPPORT ||
|
||||
+ errno == EAFNOSUPPORT)
|
||||
+ return; /* No audit support in kernel */
|
||||
+ else
|
||||
+ fatal("cannot open audit"); /* Must prevent login */
|
||||
+ }
|
||||
+ audit_ok = audit_log_user_message(audit_fd, AUDIT_CRYPTO_SESSION,
|
||||
+ 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)))
|
||||
+ fatal("cannot write into audit"); /* Must prevent login */
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
#endif /* USE_LINUX_AUDIT */
|
||||
diff -up openssh-5.9p0/audit.c.audit3 openssh-5.9p0/audit.c
|
||||
--- openssh-5.9p0/audit.c.audit3 2011-09-03 19:28:52.166026259 +0200
|
||||
+++ openssh-5.9p0/audit.c 2011-09-03 19:28:53.673151432 +0200
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
+#include <unistd.h>
|
||||
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
|
||||
@@ -36,6 +37,8 @@
|
||||
#include "key.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
+#include "ssh-gss.h"
|
||||
+#include "monitor_wrap.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
/*
|
||||
@@ -128,6 +131,18 @@ audit_key(int host_user, int *rv, const
|
||||
xfree(fp);
|
||||
}
|
||||
|
||||
+void
|
||||
+audit_unsupported(int what)
|
||||
+{
|
||||
+ PRIVSEP(audit_unsupported_body(what));
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+audit_kex(int ctos, char *enc, char *mac, char *comp)
|
||||
+{
|
||||
+ PRIVSEP(audit_kex_body(ctos, enc, mac, comp, getpid(), getuid()));
|
||||
+}
|
||||
+
|
||||
# ifndef CUSTOM_SSH_AUDIT_EVENTS
|
||||
/*
|
||||
* Null implementations of audit functions.
|
||||
@@ -238,5 +253,26 @@ audit_keyusage(int host_user, const char
|
||||
host_user ? "pubkey" : "hostbased", geteuid(), audit_username(), type, bits,
|
||||
key_fingerprint_prefix(), fp, rv);
|
||||
}
|
||||
+
|
||||
+/*
|
||||
+ * This will be called when the protocol negotiation fails.
|
||||
+ */
|
||||
+void
|
||||
+audit_unsupported_body(int what)
|
||||
+{
|
||||
+ debug("audit unsupported protocol euid %d type %d", geteuid(), what);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * This will be called on succesfull protocol negotiation.
|
||||
+ */
|
||||
+void
|
||||
+audit_kex_body(int ctos, char *enc, char *mac, char *compress, pid_t pid,
|
||||
+ uid_t uid)
|
||||
+{
|
||||
+ debug("audit protocol negotiation euid %d direction %d cipher %s mac %s compresion %s from pid %ld uid %u",
|
||||
+ (unsigned)geteuid(), ctos, enc, mac, compress, (long)pid,
|
||||
+ (unsigned)uid);
|
||||
+}
|
||||
# endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */
|
||||
#endif /* SSH_AUDIT_EVENTS */
|
||||
diff -up openssh-5.9p0/audit.h.audit3 openssh-5.9p0/audit.h
|
||||
--- openssh-5.9p0/audit.h.audit3 2011-09-03 19:28:52.286024211 +0200
|
||||
+++ openssh-5.9p0/audit.h 2011-09-03 19:28:53.783027870 +0200
|
||||
@@ -58,5 +58,9 @@ void audit_end_command(int, const char
|
||||
ssh_audit_event_t audit_classify_auth(const char *);
|
||||
int audit_keyusage(int, const char *, unsigned, char *, int);
|
||||
void audit_key(int, int *, const Key *);
|
||||
+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);
|
||||
|
||||
#endif /* _SSH_AUDIT_H */
|
||||
diff -up openssh-5.9p0/auditstub.c.audit3 openssh-5.9p0/auditstub.c
|
||||
--- openssh-5.9p0/auditstub.c.audit3 2011-09-03 19:28:53.879026270 +0200
|
||||
+++ openssh-5.9p0/auditstub.c 2011-09-03 19:28:53.882025491 +0200
|
||||
@@ -0,0 +1,39 @@
|
||||
+/* $Id: auditstub.c,v 1.1 jfch Exp $ */
|
||||
+
|
||||
+/*
|
||||
+ * Copyright 2010 Red Hat, Inc. All rights reserved.
|
||||
+ * Use is subject to license terms.
|
||||
+ *
|
||||
+ * Redistribution and use in source and binary forms, with or without
|
||||
+ * modification, are permitted provided that the following conditions
|
||||
+ * are met:
|
||||
+ * 1. Redistributions of source code must retain the above copyright
|
||||
+ * notice, this list of conditions and the following disclaimer.
|
||||
+ * 2. Redistributions in binary form must reproduce the above copyright
|
||||
+ * notice, this list of conditions and the following disclaimer in the
|
||||
+ * documentation and/or other materials provided with the distribution.
|
||||
+ *
|
||||
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
+ *
|
||||
+ * Red Hat author: Jan F. Chadima <jchadima@redhat.com>
|
||||
+ */
|
||||
+
|
||||
+void
|
||||
+audit_unsupported(int n)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+audit_kex(int ctos, char *enc, char *mac, char *comp)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
diff -up openssh-5.9p0/cipher.c.audit3 openssh-5.9p0/cipher.c
|
||||
--- openssh-5.9p0/cipher.c.audit3 2011-08-30 10:34:01.000000000 +0200
|
||||
+++ openssh-5.9p0/cipher.c 2011-09-03 19:28:53.966162869 +0200
|
||||
@@ -60,15 +60,7 @@ extern void ssh1_3des_iv(EVP_CIPHER_CTX
|
||||
extern const EVP_CIPHER *evp_aes_128_ctr(void);
|
||||
extern void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, u_int);
|
||||
|
||||
-struct Cipher {
|
||||
- char *name;
|
||||
- int number; /* for ssh1 only */
|
||||
- u_int block_size;
|
||||
- u_int key_len;
|
||||
- u_int discard_len;
|
||||
- u_int cbc_mode;
|
||||
- const EVP_CIPHER *(*evptype)(void);
|
||||
-} ciphers[] = {
|
||||
+struct Cipher ciphers[] = {
|
||||
{ "none", SSH_CIPHER_NONE, 8, 0, 0, 0, EVP_enc_null },
|
||||
{ "des", SSH_CIPHER_DES, 8, 8, 0, 1, EVP_des_cbc },
|
||||
{ "3des", SSH_CIPHER_3DES, 8, 16, 0, 1, evp_ssh1_3des },
|
||||
diff -up openssh-5.9p0/cipher.h.audit3 openssh-5.9p0/cipher.h
|
||||
--- openssh-5.9p0/cipher.h.audit3 2009-01-28 06:38:41.000000000 +0100
|
||||
+++ openssh-5.9p0/cipher.h 2011-09-03 19:28:54.068070077 +0200
|
||||
@@ -61,7 +61,16 @@
|
||||
typedef struct Cipher Cipher;
|
||||
typedef struct CipherContext CipherContext;
|
||||
|
||||
-struct Cipher;
|
||||
+struct Cipher {
|
||||
+ char *name;
|
||||
+ int number; /* for ssh1 only */
|
||||
+ u_int block_size;
|
||||
+ u_int key_len;
|
||||
+ u_int discard_len;
|
||||
+ u_int cbc_mode;
|
||||
+ const EVP_CIPHER *(*evptype)(void);
|
||||
+};
|
||||
+
|
||||
struct CipherContext {
|
||||
int plaintext;
|
||||
EVP_CIPHER_CTX evp;
|
||||
diff -up openssh-5.9p0/kex.c.audit3 openssh-5.9p0/kex.c
|
||||
--- openssh-5.9p0/kex.c.audit3 2010-09-24 14:11:14.000000000 +0200
|
||||
+++ openssh-5.9p0/kex.c 2011-09-03 19:28:54.177212272 +0200
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "dispatch.h"
|
||||
#include "monitor.h"
|
||||
#include "roaming.h"
|
||||
+#include "audit.h"
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
|
||||
# if defined(HAVE_EVP_SHA256)
|
||||
@@ -286,9 +287,13 @@ static void
|
||||
choose_enc(Enc *enc, char *client, char *server)
|
||||
{
|
||||
char *name = match_list(client, server, NULL);
|
||||
- if (name == NULL)
|
||||
+ if (name == NULL) {
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+ audit_unsupported(0);
|
||||
+#endif
|
||||
fatal("no matching cipher found: client %s server %s",
|
||||
client, server);
|
||||
+ }
|
||||
if ((enc->cipher = cipher_by_name(name)) == NULL)
|
||||
fatal("matching cipher is not supported: %s", name);
|
||||
enc->name = name;
|
||||
@@ -303,9 +308,13 @@ static void
|
||||
choose_mac(Mac *mac, char *client, char *server)
|
||||
{
|
||||
char *name = match_list(client, server, NULL);
|
||||
- if (name == NULL)
|
||||
+ if (name == NULL) {
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+ audit_unsupported(1);
|
||||
+#endif
|
||||
fatal("no matching mac found: client %s server %s",
|
||||
client, server);
|
||||
+ }
|
||||
if (mac_setup(mac, name) < 0)
|
||||
fatal("unsupported mac %s", name);
|
||||
/* truncate the key */
|
||||
@@ -320,8 +329,12 @@ static void
|
||||
choose_comp(Comp *comp, char *client, char *server)
|
||||
{
|
||||
char *name = match_list(client, server, NULL);
|
||||
- if (name == NULL)
|
||||
+ if (name == NULL) {
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+ audit_unsupported(2);
|
||||
+#endif
|
||||
fatal("no matching comp found: client %s server %s", client, server);
|
||||
+ }
|
||||
if (strcmp(name, "zlib@openssh.com") == 0) {
|
||||
comp->type = COMP_DELAYED;
|
||||
} else if (strcmp(name, "zlib") == 0) {
|
||||
@@ -446,6 +459,9 @@ kex_choose_conf(Kex *kex)
|
||||
newkeys->enc.name,
|
||||
newkeys->mac.name,
|
||||
newkeys->comp.name);
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+ audit_kex(ctos, newkeys->enc.name, newkeys->mac.name, newkeys->comp.name);
|
||||
+#endif
|
||||
}
|
||||
choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]);
|
||||
choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS],
|
||||
diff -up openssh-5.9p0/monitor.c.audit3 openssh-5.9p0/monitor.c
|
||||
--- openssh-5.9p0/monitor.c.audit3 2011-09-03 19:28:52.851088094 +0200
|
||||
+++ openssh-5.9p0/monitor.c 2011-09-03 19:28:54.298087612 +0200
|
||||
@@ -97,6 +97,7 @@
|
||||
#include "ssh2.h"
|
||||
#include "jpake.h"
|
||||
#include "roaming.h"
|
||||
+#include "audit.h"
|
||||
|
||||
#ifdef GSSAPI
|
||||
static Gssctxt *gsscontext = NULL;
|
||||
@@ -187,6 +188,8 @@ int mm_answer_gss_checkmic(int, Buffer *
|
||||
int mm_answer_audit_event(int, Buffer *);
|
||||
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 *);
|
||||
#endif
|
||||
|
||||
static int monitor_read_log(struct monitor *);
|
||||
@@ -237,6 +240,8 @@ struct mon_table mon_dispatch_proto20[]
|
||||
#endif
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
{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},
|
||||
#endif
|
||||
#ifdef BSD_AUTH
|
||||
{MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery},
|
||||
@@ -275,6 +280,8 @@ struct mon_table mon_dispatch_postauth20
|
||||
{MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
|
||||
{MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT, mm_answer_audit_command},
|
||||
{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},
|
||||
#endif
|
||||
{0, 0, NULL}
|
||||
};
|
||||
@@ -306,6 +313,8 @@ struct mon_table mon_dispatch_proto15[]
|
||||
#endif
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
{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},
|
||||
#endif
|
||||
{0, 0, NULL}
|
||||
};
|
||||
@@ -318,6 +327,8 @@ struct mon_table mon_dispatch_postauth15
|
||||
{MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
|
||||
{MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT|MON_ONCE, mm_answer_audit_command},
|
||||
{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},
|
||||
#endif
|
||||
{0, 0, NULL}
|
||||
};
|
||||
@@ -2380,3 +2391,44 @@ mm_answer_jpake_check_confirm(int sock,
|
||||
}
|
||||
|
||||
#endif /* JPAKE */
|
||||
+
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+int
|
||||
+mm_answer_audit_unsupported_body(int sock, Buffer *m)
|
||||
+{
|
||||
+ int what;
|
||||
+
|
||||
+ what = buffer_get_int(m);
|
||||
+
|
||||
+ audit_unsupported_body(what);
|
||||
+
|
||||
+ buffer_clear(m);
|
||||
+
|
||||
+ mm_request_send(sock, MONITOR_ANS_AUDIT_UNSUPPORTED, m);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+mm_answer_audit_kex_body(int sock, Buffer *m)
|
||||
+{
|
||||
+ int ctos, len;
|
||||
+ char *cipher, *mac, *compress;
|
||||
+ pid_t pid;
|
||||
+ uid_t uid;
|
||||
+
|
||||
+ ctos = buffer_get_int(m);
|
||||
+ cipher = buffer_get_string(m, &len);
|
||||
+ mac = buffer_get_string(m, &len);
|
||||
+ compress = buffer_get_string(m, &len);
|
||||
+ pid = buffer_get_int64(m);
|
||||
+ uid = buffer_get_int64(m);
|
||||
+
|
||||
+ audit_kex_body(ctos, cipher, mac, compress, pid, uid);
|
||||
+
|
||||
+ buffer_clear(m);
|
||||
+
|
||||
+ mm_request_send(sock, MONITOR_ANS_AUDIT_KEX, m);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#endif /* SSH_AUDIT_EVENTS */
|
||||
diff -up openssh-5.9p0/monitor.h.audit3 openssh-5.9p0/monitor.h
|
||||
--- openssh-5.9p0/monitor.h.audit3 2011-09-03 19:28:51.000000000 +0200
|
||||
+++ openssh-5.9p0/monitor.h 2011-09-03 19:29:52.565211520 +0200
|
||||
@@ -61,6 +61,8 @@ enum monitor_reqtype {
|
||||
MONITOR_REQ_PAM_FREE_CTX, MONITOR_ANS_PAM_FREE_CTX,
|
||||
MONITOR_REQ_AUDIT_EVENT, MONITOR_REQ_AUDIT_COMMAND,
|
||||
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_TERM,
|
||||
MONITOR_REQ_JPAKE_STEP1, MONITOR_ANS_JPAKE_STEP1,
|
||||
MONITOR_REQ_JPAKE_GET_PWDATA, MONITOR_ANS_JPAKE_GET_PWDATA,
|
||||
diff -up openssh-5.9p0/monitor_wrap.c.audit3 openssh-5.9p0/monitor_wrap.c
|
||||
--- openssh-5.9p0/monitor_wrap.c.audit3 2011-09-03 19:28:52.963088596 +0200
|
||||
+++ openssh-5.9p0/monitor_wrap.c 2011-09-03 19:28:54.602024893 +0200
|
||||
@@ -1505,3 +1505,41 @@ mm_jpake_check_confirm(const BIGNUM *k,
|
||||
return success;
|
||||
}
|
||||
#endif /* JPAKE */
|
||||
+
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+void
|
||||
+mm_audit_unsupported_body(int what)
|
||||
+{
|
||||
+ Buffer m;
|
||||
+
|
||||
+ buffer_init(&m);
|
||||
+ buffer_put_int(&m, what);
|
||||
+
|
||||
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_UNSUPPORTED, &m);
|
||||
+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_UNSUPPORTED,
|
||||
+ &m);
|
||||
+
|
||||
+ buffer_free(&m);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+mm_audit_kex_body(int ctos, char *cipher, char *mac, char *compress, pid_t pid,
|
||||
+ uid_t uid)
|
||||
+{
|
||||
+ Buffer m;
|
||||
+
|
||||
+ buffer_init(&m);
|
||||
+ buffer_put_int(&m, ctos);
|
||||
+ buffer_put_cstring(&m, cipher);
|
||||
+ buffer_put_cstring(&m, mac);
|
||||
+ buffer_put_cstring(&m, compress);
|
||||
+ buffer_put_int64(&m, pid);
|
||||
+ buffer_put_int64(&m, uid);
|
||||
+
|
||||
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_KEX, &m);
|
||||
+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_KEX,
|
||||
+ &m);
|
||||
+
|
||||
+ buffer_free(&m);
|
||||
+}
|
||||
+#endif /* SSH_AUDIT_EVENTS */
|
||||
diff -up openssh-5.9p0/monitor_wrap.h.audit3 openssh-5.9p0/monitor_wrap.h
|
||||
--- openssh-5.9p0/monitor_wrap.h.audit3 2011-09-03 19:28:53.069087341 +0200
|
||||
+++ openssh-5.9p0/monitor_wrap.h 2011-09-03 19:28:54.704055439 +0200
|
||||
@@ -78,6 +78,8 @@ void mm_sshpam_free_ctx(void *);
|
||||
void mm_audit_event(ssh_audit_event_t);
|
||||
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);
|
||||
#endif
|
||||
|
||||
struct Session;
|
||||
diff -up openssh-5.9p0/sshd.c.audit3 openssh-5.9p0/sshd.c
|
||||
--- openssh-5.9p0/sshd.c.audit3 2011-09-03 19:28:51.758025429 +0200
|
||||
+++ openssh-5.9p0/sshd.c 2011-09-03 19:28:54.835049403 +0200
|
||||
@@ -118,6 +118,7 @@
|
||||
#endif
|
||||
#include "monitor_wrap.h"
|
||||
#include "roaming.h"
|
||||
+#include "audit.h"
|
||||
#include "ssh-sandbox.h"
|
||||
#include "version.h"
|
||||
|
||||
@@ -2204,6 +2205,10 @@ do_ssh1_kex(void)
|
||||
if (cookie[i] != packet_get_char())
|
||||
packet_disconnect("IP Spoofing check bytes do not match.");
|
||||
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+ audit_kex(2, cipher_name(cipher_type), "crc", "none");
|
||||
+#endif
|
||||
+
|
||||
debug("Encryption type: %.200s", cipher_name(cipher_type));
|
||||
|
||||
/* Get the encrypted integer. */
|
636
openssh-5.9p1-audit4.patch
Normal file
636
openssh-5.9p1-audit4.patch
Normal file
@ -0,0 +1,636 @@
|
||||
diff -up openssh-5.9p0/audit-bsm.c.audit4 openssh-5.9p0/audit-bsm.c
|
||||
--- openssh-5.9p0/audit-bsm.c.audit4 2011-09-03 19:32:58.053087996 +0200
|
||||
+++ openssh-5.9p0/audit-bsm.c 2011-09-03 19:32:59.670087560 +0200
|
||||
@@ -408,4 +408,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-5.9p0/audit-linux.c.audit4 openssh-5.9p0/audit-linux.c
|
||||
--- openssh-5.9p0/audit-linux.c.audit4 2011-09-03 19:32:58.177086248 +0200
|
||||
+++ openssh-5.9p0/audit-linux.c 2011-09-03 19:32:59.758096254 +0200
|
||||
@@ -292,6 +292,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)
|
||||
@@ -299,7 +301,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);
|
||||
|
||||
snprintf(buf, sizeof(buf), "op=start direction=%s cipher=%s ksize=%d spid=%jd suid=%jd rport=%d laddr=%s lport=%d ",
|
||||
@@ -323,4 +324,30 @@ 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;
|
||||
+
|
||||
+ 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(),
|
||||
+ get_local_ipaddr(packet_get_connection_in()),
|
||||
+ get_local_port());
|
||||
+ 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-5.9p0/audit.c.audit4 openssh-5.9p0/audit.c
|
||||
--- openssh-5.9p0/audit.c.audit4 2011-09-03 19:32:58.292030283 +0200
|
||||
+++ openssh-5.9p0/audit.c 2011-09-03 19:32:59.882149457 +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-5.9p0/audit.h.audit4 openssh-5.9p0/audit.h
|
||||
--- openssh-5.9p0/audit.h.audit4 2011-09-03 19:32:58.389152136 +0200
|
||||
+++ openssh-5.9p0/audit.h 2011-09-03 19:32:59.990088015 +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-5.9p0/auditstub.c.audit4 openssh-5.9p0/auditstub.c
|
||||
--- openssh-5.9p0/auditstub.c.audit4 2011-09-03 19:32:58.485025086 +0200
|
||||
+++ openssh-5.9p0/auditstub.c 2011-09-03 19:33:00.115087744 +0200
|
||||
@@ -27,6 +27,8 @@
|
||||
* Red Hat author: Jan F. Chadima <jchadima@redhat.com>
|
||||
*/
|
||||
|
||||
+#include <sys/types.h>
|
||||
+
|
||||
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-5.9p0/kex.c.audit4 openssh-5.9p0/kex.c
|
||||
--- openssh-5.9p0/kex.c.audit4 2011-09-03 19:32:58.820024508 +0200
|
||||
+++ openssh-5.9p0/kex.c 2011-09-03 19:33:00.226087442 +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-5.9p0/kex.h.audit4 openssh-5.9p0/kex.h
|
||||
--- openssh-5.9p0/kex.h.audit4 2010-09-24 14:11:14.000000000 +0200
|
||||
+++ openssh-5.9p0/kex.h 2011-09-03 19:33:00.342212519 +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-5.9p0/mac.c.audit4 openssh-5.9p0/mac.c
|
||||
--- openssh-5.9p0/mac.c.audit4 2011-08-17 02:29:03.000000000 +0200
|
||||
+++ openssh-5.9p0/mac.c 2011-09-03 19:33:00.476211919 +0200
|
||||
@@ -168,6 +168,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-5.9p0/mac.h.audit4 openssh-5.9p0/mac.h
|
||||
--- openssh-5.9p0/mac.h.audit4 2007-06-11 06:01:42.000000000 +0200
|
||||
+++ openssh-5.9p0/mac.h 2011-09-03 19:33:00.604046419 +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-5.9p0/monitor.c.audit4 openssh-5.9p0/monitor.c
|
||||
--- openssh-5.9p0/monitor.c.audit4 2011-09-03 19:32:58.992150893 +0200
|
||||
+++ openssh-5.9p0/monitor.c 2011-09-03 19:33:00.711212900 +0200
|
||||
@@ -190,6 +190,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},
|
||||
@@ -282,6 +284,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}
|
||||
};
|
||||
@@ -315,6 +318,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}
|
||||
};
|
||||
@@ -329,6 +333,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}
|
||||
};
|
||||
@@ -1927,11 +1932,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 */
|
||||
@@ -1977,6 +1984,16 @@ 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
|
||||
}
|
||||
|
||||
|
||||
@@ -2431,4 +2448,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-5.9p0/monitor.h.audit4 openssh-5.9p0/monitor.h
|
||||
--- openssh-5.9p0/monitor.h.audit4 2011-09-03 19:32:59.000000000 +0200
|
||||
+++ openssh-5.9p0/monitor.h 2011-09-03 19:33:38.376071005 +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-5.9p0/monitor_wrap.c.audit4 openssh-5.9p0/monitor_wrap.c
|
||||
--- openssh-5.9p0/monitor_wrap.c.audit4 2011-09-03 19:32:59.246088665 +0200
|
||||
+++ openssh-5.9p0/monitor_wrap.c 2011-09-03 19:33:01.032042297 +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);
|
||||
@@ -1542,4 +1544,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-5.9p0/monitor_wrap.h.audit4 openssh-5.9p0/monitor_wrap.h
|
||||
--- openssh-5.9p0/monitor_wrap.h.audit4 2011-09-03 19:32:59.357086584 +0200
|
||||
+++ openssh-5.9p0/monitor_wrap.h 2011-09-03 19:33:01.136087512 +0200
|
||||
@@ -80,6 +80,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-5.9p0/packet.c.audit4 openssh-5.9p0/packet.c
|
||||
--- openssh-5.9p0/packet.c.audit4 2011-09-03 19:32:53.452116806 +0200
|
||||
+++ openssh-5.9p0/packet.c 2011-09-03 19:33:01.267128421 +0200
|
||||
@@ -60,6 +60,7 @@
|
||||
#include <signal.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
+#include "audit.h"
|
||||
#include "buffer.h"
|
||||
#include "packet.h"
|
||||
#include "crc32.h"
|
||||
@@ -472,6 +473,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
|
||||
@@ -480,13 +488,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);
|
||||
@@ -495,8 +496,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. */
|
||||
@@ -731,6 +742,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)
|
||||
{
|
||||
@@ -756,18 +784,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)
|
||||
@@ -1926,6 +1945,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.
|
||||
@@ -1933,18 +1993,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();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1961,9 +2015,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);
|
||||
@@ -1971,4 +2023,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-5.9p0/packet.h.audit4 openssh-5.9p0/packet.h
|
||||
--- openssh-5.9p0/packet.h.audit4 2011-05-15 00:43:13.000000000 +0200
|
||||
+++ openssh-5.9p0/packet.h 2011-09-03 19:33:01.386087369 +0200
|
||||
@@ -124,4 +124,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-5.9p0/session.c.audit4 openssh-5.9p0/session.c
|
||||
--- openssh-5.9p0/session.c.audit4 2011-09-03 19:32:56.232163211 +0200
|
||||
+++ openssh-5.9p0/session.c 2011-09-03 19:33:01.516024567 +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-5.9p0/sshd.c.audit4 openssh-5.9p0/sshd.c
|
||||
--- openssh-5.9p0/sshd.c.audit4 2011-09-03 19:32:59.481087303 +0200
|
||||
+++ openssh-5.9p0/sshd.c 2011-09-03 19:33:01.657089865 +0200
|
||||
@@ -684,6 +684,8 @@ privsep_preauth(Authctxt *authctxt)
|
||||
}
|
||||
}
|
||||
|
||||
+extern Newkeys *current_keys[];
|
||||
+
|
||||
static void
|
||||
privsep_postauth(Authctxt *authctxt)
|
||||
{
|
||||
@@ -708,6 +710,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 */
|
||||
@@ -1996,6 +2002,7 @@ main(int ac, char **av)
|
||||
*/
|
||||
if (use_privsep) {
|
||||
mm_send_keystate(pmonitor);
|
||||
+ packet_destroy_all(1, 1);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@@ -2048,6 +2055,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",
|
||||
@@ -2367,6 +2376,7 @@ cleanup_exit(int i)
|
||||
{
|
||||
if (the_authctxt)
|
||||
do_cleanup(the_authctxt);
|
||||
+ 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) &&
|
499
openssh-5.9p1-audit5.patch
Normal file
499
openssh-5.9p1-audit5.patch
Normal file
@ -0,0 +1,499 @@
|
||||
diff -up openssh-5.9p0/audit-bsm.c.audit5 openssh-5.9p0/audit-bsm.c
|
||||
--- openssh-5.9p0/audit-bsm.c.audit5 2011-09-03 19:36:19.596148796 +0200
|
||||
+++ openssh-5.9p0/audit-bsm.c 2011-09-03 19:36:22.335036037 +0200
|
||||
@@ -414,4 +414,22 @@ audit_session_key_free_body(int ctos, pi
|
||||
{
|
||||
/* not implemented */
|
||||
}
|
||||
+
|
||||
+void
|
||||
+audit_destroy_sensitive_data(const char *fp)
|
||||
+{
|
||||
+ /* not implemented */
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid)
|
||||
+{
|
||||
+ /* not implemented */
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+audit_generate_ephemeral_server_key(const char *fp)
|
||||
+{
|
||||
+ /* not implemented */
|
||||
+}
|
||||
#endif /* BSM */
|
||||
diff -up openssh-5.9p0/audit-linux.c.audit5 openssh-5.9p0/audit-linux.c
|
||||
--- openssh-5.9p0/audit-linux.c.audit5 2011-09-03 19:36:19.693075842 +0200
|
||||
+++ openssh-5.9p0/audit-linux.c 2011-09-03 19:36:22.783167781 +0200
|
||||
@@ -350,4 +350,50 @@ audit_session_key_free_body(int ctos, pi
|
||||
error("cannot write into audit");
|
||||
}
|
||||
|
||||
+void
|
||||
+audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid)
|
||||
+{
|
||||
+ char buf[AUDIT_LOG_SIZE];
|
||||
+ int audit_fd, audit_ok;
|
||||
+
|
||||
+ snprintf(buf, sizeof(buf), "op=destroy kind=server fp=%s direction=? spid=%jd suid=%jd ",
|
||||
+ fp, (intmax_t)pid, (intmax_t)uid);
|
||||
+ 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,
|
||||
+ listening_for_clients() ? 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");
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+audit_generate_ephemeral_server_key(const char *fp)
|
||||
+{
|
||||
+ char buf[AUDIT_LOG_SIZE];
|
||||
+ int audit_fd, audit_ok;
|
||||
+
|
||||
+ snprintf(buf, sizeof(buf), "op=create kind=server fp=%s direction=? ", fp);
|
||||
+ 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, 0, 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-5.9p0/audit.c.audit5 openssh-5.9p0/audit.c
|
||||
--- openssh-5.9p0/audit.c.audit5 2011-09-03 19:36:19.798026930 +0200
|
||||
+++ openssh-5.9p0/audit.c 2011-09-03 19:36:22.894025519 +0200
|
||||
@@ -290,5 +290,24 @@ audit_session_key_free_body(int ctos, pi
|
||||
debug("audit session key discard euid %u direction %d from pid %ld uid %u",
|
||||
(unsigned)geteuid(), ctos, (long)pid, (unsigned)uid);
|
||||
}
|
||||
+
|
||||
+/*
|
||||
+ * This will be called on destroy private part of the server key
|
||||
+ */
|
||||
+void
|
||||
+audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid)
|
||||
+{
|
||||
+ debug("audit destroy sensitive data euid %d fingerprint %s from pid %ld uid %u",
|
||||
+ geteuid(), fp, (long)pid, (unsigned)uid);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * This will be called on generation of the ephemeral server key
|
||||
+ */
|
||||
+void
|
||||
+audit_generate_ephemeral_server_key(const char *)
|
||||
+{
|
||||
+ debug("audit create ephemeral server key euid %d fingerprint %s", geteuid(), fp);
|
||||
+}
|
||||
# endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */
|
||||
#endif /* SSH_AUDIT_EVENTS */
|
||||
diff -up openssh-5.9p0/audit.h.audit5 openssh-5.9p0/audit.h
|
||||
--- openssh-5.9p0/audit.h.audit5 2011-09-03 19:36:20.080151641 +0200
|
||||
+++ openssh-5.9p0/audit.h 2011-09-03 19:36:23.002024714 +0200
|
||||
@@ -48,6 +48,8 @@ enum ssh_audit_event_type {
|
||||
};
|
||||
typedef enum ssh_audit_event_type ssh_audit_event_t;
|
||||
|
||||
+int listening_for_clients(void);
|
||||
+
|
||||
void audit_connection_from(const char *, int);
|
||||
void audit_event(ssh_audit_event_t);
|
||||
void audit_count_session_open(void);
|
||||
@@ -64,5 +66,7 @@ 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);
|
||||
+void audit_destroy_sensitive_data(const char *, pid_t, uid_t);
|
||||
+void audit_generate_ephemeral_server_key(const char *);
|
||||
|
||||
#endif /* _SSH_AUDIT_H */
|
||||
diff -up openssh-5.9p0/key.c.audit5 openssh-5.9p0/key.c
|
||||
--- openssh-5.9p0/key.c.audit5 2011-09-03 19:36:11.788093495 +0200
|
||||
+++ openssh-5.9p0/key.c 2011-09-03 19:36:23.114023593 +0200
|
||||
@@ -1797,6 +1797,30 @@ key_demote(const Key *k)
|
||||
}
|
||||
|
||||
int
|
||||
+key_is_private(const Key *k)
|
||||
+{
|
||||
+ switch (k->type) {
|
||||
+ case KEY_RSA_CERT_V00:
|
||||
+ case KEY_RSA_CERT:
|
||||
+ case KEY_RSA1:
|
||||
+ case KEY_RSA:
|
||||
+ return k->rsa->d != NULL;
|
||||
+ case KEY_DSA_CERT_V00:
|
||||
+ case KEY_DSA_CERT:
|
||||
+ case KEY_DSA:
|
||||
+ return k->dsa->priv_key != NULL;
|
||||
+#ifdef OPENSSL_HAS_ECC
|
||||
+ case KEY_ECDSA_CERT:
|
||||
+ case KEY_ECDSA:
|
||||
+ return EC_KEY_get0_private_key(k->ecdsa) != NULL;
|
||||
+#endif
|
||||
+ default:
|
||||
+ fatal("key_is_private: bad key type %d", k->type);
|
||||
+ return 1;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+int
|
||||
key_is_cert(const Key *k)
|
||||
{
|
||||
if (k == NULL)
|
||||
diff -up openssh-5.9p0/key.h.audit5 openssh-5.9p0/key.h
|
||||
--- openssh-5.9p0/key.h.audit5 2011-09-03 19:36:11.873026290 +0200
|
||||
+++ openssh-5.9p0/key.h 2011-09-03 19:36:23.209025893 +0200
|
||||
@@ -109,6 +109,7 @@ Key *key_generate(int, u_int);
|
||||
Key *key_from_private(const Key *);
|
||||
int key_type_from_name(char *);
|
||||
int key_is_cert(const Key *);
|
||||
+int key_is_private(const Key *k);
|
||||
int key_type_plain(int);
|
||||
int key_to_certified(Key *, int);
|
||||
int key_drop_cert(Key *);
|
||||
diff -up openssh-5.9p0/monitor.c.audit5 openssh-5.9p0/monitor.c
|
||||
--- openssh-5.9p0/monitor.c.audit5 2011-09-03 19:36:20.953025745 +0200
|
||||
+++ openssh-5.9p0/monitor.c 2011-09-03 19:36:23.356034851 +0200
|
||||
@@ -114,6 +114,8 @@ extern Buffer auth_debug;
|
||||
extern int auth_debug_init;
|
||||
extern Buffer loginmsg;
|
||||
|
||||
+extern void destroy_sensitive_data(int);
|
||||
+
|
||||
/* State exported from the child */
|
||||
|
||||
struct {
|
||||
@@ -191,6 +193,7 @@ int mm_answer_audit_end_command(int, Buf
|
||||
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 *);
|
||||
+int mm_answer_audit_server_key_free(int, Buffer *);
|
||||
#endif
|
||||
|
||||
static int monitor_read_log(struct monitor *);
|
||||
@@ -244,6 +247,7 @@ struct mon_table mon_dispatch_proto20[]
|
||||
{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},
|
||||
+ {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, mm_answer_audit_server_key_free},
|
||||
#endif
|
||||
#ifdef BSD_AUTH
|
||||
{MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery},
|
||||
@@ -285,6 +289,7 @@ struct mon_table mon_dispatch_postauth20
|
||||
{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},
|
||||
+ {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, mm_answer_audit_server_key_free},
|
||||
#endif
|
||||
{0, 0, NULL}
|
||||
};
|
||||
@@ -319,6 +324,7 @@ struct mon_table mon_dispatch_proto15[]
|
||||
{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},
|
||||
+ {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, mm_answer_audit_server_key_free},
|
||||
#endif
|
||||
{0, 0, NULL}
|
||||
};
|
||||
@@ -334,6 +340,7 @@ struct mon_table mon_dispatch_postauth15
|
||||
{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},
|
||||
+ {MONITOR_REQ_AUDIT_SERVER_KEY_FREE, MON_PERMIT, mm_answer_audit_server_key_free},
|
||||
#endif
|
||||
{0, 0, NULL}
|
||||
};
|
||||
@@ -1722,6 +1729,8 @@ mm_answer_term(int sock, Buffer *req)
|
||||
sshpam_cleanup();
|
||||
#endif
|
||||
|
||||
+ destroy_sensitive_data(0);
|
||||
+
|
||||
while (waitpid(pmonitor->m_pid, &status, 0) == -1)
|
||||
if (errno != EINTR)
|
||||
exit(1);
|
||||
@@ -2466,4 +2475,24 @@ mm_answer_audit_session_key_free_body(in
|
||||
mm_request_send(sock, MONITOR_ANS_AUDIT_SESSION_KEY_FREE, m);
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
+int
|
||||
+mm_answer_audit_server_key_free(int sock, Buffer *m)
|
||||
+{
|
||||
+ int len;
|
||||
+ char *fp;
|
||||
+ pid_t pid;
|
||||
+ uid_t uid;
|
||||
+
|
||||
+ fp = buffer_get_string(m, &len);
|
||||
+ pid = buffer_get_int64(m);
|
||||
+ uid = buffer_get_int64(m);
|
||||
+
|
||||
+ audit_destroy_sensitive_data(fp, pid, uid);
|
||||
+
|
||||
+ buffer_clear(m);
|
||||
+
|
||||
+ mm_request_send(sock, MONITOR_ANS_AUDIT_SERVER_KEY_FREE, m);
|
||||
+ return 0;
|
||||
+}
|
||||
#endif /* SSH_AUDIT_EVENTS */
|
||||
diff -up openssh-5.9p0/monitor.h.audit5 openssh-5.9p0/monitor.h
|
||||
--- openssh-5.9p0/monitor.h.audit5 2011-09-03 19:36:21.000000000 +0200
|
||||
+++ openssh-5.9p0/monitor.h 2011-09-03 19:36:54.529052350 +0200
|
||||
@@ -64,6 +64,7 @@ enum monitor_reqtype {
|
||||
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_AUDIT_SERVER_KEY_FREE, MONITOR_ANS_AUDIT_SERVER_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-5.9p0/monitor_wrap.c.audit5 openssh-5.9p0/monitor_wrap.c
|
||||
--- openssh-5.9p0/monitor_wrap.c.audit5 2011-09-03 19:36:21.212025456 +0200
|
||||
+++ openssh-5.9p0/monitor_wrap.c 2011-09-03 19:36:23.714087175 +0200
|
||||
@@ -1559,4 +1559,20 @@ mm_audit_session_key_free_body(int ctos,
|
||||
&m);
|
||||
buffer_free(&m);
|
||||
}
|
||||
+
|
||||
+void
|
||||
+mm_audit_destroy_sensitive_data(const char *fp, pid_t pid, uid_t uid)
|
||||
+{
|
||||
+ Buffer m;
|
||||
+
|
||||
+ buffer_init(&m);
|
||||
+ buffer_put_cstring(&m, fp);
|
||||
+ buffer_put_int64(&m, pid);
|
||||
+ buffer_put_int64(&m, uid);
|
||||
+
|
||||
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SERVER_KEY_FREE, &m);
|
||||
+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUDIT_SERVER_KEY_FREE,
|
||||
+ &m);
|
||||
+ buffer_free(&m);
|
||||
+}
|
||||
#endif /* SSH_AUDIT_EVENTS */
|
||||
diff -up openssh-5.9p0/monitor_wrap.h.audit5 openssh-5.9p0/monitor_wrap.h
|
||||
--- openssh-5.9p0/monitor_wrap.h.audit5 2011-09-03 19:36:21.316023957 +0200
|
||||
+++ openssh-5.9p0/monitor_wrap.h 2011-09-03 19:36:23.814151174 +0200
|
||||
@@ -81,6 +81,7 @@ void mm_audit_end_command(int, const cha
|
||||
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);
|
||||
+void mm_audit_destroy_sensitive_data(const char *, pid_t, uid_t);
|
||||
#endif
|
||||
|
||||
struct Session;
|
||||
diff -up openssh-5.9p0/session.c.audit5 openssh-5.9p0/session.c
|
||||
--- openssh-5.9p0/session.c.audit5 2011-09-03 19:36:22.072087382 +0200
|
||||
+++ openssh-5.9p0/session.c 2011-09-03 19:36:23.985151473 +0200
|
||||
@@ -136,7 +136,7 @@ extern int log_stderr;
|
||||
extern int debug_flag;
|
||||
extern u_int utmp_len;
|
||||
extern int startup_pipe;
|
||||
-extern void destroy_sensitive_data(void);
|
||||
+extern void destroy_sensitive_data(int);
|
||||
extern Buffer loginmsg;
|
||||
|
||||
/* original command from peer. */
|
||||
@@ -1633,7 +1633,7 @@ do_child(Session *s, const char *command
|
||||
int r = 0;
|
||||
|
||||
/* remove hostkey from the child's memory */
|
||||
- destroy_sensitive_data();
|
||||
+ destroy_sensitive_data(1);
|
||||
/* 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);
|
||||
diff -up openssh-5.9p0/sshd.c.audit5 openssh-5.9p0/sshd.c
|
||||
--- openssh-5.9p0/sshd.c.audit5 2011-09-03 19:36:22.196087195 +0200
|
||||
+++ openssh-5.9p0/sshd.c 2011-09-03 19:36:24.126148826 +0200
|
||||
@@ -254,7 +254,7 @@ Buffer loginmsg;
|
||||
struct passwd *privsep_pw = NULL;
|
||||
|
||||
/* Prototypes for various functions defined later in this file. */
|
||||
-void destroy_sensitive_data(void);
|
||||
+void destroy_sensitive_data(int);
|
||||
void demote_sensitive_data(void);
|
||||
|
||||
static void do_ssh1_kex(void);
|
||||
@@ -273,6 +273,15 @@ close_listen_socks(void)
|
||||
num_listen_socks = -1;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Is this process listening for clients (i.e. not specific to any specific
|
||||
+ * client connection?)
|
||||
+ */
|
||||
+int listening_for_clients(void)
|
||||
+{
|
||||
+ return num_listen_socks > 0;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
close_startup_pipes(void)
|
||||
{
|
||||
@@ -533,22 +542,47 @@ sshd_exchange_identification(int sock_in
|
||||
}
|
||||
}
|
||||
|
||||
-/* Destroy the host and server keys. They will no longer be needed. */
|
||||
+/*
|
||||
+ * Destroy the host and server keys. They will no longer be needed. Careful,
|
||||
+ * this can be called from cleanup_exit() - i.e. from just about anywhere.
|
||||
+ */
|
||||
void
|
||||
-destroy_sensitive_data(void)
|
||||
+destroy_sensitive_data(int privsep)
|
||||
{
|
||||
int i;
|
||||
+ pid_t pid;
|
||||
+ uid_t uid;
|
||||
|
||||
if (sensitive_data.server_key) {
|
||||
key_free(sensitive_data.server_key);
|
||||
sensitive_data.server_key = NULL;
|
||||
}
|
||||
+ pid = getpid();
|
||||
+ uid = getuid();
|
||||
for (i = 0; i < options.num_host_key_files; i++) {
|
||||
if (sensitive_data.host_keys[i]) {
|
||||
+ char *fp;
|
||||
+
|
||||
+ if (key_is_private(sensitive_data.host_keys[i]))
|
||||
+ fp = key_fingerprint(sensitive_data.host_keys[i],
|
||||
+ FIPS_mode() ? SSH_FP_SHA1 : SSH_FP_MD5,
|
||||
+ SSH_FP_HEX);
|
||||
+ else
|
||||
+ fp = NULL;
|
||||
key_free(sensitive_data.host_keys[i]);
|
||||
sensitive_data.host_keys[i] = NULL;
|
||||
+ if (fp != NULL) {
|
||||
+ if (privsep)
|
||||
+ PRIVSEP(audit_destroy_sensitive_data(fp,
|
||||
+ pid, uid));
|
||||
+ else
|
||||
+ audit_destroy_sensitive_data(fp,
|
||||
+ pid, uid);
|
||||
+ xfree(fp);
|
||||
+ }
|
||||
}
|
||||
- if (sensitive_data.host_certificates[i]) {
|
||||
+ if (sensitive_data.host_certificates
|
||||
+ && sensitive_data.host_certificates[i]) {
|
||||
key_free(sensitive_data.host_certificates[i]);
|
||||
sensitive_data.host_certificates[i] = NULL;
|
||||
}
|
||||
@@ -562,6 +596,8 @@ void
|
||||
demote_sensitive_data(void)
|
||||
{
|
||||
Key *tmp;
|
||||
+ pid_t pid;
|
||||
+ uid_t uid;
|
||||
int i;
|
||||
|
||||
if (sensitive_data.server_key) {
|
||||
@@ -570,13 +606,27 @@ demote_sensitive_data(void)
|
||||
sensitive_data.server_key = tmp;
|
||||
}
|
||||
|
||||
+ pid = getpid();
|
||||
+ uid = getuid();
|
||||
for (i = 0; i < options.num_host_key_files; i++) {
|
||||
if (sensitive_data.host_keys[i]) {
|
||||
+ char *fp;
|
||||
+
|
||||
+ if (key_is_private(sensitive_data.host_keys[i]))
|
||||
+ fp = key_fingerprint(sensitive_data.host_keys[i],
|
||||
+ FIPS_mode() ? SSH_FP_SHA1 : SSH_FP_MD5,
|
||||
+ SSH_FP_HEX);
|
||||
+ else
|
||||
+ fp = NULL;
|
||||
tmp = key_demote(sensitive_data.host_keys[i]);
|
||||
key_free(sensitive_data.host_keys[i]);
|
||||
sensitive_data.host_keys[i] = tmp;
|
||||
if (tmp->type == KEY_RSA1)
|
||||
sensitive_data.ssh1_host_key = tmp;
|
||||
+ if (fp != NULL) {
|
||||
+ audit_destroy_sensitive_data(fp, pid, uid);
|
||||
+ xfree(fp);
|
||||
+ }
|
||||
}
|
||||
/* Certs do not need demotion */
|
||||
}
|
||||
@@ -1143,6 +1193,7 @@ server_accept_loop(int *sock_in, int *so
|
||||
if (received_sigterm) {
|
||||
logit("Received signal %d; terminating.",
|
||||
(int) received_sigterm);
|
||||
+ destroy_sensitive_data(0);
|
||||
close_listen_socks();
|
||||
unlink(options.pid_file);
|
||||
exit(received_sigterm == SIGTERM ? 0 : 255);
|
||||
@@ -2045,7 +2096,7 @@ main(int ac, char **av)
|
||||
privsep_postauth(authctxt);
|
||||
/* the monitor process [priv] will not return */
|
||||
if (!compat20)
|
||||
- destroy_sensitive_data();
|
||||
+ destroy_sensitive_data(0);
|
||||
}
|
||||
|
||||
packet_set_timeout(options.client_alive_interval,
|
||||
@@ -2056,6 +2107,7 @@ main(int ac, char **av)
|
||||
|
||||
/* The connection has been terminated. */
|
||||
packet_destroy_all(1, 1);
|
||||
+ destroy_sensitive_data(1);
|
||||
|
||||
packet_get_state(MODE_IN, NULL, NULL, NULL, &ibytes);
|
||||
packet_get_state(MODE_OUT, NULL, NULL, NULL, &obytes);
|
||||
@@ -2284,7 +2336,7 @@ do_ssh1_kex(void)
|
||||
session_id[i] = session_key[i] ^ session_key[i + 16];
|
||||
}
|
||||
/* Destroy the private and public keys. No longer. */
|
||||
- destroy_sensitive_data();
|
||||
+ destroy_sensitive_data(0);
|
||||
|
||||
if (use_privsep)
|
||||
mm_ssh1_session_id(session_id);
|
||||
@@ -2374,8 +2426,22 @@ do_ssh2_kex(void)
|
||||
void
|
||||
cleanup_exit(int i)
|
||||
{
|
||||
+ static int in_cleanup;
|
||||
+
|
||||
+ 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);
|
||||
+ is_privsep_child = use_privsep && pmonitor != NULL && !mm_is_monitor();
|
||||
+ if (sensitive_data.host_keys != NULL)
|
||||
+ destroy_sensitive_data(is_privsep_child);
|
||||
packet_destroy_all(1, is_privsep_child);
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
/* done after do_cleanup so it can cancel the PAM auth 'thread' */
|
251
openssh-5.9p1-entropy.patch
Normal file
251
openssh-5.9p1-entropy.patch
Normal file
@ -0,0 +1,251 @@
|
||||
diff -up openssh-5.9p0/entropy.c.entropy openssh-5.9p0/entropy.c
|
||||
--- openssh-5.9p0/entropy.c.entropy 2011-08-31 13:20:59.660150441 +0200
|
||||
+++ openssh-5.9p0/entropy.c 2011-08-31 13:21:05.072024970 +0200
|
||||
@@ -232,6 +232,9 @@ seed_rng(void)
|
||||
memset(buf, '\0', sizeof(buf));
|
||||
|
||||
#endif /* OPENSSL_PRNG_ONLY */
|
||||
+#ifdef __linux__
|
||||
+ linux_seed();
|
||||
+#endif /* __linux__ */
|
||||
if (RAND_status() != 1)
|
||||
fatal("PRNG is not seeded");
|
||||
}
|
||||
diff -up openssh-5.9p0/openbsd-compat/Makefile.in.entropy openssh-5.9p0/openbsd-compat/Makefile.in
|
||||
--- openssh-5.9p0/openbsd-compat/Makefile.in.entropy 2011-08-31 13:20:54.000000000 +0200
|
||||
+++ openssh-5.9p0/openbsd-compat/Makefile.in 2011-08-31 13:44:25.138151565 +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 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-linux_part_2.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-linux-prng.o port-solaris.o port-tun.o port-uw.o
|
||||
|
||||
.c.o:
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -c $<
|
||||
diff -up openssh-5.9p0/openbsd-compat/port-linux-prng.c.entropy openssh-5.9p0/openbsd-compat/port-linux-prng.c
|
||||
--- openssh-5.9p0/openbsd-compat/port-linux-prng.c.entropy 2011-08-31 13:21:05.382024083 +0200
|
||||
+++ openssh-5.9p0/openbsd-compat/port-linux-prng.c 2011-08-31 13:21:05.386024776 +0200
|
||||
@@ -0,0 +1,59 @@
|
||||
+/* $Id: port-linux.c,v 1.11.4.2 2011/02/04 00:43:08 djm Exp $ */
|
||||
+
|
||||
+/*
|
||||
+ * Copyright (c) 2011 Jan F. Chadima <jchadima@redhat.com>
|
||||
+ *
|
||||
+ * 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 - prng support
|
||||
+ */
|
||||
+
|
||||
+#include "includes.h"
|
||||
+
|
||||
+#include <errno.h>
|
||||
+#include <stdarg.h>
|
||||
+#include <string.h>
|
||||
+#include <stdio.h>
|
||||
+#include <openssl/rand.h>
|
||||
+
|
||||
+#include "log.h"
|
||||
+#include "xmalloc.h"
|
||||
+#include "servconf.h"
|
||||
+#include "port-linux.h"
|
||||
+#include "key.h"
|
||||
+#include "hostfile.h"
|
||||
+#include "auth.h"
|
||||
+
|
||||
+void
|
||||
+linux_seed(void)
|
||||
+{
|
||||
+ int len;
|
||||
+ char *env = getenv("SSH_USE_STRONG_RNG");
|
||||
+ char *random = "/dev/random";
|
||||
+ size_t ienv, randlen = 6;
|
||||
+
|
||||
+ if (!env || !strcmp(env, "0"))
|
||||
+ random = "/dev/urandom";
|
||||
+ else if ((ienv = atoi(env)) > 6)
|
||||
+ randlen = ienv;
|
||||
+
|
||||
+ errno = 0;
|
||||
+ if ((len = RAND_load_file(random, randlen)) != randlen) {
|
||||
+ if (errno)
|
||||
+ fatal ("cannot read from %s, %s", random, strerror(errno));
|
||||
+ else
|
||||
+ fatal ("EOF reading %s", random);
|
||||
+ }
|
||||
+}
|
||||
diff -up openssh-5.9p0/ssh-add.1.entropy openssh-5.9p0/ssh-add.1
|
||||
--- openssh-5.9p0/ssh-add.1.entropy 2010-11-05 00:20:14.000000000 +0100
|
||||
+++ openssh-5.9p0/ssh-add.1 2011-08-31 13:21:05.597122030 +0200
|
||||
@@ -158,6 +158,20 @@ Identifies the path of a
|
||||
.Ux Ns -domain
|
||||
socket used to communicate with the agent.
|
||||
.El
|
||||
+.It Ev SSH_USE_STRONG_RNG
|
||||
+The reseeding of the OpenSSL random generator is usually done from
|
||||
+.Cm /dev/urandom .
|
||||
+If the
|
||||
+.Cm SSH_USE_STRONG_RNG
|
||||
+environment variable is set to value other than
|
||||
+.Cm 0
|
||||
+the OpenSSL random generator is reseeded from
|
||||
+.Cm /dev/random .
|
||||
+The number of bytes read is defined by the SSH_USE_STRONG_RNG value.
|
||||
+Minimum is 6 bytes.
|
||||
+This setting is not recommended on the computers without the hardware
|
||||
+random generator because insufficient entropy causes the connection to
|
||||
+be blocked until enough entropy is available.
|
||||
.Sh FILES
|
||||
.Bl -tag -width Ds
|
||||
.It Pa ~/.ssh/identity
|
||||
diff -up openssh-5.9p0/ssh-agent.1.entropy openssh-5.9p0/ssh-agent.1
|
||||
--- openssh-5.9p0/ssh-agent.1.entropy 2010-12-01 01:50:35.000000000 +0100
|
||||
+++ openssh-5.9p0/ssh-agent.1 2011-08-31 13:21:05.735150196 +0200
|
||||
@@ -198,6 +198,24 @@ sockets used to contain the connection t
|
||||
These sockets should only be readable by the owner.
|
||||
The sockets should get automatically removed when the agent exits.
|
||||
.El
|
||||
+.Sh ENVIRONMENT
|
||||
+.Bl -tag -width Ds -compact
|
||||
+.Pp
|
||||
+.It Pa SSH_USE_STRONG_RNG
|
||||
+The reseeding of the OpenSSL random generator is usually done from
|
||||
+.Cm /dev/urandom .
|
||||
+If the
|
||||
+.Cm SSH_USE_STRONG_RNG
|
||||
+environment variable is set to value other than
|
||||
+.Cm 0
|
||||
+the OpenSSL random generator is reseeded from
|
||||
+.Cm /dev/random .
|
||||
+The number of bytes read is defined by the SSH_USE_STRONG_RNG value.
|
||||
+Minimum is 6 bytes.
|
||||
+This setting is not recommended on the computers without the hardware
|
||||
+random generator because insufficient entropy causes the connection to
|
||||
+be blocked until enough entropy is available.
|
||||
+.El
|
||||
.Sh SEE ALSO
|
||||
.Xr ssh 1 ,
|
||||
.Xr ssh-add 1 ,
|
||||
diff -up openssh-5.9p0/ssh-keygen.1.entropy openssh-5.9p0/ssh-keygen.1
|
||||
--- openssh-5.9p0/ssh-keygen.1.entropy 2011-08-31 13:20:59.200212619 +0200
|
||||
+++ openssh-5.9p0/ssh-keygen.1 2011-08-31 13:21:06.077150115 +0200
|
||||
@@ -669,6 +669,24 @@ Contains Diffie-Hellman groups used for
|
||||
The file format is described in
|
||||
.Xr moduli 5 .
|
||||
.El
|
||||
+.Sh ENVIRONMENT
|
||||
+.Bl -tag -width Ds -compact
|
||||
+.Pp
|
||||
+.It Pa SSH_USE_STRONG_RNG
|
||||
+The reseeding of the OpenSSL random generator is usually done from
|
||||
+.Cm /dev/urandom .
|
||||
+If the
|
||||
+.Cm SSH_USE_STRONG_RNG
|
||||
+environment variable is set to value other than
|
||||
+.Cm 0
|
||||
+the OpenSSL random generator is reseeded from
|
||||
+.Cm /dev/random .
|
||||
+The number of bytes read is defined by the SSH_USE_STRONG_RNG value.
|
||||
+Minimum is 6 bytes.
|
||||
+This setting is not recommended on the computers without the hardware
|
||||
+random generator because insufficient entropy causes the connection to
|
||||
+be blocked until enough entropy is available.
|
||||
+.El
|
||||
.Sh SEE ALSO
|
||||
.Xr ssh 1 ,
|
||||
.Xr ssh-add 1 ,
|
||||
diff -up openssh-5.9p0/ssh-keysign.8.entropy openssh-5.9p0/ssh-keysign.8
|
||||
--- openssh-5.9p0/ssh-keysign.8.entropy 2010-08-31 14:41:14.000000000 +0200
|
||||
+++ openssh-5.9p0/ssh-keysign.8 2011-08-31 13:21:06.207024356 +0200
|
||||
@@ -78,6 +78,24 @@ must be set-uid root if host-based authe
|
||||
If these files exist they are assumed to contain public certificate
|
||||
information corresponding with the private keys above.
|
||||
.El
|
||||
+.Sh ENVIRONMENT
|
||||
+.Bl -tag -width Ds -compact
|
||||
+.Pp
|
||||
+.It Pa SSH_USE_STRONG_RNG
|
||||
+The reseeding of the OpenSSL random generator is usually done from
|
||||
+.Cm /dev/urandom .
|
||||
+If the
|
||||
+.Cm SSH_USE_STRONG_RNG
|
||||
+environment variable is set to value other than
|
||||
+.Cm 0
|
||||
+the OpenSSL random generator is reseeded from
|
||||
+.Cm /dev/random .
|
||||
+The number of bytes read is defined by the SSH_USE_STRONG_RNG value.
|
||||
+Minimum is 6 bytes.
|
||||
+This setting is not recommended on the computers without the hardware
|
||||
+random generator because insufficient entropy causes the connection to
|
||||
+be blocked until enough entropy is available.
|
||||
+.El
|
||||
.Sh SEE ALSO
|
||||
.Xr ssh 1 ,
|
||||
.Xr ssh-keygen 1 ,
|
||||
diff -up openssh-5.9p0/ssh.1.entropy openssh-5.9p0/ssh.1
|
||||
--- openssh-5.9p0/ssh.1.entropy 2011-08-31 13:21:00.835103535 +0200
|
||||
+++ openssh-5.9p0/ssh.1 2011-08-31 13:21:05.482032754 +0200
|
||||
@@ -1255,6 +1255,23 @@ For more information, see the
|
||||
.Cm PermitUserEnvironment
|
||||
option in
|
||||
.Xr sshd_config 5 .
|
||||
+.Sh ENVIRONMENT
|
||||
+.Bl -tag -width Ds -compact
|
||||
+.It Ev SSH_USE_STRONG_RNG
|
||||
+The reseeding of the OpenSSL random generator is usually done from
|
||||
+.Cm /dev/urandom .
|
||||
+If the
|
||||
+.Cm SSH_USE_STRONG_RNG
|
||||
+environment variable is set to value other than
|
||||
+.Cm 0
|
||||
+the OpenSSL random generator is reseeded from
|
||||
+.Cm /dev/random .
|
||||
+The number of bytes read is defined by the SSH_USE_STRONG_RNG value.
|
||||
+Minimum is 6 bytes.
|
||||
+This setting is not recommended on the computers without the hardware
|
||||
+random generator because insufficient entropy causes the connection to
|
||||
+be blocked until enough entropy is available.
|
||||
+.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width Ds -compact
|
||||
.It Pa ~/.rhosts
|
||||
diff -up openssh-5.9p0/sshd.8.entropy openssh-5.9p0/sshd.8
|
||||
--- openssh-5.9p0/sshd.8.entropy 2011-08-31 13:21:00.000000000 +0200
|
||||
+++ openssh-5.9p0/sshd.8 2011-08-31 13:46:27.341025537 +0200
|
||||
@@ -940,6 +940,24 @@ concurrently for different ports, this c
|
||||
started last).
|
||||
The content of this file is not sensitive; it can be world-readable.
|
||||
.El
|
||||
+.Sh ENVIRONMENT
|
||||
+.Bl -tag -width Ds -compact
|
||||
+.Pp
|
||||
+.It Pa SSH_USE_STRONG_RNG
|
||||
+The reseeding of the OpenSSL random generator is usually done from
|
||||
+.Cm /dev/urandom .
|
||||
+If the
|
||||
+.Cm SSH_USE_STRONG_RNG
|
||||
+environment variable is set to value other than
|
||||
+.Cm 0
|
||||
+the OpenSSL random generator is reseeded from
|
||||
+.Cm /dev/random .
|
||||
+The number of bytes read is defined by the SSH_USE_STRONG_RNG value.
|
||||
+Minimum is 6 bytes.
|
||||
+This setting is not recommended on the computers without the hardware
|
||||
+random generator because insufficient entropy causes the connection to
|
||||
+be blocked until enough entropy is available.
|
||||
+.El
|
||||
.Sh IPV6
|
||||
IPv6 address can be used everywhere where IPv4 address. In all entries must be the IPv6 address enclosed in square brackets. Note: The square brackets are metacharacters for the shell and must be escaped in shell.
|
||||
.Sh SEE ALSO
|
521
openssh-5.9p1-fips.patch
Normal file
521
openssh-5.9p1-fips.patch
Normal file
@ -0,0 +1,521 @@
|
||||
diff -up openssh-5.9p0/Makefile.in.fips openssh-5.9p0/Makefile.in
|
||||
--- openssh-5.9p0/Makefile.in.fips 2011-08-31 13:16:25.548087929 +0200
|
||||
+++ openssh-5.9p0/Makefile.in 2011-08-31 13:17:42.820212398 +0200
|
||||
@@ -142,25 +142,25 @@ libssh.a: $(LIBSSH_OBJS)
|
||||
$(RANLIB) $@
|
||||
|
||||
ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS)
|
||||
- $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHLIBS) $(LIBS)
|
||||
+ $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(SSHLIBS) $(LIBS)
|
||||
|
||||
sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS)
|
||||
- $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS)
|
||||
+ $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(SSHDLIBS) $(LIBS)
|
||||
|
||||
scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o
|
||||
$(LD) -o $@ scp.o progressmeter.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
|
||||
|
||||
ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-add.o
|
||||
- $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
|
||||
+ $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS)
|
||||
|
||||
ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-agent.o ssh-pkcs11-client.o
|
||||
- $(LD) -o $@ ssh-agent.o ssh-pkcs11-client.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
|
||||
+ $(LD) -o $@ ssh-agent.o ssh-pkcs11-client.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS)
|
||||
|
||||
ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o
|
||||
- $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
|
||||
+ $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS)
|
||||
|
||||
ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o roaming_dummy.o readconf.o
|
||||
- $(LD) -o $@ ssh-keysign.o readconf.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
|
||||
+ $(LD) -o $@ ssh-keysign.o readconf.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS)
|
||||
|
||||
ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11.o
|
||||
$(LD) -o $@ ssh-pkcs11-helper.o ssh-pkcs11.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS)
|
||||
@@ -172,7 +172,7 @@ ssh-keycat$(EXEEXT): $(LIBCOMPAT) libssh
|
||||
$(LD) -o $@ ssh-keycat.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(SSHDLIBS)
|
||||
|
||||
ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o
|
||||
- $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
|
||||
+ $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS)
|
||||
|
||||
sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o sftp-server-main.o
|
||||
$(LD) -o $@ sftp-server.o sftp-common.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
|
||||
diff -up openssh-5.9p0/authfile.c.fips openssh-5.9p0/authfile.c
|
||||
--- openssh-5.9p0/authfile.c.fips 2011-08-31 13:16:26.896087056 +0200
|
||||
+++ openssh-5.9p0/authfile.c 2011-08-31 13:16:28.586211616 +0200
|
||||
@@ -148,8 +148,14 @@ key_private_rsa1_to_blob(Key *key, Buffe
|
||||
/* Allocate space for the private part of the key in the buffer. */
|
||||
cp = buffer_append_space(&encrypted, buffer_len(&buffer));
|
||||
|
||||
- cipher_set_key_string(&ciphercontext, cipher, passphrase,
|
||||
- CIPHER_ENCRYPT);
|
||||
+ if (cipher_set_key_string(&ciphercontext, cipher, passphrase,
|
||||
+ CIPHER_ENCRYPT) < 0) {
|
||||
+ error("cipher_set_key_string failed.");
|
||||
+ buffer_free(&encrypted);
|
||||
+ buffer_free(&buffer);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
cipher_crypt(&ciphercontext, cp,
|
||||
buffer_ptr(&buffer), buffer_len(&buffer));
|
||||
cipher_cleanup(&ciphercontext);
|
||||
@@ -472,8 +478,13 @@ key_parse_private_rsa1(Buffer *blob, con
|
||||
cp = buffer_append_space(&decrypted, buffer_len(©));
|
||||
|
||||
/* Rest of the buffer is encrypted. Decrypt it using the passphrase. */
|
||||
- cipher_set_key_string(&ciphercontext, cipher, passphrase,
|
||||
- CIPHER_DECRYPT);
|
||||
+ if (cipher_set_key_string(&ciphercontext, cipher, passphrase,
|
||||
+ CIPHER_DECRYPT) < 0) {
|
||||
+ error("cipher_set_key_string failed.");
|
||||
+ buffer_free(&decrypted);
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
cipher_crypt(&ciphercontext, cp,
|
||||
buffer_ptr(©), buffer_len(©));
|
||||
cipher_cleanup(&ciphercontext);
|
||||
diff -up openssh-5.9p0/cipher-ctr.c.fips openssh-5.9p0/cipher-ctr.c
|
||||
--- openssh-5.9p0/cipher-ctr.c.fips 2010-10-07 13:06:42.000000000 +0200
|
||||
+++ openssh-5.9p0/cipher-ctr.c 2011-08-31 13:16:28.690026009 +0200
|
||||
@@ -140,7 +140,8 @@ evp_aes_128_ctr(void)
|
||||
aes_ctr.do_cipher = ssh_aes_ctr;
|
||||
#ifndef SSH_OLD_EVP
|
||||
aes_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH |
|
||||
- EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV;
|
||||
+ EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV |
|
||||
+ EVP_CIPH_FLAG_FIPS;
|
||||
#endif
|
||||
return (&aes_ctr);
|
||||
}
|
||||
diff -up openssh-5.9p0/cipher.c.fips openssh-5.9p0/cipher.c
|
||||
--- openssh-5.9p0/cipher.c.fips 2011-08-31 13:16:14.685087304 +0200
|
||||
+++ openssh-5.9p0/cipher.c 2011-08-31 13:16:28.815092896 +0200
|
||||
@@ -40,6 +40,7 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <openssl/md5.h>
|
||||
+#include <openssl/fips.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
@@ -86,6 +87,22 @@ struct Cipher ciphers[] = {
|
||||
{ NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, NULL }
|
||||
};
|
||||
|
||||
+struct Cipher fips_ciphers[] = {
|
||||
+ { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, EVP_enc_null },
|
||||
+ { "3des", SSH_CIPHER_3DES, 8, 16, 0, 1, evp_ssh1_3des },
|
||||
+
|
||||
+ { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 1, EVP_des_ede3_cbc },
|
||||
+ { "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, 0, 1, EVP_aes_128_cbc },
|
||||
+ { "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, 0, 1, EVP_aes_192_cbc },
|
||||
+ { "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, 0, 1, EVP_aes_256_cbc },
|
||||
+ { "rijndael-cbc@lysator.liu.se",
|
||||
+ SSH_CIPHER_SSH2, 16, 32, 0, 1, EVP_aes_256_cbc },
|
||||
+ { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, evp_aes_128_ctr },
|
||||
+ { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, evp_aes_128_ctr },
|
||||
+ { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, evp_aes_128_ctr },
|
||||
+ { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, NULL }
|
||||
+};
|
||||
+
|
||||
/*--*/
|
||||
|
||||
u_int
|
||||
@@ -128,7 +145,7 @@ Cipher *
|
||||
cipher_by_name(const char *name)
|
||||
{
|
||||
Cipher *c;
|
||||
- for (c = ciphers; c->name != NULL; c++)
|
||||
+ for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++)
|
||||
if (strcmp(c->name, name) == 0)
|
||||
return c;
|
||||
return NULL;
|
||||
@@ -138,7 +155,7 @@ Cipher *
|
||||
cipher_by_number(int id)
|
||||
{
|
||||
Cipher *c;
|
||||
- for (c = ciphers; c->name != NULL; c++)
|
||||
+ for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++)
|
||||
if (c->number == id)
|
||||
return c;
|
||||
return NULL;
|
||||
@@ -182,7 +199,7 @@ cipher_number(const char *name)
|
||||
Cipher *c;
|
||||
if (name == NULL)
|
||||
return -1;
|
||||
- for (c = ciphers; c->name != NULL; c++)
|
||||
+ for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++)
|
||||
if (strcasecmp(c->name, name) == 0)
|
||||
return c->number;
|
||||
return -1;
|
||||
@@ -289,14 +306,15 @@ cipher_cleanup(CipherContext *cc)
|
||||
* passphrase and using the resulting 16 bytes as the key.
|
||||
*/
|
||||
|
||||
-void
|
||||
+int
|
||||
cipher_set_key_string(CipherContext *cc, Cipher *cipher,
|
||||
const char *passphrase, int do_encrypt)
|
||||
{
|
||||
MD5_CTX md;
|
||||
u_char digest[16];
|
||||
|
||||
- MD5_Init(&md);
|
||||
+ if (MD5_Init(&md) <= 0)
|
||||
+ return -1;
|
||||
MD5_Update(&md, (const u_char *)passphrase, strlen(passphrase));
|
||||
MD5_Final(digest, &md);
|
||||
|
||||
@@ -304,6 +322,7 @@ cipher_set_key_string(CipherContext *cc,
|
||||
|
||||
memset(digest, 0, sizeof(digest));
|
||||
memset(&md, 0, sizeof(md));
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
diff -up openssh-5.9p0/cipher.h.fips openssh-5.9p0/cipher.h
|
||||
--- openssh-5.9p0/cipher.h.fips 2011-08-31 13:16:14.816212495 +0200
|
||||
+++ openssh-5.9p0/cipher.h 2011-08-31 13:16:28.939073884 +0200
|
||||
@@ -87,7 +87,7 @@ void cipher_init(CipherContext *, Ciphe
|
||||
const u_char *, u_int, int);
|
||||
void cipher_crypt(CipherContext *, u_char *, const u_char *, u_int);
|
||||
void cipher_cleanup(CipherContext *);
|
||||
-void cipher_set_key_string(CipherContext *, Cipher *, const char *, int);
|
||||
+int cipher_set_key_string(CipherContext *, Cipher *, const char *, int);
|
||||
u_int cipher_blocksize(const Cipher *);
|
||||
u_int cipher_keylen(const Cipher *);
|
||||
u_int cipher_is_cbc(const Cipher *);
|
||||
diff -up openssh-5.9p0/key.c.fips openssh-5.9p0/key.c
|
||||
--- openssh-5.9p0/key.c.fips 2011-08-31 13:16:18.179212858 +0200
|
||||
+++ openssh-5.9p0/key.c 2011-08-31 13:16:29.069031653 +0200
|
||||
@@ -40,6 +40,7 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <openssl/evp.h>
|
||||
+#include <openssl/fips.h>
|
||||
#include <openbsd-compat/openssl-compat.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
@@ -602,9 +603,13 @@ key_fingerprint_selection(void)
|
||||
char *env;
|
||||
|
||||
if (!rv_defined) {
|
||||
- env = getenv("SSH_FINGERPRINT_TYPE");
|
||||
- rv = (env && !strcmp (env, "sha")) ?
|
||||
- SSH_FP_SHA1 : SSH_FP_MD5;
|
||||
+ if (FIPS_mode())
|
||||
+ rv = SSH_FP_SHA1;
|
||||
+ else {
|
||||
+ env = getenv("SSH_FINGERPRINT_TYPE");
|
||||
+ rv = (env && !strcmp (env, "sha")) ?
|
||||
+ SSH_FP_SHA1 : SSH_FP_MD5;
|
||||
+ }
|
||||
rv_defined = 1;
|
||||
}
|
||||
return rv;
|
||||
diff -up openssh-5.9p0/mac.c.fips openssh-5.9p0/mac.c
|
||||
--- openssh-5.9p0/mac.c.fips 2011-08-31 13:16:16.521087343 +0200
|
||||
+++ openssh-5.9p0/mac.c 2011-08-31 13:16:29.171039694 +0200
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <openssl/hmac.h>
|
||||
+#include <openssl/fips.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
@@ -47,14 +48,14 @@
|
||||
#define SSH_EVP 1 /* OpenSSL EVP-based MAC */
|
||||
#define SSH_UMAC 2 /* UMAC (not integrated with OpenSSL) */
|
||||
|
||||
-struct {
|
||||
+struct Macs {
|
||||
char *name;
|
||||
int type;
|
||||
const EVP_MD * (*mdfunc)(void);
|
||||
int truncatebits; /* truncate digest if != 0 */
|
||||
int key_len; /* just for UMAC */
|
||||
int len; /* just for UMAC */
|
||||
-} macs[] = {
|
||||
+} all_macs[] = {
|
||||
{ "hmac-sha1", SSH_EVP, EVP_sha1, 0, -1, -1 },
|
||||
{ "hmac-sha1-96", SSH_EVP, EVP_sha1, 96, -1, -1 },
|
||||
#ifdef HAVE_EVP_SHA256
|
||||
@@ -71,9 +72,15 @@ struct {
|
||||
{ NULL, 0, NULL, 0, -1, -1 }
|
||||
};
|
||||
|
||||
+struct Macs fips_macs[] = {
|
||||
+ { "hmac-sha1", SSH_EVP, EVP_sha1, 0, -1, -1 },
|
||||
+ { NULL, 0, NULL, 0, -1, -1 }
|
||||
+};
|
||||
+
|
||||
static void
|
||||
mac_setup_by_id(Mac *mac, int which)
|
||||
{
|
||||
+ struct Macs *macs = FIPS_mode() ? fips_macs : all_macs;
|
||||
int evp_len;
|
||||
mac->type = macs[which].type;
|
||||
if (mac->type == SSH_EVP) {
|
||||
@@ -94,6 +101,7 @@ int
|
||||
mac_setup(Mac *mac, char *name)
|
||||
{
|
||||
int i;
|
||||
+ struct Macs *macs = FIPS_mode() ? fips_macs : all_macs;
|
||||
|
||||
for (i = 0; macs[i].name; i++) {
|
||||
if (strcmp(name, macs[i].name) == 0) {
|
||||
diff -up openssh-5.9p0/myproposal.h.fips openssh-5.9p0/myproposal.h
|
||||
--- openssh-5.9p0/myproposal.h.fips 2011-08-17 02:29:03.000000000 +0200
|
||||
+++ openssh-5.9p0/myproposal.h 2011-08-31 13:16:29.301087416 +0200
|
||||
@@ -97,6 +97,12 @@
|
||||
#define KEX_DEFAULT_COMP "none,zlib@openssh.com,zlib"
|
||||
#define KEX_DEFAULT_LANG ""
|
||||
|
||||
+#define KEX_FIPS_ENCRYPT \
|
||||
+ "aes128-ctr,aes192-ctr,aes256-ctr," \
|
||||
+ "aes128-cbc,3des-cbc," \
|
||||
+ "aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se"
|
||||
+#define KEX_FIPS_MAC \
|
||||
+ "hmac-sha1"
|
||||
|
||||
static char *myproposal[PROPOSAL_MAX] = {
|
||||
KEX_DEFAULT_KEX,
|
||||
diff -up openssh-5.9p0/openbsd-compat/bsd-arc4random.c.fips openssh-5.9p0/openbsd-compat/bsd-arc4random.c
|
||||
--- openssh-5.9p0/openbsd-compat/bsd-arc4random.c.fips 2010-03-25 22:52:02.000000000 +0100
|
||||
+++ openssh-5.9p0/openbsd-compat/bsd-arc4random.c 2011-08-31 13:16:29.741086847 +0200
|
||||
@@ -37,25 +37,18 @@
|
||||
#define REKEY_BYTES (1 << 24)
|
||||
|
||||
static int rc4_ready = 0;
|
||||
-static RC4_KEY rc4;
|
||||
|
||||
unsigned int
|
||||
arc4random(void)
|
||||
{
|
||||
unsigned int r = 0;
|
||||
- static int first_time = 1;
|
||||
+ void *rp = &r;
|
||||
|
||||
- if (rc4_ready <= 0) {
|
||||
- if (first_time)
|
||||
- seed_rng();
|
||||
- first_time = 0;
|
||||
+ if (!rc4_ready) {
|
||||
arc4random_stir();
|
||||
}
|
||||
+ RAND_bytes(rp, sizeof(r));
|
||||
|
||||
- RC4(&rc4, sizeof(r), (unsigned char *)&r, (unsigned char *)&r);
|
||||
-
|
||||
- rc4_ready -= sizeof(r);
|
||||
-
|
||||
return(r);
|
||||
}
|
||||
|
||||
@@ -63,24 +56,11 @@ void
|
||||
arc4random_stir(void)
|
||||
{
|
||||
unsigned char rand_buf[SEED_SIZE];
|
||||
- int i;
|
||||
|
||||
- memset(&rc4, 0, sizeof(rc4));
|
||||
if (RAND_bytes(rand_buf, sizeof(rand_buf)) <= 0)
|
||||
fatal("Couldn't obtain random bytes (error %ld)",
|
||||
ERR_get_error());
|
||||
- RC4_set_key(&rc4, sizeof(rand_buf), rand_buf);
|
||||
-
|
||||
- /*
|
||||
- * Discard early keystream, as per recommendations in:
|
||||
- * http://www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps
|
||||
- */
|
||||
- for(i = 0; i <= 256; i += sizeof(rand_buf))
|
||||
- RC4(&rc4, sizeof(rand_buf), rand_buf, rand_buf);
|
||||
-
|
||||
- memset(rand_buf, 0, sizeof(rand_buf));
|
||||
-
|
||||
- rc4_ready = REKEY_BYTES;
|
||||
+ rc4_ready = 1;
|
||||
}
|
||||
#endif /* !HAVE_ARC4RANDOM */
|
||||
|
||||
diff -up openssh-5.9p0/ssh.c.fips openssh-5.9p0/ssh.c
|
||||
--- openssh-5.9p0/ssh.c.fips 2011-08-05 22:18:16.000000000 +0200
|
||||
+++ openssh-5.9p0/ssh.c 2011-08-31 13:16:29.852212356 +0200
|
||||
@@ -73,6 +73,8 @@
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/err.h>
|
||||
+#include <openssl/fips.h>
|
||||
+#include <fipscheck.h>
|
||||
#include "openbsd-compat/openssl-compat.h"
|
||||
#include "openbsd-compat/sys-queue.h"
|
||||
|
||||
@@ -253,6 +255,10 @@ main(int ac, char **av)
|
||||
sanitise_stdfd();
|
||||
|
||||
__progname = ssh_get_progname(av[0]);
|
||||
+ SSLeay_add_all_algorithms();
|
||||
+ if (FIPS_mode() && !FIPSCHECK_verify(NULL, NULL)) {
|
||||
+ fatal("FIPS integrity verification test failed.");
|
||||
+ }
|
||||
|
||||
#ifndef HAVE_SETPROCTITLE
|
||||
/* Prepare for later setproctitle emulation */
|
||||
@@ -329,6 +335,9 @@ main(int ac, char **av)
|
||||
"ACD:F:I:KL:MNO:PR:S:TVw:W:XYy")) != -1) {
|
||||
switch (opt) {
|
||||
case '1':
|
||||
+ if (FIPS_mode()) {
|
||||
+ fatal("Protocol 1 not allowed in the FIPS mode.");
|
||||
+ }
|
||||
options.protocol = SSH_PROTO_1;
|
||||
break;
|
||||
case '2':
|
||||
@@ -630,7 +639,6 @@ main(int ac, char **av)
|
||||
if (!host)
|
||||
usage();
|
||||
|
||||
- OpenSSL_add_all_algorithms();
|
||||
ERR_load_crypto_strings();
|
||||
|
||||
/* Initialize the command to execute on remote host. */
|
||||
@@ -721,6 +729,10 @@ main(int ac, char **av)
|
||||
|
||||
seed_rng();
|
||||
|
||||
+ if (FIPS_mode()) {
|
||||
+ logit("FIPS mode initialized");
|
||||
+ }
|
||||
+
|
||||
if (options.user == NULL)
|
||||
options.user = xstrdup(pw->pw_name);
|
||||
|
||||
@@ -789,6 +801,12 @@ main(int ac, char **av)
|
||||
|
||||
timeout_ms = options.connection_timeout * 1000;
|
||||
|
||||
+ if (FIPS_mode()) {
|
||||
+ options.protocol &= SSH_PROTO_2;
|
||||
+ if (options.protocol == 0)
|
||||
+ fatal("Protocol 2 disabled by configuration but required in the FIPS mode.");
|
||||
+ }
|
||||
+
|
||||
/* Open a connection to the remote host. */
|
||||
if (ssh_connect(host, &hostaddr, options.port,
|
||||
options.address_family, options.connection_attempts, &timeout_ms,
|
||||
diff -up openssh-5.9p0/sshconnect2.c.fips openssh-5.9p0/sshconnect2.c
|
||||
--- openssh-5.9p0/sshconnect2.c.fips 2011-08-31 13:16:09.532024846 +0200
|
||||
+++ openssh-5.9p0/sshconnect2.c 2011-08-31 13:16:29.959087217 +0200
|
||||
@@ -44,6 +44,8 @@
|
||||
#include <vis.h>
|
||||
#endif
|
||||
|
||||
+#include <openssl/fips.h>
|
||||
+
|
||||
#include "openbsd-compat/sys-queue.h"
|
||||
|
||||
#include "xmalloc.h"
|
||||
@@ -170,6 +172,10 @@ ssh_kex2(char *host, struct sockaddr *ho
|
||||
if (options.ciphers != NULL) {
|
||||
myproposal[PROPOSAL_ENC_ALGS_CTOS] =
|
||||
myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
|
||||
+ } else if (FIPS_mode()) {
|
||||
+ myproposal[PROPOSAL_ENC_ALGS_CTOS] =
|
||||
+ myproposal[PROPOSAL_ENC_ALGS_STOC] = KEX_FIPS_ENCRYPT;
|
||||
+
|
||||
}
|
||||
myproposal[PROPOSAL_ENC_ALGS_CTOS] =
|
||||
compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]);
|
||||
@@ -185,7 +191,11 @@ ssh_kex2(char *host, struct sockaddr *ho
|
||||
if (options.macs != NULL) {
|
||||
myproposal[PROPOSAL_MAC_ALGS_CTOS] =
|
||||
myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs;
|
||||
+ } else if (FIPS_mode()) {
|
||||
+ myproposal[PROPOSAL_MAC_ALGS_CTOS] =
|
||||
+ myproposal[PROPOSAL_MAC_ALGS_STOC] = KEX_FIPS_MAC;
|
||||
}
|
||||
+
|
||||
if (options.hostkeyalgorithms != NULL)
|
||||
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
|
||||
options.hostkeyalgorithms;
|
||||
diff -up openssh-5.9p0/sshd.c.fips openssh-5.9p0/sshd.c
|
||||
--- openssh-5.9p0/sshd.c.fips 2011-08-31 13:16:22.525057137 +0200
|
||||
+++ openssh-5.9p0/sshd.c 2011-08-31 13:16:30.078212687 +0200
|
||||
@@ -76,6 +76,8 @@
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/rand.h>
|
||||
+#include <openssl/fips.h>
|
||||
+#include <fipscheck.h>
|
||||
#include "openbsd-compat/openssl-compat.h"
|
||||
|
||||
#ifdef HAVE_SECUREWARE
|
||||
@@ -1388,6 +1390,11 @@ main(int ac, char **av)
|
||||
#endif
|
||||
__progname = ssh_get_progname(av[0]);
|
||||
|
||||
+ SSLeay_add_all_algorithms();
|
||||
+ if (FIPS_mode() && !FIPSCHECK_verify(NULL, NULL)) {
|
||||
+ fatal("FIPS integrity verification test failed.");
|
||||
+ }
|
||||
+
|
||||
/* Save argv. Duplicate so setproctitle emulation doesn't clobber it */
|
||||
saved_argc = ac;
|
||||
rexec_argc = ac;
|
||||
@@ -1547,8 +1554,6 @@ main(int ac, char **av)
|
||||
else
|
||||
closefrom(REEXEC_DEVCRYPTO_RESERVED_FD);
|
||||
|
||||
- OpenSSL_add_all_algorithms();
|
||||
-
|
||||
/*
|
||||
* Force logging to stderr until we have loaded the private host
|
||||
* key (unless started from inetd)
|
||||
@@ -1666,6 +1671,10 @@ main(int ac, char **av)
|
||||
debug("private host key: #%d type %d %s", i, key->type,
|
||||
key_type(key));
|
||||
}
|
||||
+ if ((options.protocol & SSH_PROTO_1) && FIPS_mode()) {
|
||||
+ logit("Disabling protocol version 1. Not allowed in the FIPS mode.");
|
||||
+ options.protocol &= ~SSH_PROTO_1;
|
||||
+ }
|
||||
if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) {
|
||||
logit("Disabling protocol version 1. Could not load host key");
|
||||
options.protocol &= ~SSH_PROTO_1;
|
||||
@@ -1830,6 +1839,10 @@ main(int ac, char **av)
|
||||
/* Initialize the random number generator. */
|
||||
arc4random_stir();
|
||||
|
||||
+ if (FIPS_mode()) {
|
||||
+ logit("FIPS mode initialized");
|
||||
+ }
|
||||
+
|
||||
/* Chdir to the root directory so that the current disk can be
|
||||
unmounted if desired. */
|
||||
chdir("/");
|
||||
@@ -2372,6 +2385,9 @@ do_ssh2_kex(void)
|
||||
if (options.ciphers != NULL) {
|
||||
myproposal[PROPOSAL_ENC_ALGS_CTOS] =
|
||||
myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
|
||||
+ } else if (FIPS_mode()) {
|
||||
+ myproposal[PROPOSAL_ENC_ALGS_CTOS] =
|
||||
+ myproposal[PROPOSAL_ENC_ALGS_STOC] = KEX_FIPS_ENCRYPT;
|
||||
}
|
||||
myproposal[PROPOSAL_ENC_ALGS_CTOS] =
|
||||
compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]);
|
||||
@@ -2381,6 +2397,9 @@ do_ssh2_kex(void)
|
||||
if (options.macs != NULL) {
|
||||
myproposal[PROPOSAL_MAC_ALGS_CTOS] =
|
||||
myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs;
|
||||
+ } else if (FIPS_mode()) {
|
||||
+ myproposal[PROPOSAL_MAC_ALGS_CTOS] =
|
||||
+ myproposal[PROPOSAL_MAC_ALGS_STOC] = KEX_FIPS_MAC;
|
||||
}
|
||||
if (options.compression == COMP_NONE) {
|
||||
myproposal[PROPOSAL_COMP_ALGS_CTOS] =
|
2932
openssh-5.9p1-gsskex.patch
Normal file
2932
openssh-5.9p1-gsskex.patch
Normal file
File diff suppressed because it is too large
Load Diff
24
openssh-5.9p1-ipv6man.patch
Normal file
24
openssh-5.9p1-ipv6man.patch
Normal file
@ -0,0 +1,24 @@
|
||||
diff -up openssh-5.9p0/ssh.1.ipv6man openssh-5.9p0/ssh.1
|
||||
--- openssh-5.9p0/ssh.1.ipv6man 2011-08-05 22:17:32.000000000 +0200
|
||||
+++ openssh-5.9p0/ssh.1 2011-08-31 13:08:34.880024485 +0200
|
||||
@@ -1400,6 +1400,8 @@ manual page for more information.
|
||||
.Nm
|
||||
exits with the exit status of the remote command or with 255
|
||||
if an error occurred.
|
||||
+.Sh IPV6
|
||||
+IPv6 address can be used everywhere where IPv4 address. In all entries must be the IPv6 address enclosed in square brackets. Note: The square brackets are metacharacters for the shell and must be escaped in shell.
|
||||
.Sh SEE ALSO
|
||||
.Xr scp 1 ,
|
||||
.Xr sftp 1 ,
|
||||
diff -up openssh-5.9p0/sshd.8.ipv6man openssh-5.9p0/sshd.8
|
||||
--- openssh-5.9p0/sshd.8.ipv6man 2011-08-05 22:17:32.000000000 +0200
|
||||
+++ openssh-5.9p0/sshd.8 2011-08-31 13:10:34.129039094 +0200
|
||||
@@ -940,6 +940,8 @@ concurrently for different ports, this c
|
||||
started last).
|
||||
The content of this file is not sensitive; it can be world-readable.
|
||||
.El
|
||||
+.Sh IPV6
|
||||
+IPv6 address can be used everywhere where IPv4 address. In all entries must be the IPv6 address enclosed in square brackets. Note: The square brackets are metacharacters for the shell and must be escaped in shell.
|
||||
.Sh SEE ALSO
|
||||
.Xr scp 1 ,
|
||||
.Xr sftp 1 ,
|
371
openssh-5.9p1-keycat.patch
Normal file
371
openssh-5.9p1-keycat.patch
Normal file
@ -0,0 +1,371 @@
|
||||
diff -up openssh-5.9p0/HOWTO.ssh-keycat.keycat openssh-5.9p0/HOWTO.ssh-keycat
|
||||
--- openssh-5.9p0/HOWTO.ssh-keycat.keycat 2011-08-31 11:51:49.886087176 +0200
|
||||
+++ openssh-5.9p0/HOWTO.ssh-keycat 2011-08-31 11:51:49.890087179 +0200
|
||||
@@ -0,0 +1,12 @@
|
||||
+The ssh-keycat retrieves the content of the ~/.ssh/authorized_keys
|
||||
+of an user in any environment. This includes environments with
|
||||
+polyinstantiation of home directories and SELinux MLS policy enabled.
|
||||
+
|
||||
+To use ssh-keycat, set these options in /etc/ssh/sshd_config file:
|
||||
+ AuthorizedKeysCommand /usr/libexec/openssh/ssh-keycat
|
||||
+ AuthorizedKeysCommandRunAs root
|
||||
+
|
||||
+Do not forget to enable public key authentication:
|
||||
+ PubkeyAuthentication yes
|
||||
+
|
||||
+
|
||||
diff -up openssh-5.9p0/Makefile.in.keycat openssh-5.9p0/Makefile.in
|
||||
--- openssh-5.9p0/Makefile.in.keycat 2011-08-31 11:51:48.367122382 +0200
|
||||
+++ openssh-5.9p0/Makefile.in 2011-08-31 12:03:46.433088864 +0200
|
||||
@@ -27,6 +27,7 @@ SFTP_SERVER=$(libexecdir)/sftp-server
|
||||
SSH_KEYSIGN=$(libexecdir)/ssh-keysign
|
||||
SSH_LDAP_HELPER=$(libexecdir)/ssh-ldap-helper
|
||||
SSH_LDAP_WRAPPER=$(libexecdir)/ssh-ldap-wrapper
|
||||
+SSH_KEYCAT=$(libexecdir)/ssh-keycat
|
||||
SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper
|
||||
PRIVSEP_PATH=@PRIVSEP_PATH@
|
||||
SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@
|
||||
@@ -62,7 +63,7 @@ EXEEXT=@EXEEXT@
|
||||
MANFMT=@MANFMT@
|
||||
INSTALL_SSH_LDAP_HELPER=@INSTALL_SSH_LDAP_HELPER@
|
||||
|
||||
-TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-ldap-helper$(EXEEXT)
|
||||
+TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-ldap-helper$(EXEEXT) ssh-keycat$(EXEEXT)
|
||||
|
||||
LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \
|
||||
canohost.o channels.o cipher.o cipher-acss.o cipher-aes.o \
|
||||
@@ -167,6 +168,9 @@ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT)
|
||||
ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o
|
||||
$(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS)
|
||||
|
||||
+ssh-keycat$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keycat.o
|
||||
+ $(LD) -o $@ ssh-keycat.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(SSHDLIBS)
|
||||
+
|
||||
ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o
|
||||
$(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
|
||||
|
||||
@@ -266,6 +270,7 @@ install-files:
|
||||
$(INSTALL) -m 0700 $(STRIP_OPT) ssh-ldap-helper $(DESTDIR)$(SSH_LDAP_HELPER) ; \
|
||||
$(INSTALL) -m 0700 ssh-ldap-wrapper $(DESTDIR)$(SSH_LDAP_WRAPPER) ; \
|
||||
fi
|
||||
+ $(INSTALL) -m 0755 $(STRIP_OPT) ssh-keycat$(EXEEXT) $(DESTDIR)$(libexecdir)/ssh-keycat$(EXEEXT)
|
||||
$(INSTALL) -m 0755 $(STRIP_OPT) sftp$(EXEEXT) $(DESTDIR)$(bindir)/sftp$(EXEEXT)
|
||||
$(INSTALL) -m 0755 $(STRIP_OPT) sftp-server$(EXEEXT) $(DESTDIR)$(SFTP_SERVER)$(EXEEXT)
|
||||
$(INSTALL) -m 644 ssh.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1
|
||||
diff -up openssh-5.9p0/auth2-pubkey.c.keycat openssh-5.9p0/auth2-pubkey.c
|
||||
--- openssh-5.9p0/auth2-pubkey.c.keycat 2011-08-31 11:51:47.066149816 +0200
|
||||
+++ openssh-5.9p0/auth2-pubkey.c 2011-08-31 11:51:50.143087097 +0200
|
||||
@@ -579,6 +579,14 @@ user_key_via_command_allowed2(struct pas
|
||||
close(i);
|
||||
}
|
||||
|
||||
+#ifdef WITH_SELINUX
|
||||
+ if (ssh_selinux_setup_env_variables() < 0) {
|
||||
+ error ("failed to copy environment: %s",
|
||||
+ strerror(errno));
|
||||
+ _exit(127);
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
execl(options.authorized_keys_command, options.authorized_keys_command, pw->pw_name, NULL);
|
||||
|
||||
/* if we got here, it didn't work */
|
||||
diff -up openssh-5.9p0/openbsd-compat/port-linux.c.keycat openssh-5.9p0/openbsd-compat/port-linux.c
|
||||
--- openssh-5.9p0/openbsd-compat/port-linux.c.keycat 2011-08-31 11:51:46.275119773 +0200
|
||||
+++ openssh-5.9p0/openbsd-compat/port-linux.c 2011-08-31 11:51:50.240087963 +0200
|
||||
@@ -313,7 +313,7 @@ ssh_selinux_getctxbyname(char *pwname,
|
||||
|
||||
/* Setup environment variables for pam_selinux */
|
||||
static int
|
||||
-ssh_selinux_setup_pam_variables(void)
|
||||
+ssh_selinux_setup_variables(int(*set_it)(const char *, const char *))
|
||||
{
|
||||
const char *reqlvl;
|
||||
char *role;
|
||||
@@ -324,16 +324,16 @@ ssh_selinux_setup_pam_variables(void)
|
||||
|
||||
ssh_selinux_get_role_level(&role, &reqlvl);
|
||||
|
||||
- rv = do_pam_putenv("SELINUX_ROLE_REQUESTED", role ? role : "");
|
||||
+ rv = set_it("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 || set_it("SELINUX_LEVEL_REQUESTED", reqlvl ? reqlvl: "");
|
||||
}
|
||||
|
||||
- rv = rv || do_pam_putenv("SELINUX_USE_CURRENT_RANGE", use_current);
|
||||
+ rv = rv || set_it("SELINUX_USE_CURRENT_RANGE", use_current);
|
||||
|
||||
if (role != NULL)
|
||||
xfree(role);
|
||||
@@ -341,6 +341,24 @@ ssh_selinux_setup_pam_variables(void)
|
||||
return rv;
|
||||
}
|
||||
|
||||
+static int
|
||||
+ssh_selinux_setup_pam_variables(void)
|
||||
+{
|
||||
+ return ssh_selinux_setup_variables(do_pam_putenv);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_setenv(char *name, char *value)
|
||||
+{
|
||||
+ return setenv(name, value, 1);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+ssh_selinux_setup_env_variables(void)
|
||||
+{
|
||||
+ return ssh_selinux_setup_variables(do_setenv);
|
||||
+}
|
||||
+
|
||||
/* Set the execution context to the default for the specified user */
|
||||
void
|
||||
ssh_selinux_setup_exec_context(char *pwname)
|
||||
diff -up openssh-5.9p0/ssh-keycat.c.keycat openssh-5.9p0/ssh-keycat.c
|
||||
--- openssh-5.9p0/ssh-keycat.c.keycat 2011-08-31 11:51:50.354136025 +0200
|
||||
+++ openssh-5.9p0/ssh-keycat.c 2011-08-31 11:51:50.359087309 +0200
|
||||
@@ -0,0 +1,238 @@
|
||||
+/*
|
||||
+ * Redistribution and use in source and binary forms, with or without
|
||||
+ * modification, are permitted provided that the following conditions
|
||||
+ * are met:
|
||||
+ * 1. Redistributions of source code must retain the above copyright
|
||||
+ * notice, and the entire permission notice in its entirety,
|
||||
+ * including the disclaimer of warranties.
|
||||
+ * 2. Redistributions in binary form must reproduce the above copyright
|
||||
+ * notice, this list of conditions and the following disclaimer in the
|
||||
+ * documentation and/or other materials provided with the distribution.
|
||||
+ * 3. The name of the author may not be used to endorse or promote
|
||||
+ * products derived from this software without specific prior
|
||||
+ * written permission.
|
||||
+ *
|
||||
+ * ALTERNATIVELY, this product may be distributed under the terms of
|
||||
+ * the GNU Public License, in which case the provisions of the GPL are
|
||||
+ * required INSTEAD OF the above restrictions. (This clause is
|
||||
+ * necessary due to a potential bad interaction between the GPL and
|
||||
+ * the restrictions contained in a BSD-style copyright.)
|
||||
+ *
|
||||
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
+ */
|
||||
+
|
||||
+/*
|
||||
+ * Copyright (c) 2011 Red Hat, Inc.
|
||||
+ * Written by Tomas Mraz <tmraz@redhat.com>
|
||||
+*/
|
||||
+
|
||||
+#define _GNU_SOURCE
|
||||
+
|
||||
+#include "config.h"
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+#include <sys/types.h>
|
||||
+#include <sys/stat.h>
|
||||
+#include <pwd.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <unistd.h>
|
||||
+
|
||||
+#include <security/pam_appl.h>
|
||||
+
|
||||
+#include "uidswap.h"
|
||||
+#include "misc.h"
|
||||
+
|
||||
+#define ERR_USAGE 1
|
||||
+#define ERR_PAM_START 2
|
||||
+#define ERR_OPEN_SESSION 3
|
||||
+#define ERR_CLOSE_SESSION 4
|
||||
+#define ERR_PAM_END 5
|
||||
+#define ERR_GETPWNAM 6
|
||||
+#define ERR_MEMORY 7
|
||||
+#define ERR_OPEN 8
|
||||
+#define ERR_FILE_MODE 9
|
||||
+#define ERR_FDOPEN 10
|
||||
+#define ERR_STAT 11
|
||||
+#define ERR_WRITE 12
|
||||
+#define ERR_PAM_PUTENV 13
|
||||
+#define BUFLEN 4096
|
||||
+
|
||||
+/* Just ignore the messages in the conversation function */
|
||||
+static int
|
||||
+dummy_conv(int num_msg, const struct pam_message **msgm,
|
||||
+ struct pam_response **response, void *appdata_ptr)
|
||||
+{
|
||||
+ struct pam_response *rsp;
|
||||
+
|
||||
+ (void)msgm;
|
||||
+ (void)appdata_ptr;
|
||||
+
|
||||
+ if (num_msg <= 0)
|
||||
+ return PAM_CONV_ERR;
|
||||
+
|
||||
+ /* Just allocate the array as empty responses */
|
||||
+ rsp = calloc (num_msg, sizeof (struct pam_response));
|
||||
+ if (rsp == NULL)
|
||||
+ return PAM_CONV_ERR;
|
||||
+
|
||||
+ *response = rsp;
|
||||
+ return PAM_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+static struct pam_conv conv = {
|
||||
+ dummy_conv,
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+char *
|
||||
+make_auth_keys_name(const struct passwd *pwd)
|
||||
+{
|
||||
+ char *fname;
|
||||
+
|
||||
+ if (asprintf(&fname, "%s/.ssh/authorized_keys", pwd->pw_dir) < 0)
|
||||
+ return NULL;
|
||||
+
|
||||
+ return fname;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+dump_keys(const char *user)
|
||||
+{
|
||||
+ struct passwd *pwd;
|
||||
+ int fd = -1;
|
||||
+ FILE *f = NULL;
|
||||
+ char *fname = NULL;
|
||||
+ int rv = 0;
|
||||
+ char buf[BUFLEN];
|
||||
+ size_t len;
|
||||
+ struct stat st;
|
||||
+
|
||||
+ if ((pwd = getpwnam(user)) == NULL) {
|
||||
+ return ERR_GETPWNAM;
|
||||
+ }
|
||||
+
|
||||
+ if ((fname = make_auth_keys_name(pwd)) == NULL) {
|
||||
+ return ERR_MEMORY;
|
||||
+ }
|
||||
+
|
||||
+ temporarily_use_uid(pwd);
|
||||
+
|
||||
+ if ((fd = open(fname, O_RDONLY|O_NONBLOCK|O_NOFOLLOW, 0)) < 0) {
|
||||
+ rv = ERR_OPEN;
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ if (fstat(fd, &st) < 0) {
|
||||
+ rv = ERR_STAT;
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ if (!S_ISREG(st.st_mode) ||
|
||||
+ (st.st_uid != pwd->pw_uid && st.st_uid != 0)) {
|
||||
+ rv = ERR_FILE_MODE;
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ unset_nonblock(fd);
|
||||
+
|
||||
+ if ((f = fdopen(fd, "r")) == NULL) {
|
||||
+ rv = ERR_FDOPEN;
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ fd = -1;
|
||||
+
|
||||
+ while ((len = fread(buf, 1, sizeof(buf), f)) > 0) {
|
||||
+ rv = fwrite(buf, 1, len, stdout) != len ? ERR_WRITE : 0;
|
||||
+ }
|
||||
+
|
||||
+fail:
|
||||
+ if (fd != -1)
|
||||
+ close(fd);
|
||||
+ if (f != NULL)
|
||||
+ fclose(f);
|
||||
+ free(fname);
|
||||
+ restore_uid();
|
||||
+ return rv;
|
||||
+}
|
||||
+
|
||||
+static const char *env_names[] = { "SELINUX_ROLE_REQUESTED",
|
||||
+ "SELINUX_LEVEL_REQUESTED",
|
||||
+ "SELINUX_USE_CURRENT_RANGE"
|
||||
+};
|
||||
+
|
||||
+extern char **environ;
|
||||
+
|
||||
+int
|
||||
+set_pam_environment(pam_handle_t *pamh)
|
||||
+{
|
||||
+ int i;
|
||||
+ size_t j;
|
||||
+
|
||||
+ for (j = 0; j < sizeof(env_names)/sizeof(env_names[0]); ++j) {
|
||||
+ int len = strlen(env_names[j]);
|
||||
+
|
||||
+ for (i = 0; environ[i] != NULL; ++i) {
|
||||
+ if (strncmp(env_names[j], environ[i], len) == 0 &&
|
||||
+ environ[i][len] == '=') {
|
||||
+ if (pam_putenv(pamh, environ[i]) != PAM_SUCCESS)
|
||||
+ return ERR_PAM_PUTENV;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+main(int argc, char *argv[])
|
||||
+{
|
||||
+ pam_handle_t *pamh = NULL;
|
||||
+ int retval;
|
||||
+ int ev = 0;
|
||||
+
|
||||
+ if (argc != 2) {
|
||||
+ fprintf(stderr, "Usage: %s <user-name>\n", argv[0]);
|
||||
+ return ERR_USAGE;
|
||||
+ }
|
||||
+
|
||||
+ retval = pam_start("ssh-keycat", argv[1], &conv, &pamh);
|
||||
+ if (retval != PAM_SUCCESS) {
|
||||
+ return ERR_PAM_START;
|
||||
+ }
|
||||
+
|
||||
+ ev = set_pam_environment(pamh);
|
||||
+ if (ev != 0)
|
||||
+ goto finish;
|
||||
+
|
||||
+ retval = pam_open_session(pamh, PAM_SILENT);
|
||||
+ if (retval != PAM_SUCCESS) {
|
||||
+ ev = ERR_OPEN_SESSION;
|
||||
+ goto finish;
|
||||
+ }
|
||||
+
|
||||
+ ev = dump_keys(argv[1]);
|
||||
+
|
||||
+ retval = pam_close_session(pamh, PAM_SILENT);
|
||||
+ if (retval != PAM_SUCCESS) {
|
||||
+ ev = ERR_CLOSE_SESSION;
|
||||
+ }
|
||||
+
|
||||
+finish:
|
||||
+ retval = pam_end (pamh,retval);
|
||||
+ if (retval != PAM_SUCCESS) {
|
||||
+ ev = ERR_PAM_END;
|
||||
+ }
|
||||
+ return ev;
|
||||
+}
|
80
openssh-5.9p1-keygen.patch
Normal file
80
openssh-5.9p1-keygen.patch
Normal file
@ -0,0 +1,80 @@
|
||||
diff -up openssh-5.9p0/ssh-keygen.0.keygen openssh-5.9p0/ssh-keygen.0
|
||||
--- openssh-5.9p0/ssh-keygen.0.keygen 2011-08-29 16:30:02.000000000 +0200
|
||||
+++ openssh-5.9p0/ssh-keygen.0 2011-08-30 13:47:56.208087184 +0200
|
||||
@@ -4,7 +4,7 @@ NAME
|
||||
ssh-keygen - authentication key generation, management and conversion
|
||||
|
||||
SYNOPSIS
|
||||
- ssh-keygen [-q] [-b bits] -t type [-N new_passphrase] [-C comment]
|
||||
+ ssh-keygen [-q] [-o] [-b bits] -t type [-N new_passphrase] [-C comment]
|
||||
[-f output_keyfile]
|
||||
ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile]
|
||||
ssh-keygen -i [-m key_format] [-f input_keyfile]
|
||||
@@ -181,6 +181,8 @@ DESCRIPTION
|
||||
principals may be specified, separated by commas. Please see the
|
||||
CERTIFICATES section for details.
|
||||
|
||||
+ -o Overwrite the key without prompting user.
|
||||
+
|
||||
-O option
|
||||
Specify a certificate option when signing a key. This option may
|
||||
be specified multiple times. Please see the CERTIFICATES section
|
||||
diff -up openssh-5.9p0/ssh-keygen.1.keygen openssh-5.9p0/ssh-keygen.1
|
||||
--- openssh-5.9p0/ssh-keygen.1.keygen 2011-08-30 13:32:30.787149917 +0200
|
||||
+++ openssh-5.9p0/ssh-keygen.1 2011-08-30 13:46:42.638087171 +0200
|
||||
@@ -45,6 +45,7 @@
|
||||
.Bk -words
|
||||
.Nm ssh-keygen
|
||||
.Op Fl q
|
||||
+.Op Fl o
|
||||
.Op Fl b Ar bits
|
||||
.Fl t Ar type
|
||||
.Op Fl N Ar new_passphrase
|
||||
@@ -339,6 +340,8 @@ Multiple principals may be specified, se
|
||||
Please see the
|
||||
.Sx CERTIFICATES
|
||||
section for details.
|
||||
+.It Fl o
|
||||
+Overwrite the key without prompting user.
|
||||
.It Fl O Ar option
|
||||
Specify a certificate option when signing a key.
|
||||
This option may be specified multiple times.
|
||||
diff -up openssh-5.9p0/ssh-keygen.c.keygen openssh-5.9p0/ssh-keygen.c
|
||||
--- openssh-5.9p0/ssh-keygen.c.keygen 2011-08-30 13:32:20.268149992 +0200
|
||||
+++ openssh-5.9p0/ssh-keygen.c 2011-08-30 13:39:34.550214102 +0200
|
||||
@@ -73,6 +73,7 @@ int change_passphrase = 0;
|
||||
int change_comment = 0;
|
||||
|
||||
int quiet = 0;
|
||||
+int overwrite = 0;
|
||||
|
||||
int log_level = SYSLOG_LEVEL_INFO;
|
||||
|
||||
@@ -1959,7 +1960,7 @@ main(int argc, char **argv)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
- while ((opt = getopt(argc, argv, "AegiqpclBHLhvxXyF:b:f:t:D:I:P:m:N:n:"
|
||||
+ while ((opt = getopt(argc, argv, "AegiqopclBHLhvxXyF:b:f:t:D:I:P:m:N:n:"
|
||||
"O:C:r:g:R:T:G:M:S:s:a:V:W:z:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'A':
|
||||
@@ -2042,6 +2043,9 @@ main(int argc, char **argv)
|
||||
case 'q':
|
||||
quiet = 1;
|
||||
break;
|
||||
+ case 'o':
|
||||
+ overwrite = 1;
|
||||
+ break;
|
||||
case 'e':
|
||||
case 'x':
|
||||
/* export key */
|
||||
@@ -2278,7 +2282,7 @@ main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
/* If the file already exists, ask the user to confirm. */
|
||||
- if (stat(identity_file, &st) >= 0) {
|
||||
+ if (!overwrite && stat(identity_file, &st) >= 0) {
|
||||
char yesno[3];
|
||||
printf("%s already exists.\n", identity_file);
|
||||
printf("Overwrite (y/n)? ");
|
167
openssh-5.9p1-kuserok.patch
Normal file
167
openssh-5.9p1-kuserok.patch
Normal file
@ -0,0 +1,167 @@
|
||||
diff -up openssh-5.9p0/auth-krb5.c.kuserok openssh-5.9p0/auth-krb5.c
|
||||
--- openssh-5.9p0/auth-krb5.c.kuserok 2011-08-30 16:37:32.651150128 +0200
|
||||
+++ openssh-5.9p0/auth-krb5.c 2011-08-30 16:37:37.549087368 +0200
|
||||
@@ -54,6 +54,20 @@
|
||||
|
||||
extern ServerOptions options;
|
||||
|
||||
+int
|
||||
+ssh_krb5_kuserok(krb5_context krb5_ctx, krb5_principal krb5_user, const char *client)
|
||||
+{
|
||||
+ if (options.use_kuserok)
|
||||
+ return krb5_kuserok(krb5_ctx, krb5_user, client);
|
||||
+ else {
|
||||
+ char kuser[65];
|
||||
+
|
||||
+ if (krb5_aname_to_localname(krb5_ctx, krb5_user, sizeof(kuser), kuser))
|
||||
+ return 0;
|
||||
+ return strcmp(kuser, client) == 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static int
|
||||
krb5_init(void *context)
|
||||
{
|
||||
@@ -146,7 +160,7 @@ auth_krb5_password(Authctxt *authctxt, c
|
||||
if (problem)
|
||||
goto out;
|
||||
|
||||
- if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, client)) {
|
||||
+ if (!ssh_krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, client)) {
|
||||
problem = -1;
|
||||
goto out;
|
||||
}
|
||||
diff -up openssh-5.9p0/gss-serv-krb5.c.kuserok openssh-5.9p0/gss-serv-krb5.c
|
||||
--- openssh-5.9p0/gss-serv-krb5.c.kuserok 2011-08-30 16:37:36.988024804 +0200
|
||||
+++ openssh-5.9p0/gss-serv-krb5.c 2011-08-30 16:37:37.659088030 +0200
|
||||
@@ -68,6 +68,7 @@ static int ssh_gssapi_krb5_cmdok(krb5_pr
|
||||
int);
|
||||
|
||||
static krb5_context krb_context = NULL;
|
||||
+extern int ssh_krb5_kuserok(krb5_context, krb5_principal, const char *);
|
||||
|
||||
/* Initialise the krb5 library, for the stuff that GSSAPI won't do */
|
||||
|
||||
@@ -115,7 +116,7 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client
|
||||
/* NOTE: .k5login and .k5users must opened as root, not the user,
|
||||
* because if they are on a krb5-protected filesystem, user credentials
|
||||
* to access these files aren't available yet. */
|
||||
- if (krb5_kuserok(krb_context, princ, luser) && k5login_exists) {
|
||||
+ if (ssh_krb5_kuserok(krb_context, princ, luser) && k5login_exists) {
|
||||
retval = 1;
|
||||
logit("Authorized to %s, krb5 principal %s (krb5_kuserok)",
|
||||
luser, (char *)client->displayname.value);
|
||||
diff -up openssh-5.9p0/servconf.c.kuserok openssh-5.9p0/servconf.c
|
||||
--- openssh-5.9p0/servconf.c.kuserok 2011-08-30 16:37:35.093073603 +0200
|
||||
+++ openssh-5.9p0/servconf.c 2011-08-30 16:41:13.568087145 +0200
|
||||
@@ -144,6 +144,7 @@ initialize_server_options(ServerOptions
|
||||
options->authorized_principals_file = NULL;
|
||||
options->ip_qos_interactive = -1;
|
||||
options->ip_qos_bulk = -1;
|
||||
+ options->use_kuserok = -1;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -291,6 +292,8 @@ fill_default_server_options(ServerOption
|
||||
options->ip_qos_bulk = IPTOS_THROUGHPUT;
|
||||
if (options->show_patchlevel == -1)
|
||||
options->show_patchlevel = 0;
|
||||
+ if (options->use_kuserok == -1)
|
||||
+ options->use_kuserok = 1;
|
||||
|
||||
/* Turn privilege separation on by default */
|
||||
if (use_privsep == -1)
|
||||
@@ -317,7 +320,7 @@ typedef enum {
|
||||
sPermitRootLogin, sLogFacility, sLogLevel,
|
||||
sRhostsRSAAuthentication, sRSAAuthentication,
|
||||
sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
|
||||
- sKerberosGetAFSToken,
|
||||
+ sKerberosGetAFSToken, sKerberosUseKuserok,
|
||||
sKerberosTgtPassing, sChallengeResponseAuthentication,
|
||||
sPasswordAuthentication, sKbdInteractiveAuthentication,
|
||||
sListenAddress, sAddressFamily,
|
||||
@@ -388,11 +391,13 @@ static struct {
|
||||
#else
|
||||
{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
|
||||
#endif
|
||||
+ { "kerberosusekuserok", sKerberosUseKuserok, SSHCFG_ALL },
|
||||
#else
|
||||
{ "kerberosauthentication", sUnsupported, SSHCFG_ALL },
|
||||
{ "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
|
||||
{ "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
|
||||
{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
|
||||
+ { "kerberosusekuserok", sUnsupported, SSHCFG_ALL },
|
||||
#endif
|
||||
{ "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
|
||||
{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
|
||||
@@ -1371,6 +1376,10 @@ process_server_config_line(ServerOptions
|
||||
*activep = value;
|
||||
break;
|
||||
|
||||
+ case sKerberosUseKuserok:
|
||||
+ intptr = &options->use_kuserok;
|
||||
+ goto parse_flag;
|
||||
+
|
||||
case sPermitOpen:
|
||||
arg = strdelim(&cp);
|
||||
if (!arg || *arg == '\0')
|
||||
@@ -1580,6 +1589,7 @@ copy_set_server_options(ServerOptions *d
|
||||
M_CP_INTOPT(max_authtries);
|
||||
M_CP_INTOPT(ip_qos_interactive);
|
||||
M_CP_INTOPT(ip_qos_bulk);
|
||||
+ M_CP_INTOPT(use_kuserok);
|
||||
|
||||
/* See comment in servconf.h */
|
||||
COPY_MATCH_STRING_OPTS();
|
||||
@@ -1816,6 +1826,7 @@ dump_config(ServerOptions *o)
|
||||
dump_cfg_fmtint(sUseDNS, o->use_dns);
|
||||
dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
|
||||
dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep);
|
||||
+ dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok);
|
||||
|
||||
/* string arguments */
|
||||
dump_cfg_string(sPidFile, o->pid_file);
|
||||
diff -up openssh-5.9p0/servconf.h.kuserok openssh-5.9p0/servconf.h
|
||||
--- openssh-5.9p0/servconf.h.kuserok 2011-08-30 16:37:35.201051957 +0200
|
||||
+++ openssh-5.9p0/servconf.h 2011-08-30 16:37:37.926087431 +0200
|
||||
@@ -166,6 +166,7 @@ typedef struct {
|
||||
|
||||
int num_permitted_opens;
|
||||
|
||||
+ int use_kuserok;
|
||||
char *chroot_directory;
|
||||
char *revoked_keys_file;
|
||||
char *trusted_user_ca_keys;
|
||||
diff -up openssh-5.9p0/sshd_config.5.kuserok openssh-5.9p0/sshd_config.5
|
||||
--- openssh-5.9p0/sshd_config.5.kuserok 2011-08-30 16:37:35.979024607 +0200
|
||||
+++ openssh-5.9p0/sshd_config.5 2011-08-30 16:37:38.040087843 +0200
|
||||
@@ -603,6 +603,10 @@ Specifies whether to automatically destr
|
||||
file on logout.
|
||||
The default is
|
||||
.Dq yes .
|
||||
+.It Cm KerberosUseKuserok
|
||||
+Specifies whether to look at .k5login file for user's aliases.
|
||||
+The default is
|
||||
+.Dq yes .
|
||||
.It Cm KexAlgorithms
|
||||
Specifies the available KEX (Key Exchange) algorithms.
|
||||
Multiple algorithms must be comma-separated.
|
||||
@@ -746,6 +750,7 @@ Available keywords are
|
||||
.Cm HostbasedUsesNameFromPacketOnly ,
|
||||
.Cm KbdInteractiveAuthentication ,
|
||||
.Cm KerberosAuthentication ,
|
||||
+.Cm KerberosUseKuserok ,
|
||||
.Cm MaxAuthTries ,
|
||||
.Cm MaxSessions ,
|
||||
.Cm PubkeyAuthentication ,
|
||||
diff -up openssh-5.9p0/sshd_config.kuserok openssh-5.9p0/sshd_config
|
||||
--- openssh-5.9p0/sshd_config.kuserok 2011-08-30 16:37:36.808026328 +0200
|
||||
+++ openssh-5.9p0/sshd_config 2011-08-30 16:37:38.148071520 +0200
|
||||
@@ -77,6 +77,7 @@ ChallengeResponseAuthentication no
|
||||
#KerberosOrLocalPasswd yes
|
||||
#KerberosTicketCleanup yes
|
||||
#KerberosGetAFSToken no
|
||||
+#KerberosUseKuserok yes
|
||||
|
||||
# GSSAPI options
|
||||
#GSSAPIAuthentication no
|
2596
openssh-5.9p1-ldap.patch
Normal file
2596
openssh-5.9p1-ldap.patch
Normal file
File diff suppressed because it is too large
Load Diff
400
openssh-5.9p1-mls.patch
Normal file
400
openssh-5.9p1-mls.patch
Normal file
@ -0,0 +1,400 @@
|
||||
diff -up openssh-5.9p0/misc.c.mls openssh-5.9p0/misc.c
|
||||
--- openssh-5.9p0/misc.c.mls 2011-05-05 06:14:34.000000000 +0200
|
||||
+++ openssh-5.9p0/misc.c 2011-08-30 12:29:29.157087474 +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-5.9p0/openbsd-compat/port-linux.c.mls openssh-5.9p0/openbsd-compat/port-linux.c
|
||||
--- openssh-5.9p0/openbsd-compat/port-linux.c.mls 2011-08-30 12:29:28.873086987 +0200
|
||||
+++ openssh-5.9p0/openbsd-compat/port-linux.c 2011-08-30 13:28:12.584149668 +0200
|
||||
@@ -40,7 +40,15 @@
|
||||
#ifdef WITH_SELINUX
|
||||
#include <selinux/selinux.h>
|
||||
#include <selinux/flask.h>
|
||||
+#include <selinux/context.h>
|
||||
#include <selinux/get_context_list.h>
|
||||
+#include <selinux/get_default_type.h>
|
||||
+#include <selinux/av_permissions.h>
|
||||
+
|
||||
+#ifdef HAVE_LINUX_AUDIT
|
||||
+#include <libaudit.h>
|
||||
+#include <unistd.h>
|
||||
+#endif
|
||||
|
||||
#ifndef SSH_SELINUX_UNCONFINED_TYPE
|
||||
# define SSH_SELINUX_UNCONFINED_TYPE ":unconfined_t:"
|
||||
@@ -51,6 +59,149 @@ 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)
|
||||
+{
|
||||
+ 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;
|
||||
+ }
|
||||
+
|
||||
+ 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;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
ssh_selinux_get_role_level(char **role, const char **level)
|
||||
{
|
||||
@@ -69,14 +220,15 @@ ssh_selinux_get_role_level(char **role,
|
||||
}
|
||||
|
||||
/* Return the default security context for the given username */
|
||||
-static security_context_t
|
||||
-ssh_selinux_getctxbyname(char *pwname)
|
||||
+static int
|
||||
+ssh_selinux_getctxbyname(char *pwname,
|
||||
+ security_context_t *default_sc, security_context_t *user_sc)
|
||||
{
|
||||
- security_context_t sc = NULL;
|
||||
char *sename, *lvl;
|
||||
char *role;
|
||||
const char *reqlvl;
|
||||
int r = 0;
|
||||
+ context_t con = NULL;
|
||||
|
||||
ssh_selinux_get_role_level(&role, &reqlvl);
|
||||
|
||||
@@ -87,37 +239,62 @@ ssh_selinux_getctxbyname(char *pwname)
|
||||
}
|
||||
#else
|
||||
sename = pwname;
|
||||
- lvl = NULL;
|
||||
+ lvl = "";
|
||||
#endif
|
||||
|
||||
if (r == 0) {
|
||||
#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
|
||||
- if (role != NULL && role[0])
|
||||
- r = get_default_context_with_rolelevel(sename, role, lvl, NULL, &sc);
|
||||
- else
|
||||
- r = get_default_context_with_level(sename, lvl, NULL, &sc);
|
||||
+ r = get_default_context_with_level(sename, lvl, NULL, default_sc);
|
||||
#else
|
||||
- if (role != NULL && role[0])
|
||||
- r = get_default_context_with_role(sename, role, NULL, &sc);
|
||||
- else
|
||||
- r = get_default_context(sename, NULL, &sc);
|
||||
+ r = get_default_context(sename, NULL, default_sc);
|
||||
#endif
|
||||
}
|
||||
|
||||
- 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);
|
||||
- break;
|
||||
- default:
|
||||
- fatal("%s: Failed to get default SELinux security "
|
||||
- "context for %s (in enforcing mode)",
|
||||
- __func__, pwname);
|
||||
+ 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 ((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
|
||||
@@ -126,8 +303,12 @@ ssh_selinux_getctxbyname(char *pwname)
|
||||
if (lvl != NULL)
|
||||
xfree(lvl);
|
||||
#endif
|
||||
-
|
||||
- return (sc);
|
||||
+ if (role != NULL)
|
||||
+ xfree(role);
|
||||
+ if (con)
|
||||
+ context_free(con);
|
||||
+
|
||||
+ return (r);
|
||||
}
|
||||
|
||||
/* Setup environment variables for pam_selinux */
|
||||
@@ -165,6 +346,8 @@ 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;
|
||||
@@ -189,22 +372,45 @@ ssh_selinux_setup_exec_context(char *pwn
|
||||
|
||||
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__);
|
||||
}
|
||||
@@ -222,7 +428,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? */
|
||||
|
||||
diff -up openssh-5.9p0/sshd.c.mls openssh-5.9p0/sshd.c
|
||||
--- openssh-5.9p0/sshd.c.mls 2011-08-30 12:29:22.663149706 +0200
|
||||
+++ openssh-5.9p0/sshd.c 2011-08-30 12:29:29.524024777 +0200
|
||||
@@ -2082,6 +2082,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);
|
13
openssh-5.9p1-randclean.patch
Normal file
13
openssh-5.9p1-randclean.patch
Normal file
@ -0,0 +1,13 @@
|
||||
diff -up openssh-5.9p0/entropy.c.randclean openssh-5.9p0/entropy.c
|
||||
--- openssh-5.9p0/entropy.c.randclean 2011-08-30 13:52:45.000000000 +0200
|
||||
+++ openssh-5.9p0/entropy.c 2011-08-30 13:57:44.630111338 +0200
|
||||
@@ -217,6 +217,9 @@ seed_rng(void)
|
||||
fatal("OpenSSL version mismatch. Built against %lx, you "
|
||||
"have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay());
|
||||
|
||||
+ /* clean the PRNG status when exiting the program */
|
||||
+ atexit(RAND_cleanup);
|
||||
+
|
||||
#ifndef OPENSSL_PRNG_ONLY
|
||||
if (RAND_status() == 1) {
|
||||
debug3("RNG is ready, skipping seeding");
|
108
openssh-5.9p1-redhat.patch
Normal file
108
openssh-5.9p1-redhat.patch
Normal file
@ -0,0 +1,108 @@
|
||||
diff -up openssh-5.9p0/ssh_config.redhat openssh-5.9p0/ssh_config
|
||||
--- openssh-5.9p0/ssh_config.redhat 2010-01-12 09:40:27.000000000 +0100
|
||||
+++ openssh-5.9p0/ssh_config 2011-09-05 14:48:16.386439023 +0200
|
||||
@@ -45,3 +45,14 @@
|
||||
# PermitLocalCommand no
|
||||
# VisualHostKey no
|
||||
# ProxyCommand ssh -q -W %h:%p gateway.example.com
|
||||
+Host *
|
||||
+ GSSAPIAuthentication yes
|
||||
+# If this option is set to yes then remote X11 clients will have full access
|
||||
+# to the original X11 display. As virtually no X11 client supports the untrusted
|
||||
+# mode correctly we set this to yes.
|
||||
+ ForwardX11Trusted yes
|
||||
+# Send locale-related environment variables
|
||||
+ SendEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
|
||||
+ SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
|
||||
+ SendEnv LC_IDENTIFICATION LC_ALL LANGUAGE
|
||||
+ SendEnv XMODIFIERS
|
||||
diff -up openssh-5.9p0/sshd_config.0.redhat openssh-5.9p0/sshd_config.0
|
||||
--- openssh-5.9p0/sshd_config.0.redhat 2011-09-05 14:48:08.522441255 +0200
|
||||
+++ openssh-5.9p0/sshd_config.0 2011-09-05 14:48:16.477443868 +0200
|
||||
@@ -581,9 +581,9 @@ DESCRIPTION
|
||||
|
||||
SyslogFacility
|
||||
Gives the facility code that is used when logging messages from
|
||||
- sshd(8). The possible values are: DAEMON, USER, AUTH, LOCAL0,
|
||||
- LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. The
|
||||
- default is AUTH.
|
||||
+ sshd(8). The possible values are: DAEMON, USER, AUTH, AUTHPRIV,
|
||||
+ LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.
|
||||
+ The default is AUTH.
|
||||
|
||||
TCPKeepAlive
|
||||
Specifies whether the system should send TCP keepalive messages
|
||||
diff -up openssh-5.9p0/sshd_config.5.redhat openssh-5.9p0/sshd_config.5
|
||||
--- openssh-5.9p0/sshd_config.5.redhat 2011-09-05 14:48:08.657564688 +0200
|
||||
+++ openssh-5.9p0/sshd_config.5 2011-09-05 14:48:16.589501736 +0200
|
||||
@@ -1029,7 +1029,7 @@ Note that this option applies to protoco
|
||||
.It Cm SyslogFacility
|
||||
Gives the facility code that is used when logging messages from
|
||||
.Xr sshd 8 .
|
||||
-The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2,
|
||||
+The possible values are: DAEMON, USER, AUTH, AUTHPRIV, LOCAL0, LOCAL1, LOCAL2,
|
||||
LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.
|
||||
The default is AUTH.
|
||||
.It Cm TCPKeepAlive
|
||||
diff -up openssh-5.9p0/sshd_config.redhat openssh-5.9p0/sshd_config
|
||||
--- openssh-5.9p0/sshd_config.redhat 2011-09-05 14:48:16.250626793 +0200
|
||||
+++ openssh-5.9p0/sshd_config 2011-09-05 15:06:01.513443553 +0200
|
||||
@@ -32,6 +32,7 @@
|
||||
# Logging
|
||||
# obsoletes QuietMode and FascistLogging
|
||||
#SyslogFacility AUTH
|
||||
+SyslogFacility AUTHPRIV
|
||||
#LogLevel INFO
|
||||
|
||||
# Authentication:
|
||||
@@ -65,9 +66,11 @@ AuthorizedKeysFile .ssh/authorized_keys
|
||||
# To disable tunneled clear text passwords, change to no here!
|
||||
#PasswordAuthentication yes
|
||||
#PermitEmptyPasswords no
|
||||
+PasswordAuthentication yes
|
||||
|
||||
# Change to no to disable s/key passwords
|
||||
#ChallengeResponseAuthentication yes
|
||||
+ChallengeResponseAuthentication no
|
||||
|
||||
# Kerberos options
|
||||
#KerberosAuthentication no
|
||||
@@ -77,7 +80,9 @@ AuthorizedKeysFile .ssh/authorized_keys
|
||||
|
||||
# GSSAPI options
|
||||
#GSSAPIAuthentication no
|
||||
+GSSAPIAuthentication yes
|
||||
#GSSAPICleanupCredentials yes
|
||||
+GSSAPICleanupCredentials yes
|
||||
|
||||
# Set this to 'yes' to enable PAM authentication, account processing,
|
||||
# and session processing. If this is enabled, PAM authentication will
|
||||
@@ -89,6 +94,7 @@ AuthorizedKeysFile .ssh/authorized_keys
|
||||
# PAM authentication, then enable this but set PasswordAuthentication
|
||||
# and ChallengeResponseAuthentication to 'no'.
|
||||
#UsePAM no
|
||||
+UsePAM yes
|
||||
|
||||
#TwoFactorAuthentication no
|
||||
#SecondPubkeyAuthentication yes
|
||||
@@ -101,6 +107,7 @@ AuthorizedKeysFile .ssh/authorized_keys
|
||||
#AllowTcpForwarding yes
|
||||
#GatewayPorts no
|
||||
#X11Forwarding no
|
||||
+X11Forwarding yes
|
||||
#X11DisplayOffset 10
|
||||
#X11UseLocalhost yes
|
||||
#PrintMotd yes
|
||||
@@ -121,6 +128,12 @@ AuthorizedKeysFile .ssh/authorized_keys
|
||||
# no default banner path
|
||||
#Banner none
|
||||
|
||||
+# Accept locale-related environment variables
|
||||
+AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
|
||||
+AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
|
||||
+AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
|
||||
+AcceptEnv XMODIFIERS
|
||||
+
|
||||
# override default of no subsystems
|
||||
Subsystem sftp /usr/libexec/sftp-server
|
||||
|
613
openssh-5.9p1-role.patch
Normal file
613
openssh-5.9p1-role.patch
Normal file
@ -0,0 +1,613 @@
|
||||
diff -up openssh-5.9p0/auth-pam.c.role openssh-5.9p0/auth-pam.c
|
||||
--- openssh-5.9p0/auth-pam.c.role 2009-07-12 14:07:21.000000000 +0200
|
||||
+++ openssh-5.9p0/auth-pam.c 2011-08-31 11:42:54.870087433 +0200
|
||||
@@ -1069,7 +1069,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-5.9p0/auth-pam.h.role openssh-5.9p0/auth-pam.h
|
||||
--- openssh-5.9p0/auth-pam.h.role 2004-09-11 14:17:26.000000000 +0200
|
||||
+++ openssh-5.9p0/auth-pam.h 2011-08-31 11:42:54.979086333 +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-5.9p0/auth.h.role openssh-5.9p0/auth.h
|
||||
--- openssh-5.9p0/auth.h.role 2011-08-31 11:42:47.760024631 +0200
|
||||
+++ openssh-5.9p0/auth.h 2011-08-31 11:42:55.090151027 +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-5.9p0/auth1.c.role openssh-5.9p0/auth1.c
|
||||
--- openssh-5.9p0/auth1.c.role 2010-08-31 14:36:39.000000000 +0200
|
||||
+++ openssh-5.9p0/auth1.c 2011-08-31 11:42:55.215033075 +0200
|
||||
@@ -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-5.9p0/auth2-gss.c.role openssh-5.9p0/auth2-gss.c
|
||||
--- openssh-5.9p0/auth2-gss.c.role 2011-05-05 06:04:11.000000000 +0200
|
||||
+++ openssh-5.9p0/auth2-gss.c 2011-08-31 11:42:55.313025576 +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-5.9p0/auth2-hostbased.c.role openssh-5.9p0/auth2-hostbased.c
|
||||
--- openssh-5.9p0/auth2-hostbased.c.role 2011-08-31 11:42:47.863023264 +0200
|
||||
+++ openssh-5.9p0/auth2-hostbased.c 2011-08-31 11:42:55.421024814 +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-5.9p0/auth2-pubkey.c.role openssh-5.9p0/auth2-pubkey.c
|
||||
--- openssh-5.9p0/auth2-pubkey.c.role 2011-08-31 11:42:47.978087418 +0200
|
||||
+++ openssh-5.9p0/auth2-pubkey.c 2011-08-31 11:42:55.551025263 +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-5.9p0/auth2.c.role openssh-5.9p0/auth2.c
|
||||
--- openssh-5.9p0/auth2.c.role 2011-08-31 11:42:45.409026065 +0200
|
||||
+++ openssh-5.9p0/auth2.c 2011-08-31 11:42:55.676024869 +0200
|
||||
@@ -216,6 +216,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)
|
||||
@@ -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-5.9p0/monitor.c.role openssh-5.9p0/monitor.c
|
||||
--- openssh-5.9p0/monitor.c.role 2011-08-31 11:42:53.301024819 +0200
|
||||
+++ openssh-5.9p0/monitor.c 2011-08-31 11:42:55.796025812 +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 *);
|
||||
@@ -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
|
||||
@@ -819,6 +825,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
|
||||
@@ -862,6 +871,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)
|
||||
{
|
||||
@@ -1227,7 +1255,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;
|
||||
|
||||
@@ -1253,6 +1281,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);
|
||||
@@ -1284,7 +1314,7 @@ monitor_valid_hostbasedblob(u_char *data
|
||||
char *chost)
|
||||
{
|
||||
Buffer b;
|
||||
- char *p;
|
||||
+ char *p, *r;
|
||||
u_int len;
|
||||
int fail = 0;
|
||||
|
||||
@@ -1301,6 +1331,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-5.9p0/monitor.h.role openssh-5.9p0/monitor.h
|
||||
--- openssh-5.9p0/monitor.h.role 2011-08-31 11:42:53.409025333 +0200
|
||||
+++ openssh-5.9p0/monitor.h 2011-08-31 11:42:55.889024801 +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-5.9p0/monitor_wrap.c.role openssh-5.9p0/monitor_wrap.c
|
||||
--- openssh-5.9p0/monitor_wrap.c.role 2011-08-31 11:42:53.548024503 +0200
|
||||
+++ openssh-5.9p0/monitor_wrap.c 2011-08-31 11:42:56.029024553 +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-5.9p0/monitor_wrap.h.role openssh-5.9p0/monitor_wrap.h
|
||||
--- openssh-5.9p0/monitor_wrap.h.role 2011-08-31 11:42:53.660025271 +0200
|
||||
+++ openssh-5.9p0/monitor_wrap.h 2011-08-31 11:42:56.131025748 +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-5.9p0/openbsd-compat/Makefile.in.role openssh-5.9p0/openbsd-compat/Makefile.in
|
||||
--- openssh-5.9p0/openbsd-compat/Makefile.in.role 2010-10-07 13:19:24.000000000 +0200
|
||||
+++ openssh-5.9p0/openbsd-compat/Makefile.in 2011-08-31 11:48:02.404091479 +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 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-5.9p0/openbsd-compat/port-linux.c.role openssh-5.9p0/openbsd-compat/port-linux.c
|
||||
--- openssh-5.9p0/openbsd-compat/port-linux.c.role 2011-08-29 08:09:57.000000000 +0200
|
||||
+++ openssh-5.9p0/openbsd-compat/port-linux.c 2011-08-31 11:42:56.492087969 +0200
|
||||
@@ -31,7 +31,11 @@
|
||||
|
||||
#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 <selinux/selinux.h>
|
||||
@@ -42,41 +46,63 @@
|
||||
# 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)
|
||||
-{
|
||||
- static int enabled = -1;
|
||||
+extern ServerOptions options;
|
||||
+extern Authctxt *the_authctxt;
|
||||
+extern int inetd_flag;
|
||||
+extern int rexeced_flag;
|
||||
|
||||
- if (enabled == -1) {
|
||||
- enabled = (is_selinux_enabled() == 1);
|
||||
- debug("SELinux support %s", enabled ? "enabled" : "disabled");
|
||||
+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 (enabled);
|
||||
}
|
||||
|
||||
/* Return the default security context for the given username */
|
||||
static security_context_t
|
||||
ssh_selinux_getctxbyname(char *pwname)
|
||||
{
|
||||
- security_context_t sc;
|
||||
- char *sename = NULL, *lvl = NULL;
|
||||
- int r;
|
||||
+ security_context_t sc = NULL;
|
||||
+ char *sename, *lvl;
|
||||
+ char *role;
|
||||
+ const char *reqlvl;
|
||||
+ int r = 0;
|
||||
+
|
||||
+ 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;
|
||||
#endif
|
||||
|
||||
+ if (r == 0) {
|
||||
#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
|
||||
- r = get_default_context_with_level(sename, lvl, NULL, &sc);
|
||||
+ if (role != NULL && role[0])
|
||||
+ r = get_default_context_with_rolelevel(sename, role, lvl, NULL, &sc);
|
||||
+ else
|
||||
+ r = get_default_context_with_level(sename, lvl, NULL, &sc);
|
||||
#else
|
||||
- r = get_default_context(sename, NULL, &sc);
|
||||
+ if (role != NULL && role[0])
|
||||
+ r = get_default_context_with_role(sename, role, NULL, &sc);
|
||||
+ else
|
||||
+ r = get_default_context(sename, NULL, &sc);
|
||||
#endif
|
||||
+ }
|
||||
|
||||
if (r != 0) {
|
||||
switch (security_getenforce()) {
|
||||
@@ -104,6 +130,36 @@ ssh_selinux_getctxbyname(char *pwname)
|
||||
return (sc);
|
||||
}
|
||||
|
||||
+/* 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 */
|
||||
void
|
||||
ssh_selinux_setup_exec_context(char *pwname)
|
||||
@@ -113,6 +169,24 @@ ssh_selinux_setup_exec_context(char *pwn
|
||||
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);
|
||||
@@ -220,21 +294,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-5.9p0/openbsd-compat/port-linux_part_2.c.role openssh-5.9p0/openbsd-compat/port-linux_part_2.c
|
||||
--- openssh-5.9p0/openbsd-compat/port-linux_part_2.c.role 2011-08-31 11:42:56.583047619 +0200
|
||||
+++ openssh-5.9p0/openbsd-compat/port-linux_part_2.c 2011-08-31 11:42:56.586178005 +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 <dwalsh@redhat.com>
|
||||
+ * Copyright (c) 2006 Damien Miller <djm@openbsd.org>
|
||||
+ *
|
||||
+ * 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 <errno.h>
|
||||
+#include <stdarg.h>
|
||||
+#include <string.h>
|
||||
+#include <stdio.h>
|
||||
+
|
||||
+#include "log.h"
|
||||
+#include "xmalloc.h"
|
||||
+#include "port-linux.h"
|
||||
+#include "key.h"
|
||||
+#include "hostfile.h"
|
||||
+#include "auth.h"
|
||||
+
|
||||
+#ifdef WITH_SELINUX
|
||||
+#include <selinux/selinux.h>
|
||||
+#include <selinux/flask.h>
|
||||
+#include <selinux/get_context_list.h>
|
||||
+
|
||||
+/* 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 */
|
63
openssh-5.9p1-sftp-chroot.patch
Normal file
63
openssh-5.9p1-sftp-chroot.patch
Normal file
@ -0,0 +1,63 @@
|
||||
diff -up openssh-5.9p0/openbsd-compat/port-linux.c.sftp-chroot openssh-5.9p0/openbsd-compat/port-linux.c
|
||||
--- openssh-5.9p0/openbsd-compat/port-linux.c.sftp-chroot 2011-09-01 04:12:22.743024608 +0200
|
||||
+++ openssh-5.9p0/openbsd-compat/port-linux.c 2011-09-01 04:12:23.069088065 +0200
|
||||
@@ -503,6 +503,23 @@ ssh_selinux_change_context(const char *n
|
||||
xfree(newctx);
|
||||
}
|
||||
|
||||
+void
|
||||
+ssh_selinux_copy_context(void)
|
||||
+{
|
||||
+ char *ctx;
|
||||
+
|
||||
+ if (!ssh_selinux_enabled())
|
||||
+ return;
|
||||
+
|
||||
+ if (getexeccon((security_context_t *)&ctx) < 0) {
|
||||
+ logit("%s: getcon failed with %s", __func__, strerror (errno));
|
||||
+ return;
|
||||
+ }
|
||||
+ if (setcon(ctx) < 0)
|
||||
+ logit("%s: setcon failed with %s", __func__, strerror (errno));
|
||||
+ xfree(ctx);
|
||||
+}
|
||||
+
|
||||
#endif /* WITH_SELINUX */
|
||||
|
||||
#ifdef LINUX_OOM_ADJUST
|
||||
diff -up openssh-5.9p0/openbsd-compat/port-linux.h.sftp-chroot openssh-5.9p0/openbsd-compat/port-linux.h
|
||||
--- openssh-5.9p0/openbsd-compat/port-linux.h.sftp-chroot 2011-01-25 02:16:18.000000000 +0100
|
||||
+++ openssh-5.9p0/openbsd-compat/port-linux.h 2011-09-01 04:12:23.163088777 +0200
|
||||
@@ -24,6 +24,7 @@ int ssh_selinux_enabled(void);
|
||||
void ssh_selinux_setup_pty(char *, const char *);
|
||||
void ssh_selinux_setup_exec_context(char *);
|
||||
void ssh_selinux_change_context(const char *);
|
||||
+void ssh_selinux_chopy_context(void);
|
||||
void ssh_selinux_setfscreatecon(const char *);
|
||||
#endif
|
||||
|
||||
diff -up openssh-5.9p0/session.c.sftp-chroot openssh-5.9p0/session.c
|
||||
--- openssh-5.9p0/session.c.sftp-chroot 2011-09-01 04:12:19.698049195 +0200
|
||||
+++ openssh-5.9p0/session.c 2011-09-01 04:40:03.598148719 +0200
|
||||
@@ -1519,6 +1519,9 @@ do_setusercontext(struct passwd *pw)
|
||||
pw->pw_uid);
|
||||
chroot_path = percent_expand(tmp, "h", pw->pw_dir,
|
||||
"u", pw->pw_name, (char *)NULL);
|
||||
+#ifdef WITH_SELINUX
|
||||
+ ssh_selinux_change_context("chroot_user_t");
|
||||
+#endif
|
||||
safely_chroot(chroot_path, pw->pw_uid);
|
||||
free(tmp);
|
||||
free(chroot_path);
|
||||
@@ -1788,7 +1791,10 @@ do_child(Session *s, const char *command
|
||||
optind = optreset = 1;
|
||||
__progname = argv[0];
|
||||
#ifdef WITH_SELINUX
|
||||
- ssh_selinux_change_context("sftpd_t");
|
||||
+ if (options.chroot_directory == NULL ||
|
||||
+ strcasecmp(options.chroot_directory, "none") == 0) {
|
||||
+ ssh_selinux_copy_context();
|
||||
+ }
|
||||
#endif
|
||||
exit(sftp_server_main(i, argv, s->pw));
|
||||
}
|
157
openssh-5.9p1-vendor.patch
Normal file
157
openssh-5.9p1-vendor.patch
Normal file
@ -0,0 +1,157 @@
|
||||
diff -up openssh-5.9p0/configure.ac.vendor openssh-5.9p0/configure.ac
|
||||
--- openssh-5.9p0/configure.ac.vendor 2011-09-03 20:24:29.899501572 +0200
|
||||
+++ openssh-5.9p0/configure.ac 2011-09-03 20:24:39.153501595 +0200
|
||||
@@ -4131,6 +4131,12 @@ AC_ARG_WITH([lastlog],
|
||||
fi
|
||||
]
|
||||
)
|
||||
+AC_ARG_ENABLE(vendor-patchlevel,
|
||||
+ [ --enable-vendor-patchlevel=TAG specify a vendor patch level],
|
||||
+ [AC_DEFINE_UNQUOTED(SSH_VENDOR_PATCHLEVEL,[SSH_RELEASE "-" "$enableval"],[Define to your vendor patch level, if it has been modified from the upstream source release.])
|
||||
+ SSH_VENDOR_PATCHLEVEL="$enableval"],
|
||||
+ [AC_DEFINE(SSH_VENDOR_PATCHLEVEL,SSH_RELEASE,[Define to your vendor patch level, if it has been modified from the upstream source release.])
|
||||
+ SSH_VENDOR_PATCHLEVEL=none])
|
||||
|
||||
dnl lastlog, [uw]tmpx? detection
|
||||
dnl NOTE: set the paths in the platform section to avoid the
|
||||
@@ -4357,6 +4363,7 @@ echo " Translate v4 in v6 hack
|
||||
echo " BSD Auth support: $BSD_AUTH_MSG"
|
||||
echo " Random number source: $RAND_MSG"
|
||||
echo " Privsep sandbox style: $SANDBOX_STYLE"
|
||||
+echo " Vendor patch level: $SSH_VENDOR_PATCHLEVEL"
|
||||
|
||||
echo ""
|
||||
|
||||
diff -up openssh-5.9p0/servconf.c.vendor openssh-5.9p0/servconf.c
|
||||
--- openssh-5.9p0/servconf.c.vendor 2011-09-03 20:24:29.080500853 +0200
|
||||
+++ openssh-5.9p0/servconf.c 2011-09-03 20:27:15.727564566 +0200
|
||||
@@ -130,6 +130,7 @@ initialize_server_options(ServerOptions
|
||||
options->max_authtries = -1;
|
||||
options->max_sessions = -1;
|
||||
options->banner = NULL;
|
||||
+ options->show_patchlevel = -1;
|
||||
options->use_dns = -1;
|
||||
options->client_alive_interval = -1;
|
||||
options->client_alive_count_max = -1;
|
||||
@@ -300,6 +301,8 @@ fill_default_server_options(ServerOption
|
||||
options->ip_qos_interactive = IPTOS_LOWDELAY;
|
||||
if (options->ip_qos_bulk == -1)
|
||||
options->ip_qos_bulk = IPTOS_THROUGHPUT;
|
||||
+ if (options->show_patchlevel == -1)
|
||||
+ options->show_patchlevel = 0;
|
||||
|
||||
/* Turn privilege separation on by default */
|
||||
if (use_privsep == -1)
|
||||
@@ -338,7 +341,7 @@ typedef enum {
|
||||
sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
|
||||
sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
|
||||
sMaxStartups, sMaxAuthTries, sMaxSessions,
|
||||
- sBanner, sUseDNS, sHostbasedAuthentication,
|
||||
+ sBanner, sShowPatchLevel, sUseDNS, sHostbasedAuthentication,
|
||||
sHostbasedUsesNameFromPacketOnly, sTwoFactorAuthentication,
|
||||
sSecondPubkeyAuthentication, sSecondGssAuthentication,
|
||||
sSecondPasswordAuthentication, sSecondKbdInteractiveAuthentication,
|
||||
@@ -470,6 +473,7 @@ static struct {
|
||||
{ "maxauthtries", sMaxAuthTries, SSHCFG_ALL },
|
||||
{ "maxsessions", sMaxSessions, SSHCFG_ALL },
|
||||
{ "banner", sBanner, SSHCFG_ALL },
|
||||
+ { "showpatchlevel", sShowPatchLevel, SSHCFG_GLOBAL },
|
||||
{ "usedns", sUseDNS, SSHCFG_GLOBAL },
|
||||
{ "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
|
||||
{ "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
|
||||
@@ -1152,6 +1156,10 @@ process_server_config_line(ServerOptions
|
||||
multistate_ptr = multistate_privsep;
|
||||
goto parse_multistate;
|
||||
|
||||
+ case sShowPatchLevel:
|
||||
+ intptr = &options->show_patchlevel;
|
||||
+ goto parse_flag;
|
||||
+
|
||||
case sAllowUsers:
|
||||
while ((arg = strdelim(&cp)) && *arg != '\0') {
|
||||
if (options->num_allow_users >= MAX_ALLOW_USERS)
|
||||
@@ -1849,6 +1857,7 @@ dump_config(ServerOptions *o)
|
||||
dump_cfg_fmtint(sUseLogin, o->use_login);
|
||||
dump_cfg_fmtint(sCompression, o->compression);
|
||||
dump_cfg_fmtint(sGatewayPorts, o->gateway_ports);
|
||||
+ dump_cfg_fmtint(sShowPatchLevel, o->show_patchlevel);
|
||||
dump_cfg_fmtint(sUseDNS, o->use_dns);
|
||||
dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
|
||||
dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep);
|
||||
diff -up openssh-5.9p0/servconf.h.vendor openssh-5.9p0/servconf.h
|
||||
--- openssh-5.9p0/servconf.h.vendor 2011-09-03 20:24:29.179632045 +0200
|
||||
+++ openssh-5.9p0/servconf.h 2011-09-03 20:24:39.426502323 +0200
|
||||
@@ -148,6 +148,7 @@ typedef struct {
|
||||
int max_authtries;
|
||||
int max_sessions;
|
||||
char *banner; /* SSH-2 banner message */
|
||||
+ int show_patchlevel; /* Show vendor patch level to clients */
|
||||
int use_dns;
|
||||
int client_alive_interval; /*
|
||||
* poke the client this often to
|
||||
diff -up openssh-5.9p0/sshd.c.vendor openssh-5.9p0/sshd.c
|
||||
--- openssh-5.9p0/sshd.c.vendor 2011-09-03 20:24:35.987501565 +0200
|
||||
+++ openssh-5.9p0/sshd.c 2011-09-03 20:24:39.542501643 +0200
|
||||
@@ -431,7 +431,7 @@ sshd_exchange_identification(int sock_in
|
||||
minor = PROTOCOL_MINOR_1;
|
||||
}
|
||||
snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s%s", major, minor,
|
||||
- SSH_VERSION, newline);
|
||||
+ (options.show_patchlevel == 1) ? SSH_VENDOR_PATCHLEVEL : SSH_VERSION, newline);
|
||||
server_version_string = xstrdup(buf);
|
||||
|
||||
/* Send our protocol version identification. */
|
||||
@@ -1627,7 +1627,8 @@ main(int ac, char **av)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
- debug("sshd version %.100s", SSH_RELEASE);
|
||||
+ debug("sshd version %.100s",
|
||||
+ (options.show_patchlevel == 1) ? SSH_VENDOR_PATCHLEVEL : SSH_RELEASE);
|
||||
|
||||
/* Store privilege separation user for later use if required. */
|
||||
if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) {
|
||||
diff -up openssh-5.9p0/sshd_config.0.vendor openssh-5.9p0/sshd_config.0
|
||||
--- openssh-5.9p0/sshd_config.0.vendor 2011-09-03 20:24:37.524438185 +0200
|
||||
+++ openssh-5.9p0/sshd_config.0 2011-09-03 20:24:39.677508255 +0200
|
||||
@@ -556,6 +556,11 @@ DESCRIPTION
|
||||
Defines the number of bits in the ephemeral protocol version 1
|
||||
server key. The minimum value is 512, and the default is 1024.
|
||||
|
||||
+ ShowPatchLevel
|
||||
+ Specifies whether sshd will display the specific patch level of
|
||||
+ the binary in the server identification string. The patch level
|
||||
+ is set at compile-time. The default is M-bM-^@M-^\noM-bM-^@M-^].
|
||||
+
|
||||
StrictModes
|
||||
Specifies whether sshd(8) should check file modes and ownership
|
||||
of the user's files and home directory before accepting login.
|
||||
diff -up openssh-5.9p0/sshd_config.5.vendor openssh-5.9p0/sshd_config.5
|
||||
--- openssh-5.9p0/sshd_config.5.vendor 2011-09-03 20:24:37.640442022 +0200
|
||||
+++ openssh-5.9p0/sshd_config.5 2011-09-03 20:24:40.176544206 +0200
|
||||
@@ -952,6 +952,14 @@ This option applies to protocol version
|
||||
.It Cm ServerKeyBits
|
||||
Defines the number of bits in the ephemeral protocol version 1 server key.
|
||||
The minimum value is 512, and the default is 1024.
|
||||
+.It Cm ShowPatchLevel
|
||||
+Specifies whether
|
||||
+.Nm sshd
|
||||
+will display the patch level of the binary in the identification string.
|
||||
+The patch level is set at compile-time.
|
||||
+The default is
|
||||
+.Dq no .
|
||||
+This option applies to protocol version 1 only.
|
||||
.It Cm StrictModes
|
||||
Specifies whether
|
||||
.Xr sshd 8
|
||||
diff -up openssh-5.9p0/sshd_config.vendor openssh-5.9p0/sshd_config
|
||||
--- openssh-5.9p0/sshd_config.vendor 2011-09-03 20:24:37.770439735 +0200
|
||||
+++ openssh-5.9p0/sshd_config 2011-09-03 20:24:40.278628002 +0200
|
||||
@@ -120,6 +120,7 @@ X11Forwarding yes
|
||||
#Compression delayed
|
||||
#ClientAliveInterval 0
|
||||
#ClientAliveCountMax 3
|
||||
+#ShowPatchLevel no
|
||||
#UseDNS yes
|
||||
#PidFile /var/run/sshd.pid
|
||||
#MaxStartups 10
|
@ -18,3 +18,4 @@ patch -sp0 << EOF
|
||||
extern const EVP_CIPHER *evp_ssh1_bf(void);
|
||||
extern const EVP_CIPHER *evp_ssh1_3des(void);
|
||||
EOF
|
||||
echo "Well done."
|
||||
|
266
openssh.spec
266
openssh.spec
@ -78,10 +78,10 @@
|
||||
%endif
|
||||
|
||||
# Do not forget to bump pam_ssh_agent_auth release if you rewind the main package release to 1
|
||||
%define openssh_ver 5.8p2
|
||||
%define openssh_rel 21
|
||||
%define openssh_ver 5.9p1
|
||||
%define openssh_rel 1
|
||||
%define pam_ssh_agent_ver 0.9.2
|
||||
%define pam_ssh_agent_rel 31
|
||||
%define pam_ssh_agent_rel 32
|
||||
|
||||
Summary: An open source implementation of SSH protocol versions 1 and 2
|
||||
Name: openssh
|
||||
@ -108,98 +108,100 @@ Source10: sshd.socket
|
||||
Source11: sshd.service
|
||||
Source13: sshd-keygen
|
||||
|
||||
Patch99: openssh-5.8p1-wIm.patch
|
||||
#https://bugzilla.mindrot.org/show_bug.cgi?id=1635 (WONTFIX)
|
||||
Patch0: openssh-5.6p1-redhat.patch
|
||||
# Internal debug
|
||||
Patch0: openssh-5.8p1-wIm.patch
|
||||
|
||||
#https://bugzilla.mindrot.org/show_bug.cgi?id=1872
|
||||
Patch100: openssh-5.8p1-fingerprint.patch
|
||||
#https://bugzilla.mindrot.org/show_bug.cgi?id=1879
|
||||
Patch200: openssh-5.8p1-exit.patch
|
||||
#https://bugzilla.mindrot.org/show_bug.cgi?id=1894
|
||||
Patch300: openssh-5.8p1-getaddrinfo.patch
|
||||
#https://bugzilla.mindrot.org/show_bug.cgi?id=1402
|
||||
Patch8: openssh-5.8p1-audit0.patch
|
||||
Patch1: openssh-5.8p1-audit1.patch
|
||||
Patch2: openssh-5.8p1-audit2.patch
|
||||
Patch3: openssh-5.8p1-audit3.patch
|
||||
Patch4: openssh-5.8p1-audit4.patch
|
||||
Patch5: openssh-5.8p1-audit5.patch
|
||||
Patch101: openssh-5.8p1-getaddrinfo.patch
|
||||
#https://bugzilla.mindrot.org/show_bug.cgi?id=1889
|
||||
Patch6: openssh-5.8p1-packet.patch
|
||||
#https://bugzilla.mindrot.org/show_bug.cgi?id=1890 (WONTFIX) need integration to prng helper
|
||||
Patch7: openssh-5.8p1-entropy.patch
|
||||
#https://bugzilla.mindrot.org/show_bug.cgi?id=1640 (WONTFIX)
|
||||
Patch9: openssh-5.8p1-vendor.patch
|
||||
Patch102: openssh-5.8p1-packet.patch
|
||||
#?
|
||||
Patch103: openssh-5.9p1-2auth.patch
|
||||
|
||||
#https://bugzilla.mindrot.org/show_bug.cgi?id=1402
|
||||
Patch200: openssh-5.8p1-audit0.patch
|
||||
# -"-
|
||||
Patch201: openssh-5.9p1-audit1.patch
|
||||
# -"-
|
||||
Patch202: openssh-5.9p1-audit2.patch
|
||||
# -"-
|
||||
Patch203: openssh-5.9p1-audit3.patch
|
||||
# -"-
|
||||
Patch204: openssh-5.9p1-audit4.patch
|
||||
# -"-
|
||||
Patch205: openssh-5.9p1-audit5.patch
|
||||
|
||||
# --- pam_ssh-agent ---
|
||||
Patch10: pam_ssh_agent_auth-0.9-build.patch
|
||||
Patch11: pam_ssh_agent_auth-0.9.2-seteuid.patch
|
||||
#https://bugzilla.mindrot.org/show_bug.cgi?id=1663
|
||||
Patch20: openssh-5.8p1-authorized-keys-command.patch
|
||||
#?-- unwanted child :(
|
||||
Patch21: openssh-5.8p1-ldap.patch
|
||||
# #-mail-conf
|
||||
# Patch22: openssh-5.8p1-selinux.patch
|
||||
Patch300: pam_ssh_agent_auth-0.9-build.patch
|
||||
Patch301: pam_ssh_agent_auth-0.9.2-seteuid.patch
|
||||
|
||||
#https://bugzilla.mindrot.org/show_bug.cgi?id=1641 (WONTFIX)
|
||||
Patch23: openssh-5.8p1-selinux-role.patch
|
||||
Patch400: openssh-5.9p1-role.patch
|
||||
#?
|
||||
Patch24: openssh-5.8p1-mls.patch
|
||||
# #https://bugzilla.mindrot.org/show_bug.cgi?id=1614
|
||||
# Patch25: openssh-5.6p1-selabel.patch
|
||||
#was https://bugzilla.mindrot.org/show_bug.cgi?id=1637
|
||||
Patch401: openssh-5.9p1-mls.patch
|
||||
#?
|
||||
Patch26: openssh-5.8p1-sftpcontext.patch
|
||||
Patch402: openssh-5.9p1-sftp-chroot.patch
|
||||
|
||||
#https://bugzilla.mindrot.org/show_bug.cgi?id=1663
|
||||
Patch500: openssh-5.9p1-akc.patch
|
||||
#?-- unwanted child :(
|
||||
Patch501: openssh-5.9p1-ldap.patch
|
||||
#?
|
||||
Patch502: openssh-5.9p1-keycat.patch
|
||||
|
||||
#https://bugzilla.mindrot.org/show_bug.cgi?id=1668
|
||||
Patch30: openssh-5.6p1-keygen.patch
|
||||
#https://bugzilla.mindrot.org/show_bug.cgi?id=1644
|
||||
Patch31: openssh-5.2p1-allow-ip-opts.patch
|
||||
Patch600: openssh-5.9p1-keygen.patch
|
||||
#http6://bugzilla.mindrot.org/show_bug.cgi?id=1644
|
||||
Patch601: openssh-5.2p1-allow-ip-opts.patch
|
||||
#https://bugzilla.mindrot.org/show_bug.cgi?id=1701
|
||||
Patch32: openssh-5.8p1-randclean.patch
|
||||
# #https://bugzilla.mindrot.org/show_bug.cgi?id=1636
|
||||
# Patch33: openssh-5.1p1-log-in-chroot.patch
|
||||
Patch602: openssh-5.9p1-randclean.patch
|
||||
#http://cvsweb.netbsd.org/cgi-bin/cvsweb.cgi/src/crypto/dist/ssh/Attic/sftp-glob.c.diff?r1=1.13&r2=1.13.12.1&f=h
|
||||
Patch35: openssh-5.8p1-glob.patch
|
||||
#https://bugzilla.mindrot.org/show_bug.cgi?id=1891
|
||||
Patch36: openssh-5.8p1-pwchange.patch
|
||||
Patch603: openssh-5.8p1-glob.patch
|
||||
#https://bugzilla.mindrot.org/show_bug.cgi?id=1893
|
||||
Patch37: openssh-5.8p1-keyperm.patch
|
||||
#?
|
||||
Patch50: openssh-5.8p1-fips.patch
|
||||
#https://bugzilla.mindrot.org/show_bug.cgi?id=1789
|
||||
Patch51: openssh-5.5p1-x11.patch
|
||||
#?
|
||||
Patch52: openssh-5.6p1-exit-deadlock.patch
|
||||
#?
|
||||
Patch53: openssh-5.1p1-askpass-progress.patch
|
||||
#?
|
||||
Patch54: openssh-4.3p2-askpass-grab-info.patch
|
||||
#?
|
||||
Patch56: openssh-5.2p1-edns.patch
|
||||
#?
|
||||
Patch57: openssh-5.1p1-scp-manpage.patch
|
||||
#?
|
||||
Patch58: openssh-5.8p1-keycat.patch
|
||||
#http://www.sxw.org.uk/computing/patches/openssh.html
|
||||
Patch60: openssh-5.8p1-gsskex.patch
|
||||
#?
|
||||
Patch61: openssh-5.8p1-gssapi-canohost.patch
|
||||
#?
|
||||
Patch62: openssh-5.8p1-localdomain.patch
|
||||
#http://www.mail-archive.com/kerberos@mit.edu/msg17591.html
|
||||
Patch63: openssh-5.8p2-force_krb.patch
|
||||
#https://bugzilla.mindrot.org/show_bug.cgi?id=1780
|
||||
Patch64: openssh-5.8p2-kuserok.patch
|
||||
Patch604: openssh-5.8p1-keyperm.patch
|
||||
#https://bugzilla.mindrot.org/show_bug.cgi?id=1329 (WONTFIX)
|
||||
Patch65: openssh-5.8p2-remove-stale-control-socket.patch
|
||||
Patch605: openssh-5.8p2-remove-stale-control-socket.patch
|
||||
#https://bugzilla.mindrot.org/show_bug.cgi?id=1925
|
||||
Patch66: openssh-5.8p2-ipv6man.patch
|
||||
#https://bugzilla.mindrot.org/show_bug.cgi?id=1919
|
||||
Patch67: openssh-5.8p2-unconfined.patch
|
||||
#https://bugzilla.mindrot.org/show_bug.cgi?id=1924
|
||||
Patch68: openssh-5.8p2-sesftplog.patch
|
||||
Patch606: openssh-5.9p1-ipv6man.patch
|
||||
#?
|
||||
Patch69: openssh-5.8p2-askpass-ld.patch
|
||||
Patch607: openssh-5.8p2-sigpipe.patch
|
||||
#?
|
||||
Patch70: openssh-5.8p2-sigpipe.patch
|
||||
Patch608: openssh-5.8p2-askpass-ld.patch
|
||||
#https://bugzilla.mindrot.org/show_bug.cgi?id=1789
|
||||
Patch609: openssh-5.5p1-x11.patch
|
||||
|
||||
#?
|
||||
Patch700: openssh-5.9p1-fips.patch
|
||||
#?
|
||||
Patch701: openssh-5.6p1-exit-deadlock.patch
|
||||
#?
|
||||
Patch702: openssh-5.1p1-askpass-progress.patch
|
||||
#?
|
||||
Patch703: openssh-4.3p2-askpass-grab-info.patch
|
||||
#?
|
||||
Patch704: openssh-5.2p1-edns.patch
|
||||
#?
|
||||
Patch705: openssh-5.1p1-scp-manpage.patch
|
||||
#?
|
||||
Patch706: openssh-5.8p1-localdomain.patch
|
||||
#https://bugzilla.mindrot.org/show_bug.cgi?id=1635 (WONTFIX)
|
||||
Patch707: openssh-5.9p1-redhat.patch
|
||||
#https://bugzilla.mindrot.org/show_bug.cgi?id=1890 (WONTFIX) need integration to prng helper which is discontinued :)
|
||||
Patch708: openssh-5.9p1-entropy.patch
|
||||
#https://bugzilla.mindrot.org/show_bug.cgi?id=1640 (WONTFIX)
|
||||
Patch709: openssh-5.9p1-vendor.patch
|
||||
|
||||
#http://www.sxw.org.uk/computing/patches/openssh.html
|
||||
Patch800: openssh-5.9p1-gsskex.patch
|
||||
#http://www.mail-archive.com/kerberos@mit.edu/msg17591.html
|
||||
Patch801: openssh-5.8p2-force_krb.patch
|
||||
|
||||
#?
|
||||
Patch900: openssh-5.8p1-gssapi-canohost.patch
|
||||
#https://bugzilla.mindrot.org/show_bug.cgi?id=1780
|
||||
Patch901: openssh-5.9p1-kuserok.patch
|
||||
#---
|
||||
#https://bugzilla.mindrot.org/show_bug.cgi?id=1604
|
||||
# sctp
|
||||
@ -380,66 +382,68 @@ The module is most useful for su and sudo service stacks.
|
||||
%prep
|
||||
%setup -q -a 4
|
||||
#Do not enable by default
|
||||
###%patch99 -p1 -b .wIm
|
||||
###%patch0 -p1 -b .wIm
|
||||
|
||||
%patch0 -p1 -b .redhat
|
||||
%patch100 -p1 -b .fingerprint
|
||||
%patch200 -p1 -b .exit
|
||||
%patch300 -p1 -b .getaddrinfo
|
||||
%patch8 -p1 -b .audit0
|
||||
%patch1 -p1 -b .audit1
|
||||
%patch2 -p1 -b .audit2
|
||||
%patch3 -p1 -b .audit3
|
||||
%patch4 -p1 -b .audit4
|
||||
%patch5 -p1 -b .audit5
|
||||
%patch6 -p1 -b .packet
|
||||
%patch7 -p1 -b .entropy
|
||||
%patch9 -p1 -b .vendor
|
||||
%patch101 -p1 -b .getaddrinfo
|
||||
%patch102 -p1 -b .packet
|
||||
%patch103 -p1 -b .2auth
|
||||
|
||||
%patch200 -p1 -b .audit0
|
||||
%patch201 -p1 -b .audit1
|
||||
%patch202 -p1 -b .audit2
|
||||
%patch203 -p1 -b .audit3
|
||||
%patch204 -p1 -b .audit4
|
||||
%patch205 -p1 -b .audit5
|
||||
|
||||
%if %{pam_ssh_agent}
|
||||
pushd pam_ssh_agent_auth-%{pam_ssh_agent_ver}
|
||||
%patch10 -p1 -b .psaa-build
|
||||
%patch11 -p1 -b .psaa-seteuid
|
||||
%patch300 -p1 -b .psaa-build
|
||||
%patch301 -p1 -b .psaa-seteuid
|
||||
# Remove duplicate headers
|
||||
rm -f $(cat %{SOURCE5})
|
||||
popd
|
||||
%endif
|
||||
%patch20 -p1 -b .akc
|
||||
%if %{ldap}
|
||||
%patch21 -p1 -b .ldap
|
||||
%endif
|
||||
%if %{WITH_SELINUX}
|
||||
#SELinux
|
||||
# %patch22 -p1 -b .selinux
|
||||
%patch23 -p1 -b .role
|
||||
%patch24 -p1 -b .mls
|
||||
%patch26 -p1 -b .sftpcontext
|
||||
%endif
|
||||
%patch30 -p1 -b .keygen
|
||||
%patch31 -p1 -b .ip-opts
|
||||
%patch32 -p1 -b .randclean
|
||||
%patch35 -p1 -b .glob
|
||||
%patch36 -p1 -b .pwchange
|
||||
%patch37 -p1 -b .keyperm
|
||||
|
||||
%patch50 -p1 -b .fips
|
||||
%patch51 -p1 -b .x11
|
||||
%patch52 -p1 -b .exit-deadlock
|
||||
%patch53 -p1 -b .progress
|
||||
%patch54 -p1 -b .grab-info
|
||||
%patch56 -p1 -b .edns
|
||||
%patch57 -p1 -b .manpage
|
||||
%patch58 -p1 -b .keycat
|
||||
%patch60 -p1 -b .gsskex
|
||||
%patch61 -p1 -b .canohost
|
||||
%patch62 -p1 -b .localdomain
|
||||
%patch63 -p1 -b .force_krb
|
||||
%patch64 -p1 -b .kuserok
|
||||
%patch65 -p1 -b .remove_stale
|
||||
%patch66 -p1 -b .ipv6man
|
||||
%patch67 -p1 -b .unconfined
|
||||
%patch68 -p1 -b .sesftplog
|
||||
%patch69 -p1 -b .askpass-ld
|
||||
%patch70 -p1 -b .sigpipe
|
||||
%if %{WITH_SELINUX}
|
||||
%patch400 -p1 -b .role
|
||||
%patch401 -p1 -b .mls
|
||||
%patch402 -p1 -b .sftp-chroot
|
||||
%endif
|
||||
|
||||
%patch500 -p1 -b .akc
|
||||
%if %{ldap}
|
||||
%patch501 -p1 -b .ldap
|
||||
%endif
|
||||
%patch502 -p1 -b .keycat
|
||||
|
||||
%patch600 -p1 -b .keygen
|
||||
%patch601 -p1 -b .ip-opts
|
||||
%patch602 -p1 -b .randclean
|
||||
%patch603 -p1 -b .glob
|
||||
%patch604 -p1 -b .keyperm
|
||||
%patch605 -p1 -b .remove_stale
|
||||
%patch606 -p1 -b .ipv6man
|
||||
%patch607 -p1 -b .sigpipe
|
||||
%patch608 -p1 -b .askpass-ld
|
||||
%patch609 -p1 -b .x11
|
||||
|
||||
%patch700 -p1 -b .fips
|
||||
%patch701 -p1 -b .exit-deadlock
|
||||
%patch702 -p1 -b .progress
|
||||
%patch703 -p1 -b .grab-info
|
||||
%patch704 -p1 -b .edns
|
||||
%patch705 -p1 -b .manpage
|
||||
%patch706 -p1 -b .localdomain
|
||||
%patch707 -p1 -b .redhat
|
||||
%patch708 -p1 -b .entropy
|
||||
%patch709 -p1 -b .vendor
|
||||
|
||||
%patch800 -p1 -b .gsskex
|
||||
%patch801 -p1 -b .force_krb
|
||||
|
||||
%patch900 -p1 -b .canohost
|
||||
%patch901 -p1 -b .kuserok
|
||||
|
||||
autoreconf
|
||||
pushd pam_ssh_agent_auth-%{pam_ssh_agent_ver}
|
||||
@ -675,7 +679,7 @@ fi
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
%doc CREDITS ChangeLog INSTALL LICENCE OVERVIEW PROTOCOL* README README.platform README.privsep README.tun README.dns TODO WARNING*
|
||||
%doc CREDITS ChangeLog INSTALL LICENCE OVERVIEW PROTOCOL* README README.platform README.privsep README.tun README.dns TODO
|
||||
%attr(0755,root,root) %dir %{_sysconfdir}/ssh
|
||||
%attr(0600,root,root) %config(noreplace) %{_sysconfdir}/ssh/moduli
|
||||
%if ! %{rescue}
|
||||
|
Loading…
Reference in New Issue
Block a user