Compare commits
146 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
93af84c40a | ||
|
|
17373deae6 | ||
|
|
261508c76c | ||
|
|
ab8e6d64cd | ||
|
|
dff7de33ab | ||
|
|
6a6b9524b2 | ||
|
|
4205fcb944 | ||
|
|
beffeababd | ||
|
|
850caa568b | ||
|
|
6f3daee4f0 | ||
|
|
3c2a11925b | ||
|
|
9e253dc61c |
||
|
|
06032544b5 | ||
|
|
480372390c | ||
|
|
c81b691d2c | ||
|
|
f463dc835a | ||
|
|
75b18e250a | ||
|
|
0c7244d48f | ||
|
|
85175e1ba2 | ||
|
|
8ba66847e4 | ||
|
|
bd16300680 | ||
|
|
ed01b0a2c5 | ||
|
|
3e94785b28 | ||
|
|
4a1597c64d | ||
|
|
76c16c6e5a | ||
|
|
78f4185f33 | ||
|
|
5b20a7546c | ||
|
|
c0e4707d7b | ||
|
|
0172aacf0a | ||
|
|
b26b3e1a8b | ||
|
|
1b534648ec | ||
|
|
b6fce45c3e | ||
|
|
f21cbd932c | ||
|
|
4e50d957c8 | ||
|
|
82ba7b5b8b | ||
|
|
06837d883b | ||
|
|
a8b9dae4de | ||
|
|
05c1b1980c | ||
|
|
66cc7b96c8 | ||
|
|
3c863da50a | ||
|
|
f49266f739 | ||
|
|
9e07719d88 | ||
|
|
4dc1dfc111 | ||
|
|
6960e6c5d7 | ||
|
|
5d089cb67f | ||
|
|
568625900e | ||
|
|
d614a17ecd | ||
|
|
e6eac867a9 | ||
|
|
757dff8637 | ||
|
|
3b5263e189 | ||
|
|
24087bf920 | ||
|
|
152f5ddac3 | ||
|
|
d482358b18 | ||
|
|
b7578f68fd | ||
|
|
b77bb495c7 | ||
|
|
01d6be4f82 | ||
|
|
02fff16642 | ||
|
|
409dc9ed62 | ||
|
|
79afa4b64a | ||
|
|
acf84ac51a | ||
|
|
e920d28c57 | ||
|
|
4713fab392 | ||
|
|
3e49e59ef4 | ||
|
|
c2b8146adc | ||
|
|
9549c46d29 | ||
|
|
2469144c2d | ||
|
|
03327bb7c3 | ||
|
|
abde90a9cb | ||
|
|
f67408c45e | ||
|
|
db99f0a0e6 | ||
|
|
15b86ea960 | ||
|
|
7ea48e01a0 | ||
|
|
b9cd944358 | ||
|
|
678fe5c83c | ||
|
|
aa3c245244 | ||
|
|
f25f213974 | ||
|
|
a7d5063016 | ||
|
|
515c95fb14 | ||
|
|
ae75c3d4f7 | ||
|
|
f09e89f05d | ||
|
|
bd3d327c9a | ||
|
|
460eae6bd4 | ||
|
|
b3988fbe66 |
||
|
|
f0dc592cfc | ||
|
|
afffcadde3 | ||
|
|
5923b7b936 | ||
|
|
50a1d2c054 | ||
|
|
f751fba9b3 | ||
|
|
db96e2a44d | ||
|
|
9975263d7c | ||
|
|
e4f9d53906 | ||
|
|
33eb081b60 | ||
|
|
586f2ba02d |
||
|
|
ea308e0d4c | ||
|
|
2763d0178d | ||
|
|
c6a932d446 | ||
|
|
076d654b20 | ||
|
|
261e529a3e |
||
|
|
c99ce4eacc | ||
|
|
01510d75b6 | ||
|
|
3e0625ed70 | ||
|
|
c7d42e73db | ||
|
|
2f685df7e6 | ||
|
|
b297717538 | ||
|
|
f080e94f93 | ||
|
|
9246721f0b | ||
|
|
f249377320 | ||
|
|
fba2e4ad34 | ||
|
|
4d141e4d08 | ||
|
|
a3ffcc1efa | ||
|
|
6995654e64 | ||
|
|
1f8a82b0c7 | ||
|
|
25f492eb24 | ||
|
|
8c517cb8d1 | ||
|
|
da02042fe2 | ||
|
|
a0915d8c5e | ||
|
|
0bd6bf86e4 | ||
|
|
1ad3d9f343 | ||
|
|
8c873b6826 | ||
|
|
7ecf78753c | ||
|
|
5fd763c594 | ||
|
|
873d1aca80 | ||
|
|
845bd874e8 | ||
|
|
1d944e946b | ||
|
|
414c76f112 | ||
|
|
9eea03bdb0 | ||
|
|
d8907457dc | ||
|
|
adf76a364f | ||
|
|
e3fc8ce78b | ||
|
|
ae3d65d08a | ||
|
|
b6360055e2 | ||
|
|
e2d7866367 | ||
|
|
c93878a6e6 | ||
|
|
00e17c136b | ||
|
|
bb89cad94f | ||
|
|
b88dcfd523 | ||
|
|
04aef646ab | ||
|
|
17725e15da | ||
|
|
300c081db2 | ||
|
|
b5761e5d23 | ||
|
|
913439ce70 | ||
|
|
0670469f97 | ||
|
|
0ae19bf766 | ||
|
|
a60f428d3d | ||
|
|
0823728727 | ||
|
|
36e3247d20 |
105 changed files with 37211 additions and 15936 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -1,2 +1,4 @@
|
|||
/*.tar.bz2
|
||||
/*.tar.gz
|
||||
/*.tar.gz.asc
|
||||
/*.gpg
|
||||
|
|
|
|||
912
0001-openssh-7.8p1-role-mls.patch
Normal file
912
0001-openssh-7.8p1-role-mls.patch
Normal file
|
|
@ -0,0 +1,912 @@
|
|||
From 95f4e30195382c3df7104c2ad3e5e9953f8ad554 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:28 +0200
|
||||
Subject: [PATCH 01/50] openssh-7.8p1-role-mls
|
||||
|
||||
---
|
||||
auth-pam.c | 2 +-
|
||||
auth-pam.h | 2 +-
|
||||
auth.h | 3 +
|
||||
auth2-gss.c | 11 +-
|
||||
auth2-hostbased.c | 9 +
|
||||
auth2-pubkey.c | 11 +-
|
||||
auth2.c | 14 ++
|
||||
misc.c | 8 +
|
||||
monitor.c | 37 ++-
|
||||
monitor.h | 4 +
|
||||
monitor_wrap.c | 21 ++
|
||||
monitor_wrap.h | 3 +
|
||||
openbsd-compat/Makefile.in | 3 +-
|
||||
openbsd-compat/port-linux-sshd.c | 420 +++++++++++++++++++++++++++++++
|
||||
openbsd-compat/port-linux.c | 37 +--
|
||||
openbsd-compat/port-linux.h | 3 +-
|
||||
platform.c | 2 +-
|
||||
sshd-session.c | 3 +
|
||||
18 files changed, 551 insertions(+), 42 deletions(-)
|
||||
create mode 100644 openbsd-compat/port-linux-sshd.c
|
||||
|
||||
diff --git a/auth-pam.c b/auth-pam.c
|
||||
index 13c0a792..b4100ea1 100644
|
||||
--- a/auth-pam.c
|
||||
+++ b/auth-pam.c
|
||||
@@ -1238,7 +1238,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;
|
||||
char *compound;
|
||||
diff --git a/auth-pam.h b/auth-pam.h
|
||||
index 8d801c68..9dd7ae07 100644
|
||||
--- a/auth-pam.h
|
||||
+++ b/auth-pam.h
|
||||
@@ -33,7 +33,7 @@ u_int do_pam_account(void);
|
||||
void do_pam_session(struct ssh *);
|
||||
void do_pam_setcred(void);
|
||||
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 --git a/auth.h b/auth.h
|
||||
index 98bb23d4..83d07ae8 100644
|
||||
--- a/auth.h
|
||||
+++ b/auth.h
|
||||
@@ -65,6 +65,9 @@ struct Authctxt {
|
||||
char *service;
|
||||
struct passwd *pw; /* set if 'valid' */
|
||||
char *style;
|
||||
+#ifdef WITH_SELINUX
|
||||
+ char *role;
|
||||
+#endif
|
||||
|
||||
/* Method lists for multiple authentication */
|
||||
char **auth_methods; /* modified from server config */
|
||||
diff --git a/auth2-gss.c b/auth2-gss.c
|
||||
index 75eb4e3a..f7898ab3 100644
|
||||
--- a/auth2-gss.c
|
||||
+++ b/auth2-gss.c
|
||||
@@ -284,6 +284,7 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh)
|
||||
Authctxt *authctxt = ssh->authctxt;
|
||||
Gssctxt *gssctxt;
|
||||
int r, authenticated = 0;
|
||||
+ char *micuser;
|
||||
struct sshbuf *b;
|
||||
gss_buffer_desc mic, gssbuf;
|
||||
u_char *p;
|
||||
@@ -300,7 +301,13 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh)
|
||||
fatal_f("sshbuf_new failed");
|
||||
mic.value = p;
|
||||
mic.length = len;
|
||||
- ssh_gssapi_buildmic(b, authctxt->user, authctxt->service,
|
||||
+#ifdef WITH_SELINUX
|
||||
+ if (authctxt->role && authctxt->role[0] != 0)
|
||||
+ xasprintf(&micuser, "%s/%s", authctxt->user, authctxt->role);
|
||||
+ else
|
||||
+#endif
|
||||
+ micuser = authctxt->user;
|
||||
+ ssh_gssapi_buildmic(b, micuser, authctxt->service,
|
||||
"gssapi-with-mic", ssh->kex->session_id);
|
||||
|
||||
if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL)
|
||||
@@ -313,6 +320,8 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh)
|
||||
logit("GSSAPI MIC check failed");
|
||||
|
||||
sshbuf_free(b);
|
||||
+ if (micuser != authctxt->user)
|
||||
+ free(micuser);
|
||||
free(mic.value);
|
||||
|
||||
authctxt->postponed = 0;
|
||||
diff --git a/auth2-hostbased.c b/auth2-hostbased.c
|
||||
index eb21479a..a3be6e49 100644
|
||||
--- a/auth2-hostbased.c
|
||||
+++ b/auth2-hostbased.c
|
||||
@@ -129,7 +129,16 @@ userauth_hostbased(struct ssh *ssh, const char *method)
|
||||
/* reconstruct packet */
|
||||
if ((r = sshbuf_put_stringb(b, ssh->kex->session_id)) != 0 ||
|
||||
(r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
|
||||
+#ifdef WITH_SELINUX
|
||||
+ (authctxt->role
|
||||
+ ? ( (r = sshbuf_put_u32(b, strlen(authctxt->user)+strlen(authctxt->role)+1)) != 0 ||
|
||||
+ (r = sshbuf_put(b, authctxt->user, strlen(authctxt->user))) != 0 ||
|
||||
+ (r = sshbuf_put_u8(b, '/') != 0) ||
|
||||
+ (r = sshbuf_put(b, authctxt->role, strlen(authctxt->role))) != 0)
|
||||
+ : (r = sshbuf_put_cstring(b, authctxt->user)) != 0) ||
|
||||
+#else
|
||||
(r = sshbuf_put_cstring(b, authctxt->user)) != 0 ||
|
||||
+#endif
|
||||
(r = sshbuf_put_cstring(b, authctxt->service)) != 0 ||
|
||||
(r = sshbuf_put_cstring(b, method)) != 0 ||
|
||||
(r = sshbuf_put_string(b, pkalg, alen)) != 0 ||
|
||||
diff --git a/auth2-pubkey.c b/auth2-pubkey.c
|
||||
index aa24fda0..267a27d2 100644
|
||||
--- a/auth2-pubkey.c
|
||||
+++ b/auth2-pubkey.c
|
||||
@@ -206,9 +206,16 @@ userauth_pubkey(struct ssh *ssh, const char *method)
|
||||
goto done;
|
||||
}
|
||||
/* reconstruct packet */
|
||||
- xasprintf(&userstyle, "%s%s%s", authctxt->user,
|
||||
+ xasprintf(&userstyle, "%s%s%s%s%s", authctxt->user,
|
||||
authctxt->style ? ":" : "",
|
||||
- authctxt->style ? authctxt->style : "");
|
||||
+ authctxt->style ? authctxt->style : "",
|
||||
+#ifdef WITH_SELINUX
|
||||
+ authctxt->role ? "/" : "",
|
||||
+ authctxt->role ? authctxt->role : ""
|
||||
+#else
|
||||
+ "", ""
|
||||
+#endif
|
||||
+ );
|
||||
if ((r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
|
||||
(r = sshbuf_put_cstring(b, userstyle)) != 0 ||
|
||||
(r = sshbuf_put_cstring(b, authctxt->service)) != 0 ||
|
||||
diff --git a/auth2.c b/auth2.c
|
||||
index 82f6e621..5ba45c12 100644
|
||||
--- a/auth2.c
|
||||
+++ b/auth2.c
|
||||
@@ -271,6 +271,9 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
|
||||
Authctxt *authctxt = ssh->authctxt;
|
||||
Authmethod *m = NULL;
|
||||
char *user = NULL, *service = NULL, *method = NULL, *style = NULL;
|
||||
+#ifdef WITH_SELINUX
|
||||
+ char *role = NULL;
|
||||
+#endif
|
||||
int r, authenticated = 0;
|
||||
double tstart = monotime_double();
|
||||
|
||||
@@ -284,6 +287,11 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
|
||||
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;
|
||||
|
||||
@@ -313,7 +321,13 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
|
||||
setproctitle("%s [net]", authctxt->valid ? user : "unknown");
|
||||
authctxt->service = xstrdup(service);
|
||||
authctxt->style = style ? xstrdup(style) : NULL;
|
||||
+#ifdef WITH_SELINUX
|
||||
+ authctxt->role = role ? xstrdup(role) : NULL;
|
||||
+#endif
|
||||
mm_inform_authserv(service, style);
|
||||
+#ifdef WITH_SELINUX
|
||||
+ mm_inform_authrole(role);
|
||||
+#endif
|
||||
userauth_banner(ssh);
|
||||
if ((r = kex_server_update_ext_info(ssh)) != 0)
|
||||
fatal_fr(r, "kex_server_update_ext_info failed");
|
||||
diff --git a/misc.c b/misc.c
|
||||
index dd0bd032..c932f9bb 100644
|
||||
--- a/misc.c
|
||||
+++ b/misc.c
|
||||
@@ -806,6 +806,7 @@ char *
|
||||
colon(char *cp)
|
||||
{
|
||||
int flag = 0;
|
||||
+ int start = 1;
|
||||
|
||||
if (*cp == ':') /* Leading colon is part of file name. */
|
||||
return NULL;
|
||||
@@ -821,6 +822,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 --git a/monitor.c b/monitor.c
|
||||
index 2179553d..02b3eaaa 100644
|
||||
--- a/monitor.c
|
||||
+++ b/monitor.c
|
||||
@@ -120,6 +120,9 @@ int mm_answer_sign(struct ssh *, int, struct sshbuf *);
|
||||
int mm_answer_pwnamallow(struct ssh *, int, struct sshbuf *);
|
||||
int mm_answer_auth2_read_banner(struct ssh *, int, struct sshbuf *);
|
||||
int mm_answer_authserv(struct ssh *, int, struct sshbuf *);
|
||||
+#ifdef WITH_SELINUX
|
||||
+int mm_answer_authrole(struct ssh *, int, struct sshbuf *);
|
||||
+#endif
|
||||
int mm_answer_authpassword(struct ssh *, int, struct sshbuf *);
|
||||
int mm_answer_bsdauthquery(struct ssh *, int, struct sshbuf *);
|
||||
int mm_answer_bsdauthrespond(struct ssh *, int, struct sshbuf *);
|
||||
@@ -194,6 +197,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
|
||||
@@ -912,6 +918,9 @@ mm_answer_pwnamallow(struct ssh *ssh, int sock, struct sshbuf *m)
|
||||
|
||||
/* 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
|
||||
@@ -986,6 +995,26 @@ key_base_type_match(const char *method, const struct sshkey *key,
|
||||
return found;
|
||||
}
|
||||
|
||||
+#ifdef WITH_SELINUX
|
||||
+int
|
||||
+mm_answer_authrole(struct ssh *ssh, int sock, struct sshbuf *m)
|
||||
+{
|
||||
+ int r;
|
||||
+ monitor_permit_authentications(1);
|
||||
+
|
||||
+ if ((r = sshbuf_get_cstring(m, &authctxt->role, NULL)) != 0)
|
||||
+ fatal_f("buffer error: %s", ssh_err(r));
|
||||
+ debug3_f("role=%s", authctxt->role);
|
||||
+
|
||||
+ if (strlen(authctxt->role) == 0) {
|
||||
+ free(authctxt->role);
|
||||
+ authctxt->role = NULL;
|
||||
+ }
|
||||
+
|
||||
+ return (0);
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
int
|
||||
mm_answer_authpassword(struct ssh *ssh, int sock, struct sshbuf *m)
|
||||
{
|
||||
@@ -1358,7 +1387,7 @@ monitor_valid_userblob(struct ssh *ssh, const u_char *data, u_int datalen)
|
||||
struct sshbuf *b;
|
||||
struct sshkey *hostkey = NULL;
|
||||
const u_char *p;
|
||||
- char *userstyle, *cp;
|
||||
+ char *userstyle, *s, *cp;
|
||||
size_t len;
|
||||
u_char type;
|
||||
int hostbound = 0, r, fail = 0;
|
||||
@@ -1389,6 +1418,8 @@ monitor_valid_userblob(struct ssh *ssh, const u_char *data, u_int datalen)
|
||||
fail++;
|
||||
if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0)
|
||||
fatal_fr(r, "parse userstyle");
|
||||
+ if ((s = strchr(cp, '/')) != NULL)
|
||||
+ *s = '\0';
|
||||
xasprintf(&userstyle, "%s%s%s", authctxt->user,
|
||||
authctxt->style ? ":" : "",
|
||||
authctxt->style ? authctxt->style : "");
|
||||
@@ -1439,7 +1470,7 @@ monitor_valid_hostbasedblob(const u_char *data, u_int datalen,
|
||||
{
|
||||
struct sshbuf *b;
|
||||
const u_char *p;
|
||||
- char *cp, *userstyle;
|
||||
+ char *cp, *s, *userstyle;
|
||||
size_t len;
|
||||
int r, fail = 0;
|
||||
u_char type;
|
||||
@@ -1460,6 +1491,8 @@ monitor_valid_hostbasedblob(const u_char *data, u_int datalen,
|
||||
fail++;
|
||||
if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0)
|
||||
fatal_fr(r, "parse userstyle");
|
||||
+ if ((s = strchr(cp, '/')) != NULL)
|
||||
+ *s = '\0';
|
||||
xasprintf(&userstyle, "%s%s%s", authctxt->user,
|
||||
authctxt->style ? ":" : "",
|
||||
authctxt->style ? authctxt->style : "");
|
||||
diff --git a/monitor.h b/monitor.h
|
||||
index 3f8a9bea..9dcd9c29 100644
|
||||
--- a/monitor.h
|
||||
+++ b/monitor.h
|
||||
@@ -56,6 +56,10 @@ enum monitor_reqtype {
|
||||
MONITOR_REQ_TERM = 50,
|
||||
MONITOR_REQ_STATE = 51, MONITOR_ANS_STATE = 52,
|
||||
|
||||
+#ifdef WITH_SELINUX
|
||||
+ MONITOR_REQ_AUTHROLE = 80,
|
||||
+#endif
|
||||
+
|
||||
MONITOR_REQ_PAM_START = 100,
|
||||
MONITOR_REQ_PAM_ACCOUNT = 102, MONITOR_ANS_PAM_ACCOUNT = 103,
|
||||
MONITOR_REQ_PAM_INIT_CTX = 104, MONITOR_ANS_PAM_INIT_CTX = 105,
|
||||
diff --git a/monitor_wrap.c b/monitor_wrap.c
|
||||
index bd900b2f..ef3ab1b1 100644
|
||||
--- a/monitor_wrap.c
|
||||
+++ b/monitor_wrap.c
|
||||
@@ -442,6 +442,27 @@ mm_inform_authserv(char *service, char *style)
|
||||
sshbuf_free(m);
|
||||
}
|
||||
|
||||
+/* Inform the privileged process about role */
|
||||
+
|
||||
+#ifdef WITH_SELINUX
|
||||
+void
|
||||
+mm_inform_authrole(char *role)
|
||||
+{
|
||||
+ int r;
|
||||
+ struct sshbuf *m;
|
||||
+
|
||||
+ debug3_f("entering");
|
||||
+
|
||||
+ if ((m = sshbuf_new()) == NULL)
|
||||
+ fatal_f("sshbuf_new failed");
|
||||
+ if ((r = sshbuf_put_cstring(m, role ? role : "")) != 0)
|
||||
+ fatal_f("buffer error: %s", ssh_err(r));
|
||||
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHROLE, m);
|
||||
+
|
||||
+ sshbuf_free(m);
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
/* Do the password authentication */
|
||||
int
|
||||
mm_auth_password(struct ssh *ssh, char *password)
|
||||
diff --git a/monitor_wrap.h b/monitor_wrap.h
|
||||
index 7134afee..38a280c8 100644
|
||||
--- a/monitor_wrap.h
|
||||
+++ b/monitor_wrap.h
|
||||
@@ -46,6 +46,9 @@ int mm_sshkey_sign(struct ssh *, struct sshkey *, u_char **, size_t *,
|
||||
const u_char *, size_t, const char *, const char *,
|
||||
const char *, u_int compat);
|
||||
void mm_inform_authserv(char *, char *);
|
||||
+#ifdef WITH_SELINUX
|
||||
+void mm_inform_authrole(char *);
|
||||
+#endif
|
||||
struct passwd *mm_getpwnamallow(struct ssh *, const char *);
|
||||
char *mm_auth2_read_banner(void);
|
||||
int mm_auth_password(struct ssh *, char *);
|
||||
diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in
|
||||
index 1d549954..78e6fa5b 100644
|
||||
--- a/openbsd-compat/Makefile.in
|
||||
+++ b/openbsd-compat/Makefile.in
|
||||
@@ -100,7 +100,8 @@ PORTS= port-aix.o \
|
||||
port-prngd.o \
|
||||
port-solaris.o \
|
||||
port-net.o \
|
||||
- port-uw.o
|
||||
+ port-uw.o \
|
||||
+ port-linux-sshd.o
|
||||
|
||||
.c.o:
|
||||
$(CC) $(CFLAGS_NOPIE) $(PICFLAG) $(CPPFLAGS) -c $<
|
||||
diff --git a/openbsd-compat/port-linux-sshd.c b/openbsd-compat/port-linux-sshd.c
|
||||
new file mode 100644
|
||||
index 00000000..b9fbe38b
|
||||
--- /dev/null
|
||||
+++ b/openbsd-compat/port-linux-sshd.c
|
||||
@@ -0,0 +1,420 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2005 Daniel Walsh <dwalsh@redhat.com>
|
||||
+ * Copyright (c) 2014 Petr Lautrbach <plautrba@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 - just SELinux support for sshd 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 <stdlib.h>
|
||||
+
|
||||
+#include "log.h"
|
||||
+#include "xmalloc.h"
|
||||
+#include "misc.h" /* servconf.h needs misc.h for struct ForwardOptions */
|
||||
+#include "servconf.h"
|
||||
+#include "port-linux.h"
|
||||
+#include "sshkey.h"
|
||||
+#include "hostfile.h"
|
||||
+#include "auth.h"
|
||||
+
|
||||
+#ifdef WITH_SELINUX
|
||||
+#include <selinux/selinux.h>
|
||||
+#include <selinux/context.h>
|
||||
+#include <selinux/get_context_list.h>
|
||||
+#include <selinux/get_default_type.h>
|
||||
+
|
||||
+#ifdef HAVE_LINUX_AUDIT
|
||||
+#include <libaudit.h>
|
||||
+#include <unistd.h>
|
||||
+#endif
|
||||
+
|
||||
+extern ServerOptions options;
|
||||
+extern Authctxt *the_authctxt;
|
||||
+extern int inetd_flag;
|
||||
+
|
||||
+/* Send audit message */
|
||||
+static int
|
||||
+sshd_selinux_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;
|
||||
+ access_vector_t bit;
|
||||
+ security_class_t class;
|
||||
+
|
||||
+ debug_f("src:%s dst:%s", src, dst);
|
||||
+ class = string_to_security_class("context");
|
||||
+ if (!class) {
|
||||
+ error("string_to_security_class failed to translate security class context");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ bit = string_to_av_perm(class, "contains");
|
||||
+ if (!bit) {
|
||||
+ error("string_to_av_perm failed to translate av perm contains");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ retval = security_compute_av(src, dst, class, 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)
|
||||
+{
|
||||
+ *role = NULL;
|
||||
+ *level = NULL;
|
||||
+ if (the_authctxt) {
|
||||
+ if (the_authctxt->role != NULL) {
|
||||
+ char *slash;
|
||||
+ *role = xstrdup(the_authctxt->role);
|
||||
+ if ((slash = strchr(*role, '/')) != NULL) {
|
||||
+ *slash = '\0';
|
||||
+ *level = slash + 1;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* Return the default security context for the given username */
|
||||
+static int
|
||||
+sshd_selinux_getctxbyname(char *pwname,
|
||||
+ security_context_t *default_sc, security_context_t *user_sc)
|
||||
+{
|
||||
+ char *sename, *lvl;
|
||||
+ char *role;
|
||||
+ const char *reqlvl;
|
||||
+ int r = 0;
|
||||
+ context_t con = NULL;
|
||||
+
|
||||
+ ssh_selinux_get_role_level(&role, &reqlvl);
|
||||
+
|
||||
+#ifdef HAVE_GETSEUSERBYNAME
|
||||
+ if ((r=getseuserbyname(pwname, &sename, &lvl)) != 0) {
|
||||
+ sename = NULL;
|
||||
+ lvl = NULL;
|
||||
+ }
|
||||
+#else
|
||||
+ sename = pwname;
|
||||
+ lvl = "";
|
||||
+#endif
|
||||
+
|
||||
+ if (r == 0) {
|
||||
+#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
|
||||
+ r = get_default_context_with_level(sename, lvl, NULL, default_sc);
|
||||
+#else
|
||||
+ r = get_default_context(sename, NULL, default_sc);
|
||||
+#endif
|
||||
+ }
|
||||
+
|
||||
+ if (r == 0) {
|
||||
+ /* If launched from xinetd, we must use current level */
|
||||
+ if (inetd_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_f("current connection level '%s'", 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_f("Failed to get default SELinux security "
|
||||
+ "context for %s", pwname);
|
||||
+ }
|
||||
+
|
||||
+#ifdef HAVE_GETSEUSERBYNAME
|
||||
+ free(sename);
|
||||
+ free(lvl);
|
||||
+#endif
|
||||
+
|
||||
+ if (role != NULL)
|
||||
+ free(role);
|
||||
+ if (con)
|
||||
+ context_free(con);
|
||||
+
|
||||
+ return (r);
|
||||
+}
|
||||
+
|
||||
+/* Setup environment variables for pam_selinux */
|
||||
+static int
|
||||
+sshd_selinux_setup_pam_variables(void)
|
||||
+{
|
||||
+ const char *reqlvl;
|
||||
+ char *role;
|
||||
+ char *use_current;
|
||||
+ int rv;
|
||||
+
|
||||
+ debug3_f("setting execution context");
|
||||
+
|
||||
+ ssh_selinux_get_role_level(&role, &reqlvl);
|
||||
+
|
||||
+ rv = do_pam_putenv("SELINUX_ROLE_REQUESTED", role ? role : "");
|
||||
+
|
||||
+ if (inetd_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)
|
||||
+ free(role);
|
||||
+
|
||||
+ return rv;
|
||||
+}
|
||||
+
|
||||
+/* Set the execution context to the default for the specified user */
|
||||
+void
|
||||
+sshd_selinux_setup_exec_context(char *pwname)
|
||||
+{
|
||||
+ security_context_t user_ctx = NULL;
|
||||
+ int r = 0;
|
||||
+ security_context_t default_ctx = NULL;
|
||||
+
|
||||
+ if (!ssh_selinux_enabled())
|
||||
+ return;
|
||||
+
|
||||
+ if (options.use_pam) {
|
||||
+ /* do not compute context, just setup environment for pam_selinux */
|
||||
+ if (sshd_selinux_setup_pam_variables()) {
|
||||
+ switch (security_getenforce()) {
|
||||
+ case -1:
|
||||
+ fatal_f("security_getenforce() failed");
|
||||
+ case 0:
|
||||
+ error_f("SELinux PAM variable setup failure. Continuing in permissive mode.");
|
||||
+ break;
|
||||
+ default:
|
||||
+ fatal_f("SELinux PAM variable setup failure. Aborting connection.");
|
||||
+ }
|
||||
+ }
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ debug3_f("setting execution context");
|
||||
+
|
||||
+ r = sshd_selinux_getctxbyname(pwname, &default_ctx, &user_ctx);
|
||||
+ if (r >= 0) {
|
||||
+ r = setexeccon(user_ctx);
|
||||
+ if (r < 0) {
|
||||
+ error_f("Failed to set SELinux execution context %s for %s",
|
||||
+ user_ctx, pwname);
|
||||
+ }
|
||||
+#ifdef HAVE_SETKEYCREATECON
|
||||
+ else if (setkeycreatecon(user_ctx) < 0) {
|
||||
+ error_f("Failed to set SELinux keyring creation context %s for %s",
|
||||
+ 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 */
|
||||
+ sshd_selinux_send_audit_message(r >= 0, default_ctx, user_ctx);
|
||||
+ }
|
||||
+ if (r < 0) {
|
||||
+ switch (security_getenforce()) {
|
||||
+ case -1:
|
||||
+ fatal_f("security_getenforce() failed");
|
||||
+ case 0:
|
||||
+ error_f("ELinux failure. Continuing in permissive mode.");
|
||||
+ break;
|
||||
+ default:
|
||||
+ fatal_f("SELinux failure. Aborting connection.");
|
||||
+ }
|
||||
+ }
|
||||
+ if (user_ctx != NULL && user_ctx != default_ctx)
|
||||
+ freecon(user_ctx);
|
||||
+ if (default_ctx != NULL)
|
||||
+ freecon(default_ctx);
|
||||
+
|
||||
+ debug3_f("done");
|
||||
+}
|
||||
+
|
||||
+#endif
|
||||
+#endif
|
||||
+
|
||||
diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c
|
||||
index c1d54f38..7426f6f7 100644
|
||||
--- a/openbsd-compat/port-linux.c
|
||||
+++ b/openbsd-compat/port-linux.c
|
||||
@@ -109,37 +109,6 @@ ssh_selinux_getctxbyname(char *pwname)
|
||||
return sc;
|
||||
}
|
||||
|
||||
-/* Set the execution context to the default for the specified user */
|
||||
-void
|
||||
-ssh_selinux_setup_exec_context(char *pwname)
|
||||
-{
|
||||
- char *user_ctx = NULL;
|
||||
-
|
||||
- if (!ssh_selinux_enabled())
|
||||
- return;
|
||||
-
|
||||
- debug3("%s: setting execution context", __func__);
|
||||
-
|
||||
- user_ctx = ssh_selinux_getctxbyname(pwname);
|
||||
- if (setexeccon(user_ctx) != 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);
|
||||
- break;
|
||||
- default:
|
||||
- fatal("%s: Failed to set SELinux execution context "
|
||||
- "for %s (in enforcing mode)", __func__, pwname);
|
||||
- }
|
||||
- }
|
||||
- if (user_ctx != NULL)
|
||||
- freecon(user_ctx);
|
||||
-
|
||||
- debug3("%s: done", __func__);
|
||||
-}
|
||||
-
|
||||
/* Set the TTY context for the specified user */
|
||||
void
|
||||
ssh_selinux_setup_pty(char *pwname, const char *tty)
|
||||
@@ -152,7 +121,11 @@ ssh_selinux_setup_pty(char *pwname, const char *tty)
|
||||
|
||||
debug3("%s: setting TTY context on %s", __func__, tty);
|
||||
|
||||
- user_ctx = ssh_selinux_getctxbyname(pwname);
|
||||
+ if (getexeccon(&user_ctx) != 0) {
|
||||
+ error_f("getexeccon: %s", strerror(errno));
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
|
||||
/* XXX: should these calls fatal() upon failure in enforcing mode? */
|
||||
|
||||
diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h
|
||||
index 959430de..055c825e 100644
|
||||
--- a/openbsd-compat/port-linux.h
|
||||
+++ b/openbsd-compat/port-linux.h
|
||||
@@ -20,9 +20,10 @@
|
||||
#ifdef WITH_SELINUX
|
||||
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_setfscreatecon(const char *);
|
||||
+
|
||||
+void sshd_selinux_setup_exec_context(char *);
|
||||
#endif
|
||||
|
||||
#ifdef LINUX_OOM_ADJUST
|
||||
diff --git a/platform.c b/platform.c
|
||||
index 4c4fe57e..1bfb4bea 100644
|
||||
--- a/platform.c
|
||||
+++ b/platform.c
|
||||
@@ -140,7 +140,7 @@ platform_setusercontext_post_groups(struct passwd *pw)
|
||||
}
|
||||
#endif /* HAVE_SETPCRED */
|
||||
#ifdef WITH_SELINUX
|
||||
- ssh_selinux_setup_exec_context(pw->pw_name);
|
||||
+ sshd_selinux_setup_exec_context(pw->pw_name);
|
||||
#endif
|
||||
}
|
||||
|
||||
diff --git a/sshd-session.c b/sshd-session.c
|
||||
index c64eb29f..74d2cbc7 100644
|
||||
--- a/sshd-session.c
|
||||
+++ b/sshd-session.c
|
||||
@@ -1328,6 +1328,9 @@ main(int ac, char **av)
|
||||
restore_uid();
|
||||
}
|
||||
#endif
|
||||
+#ifdef WITH_SELINUX
|
||||
+ sshd_selinux_setup_exec_context(authctxt->pw->pw_name);
|
||||
+#endif
|
||||
#ifdef USE_PAM
|
||||
if (options.use_pam) {
|
||||
do_pam_setcred();
|
||||
--
|
||||
2.49.0
|
||||
|
||||
144
0002-openssh-6.6p1-privsep-selinux.patch
Normal file
144
0002-openssh-6.6p1-privsep-selinux.patch
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
From 99d8e250514023d3b88a1c9eb724c4898aba9827 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:28 +0200
|
||||
Subject: [PATCH 02/50] openssh-6.6p1-privsep-selinux
|
||||
|
||||
---
|
||||
openbsd-compat/port-linux-sshd.c | 22 ++++++++++++++++++++++
|
||||
openbsd-compat/port-linux.h | 1 +
|
||||
session.c | 16 +++++++++-------
|
||||
sshd-auth.c | 4 ++++
|
||||
sshd-session.c | 2 +-
|
||||
5 files changed, 37 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/openbsd-compat/port-linux-sshd.c b/openbsd-compat/port-linux-sshd.c
|
||||
index b9fbe38b..dfafc622 100644
|
||||
--- a/openbsd-compat/port-linux-sshd.c
|
||||
+++ b/openbsd-compat/port-linux-sshd.c
|
||||
@@ -415,6 +415,28 @@ sshd_selinux_setup_exec_context(char *pwname)
|
||||
debug3_f("done");
|
||||
}
|
||||
|
||||
+void
|
||||
+sshd_selinux_copy_context(void)
|
||||
+{
|
||||
+ security_context_t *ctx;
|
||||
+
|
||||
+ if (!ssh_selinux_enabled())
|
||||
+ return;
|
||||
+
|
||||
+ if (getexeccon((security_context_t *)&ctx) != 0) {
|
||||
+ logit_f("getexeccon failed with %s", strerror(errno));
|
||||
+ return;
|
||||
+ }
|
||||
+ if (ctx != NULL) {
|
||||
+ /* unset exec context before we will lose this capabililty */
|
||||
+ if (setexeccon(NULL) != 0)
|
||||
+ fatal_f("setexeccon failed with %s", strerror(errno));
|
||||
+ if (setcon(ctx) != 0)
|
||||
+ fatal_f("setcon failed with %s", strerror(errno));
|
||||
+ freecon(ctx);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
#endif
|
||||
#endif
|
||||
|
||||
diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h
|
||||
index 055c825e..498d242a 100644
|
||||
--- a/openbsd-compat/port-linux.h
|
||||
+++ b/openbsd-compat/port-linux.h
|
||||
@@ -23,6 +23,7 @@ void ssh_selinux_setup_pty(char *, const char *);
|
||||
void ssh_selinux_change_context(const char *);
|
||||
void ssh_selinux_setfscreatecon(const char *);
|
||||
|
||||
+void sshd_selinux_copy_context(void);
|
||||
void sshd_selinux_setup_exec_context(char *);
|
||||
#endif
|
||||
|
||||
diff --git a/session.c b/session.c
|
||||
index 6444c77f..e4657cef 100644
|
||||
--- a/session.c
|
||||
+++ b/session.c
|
||||
@@ -1350,7 +1350,7 @@ do_setusercontext(struct passwd *pw)
|
||||
|
||||
platform_setusercontext(pw);
|
||||
|
||||
- if (platform_privileged_uidswap()) {
|
||||
+ if (platform_privileged_uidswap() && !is_child) {
|
||||
#ifdef HAVE_LOGIN_CAP
|
||||
if (setusercontext(lc, pw, pw->pw_uid,
|
||||
(LOGIN_SETALL & ~(LOGIN_SETPATH|LOGIN_SETUSER))) < 0) {
|
||||
@@ -1382,6 +1382,9 @@ do_setusercontext(struct passwd *pw)
|
||||
(unsigned long long)pw->pw_uid);
|
||||
chroot_path = percent_expand(tmp, "h", pw->pw_dir,
|
||||
"u", pw->pw_name, "U", uidstr, (char *)NULL);
|
||||
+#ifdef WITH_SELINUX
|
||||
+ sshd_selinux_copy_context();
|
||||
+#endif
|
||||
safely_chroot(chroot_path, pw->pw_uid);
|
||||
free(tmp);
|
||||
free(chroot_path);
|
||||
@@ -1417,6 +1420,11 @@ do_setusercontext(struct passwd *pw)
|
||||
/* Permanently switch to the desired uid. */
|
||||
permanently_set_uid(pw);
|
||||
#endif
|
||||
+
|
||||
+#ifdef WITH_SELINUX
|
||||
+ if (in_chroot == 0)
|
||||
+ sshd_selinux_copy_context();
|
||||
+#endif
|
||||
} else if (options.chroot_directory != NULL &&
|
||||
strcasecmp(options.chroot_directory, "none") != 0) {
|
||||
fatal("server lacks privileges to chroot to ChrootDirectory");
|
||||
@@ -1434,9 +1442,6 @@ do_pwchange(Session *s)
|
||||
if (s->ttyfd != -1) {
|
||||
fprintf(stderr,
|
||||
"You must change your password now and log in again!\n");
|
||||
-#ifdef WITH_SELINUX
|
||||
- setexeccon(NULL);
|
||||
-#endif
|
||||
#ifdef PASSWD_NEEDS_USERNAME
|
||||
execl(_PATH_PASSWD_PROG, "passwd", s->pw->pw_name,
|
||||
(char *)NULL);
|
||||
@@ -1649,9 +1654,6 @@ do_child(struct ssh *ssh, Session *s, const char *command)
|
||||
argv[i] = NULL;
|
||||
optind = optreset = 1;
|
||||
__progname = argv[0];
|
||||
-#ifdef WITH_SELINUX
|
||||
- ssh_selinux_change_context("sftpd_t");
|
||||
-#endif
|
||||
exit(sftp_server_main(i, argv, s->pw));
|
||||
}
|
||||
|
||||
diff --git a/sshd-auth.c b/sshd-auth.c
|
||||
index 30eecd8a..f957dc22 100644
|
||||
--- a/sshd-auth.c
|
||||
+++ b/sshd-auth.c
|
||||
@@ -187,6 +187,10 @@ privsep_child_demote(void)
|
||||
if ((box = ssh_sandbox_init(pmonitor)) == NULL)
|
||||
fatal_f("ssh_sandbox_init failed");
|
||||
#endif
|
||||
+#ifdef WITH_SELINUX
|
||||
+ ssh_selinux_change_context("sshd_net_t");
|
||||
+#endif
|
||||
+
|
||||
/* Demote the child */
|
||||
if (privsep_chroot) {
|
||||
/* Change our root directory */
|
||||
diff --git a/sshd-session.c b/sshd-session.c
|
||||
index 74d2cbc7..4a148db4 100644
|
||||
--- a/sshd-session.c
|
||||
+++ b/sshd-session.c
|
||||
@@ -432,7 +432,7 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt)
|
||||
* fd passing, as AFAIK PTY allocation on this platform doesn't require
|
||||
* special privileges to begin with.
|
||||
*/
|
||||
-#if defined(DISABLE_FD_PASSING) && !defined(HAVE_CYGWIN)
|
||||
+#if defined(DISABLE_FD_PASSING) && !defined(HAVE_CYGWIN) && !defined(WITH_SELINUX)
|
||||
skip_privdrop = 1;
|
||||
#endif
|
||||
|
||||
--
|
||||
2.49.0
|
||||
|
||||
|
|
@ -1,6 +1,26 @@
|
|||
diff -up openssh-6.3p1/HOWTO.ssh-keycat.keycat openssh-6.3p1/HOWTO.ssh-keycat
|
||||
--- openssh-6.3p1/HOWTO.ssh-keycat.keycat 2013-10-10 15:16:33.445566916 +0200
|
||||
+++ openssh-6.3p1/HOWTO.ssh-keycat 2013-10-10 15:16:33.445566916 +0200
|
||||
From 5e35e18a419a5a66b6e1cb2b98beaaf4d9db0dc6 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:28 +0200
|
||||
Subject: [PATCH 03/50] openssh-6.6p1-keycat
|
||||
|
||||
---
|
||||
HOWTO.ssh-keycat | 12 ++
|
||||
Makefile.in | 8 +-
|
||||
configure.ac | 6 +
|
||||
misc.c | 7 +
|
||||
openbsd-compat/port-linux-sshd.c | 44 +++++-
|
||||
openbsd-compat/port-linux.h | 2 +
|
||||
platform.c | 2 +-
|
||||
ssh-keycat.c | 241 +++++++++++++++++++++++++++++++
|
||||
8 files changed, 314 insertions(+), 8 deletions(-)
|
||||
create mode 100644 HOWTO.ssh-keycat
|
||||
create mode 100644 ssh-keycat.c
|
||||
|
||||
diff --git a/HOWTO.ssh-keycat b/HOWTO.ssh-keycat
|
||||
new file mode 100644
|
||||
index 00000000..630ec628
|
||||
--- /dev/null
|
||||
+++ b/HOWTO.ssh-keycat
|
||||
@@ -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
|
||||
|
|
@ -14,82 +34,151 @@ diff -up openssh-6.3p1/HOWTO.ssh-keycat.keycat openssh-6.3p1/HOWTO.ssh-keycat
|
|||
+ PubkeyAuthentication yes
|
||||
+
|
||||
+
|
||||
diff -up openssh-6.3p1/Makefile.in.keycat openssh-6.3p1/Makefile.in
|
||||
--- openssh-6.3p1/Makefile.in.keycat 2013-10-10 15:16:33.442566930 +0200
|
||||
+++ openssh-6.3p1/Makefile.in 2013-10-10 15:16:33.445566916 +0200
|
||||
@@ -27,6 +27,7 @@ SFTP_SERVER=$(libexecdir)/sftp-server
|
||||
diff --git a/Makefile.in b/Makefile.in
|
||||
index 4617cebc..438efc51 100644
|
||||
--- a/Makefile.in
|
||||
+++ b/Makefile.in
|
||||
@@ -23,6 +23,7 @@ SSH_PROGRAM=@bindir@/ssh
|
||||
ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass
|
||||
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
|
||||
SSHD_SESSION=$(libexecdir)/sshd-session
|
||||
SSHD_AUTH=$(libexecdir)/sshd-auth
|
||||
SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper
|
||||
PRIVSEP_PATH=@PRIVSEP_PATH@
|
||||
SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@
|
||||
@@ -64,7 +65,7 @@ EXEEXT=@EXEEXT@
|
||||
MANFMT=@MANFMT@
|
||||
INSTALL_SSH_LDAP_HELPER=@INSTALL_SSH_LDAP_HELPER@
|
||||
@@ -57,6 +58,7 @@ CHANNELLIBS=@CHANNELLIBS@
|
||||
K5LIBS=@K5LIBS@
|
||||
GSSLIBS=@GSSLIBS@
|
||||
SSHDLIBS=@SSHDLIBS@
|
||||
+KEYCATLIBS=@KEYCATLIBS@
|
||||
LIBEDIT=@LIBEDIT@
|
||||
LIBFIDO2=@LIBFIDO2@
|
||||
LIBWTMPDB=@LIBWTMPDB@
|
||||
@@ -74,7 +76,7 @@ MKDIR_P=@MKDIR_P@
|
||||
|
||||
-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)
|
||||
.SUFFIXES: .lo
|
||||
|
||||
LIBSSH_OBJS=authfd.o authfile.o bufaux.o bufbn.o buffer.o \
|
||||
canohost.o channels.o cipher.o cipher-aes.o \
|
||||
@@ -172,6 +173,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)
|
||||
-TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) sshd-session$(EXEEXT) sshd-auth$(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-sk-helper$(EXEEXT) $(SK_STANDALONE)
|
||||
+TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) sshd-session$(EXEEXT) sshd-auth$(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-sk-helper$(EXEEXT) ssh-keycat$(EXEEXT) $(SK_STANDALONE)
|
||||
|
||||
+ssh-keycat$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keycat.o
|
||||
+ $(LD) -o $@ ssh-keycat.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(SSHDLIBS)
|
||||
XMSS_OBJS=\
|
||||
ssh-xmss.o \
|
||||
@@ -260,6 +262,9 @@ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a $(P11HELPER_OBJS)
|
||||
ssh-sk-helper$(EXEEXT): $(LIBCOMPAT) libssh.a $(SKHELPER_OBJS)
|
||||
$(LD) -o $@ $(SKHELPER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(LIBFIDO2) $(CHANNELLIBS)
|
||||
|
||||
+ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHDOBJS) libssh.a ssh-keycat.o uidswap.o
|
||||
+ $(LD) -o $@ ssh-keycat.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat $(KEYCATLIBS) $(LIBS)
|
||||
+
|
||||
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)
|
||||
ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYSCAN_OBJS)
|
||||
$(LD) -o $@ $(SSHKEYSCAN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) $(CHANNELLIBS)
|
||||
|
||||
@@ -279,6 +283,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
|
||||
@@ -447,6 +452,7 @@ install-files:
|
||||
$(INSTALL) -m 4711 $(STRIP_OPT) ssh-keysign$(EXEEXT) $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT)
|
||||
$(INSTALL) -m 0755 $(STRIP_OPT) ssh-pkcs11-helper$(EXEEXT) $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT)
|
||||
$(INSTALL) -m 0755 $(STRIP_OPT) ssh-sk-helper$(EXEEXT) $(DESTDIR)$(SSH_SK_HELPER)$(EXEEXT)
|
||||
+ $(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-6.3p1/auth2-pubkey.c.keycat openssh-6.3p1/auth2-pubkey.c
|
||||
--- openssh-6.3p1/auth2-pubkey.c.keycat 2013-10-10 15:16:33.429566992 +0200
|
||||
+++ openssh-6.3p1/auth2-pubkey.c 2013-10-10 15:16:33.445566916 +0200
|
||||
@@ -606,6 +606,14 @@ user_key_command_allowed2(struct passwd
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index ee77a048..d546788c 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -3566,6 +3566,7 @@ AC_ARG_WITH([pam],
|
||||
PAM_MSG="yes"
|
||||
|
||||
SSHDLIBS="$SSHDLIBS -lpam"
|
||||
+ KEYCATLIBS="$KEYCATLIBS -lpam"
|
||||
AC_DEFINE([USE_PAM], [1],
|
||||
[Define if you want to enable PAM support])
|
||||
|
||||
@@ -3576,6 +3577,7 @@ AC_ARG_WITH([pam],
|
||||
;;
|
||||
*)
|
||||
SSHDLIBS="$SSHDLIBS -ldl"
|
||||
+ KEYCATLIBS="$KEYCATLIBS -ldl"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
@@ -4801,6 +4803,7 @@ AC_ARG_WITH([selinux],
|
||||
fi ]
|
||||
)
|
||||
AC_SUBST([SSHDLIBS])
|
||||
+AC_SUBST([KEYCATLIBS])
|
||||
|
||||
# Check whether user wants Kerberos 5 support
|
||||
KRB5_MSG="no"
|
||||
@@ -5812,6 +5815,9 @@ fi
|
||||
if test ! -z "${SSHDLIBS}"; then
|
||||
echo " +for sshd: ${SSHDLIBS}"
|
||||
fi
|
||||
+if test ! -z "${KEYCATLIBS}"; then
|
||||
+echo " +for ssh-keycat: ${KEYCATLIBS}"
|
||||
+fi
|
||||
|
||||
echo ""
|
||||
|
||||
diff --git a/misc.c b/misc.c
|
||||
index c932f9bb..1e31acc9 100644
|
||||
--- a/misc.c
|
||||
+++ b/misc.c
|
||||
@@ -2897,6 +2897,13 @@ subprocess(const char *tag, const char *command,
|
||||
error("%s: dup2: %s", tag, strerror(errno));
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
+#ifdef WITH_SELINUX
|
||||
+ if (ssh_selinux_setup_env_variables() < 0) {
|
||||
+ if (sshd_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, user_pw->pw_name, NULL);
|
||||
if (env != NULL)
|
||||
execve(av[0], av, env);
|
||||
else
|
||||
diff --git a/openbsd-compat/port-linux-sshd.c b/openbsd-compat/port-linux-sshd.c
|
||||
index dfafc622..8c5fc1fe 100644
|
||||
--- a/openbsd-compat/port-linux-sshd.c
|
||||
+++ b/openbsd-compat/port-linux-sshd.c
|
||||
@@ -52,6 +52,20 @@ extern ServerOptions options;
|
||||
extern Authctxt *the_authctxt;
|
||||
extern int inetd_flag;
|
||||
|
||||
diff -up openssh-6.3p1/openbsd-compat/port-linux.c.keycat openssh-6.3p1/openbsd-compat/port-linux.c
|
||||
--- openssh-6.3p1/openbsd-compat/port-linux.c.keycat 2013-10-10 15:16:33.435566964 +0200
|
||||
+++ openssh-6.3p1/openbsd-compat/port-linux.c 2013-10-10 15:32:19.946065189 +0200
|
||||
@@ -313,7 +313,7 @@ ssh_selinux_getctxbyname(char *pwname,
|
||||
+/* Wrapper around is_selinux_enabled() to log its return value once only */
|
||||
+int
|
||||
+sshd_selinux_enabled(void)
|
||||
+{
|
||||
+ static int enabled = -1;
|
||||
+
|
||||
+ if (enabled == -1) {
|
||||
+ enabled = (is_selinux_enabled() == 1);
|
||||
+ debug("SELinux support %s", enabled ? "enabled" : "disabled");
|
||||
+ }
|
||||
+
|
||||
+ return (enabled);
|
||||
+}
|
||||
+
|
||||
/* Send audit message */
|
||||
static int
|
||||
sshd_selinux_send_audit_message(int success, security_context_t default_context,
|
||||
@@ -317,7 +331,7 @@ sshd_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 *))
|
||||
-sshd_selinux_setup_pam_variables(void)
|
||||
+sshd_selinux_setup_variables(int(*set_it)(char *, const char *))
|
||||
{
|
||||
const char *reqlvl;
|
||||
char *role;
|
||||
@@ -324,16 +324,16 @@ ssh_selinux_setup_pam_variables(void)
|
||||
@@ -328,16 +342,16 @@ sshd_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) {
|
||||
if (inetd_flag) {
|
||||
use_current = "1";
|
||||
} else {
|
||||
use_current = "";
|
||||
|
|
@ -102,35 +191,83 @@ diff -up openssh-6.3p1/openbsd-compat/port-linux.c.keycat openssh-6.3p1/openbsd-
|
|||
|
||||
if (role != NULL)
|
||||
free(role);
|
||||
@@ -341,6 +341,24 @@ ssh_selinux_setup_pam_variables(void)
|
||||
@@ -345,6 +359,24 @@ sshd_selinux_setup_pam_variables(void)
|
||||
return rv;
|
||||
}
|
||||
|
||||
+static int
|
||||
+ssh_selinux_setup_pam_variables(void)
|
||||
+sshd_selinux_setup_pam_variables(void)
|
||||
+{
|
||||
+ return ssh_selinux_setup_variables(do_pam_putenv);
|
||||
+ return sshd_selinux_setup_variables(do_pam_putenv);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_setenv(char *name, char *value)
|
||||
+do_setenv(char *name, const char *value)
|
||||
+{
|
||||
+ return setenv(name, value, 1);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+ssh_selinux_setup_env_variables(void)
|
||||
+sshd_selinux_setup_env_variables(void)
|
||||
+{
|
||||
+ return ssh_selinux_setup_variables(do_setenv);
|
||||
+ return sshd_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-6.3p1/ssh-keycat.c.keycat openssh-6.3p1/ssh-keycat.c
|
||||
--- openssh-6.3p1/ssh-keycat.c.keycat 2013-10-10 15:16:33.446566911 +0200
|
||||
+++ openssh-6.3p1/ssh-keycat.c 2013-10-10 15:16:33.446566911 +0200
|
||||
@@ -0,0 +1,238 @@
|
||||
sshd_selinux_setup_exec_context(char *pwname)
|
||||
@@ -353,7 +385,7 @@ sshd_selinux_setup_exec_context(char *pwname)
|
||||
int r = 0;
|
||||
security_context_t default_ctx = NULL;
|
||||
|
||||
- if (!ssh_selinux_enabled())
|
||||
+ if (!sshd_selinux_enabled())
|
||||
return;
|
||||
|
||||
if (options.use_pam) {
|
||||
@@ -420,7 +452,7 @@ sshd_selinux_copy_context(void)
|
||||
{
|
||||
security_context_t *ctx;
|
||||
|
||||
- if (!ssh_selinux_enabled())
|
||||
+ if (!sshd_selinux_enabled())
|
||||
return;
|
||||
|
||||
if (getexeccon((security_context_t *)&ctx) != 0) {
|
||||
diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h
|
||||
index 498d242a..1b745a76 100644
|
||||
--- a/openbsd-compat/port-linux.h
|
||||
+++ b/openbsd-compat/port-linux.h
|
||||
@@ -23,8 +23,10 @@ void ssh_selinux_setup_pty(char *, const char *);
|
||||
void ssh_selinux_change_context(const char *);
|
||||
void ssh_selinux_setfscreatecon(const char *);
|
||||
|
||||
+int sshd_selinux_enabled(void);
|
||||
void sshd_selinux_copy_context(void);
|
||||
void sshd_selinux_setup_exec_context(char *);
|
||||
+int sshd_selinux_setup_env_variables(void);
|
||||
#endif
|
||||
|
||||
#ifdef LINUX_OOM_ADJUST
|
||||
diff --git a/platform.c b/platform.c
|
||||
index 1bfb4bea..0d12f311 100644
|
||||
--- a/platform.c
|
||||
+++ b/platform.c
|
||||
@@ -55,7 +55,7 @@ platform_setusercontext(struct passwd *pw)
|
||||
{
|
||||
#ifdef WITH_SELINUX
|
||||
/* Cache selinux status for later use */
|
||||
- (void)ssh_selinux_enabled();
|
||||
+ (void)sshd_selinux_enabled();
|
||||
#endif
|
||||
|
||||
#ifdef USE_SOLARIS_PROJECTS
|
||||
diff --git a/ssh-keycat.c b/ssh-keycat.c
|
||||
new file mode 100644
|
||||
index 00000000..5678be07
|
||||
--- /dev/null
|
||||
+++ b/ssh-keycat.c
|
||||
@@ -0,0 +1,241 @@
|
||||
+/*
|
||||
+ * Redistribution and use in source and binary forms, with or without
|
||||
+ * modification, are permitted provided that the following conditions
|
||||
|
|
@ -180,6 +317,9 @@ diff -up openssh-6.3p1/ssh-keycat.c.keycat openssh-6.3p1/ssh-keycat.c
|
|||
+#include <pwd.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <unistd.h>
|
||||
+#ifdef HAVE_STDINT_H
|
||||
+#include <stdint.h>
|
||||
+#endif
|
||||
+
|
||||
+#include <security/pam_appl.h>
|
||||
+
|
||||
|
|
@ -369,3 +509,6 @@ diff -up openssh-6.3p1/ssh-keycat.c.keycat openssh-6.3p1/ssh-keycat.c
|
|||
+ }
|
||||
+ return ev;
|
||||
+}
|
||||
--
|
||||
2.49.0
|
||||
|
||||
55
0004-openssh-6.6p1-allow-ip-opts.patch
Normal file
55
0004-openssh-6.6p1-allow-ip-opts.patch
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
From 28333f1dfe68b0ffc80c2a4799759587b4c32d3e Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:28 +0200
|
||||
Subject: [PATCH 04/50] openssh-6.6p1-allow-ip-opts
|
||||
|
||||
---
|
||||
sshd-session.c | 32 ++++++++++++++++++++++++++------
|
||||
1 file changed, 26 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/sshd-session.c b/sshd-session.c
|
||||
index 4a148db4..a365f26f 100644
|
||||
--- a/sshd-session.c
|
||||
+++ b/sshd-session.c
|
||||
@@ -778,12 +778,32 @@ check_ip_options(struct ssh *ssh)
|
||||
|
||||
if (getsockopt(sock_in, IPPROTO_IP, IP_OPTIONS, opts,
|
||||
&option_size) >= 0 && option_size != 0) {
|
||||
- text[0] = '\0';
|
||||
- for (i = 0; i < option_size; i++)
|
||||
- snprintf(text + i*3, sizeof(text) - i*3,
|
||||
- " %2.2x", opts[i]);
|
||||
- fatal("Connection from %.100s port %d with IP opts: %.800s",
|
||||
- ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), text);
|
||||
+ i = 0;
|
||||
+ do {
|
||||
+ switch (opts[i]) {
|
||||
+ case 0:
|
||||
+ case 1:
|
||||
+ ++i;
|
||||
+ break;
|
||||
+ case 130:
|
||||
+ case 133:
|
||||
+ case 134:
|
||||
+ if (i + 1 < option_size && opts[i + 1] >= 2) {
|
||||
+ i += opts[i + 1];
|
||||
+ break;
|
||||
+ }
|
||||
+ /* FALLTHROUGH */
|
||||
+ default:
|
||||
+ /* Fail, fatally, if we detect either loose or strict
|
||||
+ * or incorrect source routing options. */
|
||||
+ text[0] = '\0';
|
||||
+ for (i = 0; i < option_size; i++)
|
||||
+ snprintf(text + i*3, sizeof(text) - i*3,
|
||||
+ " %2.2x", opts[i]);
|
||||
+ fatal("Connection from %.100s port %d with IP options:%.800s",
|
||||
+ ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), text);
|
||||
+ }
|
||||
+ } while (i < option_size);
|
||||
}
|
||||
#endif /* IP_OPTIONS */
|
||||
}
|
||||
--
|
||||
2.49.0
|
||||
|
||||
|
|
@ -1,7 +1,18 @@
|
|||
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.
|
||||
From 388be633842a9f3e4b0a76fe40cf7035912a913a Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:28 +0200
|
||||
Subject: [PATCH 05/50] openssh-5.9p1-ipv6man
|
||||
|
||||
---
|
||||
ssh.1 | 2 ++
|
||||
sshd.8 | 2 ++
|
||||
2 files changed, 4 insertions(+)
|
||||
|
||||
diff --git a/ssh.1 b/ssh.1
|
||||
index 697f4e42..db92ac9a 100644
|
||||
--- a/ssh.1
|
||||
+++ b/ssh.1
|
||||
@@ -1663,6 +1663,8 @@ manual page for more information.
|
||||
.Nm
|
||||
exits with the exit status of the remote command or with 255
|
||||
if an error occurred.
|
||||
|
|
@ -10,10 +21,11 @@ diff -up openssh-5.9p0/ssh.1.ipv6man openssh-5.9p0/ssh.1
|
|||
.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
|
||||
diff --git a/sshd.8 b/sshd.8
|
||||
index 08ebf53a..2aa73271 100644
|
||||
--- a/sshd.8
|
||||
+++ b/sshd.8
|
||||
@@ -1018,6 +1018,8 @@ concurrently for different ports, this contains the process ID of the one
|
||||
started last).
|
||||
The content of this file is not sensitive; it can be world-readable.
|
||||
.El
|
||||
|
|
@ -22,3 +34,6 @@ diff -up openssh-5.9p0/sshd.8.ipv6man openssh-5.9p0/sshd.8
|
|||
.Sh SEE ALSO
|
||||
.Xr scp 1 ,
|
||||
.Xr sftp 1 ,
|
||||
--
|
||||
2.49.0
|
||||
|
||||
26
0006-openssh-5.8p2-sigpipe.patch
Normal file
26
0006-openssh-5.8p2-sigpipe.patch
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
From 80359feb76fd8061b5ce18f73451d7b9db0c2477 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:28 +0200
|
||||
Subject: [PATCH 06/50] openssh-5.8p2-sigpipe
|
||||
|
||||
---
|
||||
ssh-keyscan.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/ssh-keyscan.c b/ssh-keyscan.c
|
||||
index 3436c0b5..9f76ad22 100644
|
||||
--- a/ssh-keyscan.c
|
||||
+++ b/ssh-keyscan.c
|
||||
@@ -798,6 +798,9 @@ main(int argc, char **argv)
|
||||
if (maxfd > fdlim_get(0))
|
||||
fdlim_set(maxfd);
|
||||
fdcon = xcalloc(maxfd, sizeof(con));
|
||||
+
|
||||
+ signal(SIGPIPE, SIG_IGN);
|
||||
+
|
||||
read_wait = xcalloc(maxfd, sizeof(struct pollfd));
|
||||
for (j = 0; j < maxfd; j++)
|
||||
read_wait[j].fd = -1;
|
||||
--
|
||||
2.49.0
|
||||
|
||||
|
|
@ -1,7 +1,17 @@
|
|||
diff -up openssh-5.3p1/channels.c.bz595935 openssh-5.3p1/channels.c
|
||||
--- openssh-5.3p1/channels.c.bz595935 2010-08-12 14:19:28.000000000 +0200
|
||||
+++ openssh-5.3p1/channels.c 2010-08-12 14:33:51.000000000 +0200
|
||||
@@ -3185,7 +3185,7 @@ x11_create_display_inet(int x11_display_
|
||||
From cf6d48305cf6601448ea7a0d96ae825cbbbf0a2c Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:28 +0200
|
||||
Subject: [PATCH 07/50] openssh-7.2p2-x11
|
||||
|
||||
---
|
||||
channels.c | 25 +++++++++++++++++++------
|
||||
1 file changed, 19 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/channels.c b/channels.c
|
||||
index bfe2e3b2..d46531ce 100644
|
||||
--- a/channels.c
|
||||
+++ b/channels.c
|
||||
@@ -5098,11 +5098,13 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset,
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -10,14 +20,18 @@ diff -up openssh-5.3p1/channels.c.bz595935 openssh-5.3p1/channels.c
|
|||
{
|
||||
int sock;
|
||||
struct sockaddr_un addr;
|
||||
@@ -3195,11 +3195,14 @@ connect_local_xsocket_path(const char *p
|
||||
|
||||
+ if (len <= 0)
|
||||
+ return -1;
|
||||
sock = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (sock == -1) {
|
||||
error("socket: %.100s", strerror(errno));
|
||||
@@ -5110,11 +5112,12 @@ connect_local_xsocket_path(const char *pathname)
|
||||
}
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sun_family = AF_UNIX;
|
||||
- strlcpy(addr.sun_path, pathname, sizeof addr.sun_path);
|
||||
- if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0)
|
||||
+ if (len <= 0)
|
||||
+ return -1;
|
||||
+ if (len > sizeof addr.sun_path)
|
||||
+ len = sizeof addr.sun_path;
|
||||
+ memcpy(addr.sun_path, pathname, len);
|
||||
|
|
@ -28,16 +42,13 @@ diff -up openssh-5.3p1/channels.c.bz595935 openssh-5.3p1/channels.c
|
|||
return -1;
|
||||
}
|
||||
|
||||
@@ -3207,8 +3210,21 @@ static int
|
||||
@@ -5122,8 +5125,18 @@ static int
|
||||
connect_local_xsocket(u_int dnr)
|
||||
{
|
||||
char buf[1024];
|
||||
- snprintf(buf, sizeof buf, _PATH_UNIX_X, dnr);
|
||||
- return connect_local_xsocket_path(buf);
|
||||
+ int len;
|
||||
+#ifdef linux
|
||||
+ int ret;
|
||||
+#endif
|
||||
+ int len, ret;
|
||||
+ len = snprintf(buf + 1, sizeof (buf) - 1, _PATH_UNIX_X, dnr);
|
||||
+#ifdef linux
|
||||
+ /* try abstract socket first */
|
||||
|
|
@ -51,4 +62,7 @@ diff -up openssh-5.3p1/channels.c.bz595935 openssh-5.3p1/channels.c
|
|||
+ return -1;
|
||||
}
|
||||
|
||||
int
|
||||
#ifdef __APPLE__
|
||||
--
|
||||
2.49.0
|
||||
|
||||
96
0008-openssh-5.1p1-askpass-progress.patch
Normal file
96
0008-openssh-5.1p1-askpass-progress.patch
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
From 6b2a33044583e892badb9ac86cd2c6252b1a532f Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:28 +0200
|
||||
Subject: [PATCH 08/50] openssh-5.1p1-askpass-progress
|
||||
|
||||
---
|
||||
contrib/gnome-ssh-askpass2.c | 39 +++++++++++++++++++++++++++++++++---
|
||||
1 file changed, 36 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/contrib/gnome-ssh-askpass2.c b/contrib/gnome-ssh-askpass2.c
|
||||
index a62f9815..cb7152dc 100644
|
||||
--- a/contrib/gnome-ssh-askpass2.c
|
||||
+++ b/contrib/gnome-ssh-askpass2.c
|
||||
@@ -58,6 +58,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
+#include <glib.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
@@ -146,6 +147,17 @@ parse_env_hex_color(const char *env, GdkColor *c)
|
||||
return 1;
|
||||
}
|
||||
|
||||
+static void
|
||||
+move_progress(GtkWidget *entry, gpointer progress)
|
||||
+{
|
||||
+ gdouble step;
|
||||
+ g_return_if_fail(GTK_IS_PROGRESS_BAR(progress));
|
||||
+
|
||||
+ step = g_random_double_range(0.03, 0.1);
|
||||
+ gtk_progress_bar_set_pulse_step(GTK_PROGRESS_BAR(progress), step);
|
||||
+ gtk_progress_bar_pulse(GTK_PROGRESS_BAR(progress));
|
||||
+}
|
||||
+
|
||||
static int
|
||||
passphrase_dialog(char *message, int prompt_type)
|
||||
{
|
||||
@@ -153,7 +165,7 @@ passphrase_dialog(char *message, int prompt_type)
|
||||
char *passphrase, *local;
|
||||
int result, grab_tries, grab_server, grab_pointer;
|
||||
int buttons, default_response;
|
||||
- GtkWidget *parent_window, *dialog, *entry;
|
||||
+ GtkWidget *parent_window, *dialog, *entry, *progress, *hbox;
|
||||
GdkGrabStatus status;
|
||||
GdkColor fg, bg;
|
||||
int fg_set = 0, bg_set = 0;
|
||||
@@ -199,14 +211,19 @@ passphrase_dialog(char *message, int prompt_type)
|
||||
gtk_widget_modify_bg(dialog, GTK_STATE_NORMAL, &bg);
|
||||
|
||||
if (prompt_type == PROMPT_ENTRY || prompt_type == PROMPT_NONE) {
|
||||
+ hbox = gtk_hbox_new(FALSE, 0);
|
||||
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE,
|
||||
+ FALSE, 0);
|
||||
+ gtk_widget_show(hbox);
|
||||
+
|
||||
entry = gtk_entry_new();
|
||||
if (fg_set)
|
||||
gtk_widget_modify_fg(entry, GTK_STATE_NORMAL, &fg);
|
||||
if (bg_set)
|
||||
gtk_widget_modify_bg(entry, GTK_STATE_NORMAL, &bg);
|
||||
gtk_box_pack_start(
|
||||
- GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
|
||||
- entry, FALSE, FALSE, 0);
|
||||
+ GTK_BOX(hbox), entry, TRUE, FALSE, 0);
|
||||
+ gtk_entry_set_width_chars(GTK_ENTRY(entry), 2);
|
||||
gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
|
||||
gtk_widget_grab_focus(entry);
|
||||
if (prompt_type == PROMPT_ENTRY) {
|
||||
@@ -225,6 +242,22 @@ passphrase_dialog(char *message, int prompt_type)
|
||||
g_signal_connect(G_OBJECT(entry), "key_press_event",
|
||||
G_CALLBACK(check_none), dialog);
|
||||
}
|
||||
+
|
||||
+ hbox = gtk_hbox_new(FALSE, 0);
|
||||
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
|
||||
+ hbox, FALSE, FALSE, 8);
|
||||
+ gtk_widget_show(hbox);
|
||||
+
|
||||
+ progress = gtk_progress_bar_new();
|
||||
+
|
||||
+ gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress),
|
||||
+ "Passphrase length hidden intentionally");
|
||||
+ gtk_box_pack_start(GTK_BOX(hbox), progress, TRUE,
|
||||
+ TRUE, 5);
|
||||
+ gtk_widget_show(progress);
|
||||
+ g_signal_connect(G_OBJECT(entry), "changed",
|
||||
+ G_CALLBACK(move_progress), progress);
|
||||
+
|
||||
}
|
||||
|
||||
/* Grab focus */
|
||||
--
|
||||
2.49.0
|
||||
|
||||
31
0009-openssh-4.3p2-askpass-grab-info.patch
Normal file
31
0009-openssh-4.3p2-askpass-grab-info.patch
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
From 710ce53fdf1d32a0629fce2e42fb49d407e2b06c Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:28 +0200
|
||||
Subject: [PATCH 09/50] openssh-4.3p2-askpass-grab-info
|
||||
|
||||
---
|
||||
contrib/gnome-ssh-askpass2.c | 8 ++++++--
|
||||
1 file changed, 6 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/contrib/gnome-ssh-askpass2.c b/contrib/gnome-ssh-askpass2.c
|
||||
index cb7152dc..bbe93d83 100644
|
||||
--- a/contrib/gnome-ssh-askpass2.c
|
||||
+++ b/contrib/gnome-ssh-askpass2.c
|
||||
@@ -70,8 +70,12 @@ report_failed_grab (GtkWidget *parent_window, const char *what)
|
||||
|
||||
err = gtk_message_dialog_new(GTK_WINDOW(parent_window), 0,
|
||||
GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
|
||||
- "Could not grab %s. A malicious client may be eavesdropping "
|
||||
- "on your session.", what);
|
||||
+ "SSH password dialog could not grab the %s input.\n"
|
||||
+ "This might be caused by application such as screensaver, "
|
||||
+ "however it could also mean that someone may be eavesdropping "
|
||||
+ "on your session.\n"
|
||||
+ "Either close the application which grabs the %s or "
|
||||
+ "log out and log in again to prevent this from happening.", what, what);
|
||||
gtk_window_set_position(GTK_WINDOW(err), GTK_WIN_POS_CENTER);
|
||||
|
||||
gtk_dialog_run(GTK_DIALOG(err));
|
||||
--
|
||||
2.49.0
|
||||
|
||||
146
0010-openssh-8.7p1-redhat.patch
Normal file
146
0010-openssh-8.7p1-redhat.patch
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
From 5f21983f6472b26693babea4d6ca6b95a7dc7b05 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:28 +0200
|
||||
Subject: [PATCH 10/50] openssh-8.7p1-redhat
|
||||
|
||||
---
|
||||
ssh_config | 7 +++++++
|
||||
ssh_config_redhat | 18 ++++++++++++++++++
|
||||
sshd_config | 8 ++++++++
|
||||
sshd_config.0 | 6 +++---
|
||||
sshd_config.5 | 2 +-
|
||||
sshd_config_redhat | 18 ++++++++++++++++++
|
||||
sshd_config_redhat_cp | 7 +++++++
|
||||
7 files changed, 62 insertions(+), 4 deletions(-)
|
||||
create mode 100644 ssh_config_redhat
|
||||
create mode 100644 sshd_config_redhat
|
||||
create mode 100644 sshd_config_redhat_cp
|
||||
|
||||
diff --git a/ssh_config b/ssh_config
|
||||
index cc566356..18169187 100644
|
||||
--- a/ssh_config
|
||||
+++ b/ssh_config
|
||||
@@ -44,3 +44,10 @@
|
||||
# ProxyCommand ssh -q -W %h:%p gateway.example.com
|
||||
# RekeyLimit 1G 1h
|
||||
# UserKnownHostsFile ~/.ssh/known_hosts.d/%k
|
||||
+#
|
||||
+# This system is following system-wide crypto policy.
|
||||
+# To modify the crypto properties (Ciphers, MACs, ...), create a *.conf
|
||||
+# file under /etc/ssh/ssh_config.d/ which will be automatically
|
||||
+# included below. For more information, see manual page for
|
||||
+# update-crypto-policies(8) and ssh_config(5).
|
||||
+Include /etc/ssh/ssh_config.d/*.conf
|
||||
diff --git a/ssh_config_redhat b/ssh_config_redhat
|
||||
new file mode 100644
|
||||
index 00000000..8b1b5902
|
||||
--- /dev/null
|
||||
+++ b/ssh_config_redhat
|
||||
@@ -0,0 +1,18 @@
|
||||
+# The options here are in the "Match final block" to be applied as the last
|
||||
+# options and could be potentially overwritten by the user configuration
|
||||
+Match final all
|
||||
+ # Follow system-wide Crypto Policy, if defined:
|
||||
+ Include /etc/crypto-policies/back-ends/openssh.config
|
||||
+
|
||||
+ 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
|
||||
+
|
||||
+# rhbz#2352653 - export COLORTERM
|
||||
+ SendEnv COLORTERM
|
||||
+
|
||||
+# Uncomment this if you want to use .local domain
|
||||
+# Host *.local
|
||||
diff --git a/sshd_config b/sshd_config
|
||||
index 0f4a3a72..608203e4 100644
|
||||
--- a/sshd_config
|
||||
+++ b/sshd_config
|
||||
@@ -10,6 +10,14 @@
|
||||
# possible, but leave them commented. Uncommented options override the
|
||||
# default value.
|
||||
|
||||
+# To modify the system-wide sshd configuration, create a *.conf file under
|
||||
+# /etc/ssh/sshd_config.d/ which will be automatically included below
|
||||
+Include /etc/ssh/sshd_config.d/*.conf
|
||||
+
|
||||
+# If you want to change the port on a SELinux system, you have to tell
|
||||
+# SELinux about this change.
|
||||
+# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER
|
||||
+#
|
||||
#Port 22
|
||||
#AddressFamily any
|
||||
#ListenAddress 0.0.0.0
|
||||
diff --git a/sshd_config.0 b/sshd_config.0
|
||||
index 2f77b4f4..49349bb3 100644
|
||||
--- a/sshd_config.0
|
||||
+++ b/sshd_config.0
|
||||
@@ -1219,9 +1219,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 --git a/sshd_config.5 b/sshd_config.5
|
||||
index c0771737..035a50c8 100644
|
||||
--- a/sshd_config.5
|
||||
+++ b/sshd_config.5
|
||||
@@ -1942,7 +1942,7 @@ By default no subsystems are defined.
|
||||
.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 --git a/sshd_config_redhat b/sshd_config_redhat
|
||||
new file mode 100644
|
||||
index 00000000..993a28d5
|
||||
--- /dev/null
|
||||
+++ b/sshd_config_redhat
|
||||
@@ -0,0 +1,18 @@
|
||||
+SyslogFacility AUTHPRIV
|
||||
+
|
||||
+KbdInteractiveAuthentication no
|
||||
+
|
||||
+GSSAPIAuthentication yes
|
||||
+GSSAPICleanupCredentials no
|
||||
+
|
||||
+UsePAM yes
|
||||
+
|
||||
+X11Forwarding yes
|
||||
+
|
||||
+# rhbz#2352653 - accept COLORTERM
|
||||
+ AcceptEnv COLORTERM
|
||||
+
|
||||
+# It is recommended to use pam_motd in /etc/pam.d/sshd instead of PrintMotd,
|
||||
+# as it is more configurable and versatile than the built-in version.
|
||||
+PrintMotd no
|
||||
+
|
||||
diff --git a/sshd_config_redhat_cp b/sshd_config_redhat_cp
|
||||
new file mode 100644
|
||||
index 00000000..1d592d13
|
||||
--- /dev/null
|
||||
+++ b/sshd_config_redhat_cp
|
||||
@@ -0,0 +1,7 @@
|
||||
+# This system is following system-wide crypto policy. The changes to
|
||||
+# crypto properties (Ciphers, MACs, ...) will not have any effect in
|
||||
+# this or following included files. To override some configuration option,
|
||||
+# write it before this block or include it before this file.
|
||||
+# Please, see manual pages for update-crypto-policies(8) and sshd_config(5).
|
||||
+Include /etc/crypto-policies/back-ends/opensshserver.config
|
||||
+
|
||||
--
|
||||
2.49.0
|
||||
|
||||
41
0011-openssh-7.8p1-UsePAM-warning.patch
Normal file
41
0011-openssh-7.8p1-UsePAM-warning.patch
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
From 56b8d082bc9e25a77b5227d576f27088446c6fb9 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:28 +0200
|
||||
Subject: [PATCH 11/50] openssh-7.8p1-UsePAM-warning
|
||||
|
||||
---
|
||||
sshd-session.c | 4 ++++
|
||||
sshd_config | 2 ++
|
||||
2 files changed, 6 insertions(+)
|
||||
|
||||
diff --git a/sshd-session.c b/sshd-session.c
|
||||
index a365f26f..a70b36c9 100644
|
||||
--- a/sshd-session.c
|
||||
+++ b/sshd-session.c
|
||||
@@ -1127,6 +1127,10 @@ main(int ac, char **av)
|
||||
"enabled authentication methods");
|
||||
}
|
||||
|
||||
+ /* 'UsePAM no' is not supported in our builds */
|
||||
+ if (! options.use_pam)
|
||||
+ logit("WARNING: 'UsePAM no' is not supported in this build and may cause several problems.");
|
||||
+
|
||||
#ifdef WITH_OPENSSL
|
||||
if (options.moduli_file != NULL)
|
||||
dh_set_moduli_file(options.moduli_file);
|
||||
diff --git a/sshd_config b/sshd_config
|
||||
index 608203e4..48af6321 100644
|
||||
--- a/sshd_config
|
||||
+++ b/sshd_config
|
||||
@@ -89,6 +89,8 @@ AuthorizedKeysFile .ssh/authorized_keys
|
||||
# If you just want the PAM account and session checks to run without
|
||||
# PAM authentication, then enable this but set PasswordAuthentication
|
||||
# and KbdInteractiveAuthentication to 'no'.
|
||||
+# WARNING: 'UsePAM no' is not supported in this build and may cause several
|
||||
+# problems.
|
||||
#UsePAM no
|
||||
|
||||
#AllowAgentForwarding yes
|
||||
--
|
||||
2.49.0
|
||||
|
||||
4310
0012-openssh-9.6p1-gssapi-keyex.patch
Normal file
4310
0012-openssh-9.6p1-gssapi-keyex.patch
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,19 @@
|
|||
diff -up openssh-6.3p1/gss-serv-krb5.c.force_krb openssh-6.3p1/gss-serv-krb5.c
|
||||
--- openssh-6.3p1/gss-serv-krb5.c.force_krb 2013-10-11 18:58:51.553948159 +0200
|
||||
+++ openssh-6.3p1/gss-serv-krb5.c 2013-10-11 21:40:49.972337025 +0200
|
||||
From f5e5ee321def2a3674600714ad98fd1ca9b2cff1 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:28 +0200
|
||||
Subject: [PATCH 13/50] openssh-6.6p1-force_krb
|
||||
|
||||
---
|
||||
gss-serv-krb5.c | 156 +++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
session.c | 23 +++++++
|
||||
ssh-gss.h | 4 ++
|
||||
sshd.8 | 7 +++
|
||||
4 files changed, 189 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c
|
||||
index 8d2b677f..14502c5a 100644
|
||||
--- a/gss-serv-krb5.c
|
||||
+++ b/gss-serv-krb5.c
|
||||
@@ -32,7 +32,9 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
|
|
@ -10,21 +23,16 @@ diff -up openssh-6.3p1/gss-serv-krb5.c.force_krb openssh-6.3p1/gss-serv-krb5.c
|
|||
+#include <unistd.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "key.h"
|
||||
@@ -40,10 +42,12 @@
|
||||
#include "auth.h"
|
||||
#include "log.h"
|
||||
#include "servconf.h"
|
||||
+#include "misc.h"
|
||||
#include "sshkey.h"
|
||||
@@ -44,6 +46,7 @@
|
||||
|
||||
#include "buffer.h"
|
||||
#include "ssh-gss.h"
|
||||
|
||||
+extern Authctxt *the_authctxt;
|
||||
extern ServerOptions options;
|
||||
|
||||
#ifdef HEIMDAL
|
||||
@@ -55,6 +59,13 @@ extern ServerOptions options;
|
||||
@@ -55,6 +58,13 @@ extern ServerOptions options;
|
||||
# include <gssapi/gssapi_krb5.h>
|
||||
#endif
|
||||
|
||||
|
|
@ -38,7 +46,7 @@ diff -up openssh-6.3p1/gss-serv-krb5.c.force_krb openssh-6.3p1/gss-serv-krb5.c
|
|||
static krb5_context krb_context = NULL;
|
||||
|
||||
/* Initialise the krb5 library, for the stuff that GSSAPI won't do */
|
||||
@@ -87,6 +98,7 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client
|
||||
@@ -87,6 +97,7 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name)
|
||||
krb5_principal princ;
|
||||
int retval;
|
||||
const char *errmsg;
|
||||
|
|
@ -46,7 +54,7 @@ diff -up openssh-6.3p1/gss-serv-krb5.c.force_krb openssh-6.3p1/gss-serv-krb5.c
|
|||
|
||||
if (ssh_gssapi_krb5_init() == 0)
|
||||
return 0;
|
||||
@@ -98,10 +110,22 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client
|
||||
@@ -98,10 +109,22 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name)
|
||||
krb5_free_error_message(krb_context, errmsg);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -70,7 +78,7 @@ diff -up openssh-6.3p1/gss-serv-krb5.c.force_krb openssh-6.3p1/gss-serv-krb5.c
|
|||
} else
|
||||
retval = 0;
|
||||
|
||||
@@ -109,6 +133,135 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client
|
||||
@@ -109,6 +132,137 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name)
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -101,13 +109,14 @@ diff -up openssh-6.3p1/gss-serv-krb5.c.force_krb openssh-6.3p1/gss-serv-krb5.c
|
|||
+{
|
||||
+ FILE *fp;
|
||||
+ char file[MAXPATHLEN];
|
||||
+ char line[BUFSIZ];
|
||||
+ char *line = NULL;
|
||||
+ char kuser[65]; /* match krb5_kuserok() */
|
||||
+ struct stat st;
|
||||
+ struct passwd *pw = the_authctxt->pw;
|
||||
+ int found_principal = 0;
|
||||
+ int ncommands = 0, allcommands = 0;
|
||||
+ u_long linenum;
|
||||
+ u_long linenum = 0;
|
||||
+ size_t linesize = 0;
|
||||
+
|
||||
+ snprintf(file, sizeof(file), "%s/.k5users", pw->pw_dir);
|
||||
+ /* If both .k5login and .k5users DNE, self-login is ok. */
|
||||
|
|
@ -151,9 +160,9 @@ diff -up openssh-6.3p1/gss-serv-krb5.c.force_krb openssh-6.3p1/gss-serv-krb5.c
|
|||
+ k5users_allowed_cmds = xcalloc(++ncommands,
|
||||
+ sizeof(*k5users_allowed_cmds));
|
||||
+
|
||||
+ /* Check each line. ksu allows unlimited length lines. We don't. */
|
||||
+ while (!allcommands && read_keyfile_line(fp, file, line, sizeof(line),
|
||||
+ &linenum) != -1) {
|
||||
+ /* Check each line. ksu allows unlimited length lines. */
|
||||
+ while (!allcommands && getline(&line, &linesize, fp) != -1) {
|
||||
+ linenum++;
|
||||
+ char *token;
|
||||
+
|
||||
+ /* we parse just like ksu, even though we could do better */
|
||||
|
|
@ -167,7 +176,7 @@ diff -up openssh-6.3p1/gss-serv-krb5.c.force_krb openssh-6.3p1/gss-serv-krb5.c
|
|||
+ k5users_allowed_cmds[ncommands-1] =
|
||||
+ xstrdup(pw->pw_shell);
|
||||
+ k5users_allowed_cmds =
|
||||
+ xrealloc(k5users_allowed_cmds, ++ncommands,
|
||||
+ xreallocarray(k5users_allowed_cmds, ++ncommands,
|
||||
+ sizeof(*k5users_allowed_cmds));
|
||||
+ break;
|
||||
+ }
|
||||
|
|
@ -180,12 +189,13 @@ diff -up openssh-6.3p1/gss-serv-krb5.c.force_krb openssh-6.3p1/gss-serv-krb5.c
|
|||
+ k5users_allowed_cmds[ncommands-1] =
|
||||
+ xstrdup(token);
|
||||
+ k5users_allowed_cmds =
|
||||
+ xrealloc(k5users_allowed_cmds, ++ncommands,
|
||||
+ xreallocarray(k5users_allowed_cmds, ++ncommands,
|
||||
+ sizeof(*k5users_allowed_cmds));
|
||||
+ token = strtok(NULL, " \t\n");
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ free(line);
|
||||
+ if (k5users_allowed_cmds) {
|
||||
+ /* terminate vector */
|
||||
+ k5users_allowed_cmds[ncommands-1] = NULL;
|
||||
|
|
@ -206,19 +216,20 @@ diff -up openssh-6.3p1/gss-serv-krb5.c.force_krb openssh-6.3p1/gss-serv-krb5.c
|
|||
|
||||
/* This writes out any forwarded credentials from the structure populated
|
||||
* during userauth. Called after we have setuid to the user */
|
||||
diff -up openssh-6.3p1/session.c.force_krb openssh-6.3p1/session.c
|
||||
--- openssh-6.3p1/session.c.force_krb 2013-10-11 18:58:51.487948468 +0200
|
||||
+++ openssh-6.3p1/session.c 2013-10-11 18:58:51.563948112 +0200
|
||||
@@ -823,6 +823,29 @@ do_exec(Session *s, const char *command)
|
||||
debug("Forced command (key option) '%.900s'", command);
|
||||
diff --git a/session.c b/session.c
|
||||
index cbfbcee8..89b3a9cf 100644
|
||||
--- a/session.c
|
||||
+++ b/session.c
|
||||
@@ -680,6 +680,29 @@ do_exec(struct ssh *ssh, Session *s, const char *command)
|
||||
command = auth_opts->force_command;
|
||||
forced = "(key-option)";
|
||||
}
|
||||
|
||||
+#ifdef GSSAPI
|
||||
+#ifdef KRB5 /* k5users_allowed_cmds only available w/ GSSAPI+KRB5 */
|
||||
+ else if (k5users_allowed_cmds) {
|
||||
+ const char *match = command;
|
||||
+ int allowed = 0, i = 0;
|
||||
+
|
||||
+
|
||||
+ if (!match)
|
||||
+ match = s->pw->pw_shell;
|
||||
+ while (k5users_allowed_cmds[i]) {
|
||||
|
|
@ -236,12 +247,13 @@ diff -up openssh-6.3p1/session.c.force_krb openssh-6.3p1/session.c
|
|||
+#endif
|
||||
+#endif
|
||||
+
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
if (s->command != NULL || s->command_handle != -1)
|
||||
fatal("do_exec: command already set");
|
||||
diff -up openssh-6.3p1/ssh-gss.h.force_krb openssh-6.3p1/ssh-gss.h
|
||||
--- openssh-6.3p1/ssh-gss.h.force_krb 2013-10-11 18:58:51.558948136 +0200
|
||||
+++ openssh-6.3p1/ssh-gss.h 2013-10-11 18:58:51.563948112 +0200
|
||||
s->forced = 0;
|
||||
if (forced != NULL) {
|
||||
s->forced = 1;
|
||||
diff --git a/ssh-gss.h b/ssh-gss.h
|
||||
index 8ec45192..db34d77f 100644
|
||||
--- a/ssh-gss.h
|
||||
+++ b/ssh-gss.h
|
||||
@@ -49,6 +49,10 @@
|
||||
# endif /* !HAVE_DECL_GSS_C_NT_... */
|
||||
|
||||
|
|
@ -253,10 +265,11 @@ diff -up openssh-6.3p1/ssh-gss.h.force_krb openssh-6.3p1/ssh-gss.h
|
|||
#endif /* KRB5 */
|
||||
|
||||
/* draft-ietf-secsh-gsskeyex-06 */
|
||||
diff -up openssh-6.3p1/sshd.8.force_krb openssh-6.3p1/sshd.8
|
||||
--- openssh-6.3p1/sshd.8.force_krb 2013-10-11 18:58:51.537948234 +0200
|
||||
+++ openssh-6.3p1/sshd.8 2013-10-11 18:58:51.563948112 +0200
|
||||
@@ -326,6 +326,7 @@ Finally, the server and the client enter
|
||||
diff --git a/sshd.8 b/sshd.8
|
||||
index 2aa73271..049d0a94 100644
|
||||
--- a/sshd.8
|
||||
+++ b/sshd.8
|
||||
@@ -286,6 +286,7 @@ Finally, the server and the client enter an authentication dialog.
|
||||
The client tries to authenticate itself using
|
||||
host-based authentication,
|
||||
public key authentication,
|
||||
|
|
@ -264,7 +277,7 @@ diff -up openssh-6.3p1/sshd.8.force_krb openssh-6.3p1/sshd.8
|
|||
challenge-response authentication,
|
||||
or password authentication.
|
||||
.Pp
|
||||
@@ -797,6 +798,12 @@ This file is used in exactly the same wa
|
||||
@@ -874,6 +875,12 @@ This file is used in exactly the same way as
|
||||
but allows host-based authentication without permitting login with
|
||||
rlogin/rsh.
|
||||
.Pp
|
||||
|
|
@ -277,3 +290,6 @@ diff -up openssh-6.3p1/sshd.8.force_krb openssh-6.3p1/sshd.8
|
|||
.It Pa ~/.ssh/
|
||||
This directory is the default location for all user-specific configuration
|
||||
and authentication information.
|
||||
--
|
||||
2.49.0
|
||||
|
||||
665
0014-openssh-7.7p1-gssapi-new-unique.patch
Normal file
665
0014-openssh-7.7p1-gssapi-new-unique.patch
Normal file
|
|
@ -0,0 +1,665 @@
|
|||
From 5fca5946aa97dce23c6824c52b070a92532752a9 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:28 +0200
|
||||
Subject: [PATCH 14/50] openssh-7.7p1-gssapi-new-unique
|
||||
|
||||
---
|
||||
auth-krb5.c | 262 ++++++++++++++++++++++++++++++++++++++++++------
|
||||
auth.h | 3 +-
|
||||
gss-serv-krb5.c | 42 +++-----
|
||||
gss-serv.c | 10 +-
|
||||
servconf.c | 12 ++-
|
||||
servconf.h | 2 +
|
||||
session.c | 5 +-
|
||||
ssh-gss.h | 4 +-
|
||||
sshd-session.c | 2 +-
|
||||
sshd_config.5 | 8 ++
|
||||
10 files changed, 279 insertions(+), 71 deletions(-)
|
||||
|
||||
diff --git a/auth-krb5.c b/auth-krb5.c
|
||||
index c99e4e43..77714e3d 100644
|
||||
--- a/auth-krb5.c
|
||||
+++ b/auth-krb5.c
|
||||
@@ -51,6 +51,7 @@
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <krb5.h>
|
||||
+#include <profile.h>
|
||||
|
||||
extern ServerOptions options;
|
||||
|
||||
@@ -77,7 +78,7 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
|
||||
#endif
|
||||
krb5_error_code problem;
|
||||
krb5_ccache ccache = NULL;
|
||||
- int len;
|
||||
+ char *ticket_name = NULL;
|
||||
char *client, *platform_client;
|
||||
const char *errmsg;
|
||||
|
||||
@@ -163,8 +164,8 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
|
||||
goto out;
|
||||
}
|
||||
|
||||
- problem = ssh_krb5_cc_gen(authctxt->krb5_ctx,
|
||||
- &authctxt->krb5_fwd_ccache);
|
||||
+ problem = ssh_krb5_cc_new_unique(authctxt->krb5_ctx,
|
||||
+ &authctxt->krb5_fwd_ccache, &authctxt->krb5_set_env);
|
||||
if (problem)
|
||||
goto out;
|
||||
|
||||
@@ -179,15 +180,14 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
|
||||
goto out;
|
||||
#endif
|
||||
|
||||
- authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
|
||||
+ problem = krb5_cc_get_full_name(authctxt->krb5_ctx,
|
||||
+ authctxt->krb5_fwd_ccache, &ticket_name);
|
||||
|
||||
- len = strlen(authctxt->krb5_ticket_file) + 6;
|
||||
- authctxt->krb5_ccname = xmalloc(len);
|
||||
- snprintf(authctxt->krb5_ccname, len, "FILE:%s",
|
||||
- authctxt->krb5_ticket_file);
|
||||
+ authctxt->krb5_ccname = xstrdup(ticket_name);
|
||||
+ krb5_free_string(authctxt->krb5_ctx, ticket_name);
|
||||
|
||||
#ifdef USE_PAM
|
||||
- if (options.use_pam)
|
||||
+ if (options.use_pam && authctxt->krb5_set_env)
|
||||
do_pam_putenv("KRB5CCNAME", authctxt->krb5_ccname);
|
||||
#endif
|
||||
|
||||
@@ -223,11 +223,54 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
|
||||
void
|
||||
krb5_cleanup_proc(Authctxt *authctxt)
|
||||
{
|
||||
+ struct stat krb5_ccname_stat;
|
||||
+ char krb5_ccname[128], *krb5_ccname_dir_start, *krb5_ccname_dir_end;
|
||||
+
|
||||
debug("krb5_cleanup_proc called");
|
||||
if (authctxt->krb5_fwd_ccache) {
|
||||
- krb5_cc_destroy(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
|
||||
+ krb5_context ctx = authctxt->krb5_ctx;
|
||||
+ krb5_cccol_cursor cursor;
|
||||
+ krb5_ccache ccache;
|
||||
+ int ret;
|
||||
+
|
||||
+ krb5_cc_destroy(ctx, authctxt->krb5_fwd_ccache);
|
||||
authctxt->krb5_fwd_ccache = NULL;
|
||||
+
|
||||
+ ret = krb5_cccol_cursor_new(ctx, &cursor);
|
||||
+ if (ret)
|
||||
+ goto out;
|
||||
+
|
||||
+ ret = krb5_cccol_cursor_next(ctx, cursor, &ccache);
|
||||
+ if (ret == 0 && ccache != NULL) {
|
||||
+ /* There is at least one other ccache in collection
|
||||
+ * we can switch to */
|
||||
+ krb5_cc_switch(ctx, ccache);
|
||||
+ } else if (authctxt->krb5_ccname != NULL) {
|
||||
+ /* Clean up the collection too */
|
||||
+ strncpy(krb5_ccname, authctxt->krb5_ccname, sizeof(krb5_ccname) - 10);
|
||||
+ krb5_ccname_dir_start = strchr(krb5_ccname, ':') + 1;
|
||||
+ *krb5_ccname_dir_start++ = '\0';
|
||||
+ if (strcmp(krb5_ccname, "DIR") == 0) {
|
||||
+
|
||||
+ strcat(krb5_ccname_dir_start, "/primary");
|
||||
+
|
||||
+ if (stat(krb5_ccname_dir_start, &krb5_ccname_stat) == 0) {
|
||||
+ if (unlink(krb5_ccname_dir_start) == 0) {
|
||||
+ krb5_ccname_dir_end = strrchr(krb5_ccname_dir_start, '/');
|
||||
+ *krb5_ccname_dir_end = '\0';
|
||||
+ if (rmdir(krb5_ccname_dir_start) == -1)
|
||||
+ debug("cache dir '%s' remove failed: %s",
|
||||
+ krb5_ccname_dir_start, strerror(errno));
|
||||
+ }
|
||||
+ else
|
||||
+ debug("cache primary file '%s', remove failed: %s",
|
||||
+ krb5_ccname_dir_start, strerror(errno));
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ krb5_cccol_cursor_free(ctx, &cursor);
|
||||
}
|
||||
+out:
|
||||
if (authctxt->krb5_user) {
|
||||
krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user);
|
||||
authctxt->krb5_user = NULL;
|
||||
@@ -238,36 +281,189 @@ krb5_cleanup_proc(Authctxt *authctxt)
|
||||
}
|
||||
}
|
||||
|
||||
-#ifndef HEIMDAL
|
||||
-krb5_error_code
|
||||
-ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) {
|
||||
- int tmpfd, ret, oerrno;
|
||||
- char ccname[40];
|
||||
- mode_t old_umask;
|
||||
|
||||
- ret = snprintf(ccname, sizeof(ccname),
|
||||
- "FILE:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid());
|
||||
- if (ret < 0 || (size_t)ret >= sizeof(ccname))
|
||||
- return ENOMEM;
|
||||
-
|
||||
- old_umask = umask(0177);
|
||||
- tmpfd = mkstemp(ccname + strlen("FILE:"));
|
||||
- oerrno = errno;
|
||||
- umask(old_umask);
|
||||
- if (tmpfd == -1) {
|
||||
- logit("mkstemp(): %.100s", strerror(oerrno));
|
||||
- return oerrno;
|
||||
+#if !defined(HEIMDAL)
|
||||
+int
|
||||
+ssh_asprintf_append(char **dsc, const char *fmt, ...) {
|
||||
+ char *src, *old;
|
||||
+ va_list ap;
|
||||
+ int i;
|
||||
+
|
||||
+ va_start(ap, fmt);
|
||||
+ i = vasprintf(&src, fmt, ap);
|
||||
+ va_end(ap);
|
||||
+
|
||||
+ if (i == -1 || src == NULL)
|
||||
+ return -1;
|
||||
+
|
||||
+ old = *dsc;
|
||||
+
|
||||
+ i = asprintf(dsc, "%s%s", *dsc, src);
|
||||
+ if (i == -1) {
|
||||
+ *dsc = old;
|
||||
+ free(src);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ free(old);
|
||||
+ free(src);
|
||||
+
|
||||
+ return i;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+ssh_krb5_expand_template(char **result, const char *template) {
|
||||
+ char *p_n, *p_o, *r, *tmp_template;
|
||||
+
|
||||
+ debug3_f("called, template = %s", template);
|
||||
+ if (template == NULL)
|
||||
+ return -1;
|
||||
+
|
||||
+ tmp_template = p_n = p_o = xstrdup(template);
|
||||
+ r = xstrdup("");
|
||||
+
|
||||
+ while ((p_n = strstr(p_o, "%{")) != NULL) {
|
||||
+
|
||||
+ *p_n++ = '\0';
|
||||
+ if (ssh_asprintf_append(&r, "%s", p_o) == -1)
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ if (strncmp(p_n, "{uid}", 5) == 0 || strncmp(p_n, "{euid}", 6) == 0 ||
|
||||
+ strncmp(p_n, "{USERID}", 8) == 0) {
|
||||
+ p_o = strchr(p_n, '}') + 1;
|
||||
+ if (ssh_asprintf_append(&r, "%d", geteuid()) == -1)
|
||||
+ goto cleanup;
|
||||
+ continue;
|
||||
+ }
|
||||
+ else if (strncmp(p_n, "{TEMP}", 6) == 0) {
|
||||
+ p_o = strchr(p_n, '}') + 1;
|
||||
+ if (ssh_asprintf_append(&r, "/tmp") == -1)
|
||||
+ goto cleanup;
|
||||
+ continue;
|
||||
+ } else {
|
||||
+ p_o = strchr(p_n, '}') + 1;
|
||||
+ *p_o = '\0';
|
||||
+ debug_f("unsupported token %s in %s", p_n, template);
|
||||
+ /* unknown token, fallback to the default */
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
}
|
||||
|
||||
- if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) {
|
||||
+ if (ssh_asprintf_append(&r, "%s", p_o) == -1)
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ *result = r;
|
||||
+ free(tmp_template);
|
||||
+ return 0;
|
||||
+
|
||||
+cleanup:
|
||||
+ free(r);
|
||||
+ free(tmp_template);
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+krb5_error_code
|
||||
+ssh_krb5_get_cctemplate(krb5_context ctx, char **ccname) {
|
||||
+ profile_t p;
|
||||
+ int ret = 0;
|
||||
+ char *value = NULL;
|
||||
+
|
||||
+ debug3_f("called");
|
||||
+ ret = krb5_get_profile(ctx, &p);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = profile_get_string(p, "libdefaults", "default_ccache_name", NULL, NULL, &value);
|
||||
+ if (ret || !value)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = ssh_krb5_expand_template(ccname, value);
|
||||
+
|
||||
+ debug3_f("returning with ccname = %s", *ccname);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+krb5_error_code
|
||||
+ssh_krb5_cc_new_unique(krb5_context ctx, krb5_ccache *ccache, int *need_environment) {
|
||||
+ int tmpfd, ret, oerrno, type_len;
|
||||
+ char *ccname = NULL;
|
||||
+ mode_t old_umask;
|
||||
+ char *type = NULL, *colon = NULL;
|
||||
+
|
||||
+ debug3_f("called");
|
||||
+ if (need_environment)
|
||||
+ *need_environment = 0;
|
||||
+ ret = ssh_krb5_get_cctemplate(ctx, &ccname);
|
||||
+ if (ret || !ccname || options.kerberos_unique_ccache) {
|
||||
+ /* Otherwise, go with the old method */
|
||||
+ if (ccname)
|
||||
+ free(ccname);
|
||||
+ ccname = NULL;
|
||||
+
|
||||
+ ret = asprintf(&ccname,
|
||||
+ "FILE:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid());
|
||||
+ if (ret < 0)
|
||||
+ return ENOMEM;
|
||||
+
|
||||
+ old_umask = umask(0177);
|
||||
+ tmpfd = mkstemp(ccname + strlen("FILE:"));
|
||||
oerrno = errno;
|
||||
- logit("fchmod(): %.100s", strerror(oerrno));
|
||||
+ umask(old_umask);
|
||||
+ if (tmpfd == -1) {
|
||||
+ logit("mkstemp(): %.100s", strerror(oerrno));
|
||||
+ return oerrno;
|
||||
+ }
|
||||
+
|
||||
+ if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) {
|
||||
+ oerrno = errno;
|
||||
+ logit("fchmod(): %.100s", strerror(oerrno));
|
||||
+ close(tmpfd);
|
||||
+ return oerrno;
|
||||
+ }
|
||||
+ /* make sure the KRB5CCNAME is set for non-standard location */
|
||||
+ if (need_environment)
|
||||
+ *need_environment = 1;
|
||||
close(tmpfd);
|
||||
- return oerrno;
|
||||
}
|
||||
- close(tmpfd);
|
||||
|
||||
- return (krb5_cc_resolve(ctx, ccname, ccache));
|
||||
+ debug3_f("setting default ccname to %s", ccname);
|
||||
+ /* set the default with already expanded user IDs */
|
||||
+ ret = krb5_cc_set_default_name(ctx, ccname);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ if ((colon = strstr(ccname, ":")) != NULL) {
|
||||
+ type_len = colon - ccname;
|
||||
+ type = malloc((type_len + 1) * sizeof(char));
|
||||
+ if (type == NULL)
|
||||
+ return ENOMEM;
|
||||
+ strncpy(type, ccname, type_len);
|
||||
+ type[type_len] = 0;
|
||||
+ } else {
|
||||
+ type = strdup(ccname);
|
||||
+ }
|
||||
+
|
||||
+ /* If we have a credential cache from krb5.conf, we need to switch
|
||||
+ * a primary cache for this collection, if it supports that (non-FILE)
|
||||
+ */
|
||||
+ if (krb5_cc_support_switch(ctx, type)) {
|
||||
+ debug3_f("calling cc_new_unique(%s)", ccname);
|
||||
+ ret = krb5_cc_new_unique(ctx, type, NULL, ccache);
|
||||
+ free(type);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ debug3_f("calling cc_switch()");
|
||||
+ return krb5_cc_switch(ctx, *ccache);
|
||||
+ } else {
|
||||
+ /* Otherwise, we can not create a unique ccname here (either
|
||||
+ * it is already unique from above or the type does not support
|
||||
+ * collections
|
||||
+ */
|
||||
+ free(type);
|
||||
+ debug3_f("calling cc_resolve(%s)", ccname);
|
||||
+ return (krb5_cc_resolve(ctx, ccname, ccache));
|
||||
+ }
|
||||
}
|
||||
#endif /* !HEIMDAL */
|
||||
#endif /* KRB5 */
|
||||
diff --git a/auth.h b/auth.h
|
||||
index 83d07ae8..10e88e11 100644
|
||||
--- a/auth.h
|
||||
+++ b/auth.h
|
||||
@@ -85,6 +85,7 @@ struct Authctxt {
|
||||
krb5_principal krb5_user;
|
||||
char *krb5_ticket_file;
|
||||
char *krb5_ccname;
|
||||
+ int krb5_set_env;
|
||||
#endif
|
||||
struct sshbuf *loginmsg;
|
||||
|
||||
@@ -245,7 +246,7 @@ FILE *auth_openprincipals(const char *, struct passwd *, int);
|
||||
int sys_auth_passwd(struct ssh *, const char *);
|
||||
|
||||
#if defined(KRB5) && !defined(HEIMDAL)
|
||||
-krb5_error_code ssh_krb5_cc_gen(krb5_context, krb5_ccache *);
|
||||
+krb5_error_code ssh_krb5_cc_new_unique(krb5_context, krb5_ccache *, int *);
|
||||
#endif
|
||||
|
||||
#endif /* AUTH_H */
|
||||
diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c
|
||||
index 14502c5a..df55512d 100644
|
||||
--- a/gss-serv-krb5.c
|
||||
+++ b/gss-serv-krb5.c
|
||||
@@ -267,7 +267,7 @@ ssh_gssapi_krb5_cmdok(krb5_principal principal, const char *name,
|
||||
/* This writes out any forwarded credentials from the structure populated
|
||||
* during userauth. Called after we have setuid to the user */
|
||||
|
||||
-static void
|
||||
+static int
|
||||
ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
|
||||
{
|
||||
krb5_ccache ccache;
|
||||
@@ -276,14 +276,15 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
|
||||
OM_uint32 maj_status, min_status;
|
||||
const char *new_ccname, *new_cctype;
|
||||
const char *errmsg;
|
||||
+ int set_env = 0;
|
||||
|
||||
if (client->creds == NULL) {
|
||||
debug("No credentials stored");
|
||||
- return;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
if (ssh_gssapi_krb5_init() == 0)
|
||||
- return;
|
||||
+ return 0;
|
||||
|
||||
#ifdef HEIMDAL
|
||||
# ifdef HAVE_KRB5_CC_NEW_UNIQUE
|
||||
@@ -297,14 +298,14 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
|
||||
krb5_get_err_text(krb_context, problem));
|
||||
# endif
|
||||
krb5_free_error_message(krb_context, errmsg);
|
||||
- return;
|
||||
+ return 0;
|
||||
}
|
||||
#else
|
||||
- if ((problem = ssh_krb5_cc_gen(krb_context, &ccache))) {
|
||||
+ if ((problem = ssh_krb5_cc_new_unique(krb_context, &ccache, &set_env)) != 0) {
|
||||
errmsg = krb5_get_error_message(krb_context, problem);
|
||||
- logit("ssh_krb5_cc_gen(): %.100s", errmsg);
|
||||
+ logit("ssh_krb5_cc_new_unique(): %.100s", errmsg);
|
||||
krb5_free_error_message(krb_context, errmsg);
|
||||
- return;
|
||||
+ return 0;
|
||||
}
|
||||
#endif /* #ifdef HEIMDAL */
|
||||
|
||||
@@ -313,7 +314,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
|
||||
errmsg = krb5_get_error_message(krb_context, problem);
|
||||
logit("krb5_parse_name(): %.100s", errmsg);
|
||||
krb5_free_error_message(krb_context, errmsg);
|
||||
- return;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
if ((problem = krb5_cc_initialize(krb_context, ccache, princ))) {
|
||||
@@ -322,7 +323,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
|
||||
krb5_free_error_message(krb_context, errmsg);
|
||||
krb5_free_principal(krb_context, princ);
|
||||
krb5_cc_destroy(krb_context, ccache);
|
||||
- return;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
krb5_free_principal(krb_context, princ);
|
||||
@@ -331,32 +332,21 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
|
||||
client->creds, ccache))) {
|
||||
logit("gss_krb5_copy_ccache() failed");
|
||||
krb5_cc_destroy(krb_context, ccache);
|
||||
- return;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
new_cctype = krb5_cc_get_type(krb_context, ccache);
|
||||
new_ccname = krb5_cc_get_name(krb_context, ccache);
|
||||
-
|
||||
- client->store.envvar = "KRB5CCNAME";
|
||||
-#ifdef USE_CCAPI
|
||||
- xasprintf(&client->store.envval, "API:%s", new_ccname);
|
||||
- client->store.filename = NULL;
|
||||
-#else
|
||||
- if (new_ccname[0] == ':')
|
||||
- new_ccname++;
|
||||
xasprintf(&client->store.envval, "%s:%s", new_cctype, new_ccname);
|
||||
- if (strcmp(new_cctype, "DIR") == 0) {
|
||||
- char *p;
|
||||
- p = strrchr(client->store.envval, '/');
|
||||
- if (p)
|
||||
- *p = '\0';
|
||||
+
|
||||
+ if (set_env) {
|
||||
+ client->store.envvar = "KRB5CCNAME";
|
||||
}
|
||||
if ((strcmp(new_cctype, "FILE") == 0) || (strcmp(new_cctype, "DIR") == 0))
|
||||
client->store.filename = xstrdup(new_ccname);
|
||||
-#endif
|
||||
|
||||
#ifdef USE_PAM
|
||||
- if (options.use_pam)
|
||||
+ if (options.use_pam && set_env)
|
||||
do_pam_putenv(client->store.envvar, client->store.envval);
|
||||
#endif
|
||||
|
||||
@@ -364,7 +354,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
|
||||
|
||||
client->store.data = krb_context;
|
||||
|
||||
- return;
|
||||
+ return set_env;
|
||||
}
|
||||
|
||||
int
|
||||
diff --git a/gss-serv.c b/gss-serv.c
|
||||
index a5cca797..9d5435ed 100644
|
||||
--- a/gss-serv.c
|
||||
+++ b/gss-serv.c
|
||||
@@ -414,13 +414,15 @@ ssh_gssapi_cleanup_creds(void)
|
||||
}
|
||||
|
||||
/* As user */
|
||||
-void
|
||||
+int
|
||||
ssh_gssapi_storecreds(void)
|
||||
{
|
||||
if (gssapi_client.mech && gssapi_client.mech->storecreds) {
|
||||
- (*gssapi_client.mech->storecreds)(&gssapi_client);
|
||||
+ return (*gssapi_client.mech->storecreds)(&gssapi_client);
|
||||
} else
|
||||
debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism");
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
/* This allows GSSAPI methods to do things to the child's environment based
|
||||
@@ -500,9 +502,7 @@ ssh_gssapi_rekey_creds(void) {
|
||||
char *envstr;
|
||||
#endif
|
||||
|
||||
- if (gssapi_client.store.filename == NULL &&
|
||||
- gssapi_client.store.envval == NULL &&
|
||||
- gssapi_client.store.envvar == NULL)
|
||||
+ if (gssapi_client.store.envval == NULL)
|
||||
return;
|
||||
|
||||
ok = mm_ssh_gssapi_update_creds(&gssapi_client.store);
|
||||
diff --git a/servconf.c b/servconf.c
|
||||
index d4f7fd66..55aa5bf0 100644
|
||||
--- a/servconf.c
|
||||
+++ b/servconf.c
|
||||
@@ -138,6 +138,7 @@ initialize_server_options(ServerOptions *options)
|
||||
options->kerberos_or_local_passwd = -1;
|
||||
options->kerberos_ticket_cleanup = -1;
|
||||
options->kerberos_get_afs_token = -1;
|
||||
+ options->kerberos_unique_ccache = -1;
|
||||
options->gss_authentication=-1;
|
||||
options->gss_keyex = -1;
|
||||
options->gss_cleanup_creds = -1;
|
||||
@@ -382,6 +383,8 @@ fill_default_server_options(ServerOptions *options)
|
||||
options->kerberos_ticket_cleanup = 1;
|
||||
if (options->kerberos_get_afs_token == -1)
|
||||
options->kerberos_get_afs_token = 0;
|
||||
+ if (options->kerberos_unique_ccache == -1)
|
||||
+ options->kerberos_unique_ccache = 0;
|
||||
if (options->gss_authentication == -1)
|
||||
options->gss_authentication = 0;
|
||||
if (options->gss_keyex == -1)
|
||||
@@ -564,7 +567,7 @@ typedef enum {
|
||||
sPort, sHostKeyFile, sLoginGraceTime,
|
||||
sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose,
|
||||
sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
|
||||
- sKerberosGetAFSToken, sPasswordAuthentication,
|
||||
+ sKerberosGetAFSToken, sKerberosUniqueCCache, sPasswordAuthentication,
|
||||
sKbdInteractiveAuthentication, sListenAddress, sAddressFamily,
|
||||
sPrintMotd, sPrintLastLog, sIgnoreRhosts,
|
||||
sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
|
||||
@@ -655,11 +658,13 @@ static struct {
|
||||
#else
|
||||
{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
|
||||
#endif
|
||||
+ { "kerberosuniqueccache", sKerberosUniqueCCache, SSHCFG_GLOBAL },
|
||||
#else
|
||||
{ "kerberosauthentication", sUnsupported, SSHCFG_ALL },
|
||||
{ "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
|
||||
{ "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
|
||||
{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
|
||||
+ { "kerberosuniqueccache", sUnsupported, SSHCFG_GLOBAL },
|
||||
#endif
|
||||
{ "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
|
||||
{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
|
||||
@@ -1668,6 +1673,10 @@ process_server_config_line_depth(ServerOptions *options, char *line,
|
||||
intptr = &options->kerberos_get_afs_token;
|
||||
goto parse_flag;
|
||||
|
||||
+ case sKerberosUniqueCCache:
|
||||
+ intptr = &options->kerberos_unique_ccache;
|
||||
+ goto parse_flag;
|
||||
+
|
||||
case sGssAuthentication:
|
||||
intptr = &options->gss_authentication;
|
||||
goto parse_flag;
|
||||
@@ -3293,6 +3302,7 @@ dump_config(ServerOptions *o)
|
||||
# ifdef USE_AFS
|
||||
dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token);
|
||||
# endif
|
||||
+ dump_cfg_fmtint(sKerberosUniqueCCache, o->kerberos_unique_ccache);
|
||||
#endif
|
||||
#ifdef GSSAPI
|
||||
dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
|
||||
diff --git a/servconf.h b/servconf.h
|
||||
index c3f50140..a4a38d6d 100644
|
||||
--- a/servconf.h
|
||||
+++ b/servconf.h
|
||||
@@ -149,6 +149,8 @@ typedef struct {
|
||||
* file on logout. */
|
||||
int kerberos_get_afs_token; /* If true, try to get AFS token if
|
||||
* authenticated with Kerberos. */
|
||||
+ int kerberos_unique_ccache; /* If true, the acquired ticket will
|
||||
+ * be stored in per-session ccache */
|
||||
int gss_authentication; /* If true, permit GSSAPI authentication */
|
||||
int gss_keyex; /* If true, permit GSSAPI key exchange */
|
||||
int gss_cleanup_creds; /* If true, destroy cred cache on logout */
|
||||
diff --git a/session.c b/session.c
|
||||
index 89b3a9cf..2620dd11 100644
|
||||
--- a/session.c
|
||||
+++ b/session.c
|
||||
@@ -1025,7 +1025,8 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell)
|
||||
/* Allow any GSSAPI methods that we've used to alter
|
||||
* the child's environment as they see fit
|
||||
*/
|
||||
- ssh_gssapi_do_child(&env, &envsize);
|
||||
+ if (s->authctxt->krb5_set_env)
|
||||
+ ssh_gssapi_do_child(&env, &envsize);
|
||||
#endif
|
||||
|
||||
/* Set basic environment. */
|
||||
@@ -1101,7 +1102,7 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell)
|
||||
}
|
||||
#endif
|
||||
#ifdef KRB5
|
||||
- if (s->authctxt->krb5_ccname)
|
||||
+ if (s->authctxt->krb5_ccname && s->authctxt->krb5_set_env)
|
||||
child_set_env(&env, &envsize, "KRB5CCNAME",
|
||||
s->authctxt->krb5_ccname);
|
||||
#endif
|
||||
diff --git a/ssh-gss.h b/ssh-gss.h
|
||||
index db34d77f..a894e23c 100644
|
||||
--- a/ssh-gss.h
|
||||
+++ b/ssh-gss.h
|
||||
@@ -116,7 +116,7 @@ typedef struct ssh_gssapi_mech_struct {
|
||||
int (*dochild) (ssh_gssapi_client *);
|
||||
int (*userok) (ssh_gssapi_client *, char *);
|
||||
int (*localname) (ssh_gssapi_client *, char **);
|
||||
- void (*storecreds) (ssh_gssapi_client *);
|
||||
+ int (*storecreds) (ssh_gssapi_client *);
|
||||
int (*updatecreds) (ssh_gssapi_ccache *, ssh_gssapi_client *);
|
||||
} ssh_gssapi_mech;
|
||||
|
||||
@@ -186,7 +186,7 @@ int ssh_gssapi_userok(char *name, struct passwd *, int kex);
|
||||
OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t);
|
||||
void ssh_gssapi_do_child(char ***, u_int *);
|
||||
void ssh_gssapi_cleanup_creds(void);
|
||||
-void ssh_gssapi_storecreds(void);
|
||||
+int ssh_gssapi_storecreds(void);
|
||||
const char *ssh_gssapi_displayname(void);
|
||||
|
||||
char *ssh_gssapi_server_mechanisms(void);
|
||||
diff --git a/sshd-session.c b/sshd-session.c
|
||||
index f8c8a797..478381db 100644
|
||||
--- a/sshd-session.c
|
||||
+++ b/sshd-session.c
|
||||
@@ -1349,7 +1349,7 @@ main(int ac, char **av)
|
||||
#ifdef GSSAPI
|
||||
if (options.gss_authentication) {
|
||||
temporarily_use_uid(authctxt->pw);
|
||||
- ssh_gssapi_storecreds();
|
||||
+ authctxt->krb5_set_env = ssh_gssapi_storecreds();
|
||||
restore_uid();
|
||||
}
|
||||
#endif
|
||||
diff --git a/sshd_config.5 b/sshd_config.5
|
||||
index 8bc6586e..1251d4d5 100644
|
||||
--- a/sshd_config.5
|
||||
+++ b/sshd_config.5
|
||||
@@ -1033,6 +1033,14 @@ Specifies whether to automatically destroy the user's ticket cache
|
||||
file on logout.
|
||||
The default is
|
||||
.Cm yes .
|
||||
+.It Cm KerberosUniqueCCache
|
||||
+Specifies whether to store the acquired tickets in the per-session credential
|
||||
+cache under /tmp/ or whether to use per-user credential cache as configured in
|
||||
+.Pa /etc/krb5.conf .
|
||||
+The default value
|
||||
+.Cm no
|
||||
+can lead to overwriting previous tickets by subseqent connections to the same
|
||||
+user account.
|
||||
.It Cm KexAlgorithms
|
||||
Specifies the permitted KEX (Key Exchange) algorithms that the server will
|
||||
offer to clients.
|
||||
--
|
||||
2.49.0
|
||||
|
||||
102
0015-openssh-7.2p2-k5login_directory.patch
Normal file
102
0015-openssh-7.2p2-k5login_directory.patch
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
From 25540939422660b024b8832f67eab82267aa8df6 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:28 +0200
|
||||
Subject: [PATCH 15/50] openssh-7.2p2-k5login_directory
|
||||
|
||||
---
|
||||
auth-krb5.c | 16 ++++++++++++++++
|
||||
auth.h | 2 ++
|
||||
gss-serv-krb5.c | 21 ++++++++++++++++++++-
|
||||
sshd.8 | 4 ++++
|
||||
4 files changed, 42 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/auth-krb5.c b/auth-krb5.c
|
||||
index 77714e3d..74f56d47 100644
|
||||
--- a/auth-krb5.c
|
||||
+++ b/auth-krb5.c
|
||||
@@ -465,5 +465,21 @@ ssh_krb5_cc_new_unique(krb5_context ctx, krb5_ccache *ccache, int *need_environm
|
||||
return (krb5_cc_resolve(ctx, ccname, ccache));
|
||||
}
|
||||
}
|
||||
+
|
||||
+/*
|
||||
+ * Reads k5login_directory option from the krb5.conf
|
||||
+ */
|
||||
+krb5_error_code
|
||||
+ssh_krb5_get_k5login_directory(krb5_context ctx, char **k5login_directory) {
|
||||
+ profile_t p;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ ret = krb5_get_profile(ctx, &p);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return profile_get_string(p, "libdefaults", "k5login_directory", NULL, NULL,
|
||||
+ k5login_directory);
|
||||
+}
|
||||
#endif /* !HEIMDAL */
|
||||
#endif /* KRB5 */
|
||||
diff --git a/auth.h b/auth.h
|
||||
index 10e88e11..39163035 100644
|
||||
--- a/auth.h
|
||||
+++ b/auth.h
|
||||
@@ -247,6 +247,8 @@ int sys_auth_passwd(struct ssh *, const char *);
|
||||
|
||||
#if defined(KRB5) && !defined(HEIMDAL)
|
||||
krb5_error_code ssh_krb5_cc_new_unique(krb5_context, krb5_ccache *, int *);
|
||||
+krb5_error_code ssh_krb5_get_k5login_directory(krb5_context ctx,
|
||||
+ char **k5login_directory);
|
||||
#endif
|
||||
|
||||
#endif /* AUTH_H */
|
||||
diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c
|
||||
index df55512d..820f794c 100644
|
||||
--- a/gss-serv-krb5.c
|
||||
+++ b/gss-serv-krb5.c
|
||||
@@ -144,8 +144,27 @@ ssh_gssapi_k5login_exists()
|
||||
{
|
||||
char file[MAXPATHLEN];
|
||||
struct passwd *pw = the_authctxt->pw;
|
||||
+ char *k5login_directory = NULL;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ ret = ssh_krb5_get_k5login_directory(krb_context, &k5login_directory);
|
||||
+ debug3_f("k5login_directory = %s (rv=%d)", k5login_directory, ret);
|
||||
+ if (k5login_directory == NULL || ret != 0) {
|
||||
+ /* If not set, the library will look for k5login
|
||||
+ * files in the user's home directory, with the filename .k5login.
|
||||
+ */
|
||||
+ snprintf(file, sizeof(file), "%s/.k5login", pw->pw_dir);
|
||||
+ } else {
|
||||
+ /* If set, the library will look for a local user's k5login file
|
||||
+ * within the named directory, with a filename corresponding to the
|
||||
+ * local username.
|
||||
+ */
|
||||
+ snprintf(file, sizeof(file), "%s%s%s", k5login_directory,
|
||||
+ k5login_directory[strlen(k5login_directory)-1] != '/' ? "/" : "",
|
||||
+ pw->pw_name);
|
||||
+ }
|
||||
+ debug_f("Checking existence of file %s", file);
|
||||
|
||||
- snprintf(file, sizeof(file), "%s/.k5login", pw->pw_dir);
|
||||
return access(file, F_OK) == 0;
|
||||
}
|
||||
|
||||
diff --git a/sshd.8 b/sshd.8
|
||||
index 049d0a94..6784286d 100644
|
||||
--- a/sshd.8
|
||||
+++ b/sshd.8
|
||||
@@ -880,6 +880,10 @@ rlogin/rsh.
|
||||
These files enforce GSSAPI/Kerberos authentication access control.
|
||||
Further details are described in
|
||||
.Xr ksu 1 .
|
||||
+The location of the k5login file depends on the configuration option
|
||||
+.Cm k5login_directory
|
||||
+in the
|
||||
+.Xr krb5.conf 5 .
|
||||
.Pp
|
||||
.It Pa ~/.ssh/
|
||||
This directory is the default location for all user-specific configuration
|
||||
--
|
||||
2.49.0
|
||||
|
||||
312
0016-openssh-6.6p1-kuserok.patch
Normal file
312
0016-openssh-6.6p1-kuserok.patch
Normal file
|
|
@ -0,0 +1,312 @@
|
|||
From bac7a9d1a654c8c2e0c71f979195e300b25d6232 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:28 +0200
|
||||
Subject: [PATCH 16/50] openssh-6.6p1-kuserok
|
||||
|
||||
---
|
||||
auth-krb5.c | 20 ++++++++-
|
||||
gss-serv-krb5.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++--
|
||||
servconf.c | 13 +++++-
|
||||
servconf.h | 1 +
|
||||
sshd_config | 1 +
|
||||
sshd_config.5 | 5 +++
|
||||
6 files changed, 139 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/auth-krb5.c b/auth-krb5.c
|
||||
index 74f56d47..bae153c9 100644
|
||||
--- a/auth-krb5.c
|
||||
+++ b/auth-krb5.c
|
||||
@@ -55,6 +55,21 @@
|
||||
|
||||
extern ServerOptions options;
|
||||
|
||||
+int
|
||||
+ssh_krb5_kuserok(krb5_context krb5_ctx, krb5_principal krb5_user, const char *client,
|
||||
+ int k5login_exists)
|
||||
+{
|
||||
+ if (options.use_kuserok || !k5login_exists)
|
||||
+ 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)
|
||||
{
|
||||
@@ -158,8 +173,9 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
|
||||
if (problem)
|
||||
goto out;
|
||||
|
||||
- if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user,
|
||||
- authctxt->pw->pw_name)) {
|
||||
+ /* Use !options.use_kuserok here to make ssh_krb5_kuserok() not
|
||||
+ * depend on the existance of .k5login */
|
||||
+ if (!ssh_krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, authctxt->pw->pw_name, !options.use_kuserok)) {
|
||||
problem = -1;
|
||||
goto out;
|
||||
}
|
||||
diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c
|
||||
index 820f794c..187faf92 100644
|
||||
--- a/gss-serv-krb5.c
|
||||
+++ b/gss-serv-krb5.c
|
||||
@@ -66,6 +66,7 @@ static int ssh_gssapi_krb5_cmdok(krb5_principal, const char *, const char *,
|
||||
int);
|
||||
|
||||
static krb5_context krb_context = NULL;
|
||||
+extern int ssh_krb5_kuserok(krb5_context, krb5_principal, const char *, int);
|
||||
|
||||
/* Initialise the krb5 library, for the stuff that GSSAPI won't do */
|
||||
|
||||
@@ -91,6 +92,103 @@ ssh_gssapi_krb5_init(void)
|
||||
* Returns true if the user is OK to log in, otherwise returns 0
|
||||
*/
|
||||
|
||||
+/* The purpose of the function is to find out if a Kerberos principal is
|
||||
+ * allowed to log in as the given local user. This is a general problem with
|
||||
+ * Kerberized services because by design the Kerberos principals are
|
||||
+ * completely independent from the local user names. This is one of the
|
||||
+ * reasons why Kerberos is working well on different operating systems like
|
||||
+ * Windows and UNIX/Linux. Nevertheless a relationship between a Kerberos
|
||||
+ * principal and a local user name must be established because otherwise every
|
||||
+ * access would be granted for every principal with a valid ticket.
|
||||
+ *
|
||||
+ * Since it is a general issue libkrb5 provides some functions for
|
||||
+ * applications to find out about the relationship between the Kerberos
|
||||
+ * principal and a local user name. They are krb5_kuserok() and
|
||||
+ * krb5_aname_to_localname().
|
||||
+ *
|
||||
+ * krb5_kuserok() can be used to "Determine if a principal is authorized to
|
||||
+ * log in as a local user" (from the MIT Kerberos documentation of this
|
||||
+ * function). Which is exactly what we are looking for and should be the
|
||||
+ * preferred choice. It accepts the Kerberos principal and a local user name
|
||||
+ * and let libkrb5 or its plugins determine if they relate to each other or
|
||||
+ * not.
|
||||
+ *
|
||||
+ * krb5_aname_to_localname() can use used to "Convert a principal name to a
|
||||
+ * local name" (from the MIT Kerberos documentation of this function). It
|
||||
+ * accepts a Kerberos principle and returns a local name and it is up to the
|
||||
+ * application to do any additional checks. There are two issues using
|
||||
+ * krb5_aname_to_localname(). First, since POSIX user names are case
|
||||
+ * sensitive, the calling application in general has no other choice than
|
||||
+ * doing a case-sensitive string comparison between the name returned by
|
||||
+ * krb5_aname_to_localname() and the name used at the login prompt. When the
|
||||
+ * users are provided by a case in-sensitive server, e.g. Active Directory,
|
||||
+ * this might lead to login failures because the user typing the name at the
|
||||
+ * login prompt might not be aware of the right case. Another issue might be
|
||||
+ * caused if there are multiple alias names available for a single user. E.g.
|
||||
+ * the canonical name of a user is user@group.department.example.com but there
|
||||
+ * exists a shorter login name, e.g. user@example.com, to safe typing at the
|
||||
+ * login prompt. Here krb5_aname_to_localname() can only return the canonical
|
||||
+ * name, but if the short alias is used at the login prompt authentication
|
||||
+ * will fail as well. All this can be avoided by using krb5_kuserok() and
|
||||
+ * configuring krb5.conf or using a suitable plugin to meet the needs of the
|
||||
+ * given environment.
|
||||
+ *
|
||||
+ * The Fedora and RHEL version of openssh contain two patches which modify the
|
||||
+ * access control behavior:
|
||||
+ * - openssh-6.6p1-kuserok.patch
|
||||
+ * - openssh-6.6p1-force_krb.patch
|
||||
+ *
|
||||
+ * openssh-6.6p1-kuserok.patch adds a new option KerberosUseKuserok for
|
||||
+ * sshd_config which controls if krb5_kuserok() is used to check if the
|
||||
+ * principle is authorized or if krb5_aname_to_localname() should be used.
|
||||
+ * The reason to add this patch was that krb5_kuserok() by default checks if
|
||||
+ * a .k5login file exits in the users home-directory. With this the user can
|
||||
+ * give access to his account for any given principal which might be
|
||||
+ * in violation with company policies and it would be useful if this can be
|
||||
+ * rejected. Nevertheless the patch ignores the fact that krb5_kuserok() does
|
||||
+ * no only check .k5login but other sources as well and checking .k5login can
|
||||
+ * be disabled for all applications in krb5.conf as well. With this new
|
||||
+ * option KerberosUseKuserok set to 'no' (and this is the default for RHEL7
|
||||
+ * and Fedora 21) openssh can only use krb5_aname_to_localname() with the
|
||||
+ * restrictions mentioned above.
|
||||
+ *
|
||||
+ * openssh-6.6p1-force_krb.patch adds a ksu like behaviour to ssh, i.e. when
|
||||
+ * using GSSAPI authentication only commands configured in the .k5user can be
|
||||
+ * executed. Here the wrong assumption that krb5_kuserok() only checks
|
||||
+ * .k5login is made as well. In contrast ksu checks .k5login directly and
|
||||
+ * does not use krb5_kuserok() which might be more useful for the given
|
||||
+ * purpose. Additionally this patch is not synced with
|
||||
+ * openssh-6.6p1-kuserok.patch.
|
||||
+ *
|
||||
+ * The current patch tries to restore the usage of krb5_kuserok() so that e.g.
|
||||
+ * localauth plugins can be used. It does so by adding a forth parameter to
|
||||
+ * ssh_krb5_kuserok() which indicates whether .k5login exists or not. If it
|
||||
+ * does not exists krb5_kuserok() is called even if KerberosUseKuserok is set
|
||||
+ * to 'no' because the intent of the option is to not check .k5login and if it
|
||||
+ * does not exists krb5_kuserok() returns a result without checking .k5login.
|
||||
+ * If .k5login does exists and KerberosUseKuserok is 'no' we fall back to
|
||||
+ * krb5_aname_to_localname(). This is in my point of view an acceptable
|
||||
+ * limitation and does not break the current behaviour.
|
||||
+ *
|
||||
+ * Additionally with this patch ssh_krb5_kuserok() is called in
|
||||
+ * ssh_gssapi_krb5_cmdok() instead of only krb5_aname_to_localname() is
|
||||
+ * neither .k5login nor .k5users exists to allow plugin evaluation via
|
||||
+ * krb5_kuserok() as well.
|
||||
+ *
|
||||
+ * I tried to keep the patch as minimal as possible, nevertheless I see some
|
||||
+ * areas for improvement which, if they make sense, have to be evaluated
|
||||
+ * carefully because they might change existing behaviour and cause breaks
|
||||
+ * during upgrade:
|
||||
+ * - I wonder if disabling .k5login usage make sense in sshd or if it should
|
||||
+ * be better disabled globally in krb5.conf
|
||||
+ * - if really needed openssh-6.6p1-kuserok.patch should be fixed to really
|
||||
+ * only disable checking .k5login and maybe .k5users
|
||||
+ * - the ksu behaviour should be configurable and maybe check the .k5login and
|
||||
+ * .k5users files directly like ksu itself does
|
||||
+ * - to make krb5_aname_to_localname() more useful an option for sshd to use
|
||||
+ * the canonical name (the one returned by getpwnam()) instead of the name
|
||||
+ * given at the login prompt might be useful */
|
||||
+
|
||||
static int
|
||||
ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name)
|
||||
{
|
||||
@@ -115,7 +213,8 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name)
|
||||
/* 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, name) && k5login_exists) {
|
||||
+ if (k5login_exists &&
|
||||
+ ssh_krb5_kuserok(krb_context, princ, name, k5login_exists)) {
|
||||
retval = 1;
|
||||
logit("Authorized to %s, krb5 principal %s (krb5_kuserok)",
|
||||
name, (char *)client->displayname.value);
|
||||
@@ -190,9 +289,8 @@ ssh_gssapi_krb5_cmdok(krb5_principal principal, const char *name,
|
||||
snprintf(file, sizeof(file), "%s/.k5users", pw->pw_dir);
|
||||
/* If both .k5login and .k5users DNE, self-login is ok. */
|
||||
if (!k5login_exists && (access(file, F_OK) == -1)) {
|
||||
- return (krb5_aname_to_localname(krb_context, principal,
|
||||
- sizeof(kuser), kuser) == 0) &&
|
||||
- (strcmp(kuser, luser) == 0);
|
||||
+ return ssh_krb5_kuserok(krb_context, principal, luser,
|
||||
+ k5login_exists);
|
||||
}
|
||||
if ((fp = fopen(file, "r")) == NULL) {
|
||||
int saved_errno = errno;
|
||||
diff --git a/servconf.c b/servconf.c
|
||||
index 55aa5bf0..5dd5ca21 100644
|
||||
--- a/servconf.c
|
||||
+++ b/servconf.c
|
||||
@@ -145,6 +145,7 @@ initialize_server_options(ServerOptions *options)
|
||||
options->gss_strict_acceptor = -1;
|
||||
options->gss_store_rekey = -1;
|
||||
options->gss_kex_algorithms = NULL;
|
||||
+ options->use_kuserok = -1;
|
||||
options->password_authentication = -1;
|
||||
options->kbd_interactive_authentication = -1;
|
||||
options->permit_empty_passwd = -1;
|
||||
@@ -399,6 +400,8 @@ fill_default_server_options(ServerOptions *options)
|
||||
if (options->gss_kex_algorithms == NULL)
|
||||
options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX);
|
||||
#endif
|
||||
+ if (options->use_kuserok == -1)
|
||||
+ options->use_kuserok = 1;
|
||||
if (options->password_authentication == -1)
|
||||
options->password_authentication = 1;
|
||||
if (options->kbd_interactive_authentication == -1)
|
||||
@@ -567,7 +570,7 @@ typedef enum {
|
||||
sPort, sHostKeyFile, sLoginGraceTime,
|
||||
sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose,
|
||||
sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
|
||||
- sKerberosGetAFSToken, sKerberosUniqueCCache, sPasswordAuthentication,
|
||||
+ sKerberosGetAFSToken, sKerberosUniqueCCache, sKerberosUseKuserok, sPasswordAuthentication,
|
||||
sKbdInteractiveAuthentication, sListenAddress, sAddressFamily,
|
||||
sPrintMotd, sPrintLastLog, sIgnoreRhosts,
|
||||
sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
|
||||
@@ -659,12 +662,14 @@ static struct {
|
||||
{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
|
||||
#endif
|
||||
{ "kerberosuniqueccache", sKerberosUniqueCCache, SSHCFG_GLOBAL },
|
||||
+ { "kerberosusekuserok", sKerberosUseKuserok, SSHCFG_ALL },
|
||||
#else
|
||||
{ "kerberosauthentication", sUnsupported, SSHCFG_ALL },
|
||||
{ "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
|
||||
{ "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
|
||||
{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
|
||||
{ "kerberosuniqueccache", sUnsupported, SSHCFG_GLOBAL },
|
||||
+ { "kerberosusekuserok", sUnsupported, SSHCFG_ALL },
|
||||
#endif
|
||||
{ "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
|
||||
{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
|
||||
@@ -2441,6 +2446,10 @@ process_server_config_line_depth(ServerOptions *options, char *line,
|
||||
}
|
||||
break;
|
||||
|
||||
+ case sKerberosUseKuserok:
|
||||
+ intptr = &options->use_kuserok;
|
||||
+ goto parse_flag;
|
||||
+
|
||||
case sMatch:
|
||||
if (cmdline)
|
||||
fatal("Match directive not supported as a command-line "
|
||||
@@ -2995,6 +3004,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
|
||||
M_CP_INTOPT(client_alive_interval);
|
||||
M_CP_INTOPT(ip_qos_interactive);
|
||||
M_CP_INTOPT(ip_qos_bulk);
|
||||
+ M_CP_INTOPT(use_kuserok);
|
||||
M_CP_INTOPT(rekey_limit);
|
||||
M_CP_INTOPT(rekey_interval);
|
||||
M_CP_INTOPT(log_level);
|
||||
@@ -3303,6 +3313,7 @@ dump_config(ServerOptions *o)
|
||||
dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token);
|
||||
# endif
|
||||
dump_cfg_fmtint(sKerberosUniqueCCache, o->kerberos_unique_ccache);
|
||||
+ dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok);
|
||||
#endif
|
||||
#ifdef GSSAPI
|
||||
dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
|
||||
diff --git a/servconf.h b/servconf.h
|
||||
index a4a38d6d..11de36a2 100644
|
||||
--- a/servconf.h
|
||||
+++ b/servconf.h
|
||||
@@ -151,6 +151,7 @@ typedef struct {
|
||||
* authenticated with Kerberos. */
|
||||
int kerberos_unique_ccache; /* If true, the acquired ticket will
|
||||
* be stored in per-session ccache */
|
||||
+ int use_kuserok;
|
||||
int gss_authentication; /* If true, permit GSSAPI authentication */
|
||||
int gss_keyex; /* If true, permit GSSAPI key exchange */
|
||||
int gss_cleanup_creds; /* If true, destroy cred cache on logout */
|
||||
diff --git a/sshd_config b/sshd_config
|
||||
index 8db9f0fb..ea5a878e 100644
|
||||
--- a/sshd_config
|
||||
+++ b/sshd_config
|
||||
@@ -75,6 +75,7 @@ AuthorizedKeysFile .ssh/authorized_keys
|
||||
#KerberosOrLocalPasswd yes
|
||||
#KerberosTicketCleanup yes
|
||||
#KerberosGetAFSToken no
|
||||
+#KerberosUseKuserok yes
|
||||
|
||||
# GSSAPI options
|
||||
#GSSAPIAuthentication no
|
||||
diff --git a/sshd_config.5 b/sshd_config.5
|
||||
index 1251d4d5..0fcb409a 100644
|
||||
--- a/sshd_config.5
|
||||
+++ b/sshd_config.5
|
||||
@@ -1041,6 +1041,10 @@ The default value
|
||||
.Cm no
|
||||
can lead to overwriting previous tickets by subseqent connections to the same
|
||||
user account.
|
||||
+.It Cm KerberosUseKuserok
|
||||
+Specifies whether to look at .k5login file for user's aliases.
|
||||
+The default is
|
||||
+.Cm yes .
|
||||
.It Cm KexAlgorithms
|
||||
Specifies the permitted KEX (Key Exchange) algorithms that the server will
|
||||
offer to clients.
|
||||
@@ -1355,6 +1359,7 @@ Available keywords are
|
||||
.Cm IPQoS ,
|
||||
.Cm KbdInteractiveAuthentication ,
|
||||
.Cm KerberosAuthentication ,
|
||||
+.Cm KerberosUseKuserok ,
|
||||
.Cm LogLevel ,
|
||||
.Cm MaxAuthTries ,
|
||||
.Cm MaxSessions ,
|
||||
--
|
||||
2.49.0
|
||||
|
||||
28
0017-openssh-6.4p1-fromto-remote.patch
Normal file
28
0017-openssh-6.4p1-fromto-remote.patch
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
From 20aabb2c445e29d211266ce7434bb0273edf88b9 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:28 +0200
|
||||
Subject: [PATCH 17/50] openssh-6.4p1-fromto-remote
|
||||
|
||||
---
|
||||
scp.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/scp.c b/scp.c
|
||||
index 57c242ff..716ae386 100644
|
||||
--- a/scp.c
|
||||
+++ b/scp.c
|
||||
@@ -1162,7 +1162,10 @@ toremote(int argc, char **argv, enum scp_mode_e mode, char *sftp_direct)
|
||||
addargs(&alist, "%s", ssh_program);
|
||||
addargs(&alist, "-x");
|
||||
addargs(&alist, "-oClearAllForwardings=yes");
|
||||
- addargs(&alist, "-n");
|
||||
+ if (isatty(fileno(stdin)))
|
||||
+ addargs(&alist, "-t");
|
||||
+ else
|
||||
+ addargs(&alist, "-n");
|
||||
for (j = 0; j < remote_remote_args.num; j++) {
|
||||
addargs(&alist, "%s",
|
||||
remote_remote_args.list[j]);
|
||||
--
|
||||
2.49.0
|
||||
|
||||
147
0018-openssh-6.6.1p1-selinux-contexts.patch
Normal file
147
0018-openssh-6.6.1p1-selinux-contexts.patch
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
From 6481ac7fbd0027a7038560e0f51dd0af056cc229 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:28 +0200
|
||||
Subject: [PATCH 18/50] openssh-6.6.1p1-selinux-contexts
|
||||
|
||||
---
|
||||
openbsd-compat/port-linux-sshd.c | 69 +++++++++++++++++++++++++++++++-
|
||||
openbsd-compat/port-linux.c | 2 +-
|
||||
openbsd-compat/port-linux.h | 1 +
|
||||
sshd-auth.c | 2 +-
|
||||
4 files changed, 71 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/openbsd-compat/port-linux-sshd.c b/openbsd-compat/port-linux-sshd.c
|
||||
index 8c5fc1fe..646f0887 100644
|
||||
--- a/openbsd-compat/port-linux-sshd.c
|
||||
+++ b/openbsd-compat/port-linux-sshd.c
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "misc.h" /* servconf.h needs misc.h for struct ForwardOptions */
|
||||
#include "servconf.h"
|
||||
#include "port-linux.h"
|
||||
+#include "misc.h"
|
||||
#include "sshkey.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
@@ -450,7 +451,7 @@ sshd_selinux_setup_exec_context(char *pwname)
|
||||
void
|
||||
sshd_selinux_copy_context(void)
|
||||
{
|
||||
- security_context_t *ctx;
|
||||
+ char *ctx;
|
||||
|
||||
if (!sshd_selinux_enabled())
|
||||
return;
|
||||
@@ -469,6 +470,72 @@ sshd_selinux_copy_context(void)
|
||||
}
|
||||
}
|
||||
|
||||
+void
|
||||
+sshd_selinux_change_privsep_preauth_context(void)
|
||||
+{
|
||||
+ int len;
|
||||
+ char line[1024], *preauth_context = NULL, *cp, *arg;
|
||||
+ const char *contexts_path;
|
||||
+ FILE *contexts_file;
|
||||
+ struct stat sb;
|
||||
+
|
||||
+ contexts_path = selinux_openssh_contexts_path();
|
||||
+ if (contexts_path == NULL) {
|
||||
+ debug3_f("Failed to get the path to SELinux context");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if ((contexts_file = fopen(contexts_path, "r")) == NULL) {
|
||||
+ debug_f("Failed to open SELinux context file");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (fstat(fileno(contexts_file), &sb) != 0 ||
|
||||
+ sb.st_uid != 0 || (sb.st_mode & 022) != 0) {
|
||||
+ logit_f("SELinux context file needs to be owned by root"
|
||||
+ " and not writable by anyone else");
|
||||
+ fclose(contexts_file);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ while (fgets(line, sizeof(line), contexts_file)) {
|
||||
+ /* Strip trailing whitespace */
|
||||
+ for (len = strlen(line) - 1; len > 0; len--) {
|
||||
+ if (strchr(" \t\r\n", line[len]) == NULL)
|
||||
+ break;
|
||||
+ line[len] = '\0';
|
||||
+ }
|
||||
+
|
||||
+ if (line[0] == '\0')
|
||||
+ continue;
|
||||
+
|
||||
+ cp = line;
|
||||
+ arg = strdelim(&cp);
|
||||
+ if (arg && *arg == '\0')
|
||||
+ arg = strdelim(&cp);
|
||||
+
|
||||
+ if (arg && strcmp(arg, "privsep_preauth") == 0) {
|
||||
+ arg = strdelim(&cp);
|
||||
+ if (!arg || *arg == '\0') {
|
||||
+ debug_f("privsep_preauth is empty");
|
||||
+ fclose(contexts_file);
|
||||
+ return;
|
||||
+ }
|
||||
+ preauth_context = xstrdup(arg);
|
||||
+ }
|
||||
+ }
|
||||
+ fclose(contexts_file);
|
||||
+
|
||||
+ if (preauth_context == NULL) {
|
||||
+ debug_f("Unable to find 'privsep_preauth' option in"
|
||||
+ " SELinux context file");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ ssh_selinux_change_context(preauth_context);
|
||||
+ free(preauth_context);
|
||||
+}
|
||||
+
|
||||
#endif
|
||||
#endif
|
||||
|
||||
diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c
|
||||
index 7426f6f7..9a6b1d6e 100644
|
||||
--- a/openbsd-compat/port-linux.c
|
||||
+++ b/openbsd-compat/port-linux.c
|
||||
@@ -188,7 +188,7 @@ ssh_selinux_change_context(const char *newname)
|
||||
xasprintf(&newctx, "%.*s%s%s", (int)(cx - oldctx + 1), oldctx,
|
||||
newname, cx2 == NULL ? "" : cx2);
|
||||
|
||||
- debug3_f("setting context from '%s' to '%s'", oldctx, newctx);
|
||||
+ debug_f("setting context from '%s' to '%s'", oldctx, newctx);
|
||||
if (setcon(newctx) < 0)
|
||||
do_log2_f(log_level, "setcon %s from %s failed with %s",
|
||||
newctx, oldctx, strerror(errno));
|
||||
diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h
|
||||
index 1b745a76..7f8ba200 100644
|
||||
--- a/openbsd-compat/port-linux.h
|
||||
+++ b/openbsd-compat/port-linux.h
|
||||
@@ -27,6 +27,7 @@ int sshd_selinux_enabled(void);
|
||||
void sshd_selinux_copy_context(void);
|
||||
void sshd_selinux_setup_exec_context(char *);
|
||||
int sshd_selinux_setup_env_variables(void);
|
||||
+void sshd_selinux_change_privsep_preauth_context(void);
|
||||
#endif
|
||||
|
||||
#ifdef LINUX_OOM_ADJUST
|
||||
diff --git a/sshd-auth.c b/sshd-auth.c
|
||||
index d51e4636..e4a8edfd 100644
|
||||
--- a/sshd-auth.c
|
||||
+++ b/sshd-auth.c
|
||||
@@ -188,7 +188,7 @@ privsep_child_demote(void)
|
||||
fatal_f("ssh_sandbox_init failed");
|
||||
#endif
|
||||
#ifdef WITH_SELINUX
|
||||
- ssh_selinux_change_context("sshd_net_t");
|
||||
+ sshd_selinux_change_privsep_preauth_context();
|
||||
#endif
|
||||
|
||||
/* Demote the child */
|
||||
--
|
||||
2.49.0
|
||||
|
||||
255
0019-openssh-6.6.1p1-log-in-chroot.patch
Normal file
255
0019-openssh-6.6.1p1-log-in-chroot.patch
Normal file
|
|
@ -0,0 +1,255 @@
|
|||
From 825018f5f2d892655f3d63167a0d1f3391cec678 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:28 +0200
|
||||
Subject: [PATCH 19/50] openssh-6.6.1p1-log-in-chroot
|
||||
|
||||
---
|
||||
log.c | 11 +++++++++--
|
||||
log.h | 1 +
|
||||
monitor.c | 17 +++++++++++++++--
|
||||
monitor.h | 2 +-
|
||||
session.c | 26 +++++++++++++++-----------
|
||||
sftp-server-main.c | 2 +-
|
||||
sftp-server.c | 6 +++---
|
||||
sftp.h | 2 +-
|
||||
sshd-session.c | 7 ++++++-
|
||||
9 files changed, 52 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/log.c b/log.c
|
||||
index 6617f267..9782cfb0 100644
|
||||
--- a/log.c
|
||||
+++ b/log.c
|
||||
@@ -196,6 +196,11 @@ void
|
||||
log_init(const char *av0, LogLevel level, SyslogFacility facility,
|
||||
int on_stderr)
|
||||
{
|
||||
+ log_init_handler(av0, level, facility, on_stderr, 1);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+log_init_handler(const char *av0, LogLevel level, SyslogFacility facility, int on_stderr, int reset_handler) {
|
||||
#if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT)
|
||||
struct syslog_data sdata = SYSLOG_DATA_INIT;
|
||||
#endif
|
||||
@@ -208,8 +213,10 @@ log_init(const char *av0, LogLevel level, SyslogFacility facility,
|
||||
exit(1);
|
||||
}
|
||||
|
||||
- log_handler = NULL;
|
||||
- log_handler_ctx = NULL;
|
||||
+ if (reset_handler) {
|
||||
+ log_handler = NULL;
|
||||
+ log_handler_ctx = NULL;
|
||||
+ }
|
||||
|
||||
log_on_stderr = on_stderr;
|
||||
if (on_stderr)
|
||||
diff --git a/log.h b/log.h
|
||||
index 8e8dfc23..70048a8a 100644
|
||||
--- a/log.h
|
||||
+++ b/log.h
|
||||
@@ -52,6 +52,7 @@ typedef enum {
|
||||
typedef void (log_handler_fn)(LogLevel, int, const char *, void *);
|
||||
|
||||
void log_init(const char *, LogLevel, SyslogFacility, int);
|
||||
+void log_init_handler(const char *, LogLevel, SyslogFacility, int, int);
|
||||
LogLevel log_level_get(void);
|
||||
int log_change_level(LogLevel);
|
||||
int log_is_on_stderr(void);
|
||||
diff --git a/monitor.c b/monitor.c
|
||||
index 2ef16cc8..43c10a4e 100644
|
||||
--- a/monitor.c
|
||||
+++ b/monitor.c
|
||||
@@ -2001,9 +2001,22 @@ monitor_init(void)
|
||||
}
|
||||
|
||||
void
|
||||
-monitor_reinit(struct monitor *mon)
|
||||
+monitor_reinit(struct monitor *mon, const char *chroot_dir)
|
||||
{
|
||||
- monitor_openfds(mon, 0);
|
||||
+ struct stat dev_log_stat;
|
||||
+ char *dev_log_path;
|
||||
+ int do_logfds = 0;
|
||||
+
|
||||
+ if (chroot_dir != NULL) {
|
||||
+ xasprintf(&dev_log_path, "%s/dev/log", chroot_dir);
|
||||
+
|
||||
+ if (stat(dev_log_path, &dev_log_stat) != 0) {
|
||||
+ debug_f("/dev/log doesn't exist in %s chroot - will try to log via monitor using [postauth] suffix", chroot_dir);
|
||||
+ do_logfds = 1;
|
||||
+ }
|
||||
+ free(dev_log_path);
|
||||
+ }
|
||||
+ monitor_openfds(mon, do_logfds);
|
||||
}
|
||||
|
||||
#ifdef GSSAPI
|
||||
diff --git a/monitor.h b/monitor.h
|
||||
index dbc7e003..d4d631dd 100644
|
||||
--- a/monitor.h
|
||||
+++ b/monitor.h
|
||||
@@ -85,7 +85,7 @@ struct monitor {
|
||||
};
|
||||
|
||||
struct monitor *monitor_init(void);
|
||||
-void monitor_reinit(struct monitor *);
|
||||
+void monitor_reinit(struct monitor *, const char *);
|
||||
|
||||
struct Authctxt;
|
||||
void monitor_child_preauth(struct ssh *, struct monitor *);
|
||||
diff --git a/session.c b/session.c
|
||||
index 2620dd11..54da09d5 100644
|
||||
--- a/session.c
|
||||
+++ b/session.c
|
||||
@@ -169,6 +169,7 @@ login_cap_t *lc;
|
||||
|
||||
static int is_child = 0;
|
||||
static int in_chroot = 0;
|
||||
+static int have_dev_log = 1;
|
||||
|
||||
/* File containing userauth info, if ExposeAuthInfo set */
|
||||
static char *auth_info_file = NULL;
|
||||
@@ -670,6 +671,7 @@ do_exec(struct ssh *ssh, Session *s, const char *command)
|
||||
int ret;
|
||||
const char *forced = NULL, *tty = NULL;
|
||||
char session_type[1024];
|
||||
+ struct stat dev_log_stat;
|
||||
|
||||
if (options.adm_forced_command) {
|
||||
original_command = command;
|
||||
@@ -729,6 +731,10 @@ do_exec(struct ssh *ssh, Session *s, const char *command)
|
||||
tty += 5;
|
||||
}
|
||||
|
||||
+ if (lstat("/dev/log", &dev_log_stat) != 0) {
|
||||
+ have_dev_log = 0;
|
||||
+ }
|
||||
+
|
||||
verbose("Starting session: %s%s%s for %s from %.200s port %d id %d",
|
||||
session_type,
|
||||
tty == NULL ? "" : " on ",
|
||||
@@ -1512,14 +1518,6 @@ child_close_fds(struct ssh *ssh)
|
||||
|
||||
/* Stop directing logs to a high-numbered fd before we close it */
|
||||
log_redirect_stderr_to(NULL);
|
||||
-
|
||||
- /*
|
||||
- * Close any extra open file descriptors so that we don't have them
|
||||
- * hanging around in clients. Note that we want to do this after
|
||||
- * initgroups, because at least on Solaris 2.3 it leaves file
|
||||
- * descriptors open.
|
||||
- */
|
||||
- closefrom(STDERR_FILENO + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1652,8 +1650,6 @@ do_child(struct ssh *ssh, Session *s, const char *command)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
- closefrom(STDERR_FILENO + 1);
|
||||
-
|
||||
do_rc_files(ssh, s, shell);
|
||||
|
||||
/* restore SIGPIPE for child */
|
||||
@@ -1678,9 +1674,17 @@ do_child(struct ssh *ssh, Session *s, const char *command)
|
||||
argv[i] = NULL;
|
||||
optind = optreset = 1;
|
||||
__progname = argv[0];
|
||||
- exit(sftp_server_main(i, argv, s->pw));
|
||||
+ exit(sftp_server_main(i, argv, s->pw, have_dev_log));
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * Close any extra open file descriptors so that we don't have them
|
||||
+ * hanging around in clients. Note that we want to do this after
|
||||
+ * initgroups, because at least on Solaris 2.3 it leaves file
|
||||
+ * descriptors open.
|
||||
+ */
|
||||
+ closefrom(STDERR_FILENO + 1);
|
||||
+
|
||||
fflush(NULL);
|
||||
|
||||
/* Get the last component of the shell name. */
|
||||
diff --git a/sftp-server-main.c b/sftp-server-main.c
|
||||
index 2c70f89b..bbb79f27 100644
|
||||
--- a/sftp-server-main.c
|
||||
+++ b/sftp-server-main.c
|
||||
@@ -48,5 +48,5 @@ main(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
- return (sftp_server_main(argc, argv, user_pw));
|
||||
+ return (sftp_server_main(argc, argv, user_pw, 0));
|
||||
}
|
||||
diff --git a/sftp-server.c b/sftp-server.c
|
||||
index a4abb9f7..4985da38 100644
|
||||
--- a/sftp-server.c
|
||||
+++ b/sftp-server.c
|
||||
@@ -1901,7 +1901,7 @@ sftp_server_usage(void)
|
||||
}
|
||||
|
||||
int
|
||||
-sftp_server_main(int argc, char **argv, struct passwd *user_pw)
|
||||
+sftp_server_main(int argc, char **argv, struct passwd *user_pw, int reset_handler)
|
||||
{
|
||||
int i, r, in, out, ch, skipargs = 0, log_stderr = 0;
|
||||
ssize_t len, olen;
|
||||
@@ -1913,7 +1913,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
|
||||
extern char *__progname;
|
||||
|
||||
__progname = ssh_get_progname(argv[0]);
|
||||
- log_init(__progname, log_level, log_facility, log_stderr);
|
||||
+ log_init_handler(__progname, log_level, log_facility, log_stderr, reset_handler);
|
||||
|
||||
pw = pwcopy(user_pw);
|
||||
|
||||
@@ -1986,7 +1986,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
|
||||
}
|
||||
}
|
||||
|
||||
- log_init(__progname, log_level, log_facility, log_stderr);
|
||||
+ log_init_handler(__progname, log_level, log_facility, log_stderr, reset_handler);
|
||||
|
||||
/*
|
||||
* On platforms where we can, avoid making /proc/self/{mem,maps}
|
||||
diff --git a/sftp.h b/sftp.h
|
||||
index 2bde8bb7..ddf1a396 100644
|
||||
--- a/sftp.h
|
||||
+++ b/sftp.h
|
||||
@@ -97,5 +97,5 @@
|
||||
|
||||
struct passwd;
|
||||
|
||||
-int sftp_server_main(int, char **, struct passwd *);
|
||||
+int sftp_server_main(int, char **, struct passwd *, int);
|
||||
void sftp_server_cleanup_exit(int) __attribute__((noreturn));
|
||||
diff --git a/sshd-session.c b/sshd-session.c
|
||||
index 478381db..9342e416 100644
|
||||
--- a/sshd-session.c
|
||||
+++ b/sshd-session.c
|
||||
@@ -437,7 +437,7 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt)
|
||||
#endif
|
||||
|
||||
/* New socket pair */
|
||||
- monitor_reinit(pmonitor);
|
||||
+ monitor_reinit(pmonitor, options.chroot_directory);
|
||||
|
||||
pmonitor->m_pid = fork();
|
||||
if (pmonitor->m_pid == -1)
|
||||
@@ -456,6 +456,11 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt)
|
||||
|
||||
close(pmonitor->m_sendfd);
|
||||
pmonitor->m_sendfd = -1;
|
||||
+ close(pmonitor->m_log_recvfd);
|
||||
+ pmonitor->m_log_recvfd = -1;
|
||||
+
|
||||
+ if (pmonitor->m_log_sendfd != -1)
|
||||
+ set_log_handler(mm_log_handler, pmonitor);
|
||||
|
||||
/* Demote the private keys to public keys. */
|
||||
demote_sensitive_data();
|
||||
--
|
||||
2.49.0
|
||||
|
||||
27
0020-openssh-6.6.1p1-scp-non-existing-directory.patch
Normal file
27
0020-openssh-6.6.1p1-scp-non-existing-directory.patch
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
From 007ee98fa9100f7241985ac2a7eed71e17d89a9f Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:28 +0200
|
||||
Subject: [PATCH 20/50] openssh-6.6.1p1-scp-non-existing-directory
|
||||
|
||||
---
|
||||
scp.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/scp.c b/scp.c
|
||||
index 716ae386..9554b188 100644
|
||||
--- a/scp.c
|
||||
+++ b/scp.c
|
||||
@@ -1876,6 +1876,10 @@ sink(int argc, char **argv, const char *src)
|
||||
free(vect[0]);
|
||||
continue;
|
||||
}
|
||||
+ if (buf[0] == 'C' && ! exists && np[strlen(np)-1] == '/') {
|
||||
+ errno = ENOTDIR;
|
||||
+ goto bad;
|
||||
+ }
|
||||
omode = mode;
|
||||
mode |= S_IWUSR;
|
||||
if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) == -1) {
|
||||
--
|
||||
2.49.0
|
||||
|
||||
151
0021-openssh-6.6p1-GSSAPIEnablek5users.patch
Normal file
151
0021-openssh-6.6p1-GSSAPIEnablek5users.patch
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
From 9c75c175e3555377328fc5fc9b06e94f129b7cd7 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:28 +0200
|
||||
Subject: [PATCH 21/50] openssh-6.6p1-GSSAPIEnablek5users
|
||||
|
||||
---
|
||||
gss-serv-krb5.c | 3 +--
|
||||
servconf.c | 13 ++++++++++++-
|
||||
servconf.h | 1 +
|
||||
sshd_config | 1 +
|
||||
sshd_config.5 | 6 ++++++
|
||||
5 files changed, 21 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c
|
||||
index 187faf92..03188d9b 100644
|
||||
--- a/gss-serv-krb5.c
|
||||
+++ b/gss-serv-krb5.c
|
||||
@@ -278,7 +278,6 @@ ssh_gssapi_krb5_cmdok(krb5_principal principal, const char *name,
|
||||
FILE *fp;
|
||||
char file[MAXPATHLEN];
|
||||
char *line = NULL;
|
||||
- char kuser[65]; /* match krb5_kuserok() */
|
||||
struct stat st;
|
||||
struct passwd *pw = the_authctxt->pw;
|
||||
int found_principal = 0;
|
||||
@@ -288,7 +287,7 @@ ssh_gssapi_krb5_cmdok(krb5_principal principal, const char *name,
|
||||
|
||||
snprintf(file, sizeof(file), "%s/.k5users", pw->pw_dir);
|
||||
/* If both .k5login and .k5users DNE, self-login is ok. */
|
||||
- if (!k5login_exists && (access(file, F_OK) == -1)) {
|
||||
+ if ( !options.enable_k5users || (!k5login_exists && (access(file, F_OK) == -1))) {
|
||||
return ssh_krb5_kuserok(krb_context, principal, luser,
|
||||
k5login_exists);
|
||||
}
|
||||
diff --git a/servconf.c b/servconf.c
|
||||
index 5dd5ca21..c0de7110 100644
|
||||
--- a/servconf.c
|
||||
+++ b/servconf.c
|
||||
@@ -146,6 +146,7 @@ initialize_server_options(ServerOptions *options)
|
||||
options->gss_store_rekey = -1;
|
||||
options->gss_kex_algorithms = NULL;
|
||||
options->use_kuserok = -1;
|
||||
+ options->enable_k5users = -1;
|
||||
options->password_authentication = -1;
|
||||
options->kbd_interactive_authentication = -1;
|
||||
options->permit_empty_passwd = -1;
|
||||
@@ -402,6 +403,8 @@ fill_default_server_options(ServerOptions *options)
|
||||
#endif
|
||||
if (options->use_kuserok == -1)
|
||||
options->use_kuserok = 1;
|
||||
+ if (options->enable_k5users == -1)
|
||||
+ options->enable_k5users = 0;
|
||||
if (options->password_authentication == -1)
|
||||
options->password_authentication = 1;
|
||||
if (options->kbd_interactive_authentication == -1)
|
||||
@@ -585,7 +588,7 @@ typedef enum {
|
||||
sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize,
|
||||
sPerSourcePenalties, sPerSourcePenaltyExemptList,
|
||||
sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
|
||||
- sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
|
||||
+ sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor,
|
||||
sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey,
|
||||
sAcceptEnv, sSetEnv, sPermitTunnel,
|
||||
sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory,
|
||||
@@ -681,6 +684,7 @@ static struct {
|
||||
{ "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL },
|
||||
{ "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL },
|
||||
{ "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL },
|
||||
+ { "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL },
|
||||
#else
|
||||
{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
|
||||
{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
|
||||
@@ -689,6 +693,7 @@ static struct {
|
||||
{ "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL },
|
||||
{ "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL },
|
||||
{ "gssapikexalgorithms", sUnsupported, SSHCFG_GLOBAL },
|
||||
+ { "gssapienablek5users", sUnsupported, SSHCFG_ALL },
|
||||
#endif
|
||||
{ "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL },
|
||||
{ "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL },
|
||||
@@ -2450,6 +2455,10 @@ process_server_config_line_depth(ServerOptions *options, char *line,
|
||||
intptr = &options->use_kuserok;
|
||||
goto parse_flag;
|
||||
|
||||
+ case sGssEnablek5users:
|
||||
+ intptr = &options->enable_k5users;
|
||||
+ goto parse_flag;
|
||||
+
|
||||
case sMatch:
|
||||
if (cmdline)
|
||||
fatal("Match directive not supported as a command-line "
|
||||
@@ -3005,6 +3014,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
|
||||
M_CP_INTOPT(ip_qos_interactive);
|
||||
M_CP_INTOPT(ip_qos_bulk);
|
||||
M_CP_INTOPT(use_kuserok);
|
||||
+ M_CP_INTOPT(enable_k5users);
|
||||
M_CP_INTOPT(rekey_limit);
|
||||
M_CP_INTOPT(rekey_interval);
|
||||
M_CP_INTOPT(log_level);
|
||||
@@ -3314,6 +3324,7 @@ dump_config(ServerOptions *o)
|
||||
# endif
|
||||
dump_cfg_fmtint(sKerberosUniqueCCache, o->kerberos_unique_ccache);
|
||||
dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok);
|
||||
+ dump_cfg_fmtint(sGssEnablek5users, o->enable_k5users);
|
||||
#endif
|
||||
#ifdef GSSAPI
|
||||
dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
|
||||
diff --git a/servconf.h b/servconf.h
|
||||
index 11de36a2..c08cf6a7 100644
|
||||
--- a/servconf.h
|
||||
+++ b/servconf.h
|
||||
@@ -152,6 +152,7 @@ typedef struct {
|
||||
int kerberos_unique_ccache; /* If true, the acquired ticket will
|
||||
* be stored in per-session ccache */
|
||||
int use_kuserok;
|
||||
+ int enable_k5users;
|
||||
int gss_authentication; /* If true, permit GSSAPI authentication */
|
||||
int gss_keyex; /* If true, permit GSSAPI key exchange */
|
||||
int gss_cleanup_creds; /* If true, destroy cred cache on logout */
|
||||
diff --git a/sshd_config b/sshd_config
|
||||
index ea5a878e..33713c88 100644
|
||||
--- a/sshd_config
|
||||
+++ b/sshd_config
|
||||
@@ -82,6 +82,7 @@ AuthorizedKeysFile .ssh/authorized_keys
|
||||
#GSSAPICleanupCredentials yes
|
||||
#GSSAPIStrictAcceptorCheck yes
|
||||
#GSSAPIKeyExchange no
|
||||
+#GSSAPIEnablek5users no
|
||||
|
||||
# Set this to 'yes' to enable PAM authentication, account processing,
|
||||
# and session processing. If this is enabled, PAM authentication will
|
||||
diff --git a/sshd_config.5 b/sshd_config.5
|
||||
index 0fcb409a..fe246fc2 100644
|
||||
--- a/sshd_config.5
|
||||
+++ b/sshd_config.5
|
||||
@@ -739,6 +739,12 @@ Specifies whether to automatically destroy the user's credentials cache
|
||||
on logout.
|
||||
The default is
|
||||
.Cm yes .
|
||||
+.It Cm GSSAPIEnablek5users
|
||||
+Specifies whether to look at .k5users file for GSSAPI authentication
|
||||
+access control. Further details are described in
|
||||
+.Xr ksu 1 .
|
||||
+The default is
|
||||
+.Cm no .
|
||||
.It Cm GSSAPIKeyExchange
|
||||
Specifies whether key exchange based on GSSAPI is allowed. GSSAPI key exchange
|
||||
doesn't rely on ssh keys to verify host identity.
|
||||
--
|
||||
2.49.0
|
||||
|
||||
25
0022-openssh-6.8p1-sshdT-output.patch
Normal file
25
0022-openssh-6.8p1-sshdT-output.patch
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
From 05b09904f431333e19cd24528ef66d1fd15e9efe Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:28 +0200
|
||||
Subject: [PATCH 22/50] openssh-6.8p1-sshdT-output
|
||||
|
||||
---
|
||||
servconf.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/servconf.c b/servconf.c
|
||||
index c0de7110..105e301d 100644
|
||||
--- a/servconf.c
|
||||
+++ b/servconf.c
|
||||
@@ -3366,7 +3366,7 @@ dump_config(ServerOptions *o)
|
||||
dump_cfg_string(sXAuthLocation, o->xauth_location);
|
||||
dump_cfg_string(sCiphers, o->ciphers);
|
||||
dump_cfg_string(sMacs, o->macs);
|
||||
- dump_cfg_string(sBanner, o->banner);
|
||||
+ dump_cfg_string(sBanner, o->banner != NULL ? o->banner : "none");
|
||||
dump_cfg_string(sForceCommand, o->adm_forced_command);
|
||||
dump_cfg_string(sChrootDirectory, o->chroot_directory);
|
||||
dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys);
|
||||
--
|
||||
2.49.0
|
||||
|
||||
115
0023-openssh-6.7p1-sftp-force-permission.patch
Normal file
115
0023-openssh-6.7p1-sftp-force-permission.patch
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
From 34b196198018059bed294fa7a08e70606b4cbc36 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:28 +0200
|
||||
Subject: [PATCH 23/50] openssh-6.7p1-sftp-force-permission
|
||||
|
||||
---
|
||||
sftp-server.8 | 7 +++++++
|
||||
sftp-server.c | 24 ++++++++++++++++++++++--
|
||||
2 files changed, 29 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/sftp-server.8 b/sftp-server.8
|
||||
index 5311bf92..5e6e3aa4 100644
|
||||
--- a/sftp-server.8
|
||||
+++ b/sftp-server.8
|
||||
@@ -38,6 +38,7 @@
|
||||
.Op Fl P Ar denied_requests
|
||||
.Op Fl p Ar allowed_requests
|
||||
.Op Fl u Ar umask
|
||||
+.Op Fl m Ar force_file_perms
|
||||
.Ek
|
||||
.Nm
|
||||
.Fl Q Ar protocol_feature
|
||||
@@ -138,6 +139,12 @@ Sets an explicit
|
||||
.Xr umask 2
|
||||
to be applied to newly-created files and directories, instead of the
|
||||
user's default mask.
|
||||
+.It Fl m Ar force_file_perms
|
||||
+Sets explicit file permissions to be applied to newly-created files instead
|
||||
+of the default or client requested mode. Numeric values include:
|
||||
+777, 755, 750, 666, 644, 640, etc. Using both -m and -u switches makes the
|
||||
+umask (-u) effective only for newly created directories and explicit mode (-m)
|
||||
+for newly created files.
|
||||
.El
|
||||
.Pp
|
||||
On some systems,
|
||||
diff --git a/sftp-server.c b/sftp-server.c
|
||||
index 4985da38..6ed1c27f 100644
|
||||
--- a/sftp-server.c
|
||||
+++ b/sftp-server.c
|
||||
@@ -76,6 +76,10 @@ struct sshbuf *oqueue;
|
||||
/* Version of client */
|
||||
static u_int version;
|
||||
|
||||
+/* Force file permissions */
|
||||
+int permforce = 0;
|
||||
+long permforcemode;
|
||||
+
|
||||
/* SSH2_FXP_INIT received */
|
||||
static int init_done;
|
||||
|
||||
@@ -745,6 +749,7 @@ process_open(u_int32_t id)
|
||||
Attrib a;
|
||||
char *name;
|
||||
int r, handle, fd, flags, mode, status = SSH2_FX_FAILURE;
|
||||
+ mode_t old_umask = 0;
|
||||
|
||||
if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 ||
|
||||
(r = sshbuf_get_u32(iqueue, &pflags)) != 0 || /* portable flags */
|
||||
@@ -754,6 +759,10 @@ process_open(u_int32_t id)
|
||||
debug3("request %u: open flags %d", id, pflags);
|
||||
flags = flags_from_portable(pflags);
|
||||
mode = (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a.perm : 0666;
|
||||
+ if (permforce == 1) { /* Force perm if -m is set */
|
||||
+ mode = permforcemode;
|
||||
+ old_umask = umask(0); /* so umask does not interfere */
|
||||
+ }
|
||||
logit("open \"%s\" flags %s mode 0%o",
|
||||
name, string_from_portable(pflags), mode);
|
||||
if (readonly &&
|
||||
@@ -775,6 +784,8 @@ process_open(u_int32_t id)
|
||||
}
|
||||
}
|
||||
}
|
||||
+ if (permforce == 1)
|
||||
+ (void) umask(old_umask); /* restore umask to something sane */
|
||||
if (status != SSH2_FX_OK)
|
||||
send_status(id, status);
|
||||
free(name);
|
||||
@@ -1894,7 +1905,7 @@ sftp_server_usage(void)
|
||||
fprintf(stderr,
|
||||
"usage: %s [-ehR] [-d start_directory] [-f log_facility] "
|
||||
"[-l log_level]\n\t[-P denied_requests] "
|
||||
- "[-p allowed_requests] [-u umask]\n"
|
||||
+ "[-p allowed_requests] [-u umask] [-m force_file_perms]\n"
|
||||
" %s -Q protocol_feature\n",
|
||||
__progname, __progname);
|
||||
exit(1);
|
||||
@@ -1918,7 +1929,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw, int reset_handle
|
||||
pw = pwcopy(user_pw);
|
||||
|
||||
while (!skipargs && (ch = getopt(argc, argv,
|
||||
- "d:f:l:P:p:Q:u:cehR")) != -1) {
|
||||
+ "d:f:l:P:p:Q:u:m:cehR")) != -1) {
|
||||
switch (ch) {
|
||||
case 'Q':
|
||||
if (strcasecmp(optarg, "requests") != 0) {
|
||||
@@ -1980,6 +1991,15 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw, int reset_handle
|
||||
fatal("Invalid umask \"%s\"", optarg);
|
||||
(void)umask((mode_t)mask);
|
||||
break;
|
||||
+ case 'm':
|
||||
+ /* Force permissions on file received via sftp */
|
||||
+ permforce = 1;
|
||||
+ permforcemode = strtol(optarg, &cp, 8);
|
||||
+ if (permforcemode < 0 || permforcemode > 0777 ||
|
||||
+ *cp != '\0' || (permforcemode == 0 &&
|
||||
+ errno != 0))
|
||||
+ fatal("Invalid file mode \"%s\"", optarg);
|
||||
+ break;
|
||||
case 'h':
|
||||
default:
|
||||
sftp_server_usage();
|
||||
--
|
||||
2.49.0
|
||||
|
||||
50
0024-openssh-7.2p2-s390-closefrom.patch
Normal file
50
0024-openssh-7.2p2-s390-closefrom.patch
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
From 9bb31b63142adaaf949e20c2d86c97f9b787217b Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:28 +0200
|
||||
Subject: [PATCH 24/50] openssh-7.2p2-s390-closefrom
|
||||
|
||||
---
|
||||
openbsd-compat/bsd-closefrom.c | 26 ++++++++++++++++++++++++++
|
||||
1 file changed, 26 insertions(+)
|
||||
|
||||
diff --git a/openbsd-compat/bsd-closefrom.c b/openbsd-compat/bsd-closefrom.c
|
||||
index 49a4f35f..f6112458 100644
|
||||
--- a/openbsd-compat/bsd-closefrom.c
|
||||
+++ b/openbsd-compat/bsd-closefrom.c
|
||||
@@ -140,7 +140,33 @@ closefrom(int lowfd)
|
||||
fd = strtol(dent->d_name, &endp, 10);
|
||||
if (dent->d_name != endp && *endp == '\0' &&
|
||||
fd >= 0 && fd < INT_MAX && fd >= lowfd && fd != dirfd(dirp))
|
||||
+#ifdef __s390__
|
||||
+ {
|
||||
+ /*
|
||||
+ * the filedescriptors used to communicate with
|
||||
+ * the device drivers to provide hardware support
|
||||
+ * should survive. HF <freude@de.ibm.com>
|
||||
+ */
|
||||
+ char fpath[PATH_MAX], lpath[PATH_MAX];
|
||||
+ len = snprintf(fpath, sizeof(fpath), "%s/%s",
|
||||
+ fdpath, dent->d_name);
|
||||
+ if (len > 0 && (size_t)len <= sizeof(fpath)) {
|
||||
+ len = readlink(fpath, lpath, sizeof(lpath));
|
||||
+ if (len > 0) {
|
||||
+ lpath[len] = 0;
|
||||
+ if (strstr(lpath, "dev/z90crypt")
|
||||
+ || strstr(lpath, "dev/zcrypt")
|
||||
+ || strstr(lpath, "dev/prandom")
|
||||
+ || strstr(lpath, "dev/shm/icastats"))
|
||||
+ fd = -1;
|
||||
+ }
|
||||
+ }
|
||||
+ if (fd >= 0)
|
||||
+ (void) close((int) fd);
|
||||
+ }
|
||||
+#else
|
||||
(void) close((int) fd);
|
||||
+#endif
|
||||
}
|
||||
(void) closedir(dirp);
|
||||
return;
|
||||
--
|
||||
2.49.0
|
||||
|
||||
191
0025-openssh-7.3p1-x11-max-displays.patch
Normal file
191
0025-openssh-7.3p1-x11-max-displays.patch
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
From 36e3430d1f81397d5f40600e075272a81f7effce Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:28 +0200
|
||||
Subject: [PATCH 25/50] openssh-7.3p1-x11-max-displays
|
||||
|
||||
---
|
||||
channels.c | 9 ++++++---
|
||||
channels.h | 2 +-
|
||||
servconf.c | 12 +++++++++++-
|
||||
servconf.h | 2 ++
|
||||
session.c | 5 +++--
|
||||
sshd_config.5 | 7 +++++++
|
||||
6 files changed, 30 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/channels.c b/channels.c
|
||||
index d46531ce..7438c1a5 100644
|
||||
--- a/channels.c
|
||||
+++ b/channels.c
|
||||
@@ -4996,7 +4996,7 @@ rdynamic_connect_finish(struct ssh *ssh, Channel *c)
|
||||
*/
|
||||
int
|
||||
x11_create_display_inet(struct ssh *ssh, int x11_display_offset,
|
||||
- int x11_use_localhost, int single_connection,
|
||||
+ int x11_use_localhost, int x11_max_displays, int single_connection,
|
||||
u_int *display_numberp, int **chanids)
|
||||
{
|
||||
Channel *nc = NULL;
|
||||
@@ -5009,8 +5009,11 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset,
|
||||
x11_display_offset > UINT16_MAX - X11_BASE_PORT - MAX_DISPLAYS)
|
||||
return -1;
|
||||
|
||||
+ /* Try to bind ports starting at 6000+X11DisplayOffset */
|
||||
+ x11_max_displays = x11_max_displays + x11_display_offset;
|
||||
+
|
||||
for (display_number = x11_display_offset;
|
||||
- display_number < MAX_DISPLAYS;
|
||||
+ display_number < x11_max_displays;
|
||||
display_number++) {
|
||||
port = X11_BASE_PORT + display_number;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
@@ -5065,7 +5068,7 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset,
|
||||
if (num_socks > 0)
|
||||
break;
|
||||
}
|
||||
- if (display_number >= MAX_DISPLAYS) {
|
||||
+ if (display_number >= x11_max_displays || port < X11_BASE_PORT ) {
|
||||
error("Failed to allocate internet-domain X11 display socket.");
|
||||
return -1;
|
||||
}
|
||||
diff --git a/channels.h b/channels.h
|
||||
index 134528d5..8a09a820 100644
|
||||
--- a/channels.h
|
||||
+++ b/channels.h
|
||||
@@ -379,7 +379,7 @@ int permitopen_port(const char *);
|
||||
|
||||
void channel_set_x11_refuse_time(struct ssh *, time_t);
|
||||
int x11_connect_display(struct ssh *);
|
||||
-int x11_create_display_inet(struct ssh *, int, int, int, u_int *, int **);
|
||||
+int x11_create_display_inet(struct ssh *, int, int, int, int, u_int *, int **);
|
||||
void x11_request_forwarding_with_spoofing(struct ssh *, int,
|
||||
const char *, const char *, const char *, int);
|
||||
int x11_channel_used_recently(struct ssh *ssh);
|
||||
diff --git a/servconf.c b/servconf.c
|
||||
index 105e301d..15c99b30 100644
|
||||
--- a/servconf.c
|
||||
+++ b/servconf.c
|
||||
@@ -117,6 +117,7 @@ initialize_server_options(ServerOptions *options)
|
||||
options->print_lastlog = -1;
|
||||
options->x11_forwarding = -1;
|
||||
options->x11_display_offset = -1;
|
||||
+ options->x11_max_displays = -1;
|
||||
options->x11_use_localhost = -1;
|
||||
options->permit_tty = -1;
|
||||
options->permit_user_rc = -1;
|
||||
@@ -353,6 +354,8 @@ fill_default_server_options(ServerOptions *options)
|
||||
options->x11_forwarding = 0;
|
||||
if (options->x11_display_offset == -1)
|
||||
options->x11_display_offset = 10;
|
||||
+ if (options->x11_max_displays == -1)
|
||||
+ options->x11_max_displays = DEFAULT_MAX_DISPLAYS;
|
||||
if (options->x11_use_localhost == -1)
|
||||
options->x11_use_localhost = 1;
|
||||
if (options->xauth_location == NULL)
|
||||
@@ -576,7 +579,7 @@ typedef enum {
|
||||
sKerberosGetAFSToken, sKerberosUniqueCCache, sKerberosUseKuserok, sPasswordAuthentication,
|
||||
sKbdInteractiveAuthentication, sListenAddress, sAddressFamily,
|
||||
sPrintMotd, sPrintLastLog, sIgnoreRhosts,
|
||||
- sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
|
||||
+ sX11Forwarding, sX11DisplayOffset, sX11MaxDisplays, sX11UseLocalhost,
|
||||
sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive,
|
||||
sPermitUserEnvironment, sAllowTcpForwarding, sCompression,
|
||||
sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
|
||||
@@ -714,6 +717,7 @@ static struct {
|
||||
{ "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
|
||||
{ "x11forwarding", sX11Forwarding, SSHCFG_ALL },
|
||||
{ "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
|
||||
+ { "x11maxdisplays", sX11MaxDisplays, SSHCFG_ALL },
|
||||
{ "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
|
||||
{ "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
|
||||
{ "strictmodes", sStrictModes, SSHCFG_GLOBAL },
|
||||
@@ -1750,6 +1754,10 @@ process_server_config_line_depth(ServerOptions *options, char *line,
|
||||
*intptr = value;
|
||||
break;
|
||||
|
||||
+ case sX11MaxDisplays:
|
||||
+ intptr = &options->x11_max_displays;
|
||||
+ goto parse_int;
|
||||
+
|
||||
case sX11UseLocalhost:
|
||||
intptr = &options->x11_use_localhost;
|
||||
goto parse_flag;
|
||||
@@ -3004,6 +3012,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
|
||||
M_CP_INTOPT(fwd_opts.streamlocal_bind_unlink);
|
||||
M_CP_INTOPT(x11_display_offset);
|
||||
M_CP_INTOPT(x11_forwarding);
|
||||
+ M_CP_INTOPT(x11_max_displays);
|
||||
M_CP_INTOPT(x11_use_localhost);
|
||||
M_CP_INTOPT(permit_tty);
|
||||
M_CP_INTOPT(permit_user_rc);
|
||||
@@ -3299,6 +3308,7 @@ dump_config(ServerOptions *o)
|
||||
#endif
|
||||
dump_cfg_int(sLoginGraceTime, o->login_grace_time);
|
||||
dump_cfg_int(sX11DisplayOffset, o->x11_display_offset);
|
||||
+ dump_cfg_int(sX11MaxDisplays, o->x11_max_displays);
|
||||
dump_cfg_int(sMaxAuthTries, o->max_authtries);
|
||||
dump_cfg_int(sMaxSessions, o->max_sessions);
|
||||
dump_cfg_int(sClientAliveInterval, o->client_alive_interval);
|
||||
diff --git a/servconf.h b/servconf.h
|
||||
index c08cf6a7..7c7e5d43 100644
|
||||
--- a/servconf.h
|
||||
+++ b/servconf.h
|
||||
@@ -38,6 +38,7 @@
|
||||
|
||||
#define DEFAULT_AUTH_FAIL_MAX 6 /* Default for MaxAuthTries */
|
||||
#define DEFAULT_SESSIONS_MAX 10 /* Default for MaxSessions */
|
||||
+#define DEFAULT_MAX_DISPLAYS 1000 /* Maximum number of fake X11 displays to try. */
|
||||
|
||||
/* Magic name for internal sftp-server */
|
||||
#define INTERNAL_SFTP_NAME "internal-sftp"
|
||||
@@ -114,6 +115,7 @@ typedef struct {
|
||||
int x11_forwarding; /* If true, permit inet (spoofing) X11 fwd. */
|
||||
int x11_display_offset; /* What DISPLAY number to start
|
||||
* searching at */
|
||||
+ int x11_max_displays; /* Number of displays to search */
|
||||
int x11_use_localhost; /* If true, use localhost for fake X11 server. */
|
||||
char *xauth_location; /* Location of xauth program */
|
||||
int permit_tty; /* If false, deny pty allocation */
|
||||
diff --git a/session.c b/session.c
|
||||
index 54da09d5..28bbb8a7 100644
|
||||
--- a/session.c
|
||||
+++ b/session.c
|
||||
@@ -2611,8 +2611,9 @@ session_setup_x11fwd(struct ssh *ssh, Session *s)
|
||||
return 0;
|
||||
}
|
||||
if (x11_create_display_inet(ssh, options.x11_display_offset,
|
||||
- options.x11_use_localhost, s->single_connection,
|
||||
- &s->display_number, &s->x11_chanids) == -1) {
|
||||
+ options.x11_use_localhost, options.x11_max_displays,
|
||||
+ s->single_connection, &s->display_number,
|
||||
+ &s->x11_chanids) == -1) {
|
||||
debug("x11_create_display_inet failed.");
|
||||
return 0;
|
||||
}
|
||||
diff --git a/sshd_config.5 b/sshd_config.5
|
||||
index fe246fc2..26fcdc84 100644
|
||||
--- a/sshd_config.5
|
||||
+++ b/sshd_config.5
|
||||
@@ -1391,6 +1391,7 @@ Available keywords are
|
||||
.Cm TrustedUserCAKeys ,
|
||||
.Cm UnusedConnectionTimeout ,
|
||||
.Cm X11DisplayOffset ,
|
||||
+.Cm X11MaxDisplays ,
|
||||
.Cm X11Forwarding
|
||||
and
|
||||
.Cm X11UseLocalhost .
|
||||
@@ -2111,6 +2112,12 @@ Specifies the first display number available for
|
||||
X11 forwarding.
|
||||
This prevents sshd from interfering with real X11 servers.
|
||||
The default is 10.
|
||||
+.It Cm X11MaxDisplays
|
||||
+Specifies the maximum number of displays available for
|
||||
+.Xr sshd 8 Ns 's
|
||||
+X11 forwarding.
|
||||
+This prevents sshd from exhausting local ports.
|
||||
+The default is 1000.
|
||||
.It Cm X11Forwarding
|
||||
Specifies whether X11 forwarding is permitted.
|
||||
The argument must be
|
||||
--
|
||||
2.49.0
|
||||
|
||||
312
0026-openssh-7.6p1-cleanup-selinux.patch
Normal file
312
0026-openssh-7.6p1-cleanup-selinux.patch
Normal file
|
|
@ -0,0 +1,312 @@
|
|||
From 43320351b6f150167190aacc84f2f87030fef3d2 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:28 +0200
|
||||
Subject: [PATCH 26/50] openssh-7.6p1-cleanup-selinux
|
||||
|
||||
---
|
||||
auth2-pubkey.c | 8 ++++--
|
||||
misc.c | 5 ++--
|
||||
misc.h | 2 +-
|
||||
openbsd-compat/port-linux-sshd.c | 42 +++++++++++++++++---------------
|
||||
openbsd-compat/port-linux.h | 4 +--
|
||||
platform.c | 6 ++++-
|
||||
sshconnect.c | 2 +-
|
||||
sshd-auth.c | 2 +-
|
||||
sshd-session.c | 6 +++--
|
||||
9 files changed, 45 insertions(+), 32 deletions(-)
|
||||
|
||||
diff --git a/auth2-pubkey.c b/auth2-pubkey.c
|
||||
index 267a27d2..0d5ae0df 100644
|
||||
--- a/auth2-pubkey.c
|
||||
+++ b/auth2-pubkey.c
|
||||
@@ -77,6 +77,8 @@
|
||||
|
||||
/* import */
|
||||
extern ServerOptions options;
|
||||
+extern int inetd_flag;
|
||||
+extern Authctxt *the_authctxt;
|
||||
extern struct authmethod_cfg methodcfg_pubkey;
|
||||
|
||||
static char *
|
||||
@@ -485,7 +487,8 @@ match_principals_command(struct passwd *user_pw, const struct sshkey *key,
|
||||
if ((pid = subprocess("AuthorizedPrincipalsCommand", command,
|
||||
ac, av, &f,
|
||||
SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD,
|
||||
- runas_pw, temporarily_use_uid, restore_uid)) == 0)
|
||||
+ runas_pw, temporarily_use_uid, restore_uid,
|
||||
+ inetd_flag, the_authctxt)) == 0)
|
||||
goto out;
|
||||
|
||||
uid_swapped = 1;
|
||||
@@ -755,7 +758,8 @@ user_key_command_allowed2(struct passwd *user_pw, struct sshkey *key,
|
||||
if ((pid = subprocess("AuthorizedKeysCommand", command,
|
||||
ac, av, &f,
|
||||
SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD,
|
||||
- runas_pw, temporarily_use_uid, restore_uid)) == 0)
|
||||
+ runas_pw, temporarily_use_uid, restore_uid,
|
||||
+ inetd_flag, the_authctxt)) == 0)
|
||||
goto out;
|
||||
|
||||
uid_swapped = 1;
|
||||
diff --git a/misc.c b/misc.c
|
||||
index 1e31acc9..09722962 100644
|
||||
--- a/misc.c
|
||||
+++ b/misc.c
|
||||
@@ -2764,7 +2764,8 @@ stdfd_devnull(int do_stdin, int do_stdout, int do_stderr)
|
||||
pid_t
|
||||
subprocess(const char *tag, const char *command,
|
||||
int ac, char **av, FILE **child, u_int flags,
|
||||
- struct passwd *pw, privdrop_fn *drop_privs, privrestore_fn *restore_privs)
|
||||
+ struct passwd *pw, privdrop_fn *drop_privs,
|
||||
+ privrestore_fn *restore_privs, int inetd, void *the_authctxt)
|
||||
{
|
||||
FILE *f = NULL;
|
||||
struct stat st;
|
||||
@@ -2898,7 +2899,7 @@ subprocess(const char *tag, const char *command,
|
||||
_exit(1);
|
||||
}
|
||||
#ifdef WITH_SELINUX
|
||||
- if (sshd_selinux_setup_env_variables() < 0) {
|
||||
+ if (sshd_selinux_setup_env_variables(inetd, the_authctxt) < 0) {
|
||||
error ("failed to copy environment: %s",
|
||||
strerror(errno));
|
||||
_exit(127);
|
||||
diff --git a/misc.h b/misc.h
|
||||
index efecdf1a..9efa9cf4 100644
|
||||
--- a/misc.h
|
||||
+++ b/misc.h
|
||||
@@ -122,7 +122,7 @@ typedef void privrestore_fn(void);
|
||||
#define SSH_SUBPROCESS_UNSAFE_PATH (1<<3) /* Don't check for safe cmd */
|
||||
#define SSH_SUBPROCESS_PRESERVE_ENV (1<<4) /* Keep parent environment */
|
||||
pid_t subprocess(const char *, const char *, int, char **, FILE **, u_int,
|
||||
- struct passwd *, privdrop_fn *, privrestore_fn *);
|
||||
+ struct passwd *, privdrop_fn *, privrestore_fn *, int, void *);
|
||||
|
||||
typedef struct arglist arglist;
|
||||
struct arglist {
|
||||
diff --git a/openbsd-compat/port-linux-sshd.c b/openbsd-compat/port-linux-sshd.c
|
||||
index 646f0887..291b569a 100644
|
||||
--- a/openbsd-compat/port-linux-sshd.c
|
||||
+++ b/openbsd-compat/port-linux-sshd.c
|
||||
@@ -49,10 +49,6 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
-extern ServerOptions options;
|
||||
-extern Authctxt *the_authctxt;
|
||||
-extern int inetd_flag;
|
||||
-
|
||||
/* Wrapper around is_selinux_enabled() to log its return value once only */
|
||||
int
|
||||
sshd_selinux_enabled(void)
|
||||
@@ -222,7 +218,8 @@ get_user_context(const char *sename, const char *role, const char *lvl,
|
||||
}
|
||||
|
||||
static void
|
||||
-ssh_selinux_get_role_level(char **role, const char **level)
|
||||
+ssh_selinux_get_role_level(char **role, const char **level,
|
||||
+ Authctxt *the_authctxt)
|
||||
{
|
||||
*role = NULL;
|
||||
*level = NULL;
|
||||
@@ -240,8 +237,8 @@ ssh_selinux_get_role_level(char **role, const char **level)
|
||||
|
||||
/* Return the default security context for the given username */
|
||||
static int
|
||||
-sshd_selinux_getctxbyname(char *pwname,
|
||||
- security_context_t *default_sc, security_context_t *user_sc)
|
||||
+sshd_selinux_getctxbyname(char *pwname, security_context_t *default_sc,
|
||||
+ security_context_t *user_sc, int inetd, Authctxt *the_authctxt)
|
||||
{
|
||||
char *sename, *lvl;
|
||||
char *role;
|
||||
@@ -249,7 +246,7 @@ sshd_selinux_getctxbyname(char *pwname,
|
||||
int r = 0;
|
||||
context_t con = NULL;
|
||||
|
||||
- ssh_selinux_get_role_level(&role, &reqlvl);
|
||||
+ ssh_selinux_get_role_level(&role, &reqlvl, the_authctxt);
|
||||
|
||||
#ifdef HAVE_GETSEUSERBYNAME
|
||||
if ((r=getseuserbyname(pwname, &sename, &lvl)) != 0) {
|
||||
@@ -271,7 +268,7 @@ sshd_selinux_getctxbyname(char *pwname,
|
||||
|
||||
if (r == 0) {
|
||||
/* If launched from xinetd, we must use current level */
|
||||
- if (inetd_flag) {
|
||||
+ if (inetd) {
|
||||
security_context_t sshdsc=NULL;
|
||||
|
||||
if (getcon_raw(&sshdsc) < 0)
|
||||
@@ -332,7 +329,8 @@ sshd_selinux_getctxbyname(char *pwname,
|
||||
|
||||
/* Setup environment variables for pam_selinux */
|
||||
static int
|
||||
-sshd_selinux_setup_variables(int(*set_it)(char *, const char *))
|
||||
+sshd_selinux_setup_variables(int(*set_it)(char *, const char *), int inetd,
|
||||
+ Authctxt *the_authctxt)
|
||||
{
|
||||
const char *reqlvl;
|
||||
char *role;
|
||||
@@ -341,11 +339,11 @@ sshd_selinux_setup_variables(int(*set_it)(char *, const char *))
|
||||
|
||||
debug3_f("setting execution context");
|
||||
|
||||
- ssh_selinux_get_role_level(&role, &reqlvl);
|
||||
+ ssh_selinux_get_role_level(&role, &reqlvl, the_authctxt);
|
||||
|
||||
rv = set_it("SELINUX_ROLE_REQUESTED", role ? role : "");
|
||||
|
||||
- if (inetd_flag) {
|
||||
+ if (inetd) {
|
||||
use_current = "1";
|
||||
} else {
|
||||
use_current = "";
|
||||
@@ -361,9 +359,10 @@ sshd_selinux_setup_variables(int(*set_it)(char *, const char *))
|
||||
}
|
||||
|
||||
static int
|
||||
-sshd_selinux_setup_pam_variables(void)
|
||||
+sshd_selinux_setup_pam_variables(int inetd,
|
||||
+ int(pam_setenv)(char *, const char *), Authctxt *the_authctxt)
|
||||
{
|
||||
- return sshd_selinux_setup_variables(do_pam_putenv);
|
||||
+ return sshd_selinux_setup_variables(pam_setenv, inetd, the_authctxt);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -373,25 +372,28 @@ do_setenv(char *name, const char *value)
|
||||
}
|
||||
|
||||
int
|
||||
-sshd_selinux_setup_env_variables(void)
|
||||
+sshd_selinux_setup_env_variables(int inetd, void *the_authctxt)
|
||||
{
|
||||
- return sshd_selinux_setup_variables(do_setenv);
|
||||
+ Authctxt *authctxt = (Authctxt *) the_authctxt;
|
||||
+ return sshd_selinux_setup_variables(do_setenv, inetd, authctxt);
|
||||
}
|
||||
|
||||
/* Set the execution context to the default for the specified user */
|
||||
void
|
||||
-sshd_selinux_setup_exec_context(char *pwname)
|
||||
+sshd_selinux_setup_exec_context(char *pwname, int inetd,
|
||||
+ int(pam_setenv)(char *, const char *), void *the_authctxt, int use_pam)
|
||||
{
|
||||
security_context_t user_ctx = NULL;
|
||||
int r = 0;
|
||||
security_context_t default_ctx = NULL;
|
||||
+ Authctxt *authctxt = (Authctxt *) the_authctxt;
|
||||
|
||||
if (!sshd_selinux_enabled())
|
||||
return;
|
||||
|
||||
- if (options.use_pam) {
|
||||
+ if (use_pam) {
|
||||
/* do not compute context, just setup environment for pam_selinux */
|
||||
- if (sshd_selinux_setup_pam_variables()) {
|
||||
+ if (sshd_selinux_setup_pam_variables(inetd, pam_setenv, authctxt)) {
|
||||
switch (security_getenforce()) {
|
||||
case -1:
|
||||
fatal_f("security_getenforce() failed");
|
||||
@@ -407,7 +409,7 @@ sshd_selinux_setup_exec_context(char *pwname)
|
||||
|
||||
debug3_f("setting execution context");
|
||||
|
||||
- r = sshd_selinux_getctxbyname(pwname, &default_ctx, &user_ctx);
|
||||
+ r = sshd_selinux_getctxbyname(pwname, &default_ctx, &user_ctx, inetd, authctxt);
|
||||
if (r >= 0) {
|
||||
r = setexeccon(user_ctx);
|
||||
if (r < 0) {
|
||||
diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h
|
||||
index 7f8ba200..3cd7da6a 100644
|
||||
--- a/openbsd-compat/port-linux.h
|
||||
+++ b/openbsd-compat/port-linux.h
|
||||
@@ -25,8 +25,8 @@ void ssh_selinux_setfscreatecon(const char *);
|
||||
|
||||
int sshd_selinux_enabled(void);
|
||||
void sshd_selinux_copy_context(void);
|
||||
-void sshd_selinux_setup_exec_context(char *);
|
||||
-int sshd_selinux_setup_env_variables(void);
|
||||
+void sshd_selinux_setup_exec_context(char *, int, int(char *, const char *), void *, int);
|
||||
+int sshd_selinux_setup_env_variables(int inetd, void *);
|
||||
void sshd_selinux_change_privsep_preauth_context(void);
|
||||
#endif
|
||||
|
||||
diff --git a/platform.c b/platform.c
|
||||
index 0d12f311..f0800b1f 100644
|
||||
--- a/platform.c
|
||||
+++ b/platform.c
|
||||
@@ -33,6 +33,8 @@
|
||||
#include "openbsd-compat/openbsd-compat.h"
|
||||
|
||||
extern ServerOptions options;
|
||||
+extern int inetd_flag;
|
||||
+extern Authctxt *the_authctxt;
|
||||
|
||||
/* return 1 if we are running with privilege to swap UIDs, 0 otherwise */
|
||||
int
|
||||
@@ -140,7 +142,9 @@ platform_setusercontext_post_groups(struct passwd *pw)
|
||||
}
|
||||
#endif /* HAVE_SETPCRED */
|
||||
#ifdef WITH_SELINUX
|
||||
- sshd_selinux_setup_exec_context(pw->pw_name);
|
||||
+ sshd_selinux_setup_exec_context(pw->pw_name,
|
||||
+ inetd_flag, do_pam_putenv, the_authctxt,
|
||||
+ options.use_pam);
|
||||
#endif
|
||||
}
|
||||
|
||||
diff --git a/sshconnect.c b/sshconnect.c
|
||||
index c86182d1..04084810 100644
|
||||
--- a/sshconnect.c
|
||||
+++ b/sshconnect.c
|
||||
@@ -925,7 +925,7 @@ load_hostkeys_command(struct hostkeys *hostkeys, const char *command_template,
|
||||
|
||||
if ((pid = subprocess(tag, command, ac, av, &f,
|
||||
SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_UNSAFE_PATH|
|
||||
- SSH_SUBPROCESS_PRESERVE_ENV, NULL, NULL, NULL)) == 0)
|
||||
+ SSH_SUBPROCESS_PRESERVE_ENV, NULL, NULL, NULL, 0, NULL)) == 0)
|
||||
goto out;
|
||||
|
||||
load_hostkeys_file(hostkeys, hostfile_hostname, tag, f, 1);
|
||||
diff --git a/sshd-auth.c b/sshd-auth.c
|
||||
index e4a8edfd..897db9b4 100644
|
||||
--- a/sshd-auth.c
|
||||
+++ b/sshd-auth.c
|
||||
@@ -122,7 +122,7 @@ char *config_file_name = _PATH_SERVER_CONFIG_FILE;
|
||||
int debug_flag = 0;
|
||||
|
||||
/* Flag indicating that the daemon is being started from inetd. */
|
||||
-static int inetd_flag = 0;
|
||||
+int inetd_flag = 0;
|
||||
|
||||
/* Saved arguments to main(). */
|
||||
static char **saved_argv;
|
||||
diff --git a/sshd-session.c b/sshd-session.c
|
||||
index 9342e416..81d30152 100644
|
||||
--- a/sshd-session.c
|
||||
+++ b/sshd-session.c
|
||||
@@ -136,7 +136,7 @@ char *config_file_name = _PATH_SERVER_CONFIG_FILE;
|
||||
int debug_flag = 0;
|
||||
|
||||
/* Flag indicating that the daemon is being started from inetd. */
|
||||
-static int inetd_flag = 0;
|
||||
+int inetd_flag = 0;
|
||||
|
||||
/* debug goes to stderr unless inetd_flag is set */
|
||||
static int log_stderr = 0;
|
||||
@@ -1359,7 +1359,9 @@ main(int ac, char **av)
|
||||
}
|
||||
#endif
|
||||
#ifdef WITH_SELINUX
|
||||
- sshd_selinux_setup_exec_context(authctxt->pw->pw_name);
|
||||
+ sshd_selinux_setup_exec_context(authctxt->pw->pw_name,
|
||||
+ inetd_flag, do_pam_putenv, the_authctxt,
|
||||
+ options.use_pam);
|
||||
#endif
|
||||
#ifdef USE_PAM
|
||||
if (options.use_pam) {
|
||||
--
|
||||
2.49.0
|
||||
|
||||
58
0027-openssh-7.5p1-sandbox.patch
Normal file
58
0027-openssh-7.5p1-sandbox.patch
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
From 35205319dd71d8e61c1596b8f9479df91aff7756 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:28 +0200
|
||||
Subject: [PATCH 27/50] openssh-7.5p1-sandbox
|
||||
|
||||
---
|
||||
sandbox-seccomp-filter.c | 21 +++++++++++++++++++++
|
||||
1 file changed, 21 insertions(+)
|
||||
|
||||
diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c
|
||||
index b31062c2..1fabf99d 100644
|
||||
--- a/sandbox-seccomp-filter.c
|
||||
+++ b/sandbox-seccomp-filter.c
|
||||
@@ -277,6 +277,9 @@ static const struct sock_filter preauth_insns[] = {
|
||||
#ifdef __NR_exit_group
|
||||
SC_ALLOW(__NR_exit_group),
|
||||
#endif
|
||||
+#if defined(__NR_flock) && defined(__s390__)
|
||||
+ SC_ALLOW(__NR_flock),
|
||||
+#endif
|
||||
#ifdef __NR_futex
|
||||
SC_FUTEX(__NR_futex),
|
||||
#endif
|
||||
@@ -295,6 +298,21 @@ static const struct sock_filter preauth_insns[] = {
|
||||
#ifdef __NR_getpid
|
||||
SC_ALLOW(__NR_getpid),
|
||||
#endif
|
||||
+#ifdef __NR_getuid
|
||||
+ SC_ALLOW(__NR_getuid),
|
||||
+#endif
|
||||
+#ifdef __NR_getuid32
|
||||
+ SC_ALLOW(__NR_getuid32),
|
||||
+#endif
|
||||
+#ifdef __NR_geteuid
|
||||
+ SC_ALLOW(__NR_geteuid),
|
||||
+#endif
|
||||
+#ifdef __NR_geteuid32
|
||||
+ SC_ALLOW(__NR_geteuid32),
|
||||
+#endif
|
||||
+#ifdef __NR_gettid
|
||||
+ SC_ALLOW(__NR_gettid),
|
||||
+#endif
|
||||
#ifdef __NR_getrandom
|
||||
SC_ALLOW(__NR_getrandom),
|
||||
#endif
|
||||
@@ -304,6 +322,9 @@ static const struct sock_filter preauth_insns[] = {
|
||||
#ifdef __NR_gettimeofday
|
||||
SC_ALLOW(__NR_gettimeofday),
|
||||
#endif
|
||||
+#if defined(__NR_ipc) && defined(__s390__)
|
||||
+ SC_ALLOW(__NR_ipc),
|
||||
+#endif
|
||||
#ifdef __NR_getuid
|
||||
SC_ALLOW(__NR_getuid),
|
||||
#endif
|
||||
--
|
||||
2.49.0
|
||||
|
||||
3182
0028-openssh-8.0p1-pkcs11-uri.patch
Normal file
3182
0028-openssh-8.0p1-pkcs11-uri.patch
Normal file
File diff suppressed because it is too large
Load diff
27
0029-openssh-7.8p1-scp-ipv6.patch
Normal file
27
0029-openssh-7.8p1-scp-ipv6.patch
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
From 507e6f245557ae7261806f7ecbd40697cb0dd389 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:28 +0200
|
||||
Subject: [PATCH 29/50] openssh-7.8p1-scp-ipv6
|
||||
|
||||
---
|
||||
scp.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/scp.c b/scp.c
|
||||
index 9554b188..7f9795a5 100644
|
||||
--- a/scp.c
|
||||
+++ b/scp.c
|
||||
@@ -1183,7 +1183,9 @@ toremote(int argc, char **argv, enum scp_mode_e mode, char *sftp_direct)
|
||||
addargs(&alist, "%s", host);
|
||||
addargs(&alist, "%s", cmd);
|
||||
addargs(&alist, "%s", src);
|
||||
- addargs(&alist, "%s%s%s:%s",
|
||||
+ addargs(&alist,
|
||||
+ /* IPv6 address needs to be enclosed with sqare brackets */
|
||||
+ strchr(host, ':') != NULL ? "%s%s[%s]:%s" : "%s%s%s:%s",
|
||||
tuser ? tuser : "", tuser ? "@" : "",
|
||||
thost, targ);
|
||||
if (do_local_cmd(&alist) != 0)
|
||||
--
|
||||
2.49.0
|
||||
|
||||
654
0030-openssh-8.0p1-crypto-policies.patch
Normal file
654
0030-openssh-8.0p1-crypto-policies.patch
Normal file
|
|
@ -0,0 +1,654 @@
|
|||
From b436140fe3abd9f97f01f9af9f5da5cf6c5d7725 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:28 +0200
|
||||
Subject: [PATCH 30/50] openssh-8.0p1-crypto-policies
|
||||
|
||||
---
|
||||
ssh_config.5 | 164 ++++++++++++++++++++-------------------------
|
||||
sshd_config.5 | 179 +++++++++++++++++++-------------------------------
|
||||
2 files changed, 140 insertions(+), 203 deletions(-)
|
||||
|
||||
diff --git a/ssh_config.5 b/ssh_config.5
|
||||
index 8d5d0722..a43b2a27 100644
|
||||
--- a/ssh_config.5
|
||||
+++ b/ssh_config.5
|
||||
@@ -438,17 +438,13 @@ A single argument of
|
||||
causes no CNAMEs to be considered for canonicalization.
|
||||
This is the default behaviour.
|
||||
.It Cm CASignatureAlgorithms
|
||||
+The default is handled system-wide by
|
||||
+.Xr crypto-policies 7 .
|
||||
+Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
|
||||
+.Xr update-crypto-policies 8 .
|
||||
+.Pp
|
||||
Specifies which algorithms are allowed for signing of certificates
|
||||
by certificate authorities (CAs).
|
||||
-The default is:
|
||||
-.Bd -literal -offset indent
|
||||
-ssh-ed25519,ecdsa-sha2-nistp256,
|
||||
-ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
|
||||
-sk-ssh-ed25519@openssh.com,
|
||||
-sk-ecdsa-sha2-nistp256@openssh.com,
|
||||
-rsa-sha2-512,rsa-sha2-256
|
||||
-.Ed
|
||||
-.Pp
|
||||
If the specified list begins with a
|
||||
.Sq +
|
||||
character, then the specified algorithms will be appended to the default set
|
||||
@@ -587,20 +583,25 @@ If the option is set to
|
||||
(the default),
|
||||
the check will not be executed.
|
||||
.It Cm Ciphers
|
||||
+The default is handled system-wide by
|
||||
+.Xr crypto-policies 7 .
|
||||
+Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
|
||||
+.Xr update-crypto-policies 8 .
|
||||
+.Pp
|
||||
Specifies the ciphers allowed and their order of preference.
|
||||
Multiple ciphers must be comma-separated.
|
||||
If the specified list begins with a
|
||||
.Sq +
|
||||
-character, then the specified ciphers will be appended to the default set
|
||||
-instead of replacing them.
|
||||
+character, then the specified ciphers will be appended to the built-in
|
||||
+openssh default set instead of replacing them.
|
||||
If the specified list begins with a
|
||||
.Sq -
|
||||
character, then the specified ciphers (including wildcards) will be removed
|
||||
-from the default set instead of replacing them.
|
||||
+from the built-in openssh default set instead of replacing them.
|
||||
If the specified list begins with a
|
||||
.Sq ^
|
||||
character, then the specified ciphers will be placed at the head of the
|
||||
-default set.
|
||||
+built-in openssh default set.
|
||||
.Pp
|
||||
The supported ciphers are:
|
||||
.Bd -literal -offset indent
|
||||
@@ -616,13 +617,6 @@ aes256-gcm@openssh.com
|
||||
chacha20-poly1305@openssh.com
|
||||
.Ed
|
||||
.Pp
|
||||
-The default is:
|
||||
-.Bd -literal -offset indent
|
||||
-chacha20-poly1305@openssh.com,
|
||||
-aes128-gcm@openssh.com,aes256-gcm@openssh.com,
|
||||
-aes128-ctr,aes192-ctr,aes256-ctr
|
||||
-.Ed
|
||||
-.Pp
|
||||
The list of available ciphers may also be obtained using
|
||||
.Qq ssh -Q cipher .
|
||||
.It Cm ClearAllForwardings
|
||||
@@ -1022,6 +1016,11 @@ command line will be passed untouched to the GSSAPI library.
|
||||
The default is
|
||||
.Dq no .
|
||||
.It Cm GSSAPIKexAlgorithms
|
||||
+The default is handled system-wide by
|
||||
+.Xr crypto-policies 7 .
|
||||
+Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
|
||||
+.Xr update-crypto-policies 8 .
|
||||
+.Pp
|
||||
The list of key exchange algorithms that are offered for GSSAPI
|
||||
key exchange. Possible values are
|
||||
.Bd -literal -offset 3n
|
||||
@@ -1034,10 +1033,8 @@ gss-nistp256-sha256-,
|
||||
gss-curve25519-sha256-
|
||||
.Ed
|
||||
.Pp
|
||||
-The default is
|
||||
-.Dq gss-group14-sha256-,gss-group16-sha512-,gss-nistp256-sha256-,
|
||||
-gss-curve25519-sha256-,gss-group14-sha1-,gss-gex-sha1- .
|
||||
This option only applies to connections using GSSAPI.
|
||||
+.Pp
|
||||
.It Cm HashKnownHosts
|
||||
Indicates that
|
||||
.Xr ssh 1
|
||||
@@ -1056,36 +1053,25 @@ will not be converted automatically,
|
||||
but may be manually hashed using
|
||||
.Xr ssh-keygen 1 .
|
||||
.It Cm HostbasedAcceptedAlgorithms
|
||||
+The default is handled system-wide by
|
||||
+.Xr crypto-policies 7 .
|
||||
+Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
|
||||
+.Xr update-crypto-policies 8 .
|
||||
+.Pp
|
||||
Specifies the signature algorithms that will be used for hostbased
|
||||
authentication as a comma-separated list of patterns.
|
||||
Alternately if the specified list begins with a
|
||||
.Sq +
|
||||
character, then the specified signature algorithms will be appended
|
||||
-to the default set instead of replacing them.
|
||||
+to the built-in openssh default set instead of replacing them.
|
||||
If the specified list begins with a
|
||||
.Sq -
|
||||
character, then the specified signature algorithms (including wildcards)
|
||||
-will be removed from the default set instead of replacing them.
|
||||
+will be removed from the built-in openssh default set instead of replacing them.
|
||||
If the specified list begins with a
|
||||
.Sq ^
|
||||
character, then the specified signature algorithms will be placed
|
||||
-at the head of the default set.
|
||||
-The default for this option is:
|
||||
-.Bd -literal -offset 3n
|
||||
-ssh-ed25519-cert-v01@openssh.com,
|
||||
-ecdsa-sha2-nistp256-cert-v01@openssh.com,
|
||||
-ecdsa-sha2-nistp384-cert-v01@openssh.com,
|
||||
-ecdsa-sha2-nistp521-cert-v01@openssh.com,
|
||||
-sk-ssh-ed25519-cert-v01@openssh.com,
|
||||
-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,
|
||||
-rsa-sha2-512-cert-v01@openssh.com,
|
||||
-rsa-sha2-256-cert-v01@openssh.com,
|
||||
-ssh-ed25519,
|
||||
-ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
|
||||
-sk-ssh-ed25519@openssh.com,
|
||||
-sk-ecdsa-sha2-nistp256@openssh.com,
|
||||
-rsa-sha2-512,rsa-sha2-256
|
||||
-.Ed
|
||||
+at the head of the built-in openssh default set.
|
||||
.Pp
|
||||
The
|
||||
.Fl Q
|
||||
@@ -1138,6 +1124,17 @@ to prefer their algorithms.
|
||||
.Pp
|
||||
The list of available signature algorithms may also be obtained using
|
||||
.Qq ssh -Q HostKeyAlgorithms .
|
||||
+.Pp
|
||||
+The proposed
|
||||
+.Cm HostKeyAlgorithms
|
||||
+during KEX are limited to the set of algorithms that is defined in
|
||||
+.Cm PubkeyAcceptedAlgorithms
|
||||
+and therefore they are indirectly affected by system-wide
|
||||
+.Xr crypto_policies 7 .
|
||||
+.Xr crypto_policies 7 can not handle the list of host key algorithms directly as doing so
|
||||
+would break the order given by the
|
||||
+.Pa known_hosts
|
||||
+file.
|
||||
.It Cm HostKeyAlias
|
||||
Specifies an alias that should be used instead of the
|
||||
real host name when looking up or saving the host key
|
||||
@@ -1376,6 +1373,11 @@ it may be zero or more of:
|
||||
and
|
||||
.Cm pam .
|
||||
.It Cm KexAlgorithms
|
||||
+The default is handled system-wide by
|
||||
+.Xr crypto-policies 7 .
|
||||
+Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
|
||||
+.Xr update-crypto-policies 8 .
|
||||
+.Pp
|
||||
Specifies the permitted KEX (Key Exchange) algorithms that will be used and
|
||||
their preference order.
|
||||
The selected algorithm will be the first algorithm in this list that
|
||||
@@ -1384,29 +1386,17 @@ Multiple algorithms must be comma-separated.
|
||||
.Pp
|
||||
If the specified list begins with a
|
||||
.Sq +
|
||||
-character, then the specified algorithms will be appended to the default set
|
||||
-instead of replacing them.
|
||||
+character, then the specified methods will be appended to the built-in
|
||||
+openssh default set instead of replacing them.
|
||||
If the specified list begins with a
|
||||
.Sq -
|
||||
character, then the specified algorithms (including wildcards) will be removed
|
||||
-from the default set instead of replacing them.
|
||||
+from the built-in openssh default set instead of replacing them.
|
||||
If the specified list begins with a
|
||||
.Sq ^
|
||||
character, then the specified algorithms will be placed at the head of the
|
||||
-default set.
|
||||
-.Pp
|
||||
-The default is:
|
||||
-.Bd -literal -offset indent
|
||||
-mlkem768x25519-sha256,
|
||||
-sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com,
|
||||
-curve25519-sha256,curve25519-sha256@libssh.org,
|
||||
-ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,
|
||||
-diffie-hellman-group-exchange-sha256,
|
||||
-diffie-hellman-group16-sha512,
|
||||
-diffie-hellman-group18-sha512,
|
||||
-diffie-hellman-group14-sha256
|
||||
-.Ed
|
||||
.Pp
|
||||
+built-in openssh default set.
|
||||
The list of supported key exchange algorithms may also be obtained using
|
||||
.Qq ssh -Q kex .
|
||||
.It Cm KnownHostsCommand
|
||||
@@ -1522,37 +1512,33 @@ function, and all code in the
|
||||
file.
|
||||
This option is intended for debugging and no overrides are enabled by default.
|
||||
.It Cm MACs
|
||||
+The default is handled system-wide by
|
||||
+.Xr crypto-policies 7 .
|
||||
+Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
|
||||
+.Xr update-crypto-policies 8 .
|
||||
+.Pp
|
||||
Specifies the MAC (message authentication code) algorithms
|
||||
in order of preference.
|
||||
The MAC algorithm is used for data integrity protection.
|
||||
Multiple algorithms must be comma-separated.
|
||||
If the specified list begins with a
|
||||
.Sq +
|
||||
-character, then the specified algorithms will be appended to the default set
|
||||
-instead of replacing them.
|
||||
+character, then the specified algorithms will be appended to the built-in
|
||||
+openssh default set instead of replacing them.
|
||||
If the specified list begins with a
|
||||
.Sq -
|
||||
character, then the specified algorithms (including wildcards) will be removed
|
||||
-from the default set instead of replacing them.
|
||||
+from the built-in openssh default set instead of replacing them.
|
||||
If the specified list begins with a
|
||||
.Sq ^
|
||||
character, then the specified algorithms will be placed at the head of the
|
||||
-default set.
|
||||
+built-in openssh default set.
|
||||
.Pp
|
||||
The algorithms that contain
|
||||
.Qq -etm
|
||||
calculate the MAC after encryption (encrypt-then-mac).
|
||||
These are considered safer and their use recommended.
|
||||
.Pp
|
||||
-The default is:
|
||||
-.Bd -literal -offset indent
|
||||
-umac-64-etm@openssh.com,umac-128-etm@openssh.com,
|
||||
-hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,
|
||||
-hmac-sha1-etm@openssh.com,
|
||||
-umac-64@openssh.com,umac-128@openssh.com,
|
||||
-hmac-sha2-256,hmac-sha2-512,hmac-sha1
|
||||
-.Ed
|
||||
-.Pp
|
||||
The list of available MAC algorithms may also be obtained using
|
||||
.Qq ssh -Q mac .
|
||||
.It Cm NoHostAuthenticationForLocalhost
|
||||
@@ -1741,39 +1727,31 @@ instead of continuing to execute and pass data.
|
||||
The default is
|
||||
.Cm no .
|
||||
.It Cm PubkeyAcceptedAlgorithms
|
||||
+The default is handled system-wide by
|
||||
+.Xr crypto-policies 7 .
|
||||
+Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
|
||||
+.Xr update-crypto-policies 8 .
|
||||
+.Pp
|
||||
Specifies the signature algorithms that will be used for public key
|
||||
authentication as a comma-separated list of patterns.
|
||||
If the specified list begins with a
|
||||
.Sq +
|
||||
-character, then the algorithms after it will be appended to the default
|
||||
-instead of replacing it.
|
||||
+character, then the algorithms after it will be appended to the built-in
|
||||
+openssh default instead of replacing it.
|
||||
If the specified list begins with a
|
||||
.Sq -
|
||||
character, then the specified algorithms (including wildcards) will be removed
|
||||
-from the default set instead of replacing them.
|
||||
+from the built-in openssh default set instead of replacing them.
|
||||
If the specified list begins with a
|
||||
.Sq ^
|
||||
character, then the specified algorithms will be placed at the head of the
|
||||
-default set.
|
||||
-The default for this option is:
|
||||
-.Bd -literal -offset 3n
|
||||
-ssh-ed25519-cert-v01@openssh.com,
|
||||
-ecdsa-sha2-nistp256-cert-v01@openssh.com,
|
||||
-ecdsa-sha2-nistp384-cert-v01@openssh.com,
|
||||
-ecdsa-sha2-nistp521-cert-v01@openssh.com,
|
||||
-sk-ssh-ed25519-cert-v01@openssh.com,
|
||||
-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,
|
||||
-rsa-sha2-512-cert-v01@openssh.com,
|
||||
-rsa-sha2-256-cert-v01@openssh.com,
|
||||
-ssh-ed25519,
|
||||
-ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
|
||||
-sk-ssh-ed25519@openssh.com,
|
||||
-sk-ecdsa-sha2-nistp256@openssh.com,
|
||||
-rsa-sha2-512,rsa-sha2-256
|
||||
-.Ed
|
||||
+built-in openssh default set.
|
||||
.Pp
|
||||
The list of available signature algorithms may also be obtained using
|
||||
.Qq ssh -Q PubkeyAcceptedAlgorithms .
|
||||
+.Pp
|
||||
+This option affects also
|
||||
+.Cm HostKeyAlgorithms
|
||||
.It Cm PubkeyAuthentication
|
||||
Specifies whether to try public key authentication.
|
||||
The argument to this keyword must be
|
||||
@@ -2497,7 +2475,9 @@ for those users who do not have a configuration file.
|
||||
This file must be world-readable.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
-.Xr ssh 1
|
||||
+.Xr ssh 1 ,
|
||||
+.Xr crypto-policies 7 ,
|
||||
+.Xr update-crypto-policies 8
|
||||
.Sh AUTHORS
|
||||
.An -nosplit
|
||||
OpenSSH is a derivative of the original and free
|
||||
diff --git a/sshd_config.5 b/sshd_config.5
|
||||
index 26fcdc84..583a01cd 100644
|
||||
--- a/sshd_config.5
|
||||
+++ b/sshd_config.5
|
||||
@@ -379,17 +379,13 @@ If the argument is
|
||||
then no banner is displayed.
|
||||
By default, no banner is displayed.
|
||||
.It Cm CASignatureAlgorithms
|
||||
+The default is handled system-wide by
|
||||
+.Xr crypto-policies 7 .
|
||||
+Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
|
||||
+.Xr update-crypto-policies 8 .
|
||||
+.Pp
|
||||
Specifies which algorithms are allowed for signing of certificates
|
||||
by certificate authorities (CAs).
|
||||
-The default is:
|
||||
-.Bd -literal -offset indent
|
||||
-ssh-ed25519,ecdsa-sha2-nistp256,
|
||||
-ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
|
||||
-sk-ssh-ed25519@openssh.com,
|
||||
-sk-ecdsa-sha2-nistp256@openssh.com,
|
||||
-rsa-sha2-512,rsa-sha2-256
|
||||
-.Ed
|
||||
-.Pp
|
||||
If the specified list begins with a
|
||||
.Sq +
|
||||
character, then the specified algorithms will be appended to the default set
|
||||
@@ -533,20 +529,25 @@ The default is
|
||||
indicating not to
|
||||
.Xr chroot 2 .
|
||||
.It Cm Ciphers
|
||||
+The default is handled system-wide by
|
||||
+.Xr crypto-policies 7 .
|
||||
+Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
|
||||
+.Xr update-crypto-policies 8 .
|
||||
+.Pp
|
||||
Specifies the ciphers allowed.
|
||||
Multiple ciphers must be comma-separated.
|
||||
If the specified list begins with a
|
||||
.Sq +
|
||||
-character, then the specified ciphers will be appended to the default set
|
||||
-instead of replacing them.
|
||||
+character, then the specified ciphers will be appended to the built-in
|
||||
+openssh default set instead of replacing them.
|
||||
If the specified list begins with a
|
||||
.Sq -
|
||||
character, then the specified ciphers (including wildcards) will be removed
|
||||
-from the default set instead of replacing them.
|
||||
+from the built-in openssh default set instead of replacing them.
|
||||
If the specified list begins with a
|
||||
.Sq ^
|
||||
character, then the specified ciphers will be placed at the head of the
|
||||
-default set.
|
||||
+built-in openssh default set.
|
||||
.Pp
|
||||
The supported ciphers are:
|
||||
.Pp
|
||||
@@ -573,13 +574,6 @@ aes256-gcm@openssh.com
|
||||
chacha20-poly1305@openssh.com
|
||||
.El
|
||||
.Pp
|
||||
-The default is:
|
||||
-.Bd -literal -offset indent
|
||||
-chacha20-poly1305@openssh.com,
|
||||
-aes128-gcm@openssh.com,aes256-gcm@openssh.com,
|
||||
-aes128-ctr,aes192-ctr,aes256-ctr
|
||||
-.Ed
|
||||
-.Pp
|
||||
The list of available ciphers may also be obtained using
|
||||
.Qq ssh -Q cipher .
|
||||
.It Cm ClientAliveCountMax
|
||||
@@ -774,53 +768,43 @@ For this to work
|
||||
.Cm GSSAPIKeyExchange
|
||||
needs to be enabled in the server and also used by the client.
|
||||
.It Cm GSSAPIKexAlgorithms
|
||||
+The default is handled system-wide by
|
||||
+.Xr crypto-policies 7 .
|
||||
+Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
|
||||
+.Xr update-crypto-policies 8 .
|
||||
+.Pp
|
||||
The list of key exchange algorithms that are accepted by GSSAPI
|
||||
key exchange. Possible values are
|
||||
.Bd -literal -offset 3n
|
||||
-gss-gex-sha1-,
|
||||
-gss-group1-sha1-,
|
||||
-gss-group14-sha1-,
|
||||
-gss-group14-sha256-,
|
||||
-gss-group16-sha512-,
|
||||
-gss-nistp256-sha256-,
|
||||
+gss-gex-sha1-
|
||||
+gss-group1-sha1-
|
||||
+gss-group14-sha1-
|
||||
+gss-group14-sha256-
|
||||
+gss-group16-sha512-
|
||||
+gss-nistp256-sha256-
|
||||
gss-curve25519-sha256-
|
||||
.Ed
|
||||
-.Pp
|
||||
-The default is
|
||||
-.Dq gss-group14-sha256-,gss-group16-sha512-,gss-nistp256-sha256-,
|
||||
-gss-curve25519-sha256-,gss-group14-sha1-,gss-gex-sha1- .
|
||||
This option only applies to connections using GSSAPI.
|
||||
.It Cm HostbasedAcceptedAlgorithms
|
||||
+The default is handled system-wide by
|
||||
+.Xr crypto-policies 7 .
|
||||
+Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
|
||||
+.Xr update-crypto-policies 8 .
|
||||
+.Pp
|
||||
Specifies the signature algorithms that will be accepted for hostbased
|
||||
authentication as a list of comma-separated patterns.
|
||||
Alternately if the specified list begins with a
|
||||
.Sq +
|
||||
character, then the specified signature algorithms will be appended to
|
||||
-the default set instead of replacing them.
|
||||
+the built-in openssh default set instead of replacing them.
|
||||
If the specified list begins with a
|
||||
.Sq -
|
||||
character, then the specified signature algorithms (including wildcards)
|
||||
-will be removed from the default set instead of replacing them.
|
||||
+will be removed from the built-in openssh default set instead of replacing them.
|
||||
If the specified list begins with a
|
||||
.Sq ^
|
||||
character, then the specified signature algorithms will be placed at
|
||||
-the head of the default set.
|
||||
-The default for this option is:
|
||||
-.Bd -literal -offset 3n
|
||||
-ssh-ed25519-cert-v01@openssh.com,
|
||||
-ecdsa-sha2-nistp256-cert-v01@openssh.com,
|
||||
-ecdsa-sha2-nistp384-cert-v01@openssh.com,
|
||||
-ecdsa-sha2-nistp521-cert-v01@openssh.com,
|
||||
-sk-ssh-ed25519-cert-v01@openssh.com,
|
||||
-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,
|
||||
-rsa-sha2-512-cert-v01@openssh.com,
|
||||
-rsa-sha2-256-cert-v01@openssh.com,
|
||||
-ssh-ed25519,
|
||||
-ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
|
||||
-sk-ssh-ed25519@openssh.com,
|
||||
-sk-ecdsa-sha2-nistp256@openssh.com,
|
||||
-rsa-sha2-512,rsa-sha2-256
|
||||
-.Ed
|
||||
+the head of the built-in openssh default set.
|
||||
.Pp
|
||||
The list of available signature algorithms may also be obtained using
|
||||
.Qq ssh -Q HostbasedAcceptedAlgorithms .
|
||||
@@ -887,25 +871,14 @@ is specified, the location of the socket will be read from the
|
||||
.Ev SSH_AUTH_SOCK
|
||||
environment variable.
|
||||
.It Cm HostKeyAlgorithms
|
||||
+The default is handled system-wide by
|
||||
+.Xr crypto-policies 7 .
|
||||
+Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
|
||||
+.Xr update-crypto-policies 8 .
|
||||
+.Pp
|
||||
Specifies the host key signature algorithms
|
||||
that the server offers.
|
||||
The default for this option is:
|
||||
-.Bd -literal -offset 3n
|
||||
-ssh-ed25519-cert-v01@openssh.com,
|
||||
-ecdsa-sha2-nistp256-cert-v01@openssh.com,
|
||||
-ecdsa-sha2-nistp384-cert-v01@openssh.com,
|
||||
-ecdsa-sha2-nistp521-cert-v01@openssh.com,
|
||||
-sk-ssh-ed25519-cert-v01@openssh.com,
|
||||
-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,
|
||||
-rsa-sha2-512-cert-v01@openssh.com,
|
||||
-rsa-sha2-256-cert-v01@openssh.com,
|
||||
-ssh-ed25519,
|
||||
-ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
|
||||
-sk-ssh-ed25519@openssh.com,
|
||||
-sk-ecdsa-sha2-nistp256@openssh.com,
|
||||
-rsa-sha2-512,rsa-sha2-256
|
||||
-.Ed
|
||||
-.Pp
|
||||
The list of available signature algorithms may also be obtained using
|
||||
.Qq ssh -Q HostKeyAlgorithms .
|
||||
.It Cm IgnoreRhosts
|
||||
@@ -1052,6 +1025,11 @@ Specifies whether to look at .k5login file for user's aliases.
|
||||
The default is
|
||||
.Cm yes .
|
||||
.It Cm KexAlgorithms
|
||||
+The default is handled system-wide by
|
||||
+.Xr crypto-policies 7 .
|
||||
+Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
|
||||
+.Xr update-crypto-policies 8 .
|
||||
+.Pp
|
||||
Specifies the permitted KEX (Key Exchange) algorithms that the server will
|
||||
offer to clients.
|
||||
The ordering of this list is not important, as the client specifies the
|
||||
@@ -1060,16 +1038,16 @@ Multiple algorithms must be comma-separated.
|
||||
.Pp
|
||||
If the specified list begins with a
|
||||
.Sq +
|
||||
-character, then the specified algorithms will be appended to the default set
|
||||
-instead of replacing them.
|
||||
+character, then the specified methods will be appended to the built-in
|
||||
+openssh default set instead of replacing them.
|
||||
If the specified list begins with a
|
||||
.Sq -
|
||||
character, then the specified algorithms (including wildcards) will be removed
|
||||
-from the default set instead of replacing them.
|
||||
+from the built-in openssh default set instead of replacing them.
|
||||
If the specified list begins with a
|
||||
.Sq ^
|
||||
character, then the specified algorithms will be placed at the head of the
|
||||
-default set.
|
||||
+built-in openssh default set.
|
||||
.Pp
|
||||
The supported algorithms are:
|
||||
.Pp
|
||||
@@ -1106,14 +1084,6 @@ sntrup761x25519-sha512
|
||||
sntrup761x25519-sha512@openssh.com
|
||||
.El
|
||||
.Pp
|
||||
-The default is:
|
||||
-.Bd -literal -offset indent
|
||||
-mlkem768x25519-sha256,
|
||||
-sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com,
|
||||
-curve25519-sha256,curve25519-sha256@libssh.org,
|
||||
-ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521
|
||||
-.Ed
|
||||
-.Pp
|
||||
The list of supported key exchange algorithms may also be obtained using
|
||||
.Qq ssh -Q KexAlgorithms .
|
||||
.It Cm ListenAddress
|
||||
@@ -1200,21 +1170,26 @@ function, and all code in the
|
||||
file.
|
||||
This option is intended for debugging and no overrides are enabled by default.
|
||||
.It Cm MACs
|
||||
+The default is handled system-wide by
|
||||
+.Xr crypto-policies 7 .
|
||||
+Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
|
||||
+.Xr update-crypto-policies 8 .
|
||||
+.Pp
|
||||
Specifies the available MAC (message authentication code) algorithms.
|
||||
The MAC algorithm is used for data integrity protection.
|
||||
Multiple algorithms must be comma-separated.
|
||||
If the specified list begins with a
|
||||
.Sq +
|
||||
-character, then the specified algorithms will be appended to the default set
|
||||
-instead of replacing them.
|
||||
+character, then the specified algorithms will be appended to the built-in
|
||||
+openssh default set instead of replacing them.
|
||||
If the specified list begins with a
|
||||
.Sq -
|
||||
character, then the specified algorithms (including wildcards) will be removed
|
||||
-from the default set instead of replacing them.
|
||||
+from the built-in openssh default set instead of replacing them.
|
||||
If the specified list begins with a
|
||||
.Sq ^
|
||||
character, then the specified algorithms will be placed at the head of the
|
||||
-default set.
|
||||
+built-in openssh default set.
|
||||
.Pp
|
||||
The algorithms that contain
|
||||
.Qq -etm
|
||||
@@ -1257,15 +1232,6 @@ umac-64-etm@openssh.com
|
||||
umac-128-etm@openssh.com
|
||||
.El
|
||||
.Pp
|
||||
-The default is:
|
||||
-.Bd -literal -offset indent
|
||||
-umac-64-etm@openssh.com,umac-128-etm@openssh.com,
|
||||
-hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,
|
||||
-hmac-sha1-etm@openssh.com,
|
||||
-umac-64@openssh.com,umac-128@openssh.com,
|
||||
-hmac-sha2-256,hmac-sha2-512,hmac-sha1
|
||||
-.Ed
|
||||
-.Pp
|
||||
The list of available MAC algorithms may also be obtained using
|
||||
.Qq ssh -Q mac .
|
||||
.It Cm Match
|
||||
@@ -1753,36 +1719,25 @@ or equivalent.)
|
||||
The default is
|
||||
.Cm yes .
|
||||
.It Cm PubkeyAcceptedAlgorithms
|
||||
+The default is handled system-wide by
|
||||
+.Xr crypto-policies 7 .
|
||||
+Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
|
||||
+.Xr update-crypto-policies 8 .
|
||||
+.Pp
|
||||
Specifies the signature algorithms that will be accepted for public key
|
||||
authentication as a list of comma-separated patterns.
|
||||
Alternately if the specified list begins with a
|
||||
.Sq +
|
||||
-character, then the specified algorithms will be appended to the default set
|
||||
-instead of replacing them.
|
||||
+character, then the specified algorithms will be appended to the built-in
|
||||
+openssh default set instead of replacing them.
|
||||
If the specified list begins with a
|
||||
.Sq -
|
||||
character, then the specified algorithms (including wildcards) will be removed
|
||||
-from the default set instead of replacing them.
|
||||
+from the built-in openssh default set instead of replacing them.
|
||||
If the specified list begins with a
|
||||
.Sq ^
|
||||
character, then the specified algorithms will be placed at the head of the
|
||||
-default set.
|
||||
-The default for this option is:
|
||||
-.Bd -literal -offset 3n
|
||||
-ssh-ed25519-cert-v01@openssh.com,
|
||||
-ecdsa-sha2-nistp256-cert-v01@openssh.com,
|
||||
-ecdsa-sha2-nistp384-cert-v01@openssh.com,
|
||||
-ecdsa-sha2-nistp521-cert-v01@openssh.com,
|
||||
-sk-ssh-ed25519-cert-v01@openssh.com,
|
||||
-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,
|
||||
-rsa-sha2-512-cert-v01@openssh.com,
|
||||
-rsa-sha2-256-cert-v01@openssh.com,
|
||||
-ssh-ed25519,
|
||||
-ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
|
||||
-sk-ssh-ed25519@openssh.com,
|
||||
-sk-ecdsa-sha2-nistp256@openssh.com,
|
||||
-rsa-sha2-512,rsa-sha2-256
|
||||
-.Ed
|
||||
+built-in openssh default set.
|
||||
.Pp
|
||||
The list of available signature algorithms may also be obtained using
|
||||
.Qq ssh -Q PubkeyAcceptedAlgorithms .
|
||||
@@ -2289,7 +2244,9 @@ This file should be writable by root only, but it is recommended
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr sftp-server 8 ,
|
||||
-.Xr sshd 8
|
||||
+.Xr sshd 8 ,
|
||||
+.Xr crypto-policies 7 ,
|
||||
+.Xr update-crypto-policies 8
|
||||
.Sh AUTHORS
|
||||
.An -nosplit
|
||||
OpenSSH is a derivative of the original and free
|
||||
--
|
||||
2.49.0
|
||||
|
||||
157
0031-openssh-8.0p1-openssl-kdf.patch
Normal file
157
0031-openssh-8.0p1-openssl-kdf.patch
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
From 430bd33963725beb8ec01a1e581529ae6bf6bec0 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:28 +0200
|
||||
Subject: [PATCH 31/50] openssh-8.0p1-openssl-kdf
|
||||
|
||||
---
|
||||
configure.ac | 1 +
|
||||
kex.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 108 insertions(+)
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index d9bd2f51..d92a8580 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -3137,6 +3137,7 @@ if test "x$openssl" = "xyes" ; then
|
||||
HMAC_CTX_init \
|
||||
RSA_generate_key_ex \
|
||||
RSA_get_default_method \
|
||||
+ EVP_KDF_CTX_new \
|
||||
])
|
||||
|
||||
# OpenSSL_add_all_algorithms may be a macro.
|
||||
diff --git a/kex.c b/kex.c
|
||||
index 19a56e8e..8b200ff4 100644
|
||||
--- a/kex.c
|
||||
+++ b/kex.c
|
||||
@@ -40,6 +40,11 @@
|
||||
#ifdef WITH_OPENSSL
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/dh.h>
|
||||
+# ifdef HAVE_EVP_KDF_CTX_NEW
|
||||
+# include <openssl/kdf.h>
|
||||
+# include <openssl/param_build.h>
|
||||
+# include <openssl/core_names.h>
|
||||
+# endif
|
||||
#endif
|
||||
|
||||
#include "ssh.h"
|
||||
@@ -1078,6 +1083,107 @@ kex_choose_conf(struct ssh *ssh, uint32_t seq)
|
||||
return r;
|
||||
}
|
||||
|
||||
+#ifdef HAVE_EVP_KDF_CTX_NEW
|
||||
+static const char *
|
||||
+digest_to_md(int digest_type)
|
||||
+{
|
||||
+ switch (digest_type) {
|
||||
+ case SSH_DIGEST_SHA1:
|
||||
+ return SN_sha1;
|
||||
+ case SSH_DIGEST_SHA256:
|
||||
+ return SN_sha256;
|
||||
+ case SSH_DIGEST_SHA384:
|
||||
+ return SN_sha384;
|
||||
+ case SSH_DIGEST_SHA512:
|
||||
+ return SN_sha512;
|
||||
+ }
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen,
|
||||
+ const struct sshbuf *shared_secret, u_char **keyp)
|
||||
+{
|
||||
+ struct kex *kex = ssh->kex;
|
||||
+ u_char *key = NULL;
|
||||
+ int r, key_len;
|
||||
+
|
||||
+ EVP_KDF *kdf = EVP_KDF_fetch(NULL, "SSHKDF", NULL);
|
||||
+ EVP_KDF_CTX *ctx = EVP_KDF_CTX_new(kdf);
|
||||
+ OSSL_PARAM_BLD *param_bld = OSSL_PARAM_BLD_new();
|
||||
+ OSSL_PARAM *params = NULL;
|
||||
+ const char *md = digest_to_md(kex->hash_alg);
|
||||
+ char keytype = (char)id;
|
||||
+
|
||||
+ EVP_KDF_free(kdf);
|
||||
+ if (!ctx) {
|
||||
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (md == NULL) {
|
||||
+ r = SSH_ERR_INVALID_ARGUMENT;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (param_bld == NULL) {
|
||||
+ EVP_KDF_CTX_free(ctx);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ if ((key_len = ssh_digest_bytes(kex->hash_alg)) == 0) {
|
||||
+ r = SSH_ERR_INVALID_ARGUMENT;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ key_len = ROUNDUP(need, key_len);
|
||||
+ if ((key = calloc(1, key_len)) == NULL) {
|
||||
+ r = SSH_ERR_ALLOC_FAIL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ r = OSSL_PARAM_BLD_push_utf8_string(param_bld, OSSL_KDF_PARAM_DIGEST,
|
||||
+ md, strlen(md)) && /* SN */
|
||||
+ OSSL_PARAM_BLD_push_octet_string(param_bld, OSSL_KDF_PARAM_KEY,
|
||||
+ sshbuf_ptr(shared_secret), sshbuf_len(shared_secret)) &&
|
||||
+ OSSL_PARAM_BLD_push_octet_string(param_bld, OSSL_KDF_PARAM_SSHKDF_XCGHASH,
|
||||
+ hash, hashlen) &&
|
||||
+ OSSL_PARAM_BLD_push_octet_string(param_bld, OSSL_KDF_PARAM_SSHKDF_SESSION_ID,
|
||||
+ sshbuf_ptr(kex->session_id), sshbuf_len(kex->session_id)) &&
|
||||
+ OSSL_PARAM_BLD_push_utf8_string(param_bld, OSSL_KDF_PARAM_SSHKDF_TYPE,
|
||||
+ &keytype, 1);
|
||||
+ if (r != 1) {
|
||||
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ params = OSSL_PARAM_BLD_to_param(param_bld);
|
||||
+ if (params == NULL) {
|
||||
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ r = EVP_KDF_derive(ctx, key, key_len, params);
|
||||
+ if (r != 1) {
|
||||
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto out;
|
||||
+ }
|
||||
+#ifdef DEBUG_KEX
|
||||
+ fprintf(stderr, "key '%c'== ", id);
|
||||
+ dump_digest("key", key, key_len);
|
||||
+#endif
|
||||
+ *keyp = key;
|
||||
+ key = NULL;
|
||||
+ r = 0;
|
||||
+
|
||||
+out:
|
||||
+ OSSL_PARAM_BLD_free(param_bld);
|
||||
+ OSSL_PARAM_free(params);
|
||||
+ free (key);
|
||||
+ EVP_KDF_CTX_free(ctx);
|
||||
+ if (r < 0) {
|
||||
+ return r;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+#else
|
||||
static int
|
||||
derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen,
|
||||
const struct sshbuf *shared_secret, u_char **keyp)
|
||||
@@ -1141,6 +1247,7 @@ derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen,
|
||||
ssh_digest_free(hashctx);
|
||||
return r;
|
||||
}
|
||||
+#endif /* HAVE_OPENSSL_EVP_KDF_CTX_NEW */
|
||||
|
||||
#define NKEYS 6
|
||||
int
|
||||
--
|
||||
2.49.0
|
||||
|
||||
52
0032-openssh-8.2p1-visibility.patch
Normal file
52
0032-openssh-8.2p1-visibility.patch
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
From 6aa231d9acfeca870ee87e3bf9c4a1239518706d Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:28 +0200
|
||||
Subject: [PATCH 32/50] openssh-8.2p1-visibility
|
||||
|
||||
---
|
||||
regress/misc/sk-dummy/sk-dummy.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/regress/misc/sk-dummy/sk-dummy.c b/regress/misc/sk-dummy/sk-dummy.c
|
||||
index 347b2122..344f8a8a 100644
|
||||
--- a/regress/misc/sk-dummy/sk-dummy.c
|
||||
+++ b/regress/misc/sk-dummy/sk-dummy.c
|
||||
@@ -81,7 +81,7 @@ skdebug(const char *func, const char *fmt, ...)
|
||||
#endif
|
||||
}
|
||||
|
||||
-uint32_t
|
||||
+uint32_t __attribute__((visibility("default")))
|
||||
sk_api_version(void)
|
||||
{
|
||||
return SSH_SK_VERSION_MAJOR;
|
||||
@@ -230,7 +230,7 @@ check_options(struct sk_option **options)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int
|
||||
+int __attribute__((visibility("default")))
|
||||
sk_enroll(uint32_t alg, const uint8_t *challenge, size_t challenge_len,
|
||||
const char *application, uint8_t flags, const char *pin,
|
||||
struct sk_option **options, struct sk_enroll_response **enroll_response)
|
||||
@@ -478,7 +478,7 @@ sig_ed25519(const uint8_t *message, size_t message_len,
|
||||
return ret;
|
||||
}
|
||||
|
||||
-int
|
||||
+int __attribute__((visibility("default")))
|
||||
sk_sign(uint32_t alg, const uint8_t *data, size_t datalen,
|
||||
const char *application, const uint8_t *key_handle, size_t key_handle_len,
|
||||
uint8_t flags, const char *pin, struct sk_option **options,
|
||||
@@ -535,7 +535,7 @@ sk_sign(uint32_t alg, const uint8_t *data, size_t datalen,
|
||||
return ret;
|
||||
}
|
||||
|
||||
-int
|
||||
+int __attribute__((visibility("default")))
|
||||
sk_load_resident_keys(const char *pin, struct sk_option **options,
|
||||
struct sk_resident_key ***rks, size_t *nrks)
|
||||
{
|
||||
--
|
||||
2.49.0
|
||||
|
||||
33
0033-openssh-8.2p1-x11-without-ipv6.patch
Normal file
33
0033-openssh-8.2p1-x11-without-ipv6.patch
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
From cfe5a99d335eb57b8c08b4eb6b4535dd042d96e3 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:28 +0200
|
||||
Subject: [PATCH 33/50] openssh-8.2p1-x11-without-ipv6
|
||||
|
||||
---
|
||||
channels.c | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
diff --git a/channels.c b/channels.c
|
||||
index 7438c1a5..95836d50 100644
|
||||
--- a/channels.c
|
||||
+++ b/channels.c
|
||||
@@ -5055,6 +5055,16 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset,
|
||||
debug2_f("bind port %d: %.100s", port,
|
||||
strerror(errno));
|
||||
close(sock);
|
||||
+
|
||||
+ /* do not remove successfully opened
|
||||
+ * sockets if the request failed because
|
||||
+ * the protocol IPv4/6 is not available
|
||||
+ * (e.g. IPv6 may be disabled while being
|
||||
+ * supported)
|
||||
+ */
|
||||
+ if (EADDRNOTAVAIL == errno)
|
||||
+ continue;
|
||||
+
|
||||
for (n = 0; n < num_socks; n++)
|
||||
close(socks[n]);
|
||||
num_socks = 0;
|
||||
--
|
||||
2.49.0
|
||||
|
||||
56
0034-openssh-8.0p1-preserve-pam-errors.patch
Normal file
56
0034-openssh-8.0p1-preserve-pam-errors.patch
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
From 8de0391e3b3eb75e23ee9f173f04a9c78f2b96c9 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:29 +0200
|
||||
Subject: [PATCH 34/50] openssh-8.0p1-preserve-pam-errors
|
||||
|
||||
---
|
||||
auth-pam.c | 18 +++++++++++++-----
|
||||
1 file changed, 13 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/auth-pam.c b/auth-pam.c
|
||||
index b4100ea1..a042c3c8 100644
|
||||
--- a/auth-pam.c
|
||||
+++ b/auth-pam.c
|
||||
@@ -523,7 +523,11 @@ sshpam_thread(void *ctxtp)
|
||||
goto auth_fail;
|
||||
|
||||
if (!do_pam_account()) {
|
||||
- sshpam_err = PAM_ACCT_EXPIRED;
|
||||
+ /* Preserve PAM_PERM_DENIED and PAM_USER_UNKNOWN.
|
||||
+ * Backward compatibility for other errors. */
|
||||
+ if (sshpam_err != PAM_PERM_DENIED
|
||||
+ && sshpam_err != PAM_USER_UNKNOWN)
|
||||
+ sshpam_err = PAM_ACCT_EXPIRED;
|
||||
goto auth_fail;
|
||||
}
|
||||
if (sshpam_authctxt->force_pwchange) {
|
||||
@@ -580,8 +584,10 @@ sshpam_thread(void *ctxtp)
|
||||
pam_strerror(sshpam_handle, sshpam_err))) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
/* XXX - can't do much about an error here */
|
||||
- if (sshpam_err == PAM_ACCT_EXPIRED)
|
||||
- ssh_msg_send(ctxt->pam_csock, PAM_ACCT_EXPIRED, buffer);
|
||||
+ if (sshpam_err == PAM_PERM_DENIED
|
||||
+ || sshpam_err == PAM_USER_UNKNOWN
|
||||
+ || sshpam_err == PAM_ACCT_EXPIRED)
|
||||
+ ssh_msg_send(ctxt->pam_csock, sshpam_err, buffer);
|
||||
else if (sshpam_maxtries_reached)
|
||||
ssh_msg_send(ctxt->pam_csock, PAM_MAXTRIES, buffer);
|
||||
else
|
||||
@@ -890,9 +896,11 @@ sshpam_query(void *ctx, char **name, char **info,
|
||||
free(msg);
|
||||
break;
|
||||
case PAM_ACCT_EXPIRED:
|
||||
+ sshpam_account_status = 0;
|
||||
+ /* FALLTHROUGH */
|
||||
case PAM_MAXTRIES:
|
||||
- if (type == PAM_ACCT_EXPIRED)
|
||||
- sshpam_account_status = 0;
|
||||
+ case PAM_USER_UNKNOWN:
|
||||
+ case PAM_PERM_DENIED:
|
||||
if (type == PAM_MAXTRIES)
|
||||
sshpam_set_maxtries_reached(1);
|
||||
/* FALLTHROUGH */
|
||||
--
|
||||
2.49.0
|
||||
|
||||
63
0035-openssh-8.7p1-scp-kill-switch.patch
Normal file
63
0035-openssh-8.7p1-scp-kill-switch.patch
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
From a68f3741fdc01bf6823a69d2442caba7de9835f9 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:29 +0200
|
||||
Subject: [PATCH 35/50] openssh-8.7p1-scp-kill-switch
|
||||
|
||||
---
|
||||
pathnames.h | 1 +
|
||||
scp.1 | 7 +++++++
|
||||
scp.c | 8 ++++++++
|
||||
3 files changed, 16 insertions(+)
|
||||
|
||||
diff --git a/pathnames.h b/pathnames.h
|
||||
index 1158bec9..43f0c570 100644
|
||||
--- a/pathnames.h
|
||||
+++ b/pathnames.h
|
||||
@@ -42,6 +42,7 @@
|
||||
#define _PATH_HOST_XMSS_KEY_FILE SSHDIR "/ssh_host_xmss_key"
|
||||
#define _PATH_HOST_RSA_KEY_FILE SSHDIR "/ssh_host_rsa_key"
|
||||
#define _PATH_DH_MODULI SSHDIR "/moduli"
|
||||
+#define _PATH_SCP_KILL_SWITCH SSHDIR "/disable_scp"
|
||||
|
||||
#ifndef _PATH_SSH_PROGRAM
|
||||
#define _PATH_SSH_PROGRAM "/usr/bin/ssh"
|
||||
diff --git a/scp.1 b/scp.1
|
||||
index aa2e2d8b..373d7237 100644
|
||||
--- a/scp.1
|
||||
+++ b/scp.1
|
||||
@@ -331,6 +331,13 @@ during download or upload.
|
||||
By default a 32KB buffer is used.
|
||||
.El
|
||||
.El
|
||||
+.Pp
|
||||
+Usage of SCP protocol can be blocked by creating a world-readable
|
||||
+.Ar /etc/ssh/disable_scp
|
||||
+file. If this file exists, when SCP protocol is in use (either remotely or
|
||||
+via the
|
||||
+.Fl O
|
||||
+option), the program will exit.
|
||||
.Sh EXIT STATUS
|
||||
.Ex -std scp
|
||||
.Sh SEE ALSO
|
||||
diff --git a/scp.c b/scp.c
|
||||
index 7f9795a5..7ed1a54c 100644
|
||||
--- a/scp.c
|
||||
+++ b/scp.c
|
||||
@@ -649,6 +649,14 @@ main(int argc, char **argv)
|
||||
if (iamremote)
|
||||
mode = MODE_SCP;
|
||||
|
||||
+ if (mode == MODE_SCP) {
|
||||
+ FILE *f = fopen(_PATH_SCP_KILL_SWITCH, "r");
|
||||
+ if (f != NULL) {
|
||||
+ fclose(f);
|
||||
+ fatal("SCP protocol is forbidden via %s", _PATH_SCP_KILL_SWITCH);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if ((pwd = getpwuid(userid = getuid())) == NULL)
|
||||
fatal("unknown user %u", (u_int) userid);
|
||||
|
||||
--
|
||||
2.49.0
|
||||
|
||||
200
0036-openssh-8.7p1-recursive-scp.patch
Normal file
200
0036-openssh-8.7p1-recursive-scp.patch
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
From 99e1e3af524376788e591ca73387f1ca37e6f5ef Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:29 +0200
|
||||
Subject: [PATCH 36/50] openssh-8.7p1-recursive-scp
|
||||
|
||||
---
|
||||
scp.c | 2 +-
|
||||
sftp-client.c | 60 +++++++++++++++++++++++++++++++++++++++------------
|
||||
sftp-client.h | 4 ++--
|
||||
sftp.c | 6 +++---
|
||||
4 files changed, 52 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/scp.c b/scp.c
|
||||
index 7ed1a54c..0c87dd0e 100644
|
||||
--- a/scp.c
|
||||
+++ b/scp.c
|
||||
@@ -1388,7 +1388,7 @@ source_sftp(int argc, char *src, char *targ, struct sftp_conn *conn)
|
||||
|
||||
if (src_is_dir && iamrecursive) {
|
||||
if (sftp_upload_dir(conn, src, abs_dst, pflag,
|
||||
- SFTP_PROGRESS_ONLY, 0, 0, 1, 1) != 0) {
|
||||
+ SFTP_PROGRESS_ONLY, 0, 0, 1, 1, 1) != 0) {
|
||||
error("failed to upload directory %s to %s", src, targ);
|
||||
errs = 1;
|
||||
}
|
||||
diff --git a/sftp-client.c b/sftp-client.c
|
||||
index 9f8ab4af..873dec04 100644
|
||||
--- a/sftp-client.c
|
||||
+++ b/sftp-client.c
|
||||
@@ -1003,7 +1003,7 @@ sftp_fsetstat(struct sftp_conn *conn, const u_char *handle, u_int handle_len,
|
||||
|
||||
/* Implements both the realpath and expand-path operations */
|
||||
static char *
|
||||
-sftp_realpath_expand(struct sftp_conn *conn, const char *path, int expand)
|
||||
+sftp_realpath_expand(struct sftp_conn *conn, const char *path, int expand, int create_dir)
|
||||
{
|
||||
struct sshbuf *msg;
|
||||
u_int expected_id, count, id;
|
||||
@@ -1049,11 +1049,43 @@ sftp_realpath_expand(struct sftp_conn *conn, const char *path, int expand)
|
||||
if ((r = sshbuf_get_u32(msg, &status)) != 0 ||
|
||||
(r = sshbuf_get_cstring(msg, &errmsg, NULL)) != 0)
|
||||
fatal_fr(r, "parse status");
|
||||
- error("%s %s: %s", expand ? "expand" : "realpath",
|
||||
- path, *errmsg == '\0' ? fx2txt(status) : errmsg);
|
||||
- free(errmsg);
|
||||
- sshbuf_free(msg);
|
||||
- return NULL;
|
||||
+ if ((status == SSH2_FX_NO_SUCH_FILE) && create_dir) {
|
||||
+ memset(&a, '\0', sizeof(a));
|
||||
+ if ((r = sftp_mkdir(conn, path, &a, 0)) != 0) {
|
||||
+ sshbuf_free(msg);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ debug2("Sending SSH2_FXP_REALPATH \"%s\" - create dir", path);
|
||||
+ send_string_request(conn, id, SSH2_FXP_REALPATH,
|
||||
+ path, strlen(path));
|
||||
+
|
||||
+ get_msg(conn, msg);
|
||||
+ if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
|
||||
+ (r = sshbuf_get_u32(msg, &id)) != 0)
|
||||
+ fatal_fr(r, "parse");
|
||||
+
|
||||
+ if (id != expected_id)
|
||||
+ fatal("ID mismatch (%u != %u)", id, expected_id);
|
||||
+
|
||||
+ if (type == SSH2_FXP_STATUS) {
|
||||
+ free(errmsg);
|
||||
+
|
||||
+ if ((r = sshbuf_get_u32(msg, &status)) != 0 ||
|
||||
+ (r = sshbuf_get_cstring(msg, &errmsg, NULL)) != 0)
|
||||
+ fatal_fr(r, "parse status");
|
||||
+ error("%s %s: %s", expand ? "expand" : "realpath",
|
||||
+ path, *errmsg == '\0' ? fx2txt(status) : errmsg);
|
||||
+ free(errmsg);
|
||||
+ sshbuf_free(msg);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ } else {
|
||||
+ error("%s %s: %s", expand ? "expand" : "realpath",
|
||||
+ path, *errmsg == '\0' ? fx2txt(status) : errmsg);
|
||||
+ free(errmsg);
|
||||
+ sshbuf_free(msg);
|
||||
+ return NULL;
|
||||
+ }
|
||||
} else if (type != SSH2_FXP_NAME)
|
||||
fatal("Expected SSH2_FXP_NAME(%u) packet, got %u",
|
||||
SSH2_FXP_NAME, type);
|
||||
@@ -1078,9 +1110,9 @@ sftp_realpath_expand(struct sftp_conn *conn, const char *path, int expand)
|
||||
}
|
||||
|
||||
char *
|
||||
-sftp_realpath(struct sftp_conn *conn, const char *path)
|
||||
+sftp_realpath(struct sftp_conn *conn, const char *path, int create_dir)
|
||||
{
|
||||
- return sftp_realpath_expand(conn, path, 0);
|
||||
+ return sftp_realpath_expand(conn, path, 0, create_dir);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -1094,9 +1126,9 @@ sftp_expand_path(struct sftp_conn *conn, const char *path)
|
||||
{
|
||||
if (!sftp_can_expand_path(conn)) {
|
||||
debug3_f("no server support, fallback to realpath");
|
||||
- return sftp_realpath_expand(conn, path, 0);
|
||||
+ return sftp_realpath_expand(conn, path, 0, 0);
|
||||
}
|
||||
- return sftp_realpath_expand(conn, path, 1);
|
||||
+ return sftp_realpath_expand(conn, path, 1, 0);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -2016,7 +2048,7 @@ sftp_download_dir(struct sftp_conn *conn, const char *src, const char *dst,
|
||||
char *src_canon;
|
||||
int ret;
|
||||
|
||||
- if ((src_canon = sftp_realpath(conn, src)) == NULL) {
|
||||
+ if ((src_canon = sftp_realpath(conn, src, 0)) == NULL) {
|
||||
error("download \"%s\": path canonicalization failed", src);
|
||||
return -1;
|
||||
}
|
||||
@@ -2366,12 +2398,12 @@ upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
|
||||
int
|
||||
sftp_upload_dir(struct sftp_conn *conn, const char *src, const char *dst,
|
||||
int preserve_flag, int print_flag, int resume, int fsync_flag,
|
||||
- int follow_link_flag, int inplace_flag)
|
||||
+ int follow_link_flag, int inplace_flag, int create_dir)
|
||||
{
|
||||
char *dst_canon;
|
||||
int ret;
|
||||
|
||||
- if ((dst_canon = sftp_realpath(conn, dst)) == NULL) {
|
||||
+ if ((dst_canon = sftp_realpath(conn, dst, create_dir)) == NULL) {
|
||||
error("upload \"%s\": path canonicalization failed", dst);
|
||||
return -1;
|
||||
}
|
||||
@@ -2826,7 +2858,7 @@ sftp_crossload_dir(struct sftp_conn *from, struct sftp_conn *to,
|
||||
char *from_path_canon;
|
||||
int ret;
|
||||
|
||||
- if ((from_path_canon = sftp_realpath(from, from_path)) == NULL) {
|
||||
+ if ((from_path_canon = sftp_realpath(from, from_path, 0)) == NULL) {
|
||||
error("crossload \"%s\": path canonicalization failed",
|
||||
from_path);
|
||||
return -1;
|
||||
diff --git a/sftp-client.h b/sftp-client.h
|
||||
index 74cdae7d..00ed6630 100644
|
||||
--- a/sftp-client.h
|
||||
+++ b/sftp-client.h
|
||||
@@ -111,7 +111,7 @@ int sftp_fsetstat(struct sftp_conn *, const u_char *, u_int, Attrib *);
|
||||
int sftp_lsetstat(struct sftp_conn *conn, const char *path, Attrib *a);
|
||||
|
||||
/* Canonicalise 'path' - caller must free result */
|
||||
-char *sftp_realpath(struct sftp_conn *, const char *);
|
||||
+char *sftp_realpath(struct sftp_conn *, const char *, int);
|
||||
|
||||
/* Canonicalisation with tilde expansion (requires server extension) */
|
||||
char *sftp_expand_path(struct sftp_conn *, const char *);
|
||||
@@ -163,7 +163,7 @@ int sftp_upload(struct sftp_conn *, const char *, const char *,
|
||||
* times if 'pflag' is set
|
||||
*/
|
||||
int sftp_upload_dir(struct sftp_conn *, const char *, const char *,
|
||||
- int, int, int, int, int, int);
|
||||
+ int, int, int, int, int, int, int);
|
||||
|
||||
/*
|
||||
* Download a 'from_path' from the 'from' connection and upload it to
|
||||
diff --git a/sftp.c b/sftp.c
|
||||
index bdedd141..322e6d1f 100644
|
||||
--- a/sftp.c
|
||||
+++ b/sftp.c
|
||||
@@ -809,7 +809,7 @@ process_put(struct sftp_conn *conn, const char *src, const char *dst,
|
||||
(rflag || global_rflag)) {
|
||||
if (sftp_upload_dir(conn, g.gl_pathv[i], abs_dst,
|
||||
pflag || global_pflag, 1, resume,
|
||||
- fflag || global_fflag, 0, 0) == -1)
|
||||
+ fflag || global_fflag, 0, 0, 0) == -1)
|
||||
err = -1;
|
||||
} else {
|
||||
if (sftp_upload(conn, g.gl_pathv[i], abs_dst,
|
||||
@@ -1644,7 +1644,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
|
||||
if (path1 == NULL || *path1 == '\0')
|
||||
path1 = xstrdup(startdir);
|
||||
path1 = sftp_make_absolute(path1, *pwd);
|
||||
- if ((tmp = sftp_realpath(conn, path1)) == NULL) {
|
||||
+ if ((tmp = sftp_realpath(conn, path1, 0)) == NULL) {
|
||||
err = 1;
|
||||
break;
|
||||
}
|
||||
@@ -2249,7 +2249,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
|
||||
}
|
||||
#endif /* USE_LIBEDIT */
|
||||
|
||||
- if ((remote_path = sftp_realpath(conn, ".")) == NULL)
|
||||
+ if ((remote_path = sftp_realpath(conn, ".", 0)) == NULL)
|
||||
fatal("Need cwd");
|
||||
startdir = xstrdup(remote_path);
|
||||
|
||||
--
|
||||
2.49.0
|
||||
|
||||
37
0037-openssh-8.7p1-minrsabits.patch
Normal file
37
0037-openssh-8.7p1-minrsabits.patch
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
From 286bc4a302b5130f732c857095ae665f7bea01dd Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:29 +0200
|
||||
Subject: [PATCH 37/50] openssh-8.7p1-minrsabits
|
||||
|
||||
---
|
||||
readconf.c | 1 +
|
||||
servconf.c | 1 +
|
||||
2 files changed, 2 insertions(+)
|
||||
|
||||
diff --git a/readconf.c b/readconf.c
|
||||
index 6c04ed43..f340bf50 100644
|
||||
--- a/readconf.c
|
||||
+++ b/readconf.c
|
||||
@@ -343,6 +343,7 @@ static struct {
|
||||
{ "securitykeyprovider", oSecurityKeyProvider },
|
||||
{ "knownhostscommand", oKnownHostsCommand },
|
||||
{ "requiredrsasize", oRequiredRSASize },
|
||||
+ { "rsaminsize", oRequiredRSASize }, /* alias */
|
||||
{ "enableescapecommandline", oEnableEscapeCommandline },
|
||||
{ "obscurekeystroketiming", oObscureKeystrokeTiming },
|
||||
{ "channeltimeout", oChannelTimeout },
|
||||
diff --git a/servconf.c b/servconf.c
|
||||
index 15c99b30..84891544 100644
|
||||
--- a/servconf.c
|
||||
+++ b/servconf.c
|
||||
@@ -788,6 +788,7 @@ static struct {
|
||||
{ "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL },
|
||||
{ "securitykeyprovider", sSecurityKeyProvider, SSHCFG_GLOBAL },
|
||||
{ "requiredrsasize", sRequiredRSASize, SSHCFG_ALL },
|
||||
+ { "rsaminsize", sRequiredRSASize, SSHCFG_ALL }, /* alias */
|
||||
{ "channeltimeout", sChannelTimeout, SSHCFG_ALL },
|
||||
{ "unusedconnectiontimeout", sUnusedConnectionTimeout, SSHCFG_ALL },
|
||||
{ "sshdsessionpath", sSshdSessionPath, SSHCFG_GLOBAL },
|
||||
--
|
||||
2.49.0
|
||||
|
||||
25
0038-openssh-8.7p1-ibmca.patch
Normal file
25
0038-openssh-8.7p1-ibmca.patch
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
From 26af04432f6404eb03780265a5cce948ecfec8dc Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:29 +0200
|
||||
Subject: [PATCH 38/50] openssh-8.7p1-ibmca
|
||||
|
||||
---
|
||||
openbsd-compat/bsd-closefrom.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/openbsd-compat/bsd-closefrom.c b/openbsd-compat/bsd-closefrom.c
|
||||
index f6112458..417c2048 100644
|
||||
--- a/openbsd-compat/bsd-closefrom.c
|
||||
+++ b/openbsd-compat/bsd-closefrom.c
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
-#if !defined(HAVE_CLOSEFROM) || defined(BROKEN_CLOSEFROM)
|
||||
+#if !defined(HAVE_CLOSEFROM) || defined(BROKEN_CLOSEFROM) || (defined __s390__)
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
--
|
||||
2.49.0
|
||||
|
||||
2296
0039-openssh-7.6p1-audit.patch
Normal file
2296
0039-openssh-7.6p1-audit.patch
Normal file
File diff suppressed because it is too large
Load diff
203
0040-openssh-7.1p2-audit-race-condition.patch
Normal file
203
0040-openssh-7.1p2-audit-race-condition.patch
Normal file
|
|
@ -0,0 +1,203 @@
|
|||
From c288d4a26ad44dc481c9d18d2920c9d70474833c Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:29 +0200
|
||||
Subject: [PATCH 40/50] openssh-7.1p2-audit-race-condition
|
||||
|
||||
---
|
||||
monitor_wrap.c | 46 +++++++++++++++++++++++++++++++++++++
|
||||
monitor_wrap.h | 2 ++
|
||||
session.c | 61 ++++++++++++++++++++++++++++++++++++++++++++------
|
||||
3 files changed, 102 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/monitor_wrap.c b/monitor_wrap.c
|
||||
index 1a079c15..768a59f9 100644
|
||||
--- a/monitor_wrap.c
|
||||
+++ b/monitor_wrap.c
|
||||
@@ -1415,4 +1415,50 @@ mm_audit_destroy_sensitive_data(struct ssh *ssh, const char *fp, pid_t pid, uid_
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SERVER_KEY_FREE, m);
|
||||
sshbuf_free(m);
|
||||
}
|
||||
+
|
||||
+int mm_forward_audit_messages(int fdin)
|
||||
+{
|
||||
+ u_char buf[4];
|
||||
+ u_int blen, msg_len;
|
||||
+ struct sshbuf *m;
|
||||
+ int r, ret = 0;
|
||||
+
|
||||
+ debug3_f("entering");
|
||||
+ if ((m = sshbuf_new()) == NULL)
|
||||
+ fatal_f("sshbuf_new failed");
|
||||
+ do {
|
||||
+ blen = atomicio(read, fdin, buf, sizeof(buf));
|
||||
+ if (blen == 0) /* closed pipe */
|
||||
+ break;
|
||||
+ if (blen != sizeof(buf)) {
|
||||
+ error_f("Failed to read the buffer from child");
|
||||
+ ret = -1;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ msg_len = get_u32(buf);
|
||||
+ if (msg_len > 256 * 1024)
|
||||
+ fatal_f("read: bad msg_len %d", msg_len);
|
||||
+ sshbuf_reset(m);
|
||||
+ if ((r = sshbuf_reserve(m, msg_len, NULL)) != 0)
|
||||
+ fatal_fr(r, "buffer error");
|
||||
+ if (atomicio(read, fdin, sshbuf_mutable_ptr(m), msg_len) != msg_len) {
|
||||
+ error_f("Failed to read the the buffer content from the child");
|
||||
+ ret = -1;
|
||||
+ break;
|
||||
+ }
|
||||
+ if (atomicio(vwrite, pmonitor->m_recvfd, buf, blen) != blen ||
|
||||
+ atomicio(vwrite, pmonitor->m_recvfd, sshbuf_mutable_ptr(m), msg_len) != msg_len) {
|
||||
+ error_f("Failed to write the message to the monitor");
|
||||
+ ret = -1;
|
||||
+ break;
|
||||
+ }
|
||||
+ } while (1);
|
||||
+ sshbuf_free(m);
|
||||
+ return ret;
|
||||
+}
|
||||
+void mm_set_monitor_pipe(int fd)
|
||||
+{
|
||||
+ pmonitor->m_recvfd = fd;
|
||||
+}
|
||||
#endif /* SSH_AUDIT_EVENTS */
|
||||
diff --git a/monitor_wrap.h b/monitor_wrap.h
|
||||
index 661ed63b..e957ba6e 100644
|
||||
--- a/monitor_wrap.h
|
||||
+++ b/monitor_wrap.h
|
||||
@@ -93,6 +93,8 @@ void mm_audit_unsupported_body(struct ssh *, int);
|
||||
void mm_audit_kex_body(struct ssh *, int, char *, char *, char *, char *, pid_t, uid_t);
|
||||
void mm_audit_session_key_free_body(struct ssh *, int, pid_t, uid_t);
|
||||
void mm_audit_destroy_sensitive_data(struct ssh *, const char *, pid_t, uid_t);
|
||||
+int mm_forward_audit_messages(int);
|
||||
+void mm_set_monitor_pipe(int);
|
||||
#endif
|
||||
|
||||
struct Session;
|
||||
diff --git a/session.c b/session.c
|
||||
index 83fc9418..b4753d93 100644
|
||||
--- a/session.c
|
||||
+++ b/session.c
|
||||
@@ -167,6 +167,10 @@ static Session *sessions = NULL;
|
||||
login_cap_t *lc;
|
||||
#endif
|
||||
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+int paudit[2];
|
||||
+#endif
|
||||
+
|
||||
static int is_child = 0;
|
||||
static int in_chroot = 0;
|
||||
static int have_dev_log = 1;
|
||||
@@ -390,6 +394,8 @@ xauth_valid_string(const char *s)
|
||||
return 1;
|
||||
}
|
||||
|
||||
+void child_destory_sensitive_data(struct ssh *ssh);
|
||||
+
|
||||
#define USE_PIPES 1
|
||||
/*
|
||||
* This is called to fork and execute a command when we have no tty. This
|
||||
@@ -513,6 +519,8 @@ do_exec_no_pty(struct ssh *ssh, Session *s, const char *command)
|
||||
close(err[0]);
|
||||
#endif
|
||||
|
||||
+ child_destory_sensitive_data(ssh);
|
||||
+
|
||||
/* Do processing for the child (exec command etc). */
|
||||
do_child(ssh, s, command);
|
||||
/* NOTREACHED */
|
||||
@@ -630,6 +638,9 @@ do_exec_pty(struct ssh *ssh, Session *s, const char *command)
|
||||
/* Close the extra descriptor for the pseudo tty. */
|
||||
close(ttyfd);
|
||||
|
||||
+ /* Do this early, so we will not block large MOTDs */
|
||||
+ child_destory_sensitive_data(ssh);
|
||||
+
|
||||
/* record login, etc. similar to login(1) */
|
||||
#ifndef HAVE_OSF_SIA
|
||||
do_login(ssh, s, command);
|
||||
@@ -766,6 +777,8 @@ do_exec(struct ssh *ssh, Session *s, const char *command)
|
||||
}
|
||||
if (s->command != NULL && s->ptyfd == -1)
|
||||
s->command_handle = mm_audit_run_command(ssh, s->command);
|
||||
+ if (pipe(paudit) < 0)
|
||||
+ fatal("pipe: %s", strerror(errno));
|
||||
#endif
|
||||
if (s->ttyfd != -1)
|
||||
ret = do_exec_pty(ssh, s, command);
|
||||
@@ -781,6 +794,20 @@ do_exec(struct ssh *ssh, Session *s, const char *command)
|
||||
*/
|
||||
sshbuf_reset(loginmsg);
|
||||
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+ close(paudit[1]);
|
||||
+ if (ret == 0) {
|
||||
+ /*
|
||||
+ * Read the audit messages from forked child and send them
|
||||
+ * back to monitor. We don't want to communicate directly,
|
||||
+ * because the messages might get mixed up.
|
||||
+ * Continue after the pipe gets closed (all messages sent).
|
||||
+ */
|
||||
+ ret = mm_forward_audit_messages(paudit[0]);
|
||||
+ }
|
||||
+ close(paudit[0]);
|
||||
+#endif /* SSH_AUDIT_EVENTS */
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1532,6 +1559,33 @@ child_close_fds(struct ssh *ssh)
|
||||
log_redirect_stderr_to(NULL);
|
||||
}
|
||||
|
||||
+void
|
||||
+child_destory_sensitive_data(struct ssh *ssh)
|
||||
+{
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+ int pparent = paudit[1];
|
||||
+ close(paudit[0]);
|
||||
+ /* Hack the monitor pipe to avoid race condition with parent */
|
||||
+ mm_set_monitor_pipe(pparent);
|
||||
+#endif
|
||||
+
|
||||
+ /* remove hostkey from the child's memory */
|
||||
+ /* FIXME beldmit destroy_sensitive_data(ssh); */
|
||||
+ /*
|
||||
+ * We can audit this, because we hacked the pipe to direct the
|
||||
+ * messages over postauth child. But this message requires answer
|
||||
+ * which we can't do using one-way pipe.
|
||||
+ */
|
||||
+ packet_destroy_all(ssh, 0, 1);
|
||||
+ /* XXX this will clean the rest but should not audit anymore */
|
||||
+ /* packet_clear_keys(ssh); */
|
||||
+
|
||||
+#ifdef SSH_AUDIT_EVENTS
|
||||
+ /* Notify parent that we are done */
|
||||
+ close(pparent);
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Performs common processing for the child, such as setting up the
|
||||
* environment, closing extra file descriptors, setting the user and group
|
||||
@@ -1549,13 +1603,6 @@ do_child(struct ssh *ssh, Session *s, const char *command)
|
||||
|
||||
sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id));
|
||||
|
||||
- /* remove keys from memory */
|
||||
- destroy_sensitive_data(ssh);
|
||||
- ssh_packet_clear_keys(ssh);
|
||||
- /* 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(ssh, 0, 1);
|
||||
-
|
||||
/* Force a password change */
|
||||
if (s->authctxt->force_pwchange) {
|
||||
do_setusercontext(pw);
|
||||
--
|
||||
2.49.0
|
||||
|
||||
265
0041-openssh-9.0p1-audit-log.patch
Normal file
265
0041-openssh-9.0p1-audit-log.patch
Normal file
|
|
@ -0,0 +1,265 @@
|
|||
From 80d967a18261156573e7385f8e534a89d2767d67 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:29 +0200
|
||||
Subject: [PATCH 41/50] openssh-9.0p1-audit-log
|
||||
|
||||
---
|
||||
audit-bsm.c | 2 +-
|
||||
audit-linux.c | 76 +++++++++++++++++++++++++++++++++++++++++++--------
|
||||
audit.c | 18 +++++++++---
|
||||
audit.h | 2 +-
|
||||
4 files changed, 81 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/audit-bsm.c b/audit-bsm.c
|
||||
index a49abb92..c6f56553 100644
|
||||
--- a/audit-bsm.c
|
||||
+++ b/audit-bsm.c
|
||||
@@ -405,7 +405,7 @@ audit_session_close(struct logininfo *li)
|
||||
}
|
||||
|
||||
int
|
||||
-audit_keyusage(struct ssh *ssh, int host_user, char *fp, int rv)
|
||||
+audit_keyusage(struct ssh *ssh, int host_user, char *key_fp, const struct sshkey_cert *cert, const char *issuer_fp, int rv)
|
||||
{
|
||||
/* not implemented */
|
||||
}
|
||||
diff --git a/audit-linux.c b/audit-linux.c
|
||||
index d484b82b..dcfde3a9 100644
|
||||
--- a/audit-linux.c
|
||||
+++ b/audit-linux.c
|
||||
@@ -52,7 +52,7 @@ extern u_int utmp_len;
|
||||
const char *audit_username(void);
|
||||
|
||||
static void
|
||||
-linux_audit_user_logxxx(int uid, const char *username,
|
||||
+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;
|
||||
@@ -66,7 +66,7 @@ linux_audit_user_logxxx(int uid, const char *username,
|
||||
}
|
||||
rc = audit_log_acct_message(audit_fd, event,
|
||||
NULL, "login", username ? username : "(unknown)",
|
||||
- username == NULL ? uid : -1, NULL, ip, ttyn, success);
|
||||
+ username == NULL ? uid : -1, hostname, ip, ttyn, success);
|
||||
saved_errno = errno;
|
||||
close(audit_fd);
|
||||
|
||||
@@ -137,10 +137,12 @@ fatal_report:
|
||||
}
|
||||
|
||||
int
|
||||
-audit_keyusage(struct ssh *ssh, int host_user, char *fp, int rv)
|
||||
+audit_keyusage(struct ssh *ssh, int host_user, const char *key_fp, const struct sshkey_cert *cert, const char *issuer_fp, int rv)
|
||||
{
|
||||
char buf[AUDIT_LOG_SIZE];
|
||||
int audit_fd, rc, saved_errno;
|
||||
+ const char *rip;
|
||||
+ u_int i;
|
||||
|
||||
audit_fd = audit_open();
|
||||
if (audit_fd < 0) {
|
||||
@@ -150,14 +152,44 @@ audit_keyusage(struct ssh *ssh, int host_user, char *fp, int rv)
|
||||
else
|
||||
return 0; /* Must prevent login */
|
||||
}
|
||||
+ rip = ssh_remote_ipaddr(ssh);
|
||||
snprintf(buf, sizeof(buf), "%s_auth grantors=auth-key", host_user ? "pubkey" : "hostbased");
|
||||
rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL,
|
||||
- buf, audit_username(), -1, NULL, ssh_remote_ipaddr(ssh), NULL, rv);
|
||||
+ buf, audit_username(), -1, NULL, rip, NULL, rv);
|
||||
if ((rc < 0) && ((rc != -1) || (getuid() == 0)))
|
||||
goto out;
|
||||
- snprintf(buf, sizeof(buf), "op=negotiate kind=auth-key fp=%s", fp);
|
||||
+ snprintf(buf, sizeof(buf), "op=negotiate kind=auth-key fp=%s", key_fp);
|
||||
rc = audit_log_user_message(audit_fd, AUDIT_CRYPTO_KEY_USER, buf, NULL,
|
||||
- ssh_remote_ipaddr(ssh), NULL, rv);
|
||||
+ rip, NULL, rv);
|
||||
+ if ((rc < 0) && ((rc != -1) || (getuid() == 0)))
|
||||
+ goto out;
|
||||
+
|
||||
+ if (cert) {
|
||||
+ char *pbuf;
|
||||
+
|
||||
+ pbuf = audit_encode_nv_string("key_id", cert->key_id, 0);
|
||||
+ if (pbuf == NULL)
|
||||
+ goto out;
|
||||
+ snprintf(buf, sizeof(buf), "cert %s cert_serial=%llu cert_issuer_alg=\"%s\" cert_issuer_fp=\"%s\"",
|
||||
+ pbuf, (unsigned long long)cert->serial, sshkey_type(cert->signature_key), issuer_fp);
|
||||
+ free(pbuf);
|
||||
+ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL,
|
||||
+ buf, audit_username(), -1, NULL, rip, NULL, rv);
|
||||
+ if ((rc < 0) && ((rc != -1) || (getuid() == 0)))
|
||||
+ goto out;
|
||||
+
|
||||
+ for (i = 0; cert->principals != NULL && i < cert->nprincipals; i++) {
|
||||
+ pbuf = audit_encode_nv_string("cert_principal", cert->principals[i], 0);
|
||||
+ if (pbuf == NULL)
|
||||
+ goto out;
|
||||
+ snprintf(buf, sizeof(buf), "principal %s", pbuf);
|
||||
+ free(pbuf);
|
||||
+ rc = audit_log_acct_message(audit_fd, AUDIT_USER_AUTH, NULL,
|
||||
+ buf, audit_username(), -1, NULL, rip, NULL, rv);
|
||||
+ if ((rc < 0) && ((rc != -1) || (getuid() == 0)))
|
||||
+ goto out;
|
||||
+ }
|
||||
+ }
|
||||
out:
|
||||
saved_errno = errno;
|
||||
audit_close(audit_fd);
|
||||
@@ -179,26 +211,34 @@ audit_connection_from(const char *host, int port)
|
||||
int
|
||||
audit_run_command(struct ssh *ssh, const char *command)
|
||||
{
|
||||
+ char * audit_hostname = options.use_dns ? remote_hostname(ssh) : NULL;
|
||||
if (!user_login_count++)
|
||||
linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL,
|
||||
+ audit_hostname,
|
||||
ssh_remote_ipaddr(ssh),
|
||||
"ssh", 1, AUDIT_USER_LOGIN);
|
||||
linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL,
|
||||
+ audit_hostname,
|
||||
ssh_remote_ipaddr(ssh),
|
||||
"ssh", 1, AUDIT_USER_START);
|
||||
+ free(audit_hostname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
audit_end_command(struct ssh *ssh, int handle, const char *command)
|
||||
{
|
||||
+ char * audit_hostname = options.use_dns ? remote_hostname(ssh) : NULL;
|
||||
linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL,
|
||||
+ audit_hostname,
|
||||
ssh_remote_ipaddr(ssh),
|
||||
"ssh", 1, AUDIT_USER_END);
|
||||
if (user_login_count && !--user_login_count)
|
||||
linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL,
|
||||
+ audit_hostname,
|
||||
ssh_remote_ipaddr(ssh),
|
||||
"ssh", 1, AUDIT_USER_LOGOUT);
|
||||
+ free(audit_hostname);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -211,31 +251,41 @@ void
|
||||
audit_session_open(struct logininfo *li)
|
||||
{
|
||||
if (!user_login_count++)
|
||||
- linux_audit_user_logxxx(li->uid, NULL, li->hostname,
|
||||
+ linux_audit_user_logxxx(li->uid, NULL,
|
||||
+ options.use_dns ? li->hostname : NULL,
|
||||
+ options.use_dns ? NULL : li->hostname,
|
||||
li->line, 1, AUDIT_USER_LOGIN);
|
||||
- linux_audit_user_logxxx(li->uid, NULL, li->hostname,
|
||||
+ linux_audit_user_logxxx(li->uid, NULL,
|
||||
+ options.use_dns ? li->hostname : NULL,
|
||||
+ options.use_dns ? NULL : li->hostname,
|
||||
li->line, 1, AUDIT_USER_START);
|
||||
}
|
||||
|
||||
void
|
||||
audit_session_close(struct logininfo *li)
|
||||
{
|
||||
- linux_audit_user_logxxx(li->uid, NULL, li->hostname,
|
||||
+ linux_audit_user_logxxx(li->uid, NULL,
|
||||
+ options.use_dns ? li->hostname : NULL,
|
||||
+ options.use_dns ? NULL : li->hostname,
|
||||
li->line, 1, AUDIT_USER_END);
|
||||
if (user_login_count && !--user_login_count)
|
||||
- linux_audit_user_logxxx(li->uid, NULL, li->hostname,
|
||||
+ linux_audit_user_logxxx(li->uid, NULL,
|
||||
+ options.use_dns ? li->hostname : NULL,
|
||||
+ options.use_dns ? NULL : li->hostname,
|
||||
li->line, 1, AUDIT_USER_LOGOUT);
|
||||
}
|
||||
|
||||
void
|
||||
audit_event(struct ssh *ssh, ssh_audit_event_t event)
|
||||
{
|
||||
+ char * audit_hostname = options.use_dns ? remote_hostname(ssh) : NULL;
|
||||
+
|
||||
switch(event) {
|
||||
case SSH_NOLOGIN:
|
||||
case SSH_LOGIN_ROOT_DENIED:
|
||||
linux_audit_user_auth(-1, audit_username(),
|
||||
ssh_remote_ipaddr(ssh), "ssh", 0, event);
|
||||
- linux_audit_user_logxxx(-1, audit_username(),
|
||||
+ linux_audit_user_logxxx(-1, audit_username(), audit_hostname,
|
||||
ssh_remote_ipaddr(ssh), "ssh", 0, AUDIT_USER_LOGIN);
|
||||
break;
|
||||
case SSH_AUTH_FAIL_PASSWD:
|
||||
@@ -255,9 +305,11 @@ audit_event(struct ssh *ssh, ssh_audit_event_t event)
|
||||
if (user_login_count) {
|
||||
while (user_login_count--)
|
||||
linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL,
|
||||
+ audit_hostname,
|
||||
ssh_remote_ipaddr(ssh),
|
||||
"ssh", 1, AUDIT_USER_END);
|
||||
linux_audit_user_logxxx(the_authctxt->pw->pw_uid, NULL,
|
||||
+ audit_hostname,
|
||||
ssh_remote_ipaddr(ssh),
|
||||
"ssh", 1, AUDIT_USER_LOGOUT);
|
||||
}
|
||||
@@ -266,12 +318,14 @@ audit_event(struct ssh *ssh, ssh_audit_event_t event)
|
||||
case SSH_CONNECTION_ABANDON:
|
||||
case SSH_INVALID_USER:
|
||||
linux_audit_user_logxxx(-1, audit_username(),
|
||||
+ audit_hostname,
|
||||
ssh_remote_ipaddr(ssh), "ssh", 0, AUDIT_USER_LOGIN);
|
||||
break;
|
||||
default:
|
||||
debug("%s: unhandled event %d", __func__, event);
|
||||
break;
|
||||
}
|
||||
+ free(audit_hostname);
|
||||
}
|
||||
|
||||
void
|
||||
diff --git a/audit.c b/audit.c
|
||||
index d0433c3a..28d51a14 100644
|
||||
--- a/audit.c
|
||||
+++ b/audit.c
|
||||
@@ -116,12 +116,22 @@ audit_event_lookup(ssh_audit_event_t ev)
|
||||
void
|
||||
audit_key(struct ssh *ssh, int host_user, int *rv, const struct sshkey *key)
|
||||
{
|
||||
- char *fp;
|
||||
+ char *key_fp = NULL;
|
||||
+ char *issuer_fp = NULL;
|
||||
+ struct sshkey_cert *cert = NULL;
|
||||
|
||||
- fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX);
|
||||
- if (audit_keyusage(ssh, host_user, fp, (*rv == 0)) == 0)
|
||||
+ key_fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_HEX);
|
||||
+ if (sshkey_is_cert(key) && key->cert != NULL && key->cert->signature_key != NULL) {
|
||||
+ cert = key->cert;
|
||||
+ issuer_fp = sshkey_fingerprint(cert->signature_key,
|
||||
+ options.fingerprint_hash, SSH_FP_DEFAULT);
|
||||
+ }
|
||||
+ if (audit_keyusage(ssh, host_user, key_fp, cert, issuer_fp, (*rv == 0)) == 0)
|
||||
*rv = -SSH_ERR_INTERNAL_ERROR;
|
||||
- free(fp);
|
||||
+ if (key_fp)
|
||||
+ free(key_fp);
|
||||
+ if (issuer_fp)
|
||||
+ free(issuer_fp);
|
||||
}
|
||||
|
||||
void
|
||||
diff --git a/audit.h b/audit.h
|
||||
index 45d66ccf..05ac132c 100644
|
||||
--- a/audit.h
|
||||
+++ b/audit.h
|
||||
@@ -64,7 +64,7 @@ void audit_session_close(struct logininfo *);
|
||||
int audit_run_command(struct ssh *, const char *);
|
||||
void audit_end_command(struct ssh *, int, const char *);
|
||||
ssh_audit_event_t audit_classify_auth(const char *);
|
||||
-int audit_keyusage(struct ssh *, int, char *, int);
|
||||
+int audit_keyusage(struct ssh *, int, const char *, const struct sshkey_cert *, const char *, int);
|
||||
void audit_key(struct ssh *, int, int *, const struct sshkey *);
|
||||
void audit_unsupported(struct ssh *, int);
|
||||
void audit_kex(struct ssh *, int, char *, char *, char *, char *);
|
||||
--
|
||||
2.49.0
|
||||
|
||||
763
0042-openssh-7.7p1-fips.patch
Normal file
763
0042-openssh-7.7p1-fips.patch
Normal file
|
|
@ -0,0 +1,763 @@
|
|||
From 79f9b2763d85ec592cb7e54dcf1c695d8dd138b1 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 28 Aug 2025 14:01:38 +0200
|
||||
Subject: [PATCH 42/54] openssh-7.7p1-fips
|
||||
|
||||
---
|
||||
dh.c | 41 ++++++++++++++++++++++
|
||||
dh.h | 1 +
|
||||
kex-names.c | 6 +++-
|
||||
kex.c | 3 +-
|
||||
kexgen.c | 74 ++++++++++++++++++++++++++++++++--------
|
||||
kexgexc.c | 5 +++
|
||||
myproposal.h | 33 ++++++++++++++++++
|
||||
readconf.c | 16 ++++++---
|
||||
sandbox-seccomp-filter.c | 3 ++
|
||||
servconf.c | 16 ++++++---
|
||||
ssh-ed25519.c | 9 +++++
|
||||
ssh-gss.h | 5 +++
|
||||
ssh-keygen.c | 22 ++++++++++--
|
||||
ssh-rsa.c | 3 ++
|
||||
ssh.c | 5 +++
|
||||
sshconnect2.c | 9 ++++-
|
||||
sshd-session.c | 1 +
|
||||
sshd.c | 13 +++++++
|
||||
sshkey.c | 37 ++++++++++++++++++++
|
||||
19 files changed, 272 insertions(+), 30 deletions(-)
|
||||
|
||||
diff --git a/dh.c b/dh.c
|
||||
index 168dea1dd..8c9a29fa7 100644
|
||||
--- a/dh.c
|
||||
+++ b/dh.c
|
||||
@@ -36,6 +36,7 @@
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/dh.h>
|
||||
+#include <openssl/fips.h>
|
||||
|
||||
#include "dh.h"
|
||||
#include "pathnames.h"
|
||||
@@ -164,6 +165,12 @@ choose_dh(int min, int wantbits, int max)
|
||||
int best, bestcount, which, linenum;
|
||||
struct dhgroup dhg;
|
||||
|
||||
+ if (FIPS_mode()) {
|
||||
+ verbose("Using arbitrary primes is not allowed in FIPS mode."
|
||||
+ " Falling back to known groups.");
|
||||
+ return (dh_new_group_fallback(max));
|
||||
+ }
|
||||
+
|
||||
if ((f = fopen(get_moduli_filename(), "r")) == NULL) {
|
||||
logit("WARNING: could not open %s (%s), using fixed modulus",
|
||||
get_moduli_filename(), strerror(errno));
|
||||
@@ -502,4 +509,38 @@ dh_estimate(int bits)
|
||||
return 8192;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Compares the received DH parameters with known-good groups,
|
||||
+ * which might be either from group14, group16 or group18.
|
||||
+ */
|
||||
+int
|
||||
+dh_is_known_group(const DH *dh)
|
||||
+{
|
||||
+ const BIGNUM *p, *g;
|
||||
+ const BIGNUM *known_p, *known_g;
|
||||
+ DH *known = NULL;
|
||||
+ int bits = 0, rv = 0;
|
||||
+
|
||||
+ DH_get0_pqg(dh, &p, NULL, &g);
|
||||
+ bits = BN_num_bits(p);
|
||||
+
|
||||
+ if (bits <= 3072) {
|
||||
+ known = dh_new_group14();
|
||||
+ } else if (bits <= 6144) {
|
||||
+ known = dh_new_group16();
|
||||
+ } else {
|
||||
+ known = dh_new_group18();
|
||||
+ }
|
||||
+
|
||||
+ DH_get0_pqg(known, &known_p, NULL, &known_g);
|
||||
+
|
||||
+ if (BN_cmp(g, known_g) == 0 &&
|
||||
+ BN_cmp(p, known_p) == 0) {
|
||||
+ rv = 1;
|
||||
+ }
|
||||
+
|
||||
+ DH_free(known);
|
||||
+ return rv;
|
||||
+}
|
||||
+
|
||||
#endif /* WITH_OPENSSL */
|
||||
diff --git a/dh.h b/dh.h
|
||||
index c6326a39d..e51e292b8 100644
|
||||
--- a/dh.h
|
||||
+++ b/dh.h
|
||||
@@ -45,6 +45,7 @@ DH *dh_new_group_fallback(int);
|
||||
|
||||
int dh_gen_key(DH *, int);
|
||||
int dh_pub_is_valid(const DH *, const BIGNUM *);
|
||||
+int dh_is_known_group(const DH *);
|
||||
|
||||
u_int dh_estimate(int);
|
||||
void dh_set_moduli_file(const char *);
|
||||
diff --git a/kex-names.c b/kex-names.c
|
||||
index 6c0b7c2b3..cd3902ad2 100644
|
||||
--- a/kex-names.c
|
||||
+++ b/kex-names.c
|
||||
@@ -33,6 +33,7 @@
|
||||
|
||||
#ifdef WITH_OPENSSL
|
||||
#include <openssl/crypto.h>
|
||||
+#include <openssl/fips.h>
|
||||
#include <openssl/evp.h>
|
||||
#endif
|
||||
|
||||
@@ -206,7 +207,10 @@ kex_names_valid(const char *names)
|
||||
for ((p = strsep(&cp, ",")); p && *p != '\0';
|
||||
(p = strsep(&cp, ","))) {
|
||||
if (kex_alg_by_name(p) == NULL) {
|
||||
- error("Unsupported KEX algorithm \"%.100s\"", p);
|
||||
+ if (FIPS_mode())
|
||||
+ error("\"%.100s\" is not allowed in FIPS mode", p);
|
||||
+ else
|
||||
+ error("Unsupported KEX algorithm \"%.100s\"", p);
|
||||
free(s);
|
||||
return 0;
|
||||
}
|
||||
diff --git a/kex.c b/kex.c
|
||||
index 62f607d6f..71fbe5cbe 100644
|
||||
--- a/kex.c
|
||||
+++ b/kex.c
|
||||
@@ -40,6 +40,7 @@
|
||||
#ifdef WITH_OPENSSL
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/dh.h>
|
||||
+#include <openssl/fips.h>
|
||||
# ifdef HAVE_EVP_KDF_CTX_NEW
|
||||
# include <openssl/kdf.h>
|
||||
# include <openssl/param_build.h>
|
||||
@@ -109,7 +110,7 @@ kex_proposal_populate_entries(struct ssh *ssh, char *prop[PROPOSAL_MAX],
|
||||
|
||||
/* Append EXT_INFO signalling to KexAlgorithms */
|
||||
if (kexalgos == NULL)
|
||||
- kexalgos = defprop[PROPOSAL_KEX_ALGS];
|
||||
+ kexalgos = FIPS_mode() ? KEX_DEFAULT_KEX_FIPS : defprop[PROPOSAL_KEX_ALGS];
|
||||
if ((cp = kex_names_cat(kexalgos, ssh->kex->server ?
|
||||
"ext-info-s,kex-strict-s-v00@openssh.com" :
|
||||
"ext-info-c,kex-strict-c-v00@openssh.com")) == NULL)
|
||||
diff --git a/kexgen.c b/kexgen.c
|
||||
index 15df591ca..eecdceba2 100644
|
||||
--- a/kexgen.c
|
||||
+++ b/kexgen.c
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
+#include <openssl/fips.h>
|
||||
|
||||
#include "sshkey.h"
|
||||
#include "kex.h"
|
||||
@@ -115,13 +116,28 @@ kex_gen_client(struct ssh *ssh)
|
||||
break;
|
||||
#endif
|
||||
case KEX_C25519_SHA256:
|
||||
- r = kex_c25519_keypair(kex);
|
||||
+ if (FIPS_mode()) {
|
||||
+ logit_f("Key exchange type c25519 is not allowed in FIPS mode");
|
||||
+ r = SSH_ERR_INVALID_ARGUMENT;
|
||||
+ } else {
|
||||
+ r = kex_c25519_keypair(kex);
|
||||
+ }
|
||||
break;
|
||||
case KEX_KEM_SNTRUP761X25519_SHA512:
|
||||
- r = kex_kem_sntrup761x25519_keypair(kex);
|
||||
+ if (FIPS_mode()) {
|
||||
+ logit_f("Key exchange type sntrup761 is not allowed in FIPS mode");
|
||||
+ r = SSH_ERR_INVALID_ARGUMENT;
|
||||
+ } else {
|
||||
+ r = kex_kem_sntrup761x25519_keypair(kex);
|
||||
+ }
|
||||
break;
|
||||
case KEX_KEM_MLKEM768X25519_SHA256:
|
||||
- r = kex_kem_mlkem768x25519_keypair(kex);
|
||||
+ if (FIPS_mode()) {
|
||||
+ logit_f("Key exchange type mlkem768x25519 is not allowed in FIPS mode");
|
||||
+ r = SSH_ERR_INVALID_ARGUMENT;
|
||||
+ } else {
|
||||
+ r = kex_kem_mlkem768x25519_keypair(kex);
|
||||
+ }
|
||||
break;
|
||||
default:
|
||||
r = SSH_ERR_INVALID_ARGUMENT;
|
||||
@@ -189,15 +205,30 @@ input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh)
|
||||
break;
|
||||
#endif
|
||||
case KEX_C25519_SHA256:
|
||||
- r = kex_c25519_dec(kex, server_blob, &shared_secret);
|
||||
+ if (FIPS_mode()) {
|
||||
+ logit_f("Key exchange type c25519 is not allowed in FIPS mode");
|
||||
+ r = SSH_ERR_INVALID_ARGUMENT;
|
||||
+ } else {
|
||||
+ r = kex_c25519_dec(kex, server_blob, &shared_secret);
|
||||
+ }
|
||||
break;
|
||||
case KEX_KEM_SNTRUP761X25519_SHA512:
|
||||
- r = kex_kem_sntrup761x25519_dec(kex, server_blob,
|
||||
- &shared_secret);
|
||||
+ if (FIPS_mode()) {
|
||||
+ logit_f("Key exchange type sntrup761 is not allowed in FIPS mode");
|
||||
+ r = SSH_ERR_INVALID_ARGUMENT;
|
||||
+ } else {
|
||||
+ r = kex_kem_sntrup761x25519_dec(kex, server_blob,
|
||||
+ &shared_secret);
|
||||
+ }
|
||||
break;
|
||||
case KEX_KEM_MLKEM768X25519_SHA256:
|
||||
- r = kex_kem_mlkem768x25519_dec(kex, server_blob,
|
||||
- &shared_secret);
|
||||
+ if (FIPS_mode()) {
|
||||
+ logit_f("Key exchange type mlkem768x25519 is not allowed in FIPS mode");
|
||||
+ r = SSH_ERR_INVALID_ARGUMENT;
|
||||
+ } else {
|
||||
+ r = kex_kem_mlkem768x25519_dec(kex, server_blob,
|
||||
+ &shared_secret);
|
||||
+ }
|
||||
break;
|
||||
default:
|
||||
r = SSH_ERR_INVALID_ARGUMENT;
|
||||
@@ -312,16 +343,31 @@ input_kex_gen_init(int type, u_int32_t seq, struct ssh *ssh)
|
||||
break;
|
||||
#endif
|
||||
case KEX_C25519_SHA256:
|
||||
- r = kex_c25519_enc(kex, client_pubkey, &server_pubkey,
|
||||
- &shared_secret);
|
||||
+ if (FIPS_mode()) {
|
||||
+ logit_f("Key exchange type c25519 is not allowed in FIPS mode");
|
||||
+ r = SSH_ERR_INVALID_ARGUMENT;
|
||||
+ } else {
|
||||
+ r = kex_c25519_enc(kex, client_pubkey, &server_pubkey,
|
||||
+ &shared_secret);
|
||||
+ }
|
||||
break;
|
||||
case KEX_KEM_SNTRUP761X25519_SHA512:
|
||||
- r = kex_kem_sntrup761x25519_enc(kex, client_pubkey,
|
||||
- &server_pubkey, &shared_secret);
|
||||
+ if (FIPS_mode()) {
|
||||
+ logit_f("Key exchange type sntrup761 is not allowed in FIPS mode");
|
||||
+ r = SSH_ERR_INVALID_ARGUMENT;
|
||||
+ } else {
|
||||
+ r = kex_kem_sntrup761x25519_enc(kex, client_pubkey,
|
||||
+ &server_pubkey, &shared_secret);
|
||||
+ }
|
||||
break;
|
||||
case KEX_KEM_MLKEM768X25519_SHA256:
|
||||
- r = kex_kem_mlkem768x25519_enc(kex, client_pubkey,
|
||||
- &server_pubkey, &shared_secret);
|
||||
+ if (FIPS_mode()) {
|
||||
+ logit_f("Key exchange type mlkem768x25519 is not allowed in FIPS mode");
|
||||
+ r = SSH_ERR_INVALID_ARGUMENT;
|
||||
+ } else {
|
||||
+ r = kex_kem_mlkem768x25519_enc(kex, client_pubkey,
|
||||
+ &server_pubkey, &shared_secret);
|
||||
+ }
|
||||
break;
|
||||
default:
|
||||
r = SSH_ERR_INVALID_ARGUMENT;
|
||||
diff --git a/kexgexc.c b/kexgexc.c
|
||||
index e99e0cf21..4c3feae09 100644
|
||||
--- a/kexgexc.c
|
||||
+++ b/kexgexc.c
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
#ifdef WITH_OPENSSL
|
||||
|
||||
+#include <openssl/fips.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <openssl/dh.h>
|
||||
@@ -115,6 +116,10 @@ input_kex_dh_gex_group(int type, u_int32_t seq, struct ssh *ssh)
|
||||
r = SSH_ERR_ALLOC_FAIL;
|
||||
goto out;
|
||||
}
|
||||
+ if (FIPS_mode() && dh_is_known_group(kex->dh) == 0) {
|
||||
+ r = SSH_ERR_INVALID_ARGUMENT;
|
||||
+ goto out;
|
||||
+ }
|
||||
p = g = NULL; /* belong to kex->dh now */
|
||||
|
||||
/* generate and send 'e', client DH public key */
|
||||
diff --git a/myproposal.h b/myproposal.h
|
||||
index 8fe9276c2..3e0ec6826 100644
|
||||
--- a/myproposal.h
|
||||
+++ b/myproposal.h
|
||||
@@ -58,6 +58,18 @@
|
||||
"rsa-sha2-512," \
|
||||
"rsa-sha2-256"
|
||||
|
||||
+#define KEX_FIPS_PK_ALG \
|
||||
+ "ecdsa-sha2-nistp256-cert-v01@openssh.com," \
|
||||
+ "ecdsa-sha2-nistp384-cert-v01@openssh.com," \
|
||||
+ "ecdsa-sha2-nistp521-cert-v01@openssh.com," \
|
||||
+ "rsa-sha2-512-cert-v01@openssh.com," \
|
||||
+ "rsa-sha2-256-cert-v01@openssh.com," \
|
||||
+ "ecdsa-sha2-nistp256," \
|
||||
+ "ecdsa-sha2-nistp384," \
|
||||
+ "ecdsa-sha2-nistp521," \
|
||||
+ "rsa-sha2-512," \
|
||||
+ "rsa-sha2-256"
|
||||
+
|
||||
#define KEX_SERVER_ENCRYPT \
|
||||
"chacha20-poly1305@openssh.com," \
|
||||
"aes128-gcm@openssh.com,aes256-gcm@openssh.com," \
|
||||
@@ -79,6 +91,27 @@
|
||||
|
||||
#define KEX_CLIENT_MAC KEX_SERVER_MAC
|
||||
|
||||
+#define KEX_FIPS_ENCRYPT \
|
||||
+ "aes128-ctr,aes192-ctr,aes256-ctr," \
|
||||
+ "aes128-cbc,3des-cbc," \
|
||||
+ "aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se," \
|
||||
+ "aes128-gcm@openssh.com,aes256-gcm@openssh.com"
|
||||
+#define KEX_DEFAULT_KEX_FIPS \
|
||||
+ "ecdh-sha2-nistp256," \
|
||||
+ "ecdh-sha2-nistp384," \
|
||||
+ "ecdh-sha2-nistp521," \
|
||||
+ "diffie-hellman-group-exchange-sha256," \
|
||||
+ "diffie-hellman-group16-sha512," \
|
||||
+ "diffie-hellman-group18-sha512," \
|
||||
+ "diffie-hellman-group14-sha256"
|
||||
+#define KEX_FIPS_MAC \
|
||||
+ "hmac-sha1," \
|
||||
+ "hmac-sha2-256," \
|
||||
+ "hmac-sha2-512," \
|
||||
+ "hmac-sha1-etm@openssh.com," \
|
||||
+ "hmac-sha2-256-etm@openssh.com," \
|
||||
+ "hmac-sha2-512-etm@openssh.com"
|
||||
+
|
||||
/* Not a KEX value, but here so all the algorithm defaults are together */
|
||||
#define SSH_ALLOWED_CA_SIGALGS \
|
||||
"ssh-ed25519," \
|
||||
diff --git a/readconf.c b/readconf.c
|
||||
index f340bf501..ea9d293c3 100644
|
||||
--- a/readconf.c
|
||||
+++ b/readconf.c
|
||||
@@ -43,6 +43,7 @@
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
+#include <openssl/fips.h>
|
||||
#ifdef USE_SYSTEM_GLOB
|
||||
# include <glob.h>
|
||||
#else
|
||||
@@ -3043,11 +3044,16 @@ fill_default_options(Options * options)
|
||||
all_key = sshkey_alg_list(0, 0, 1, ',');
|
||||
all_sig = sshkey_alg_list(0, 1, 1, ',');
|
||||
/* remove unsupported algos from default lists */
|
||||
- def_cipher = match_filter_allowlist(KEX_CLIENT_ENCRYPT, all_cipher);
|
||||
- def_mac = match_filter_allowlist(KEX_CLIENT_MAC, all_mac);
|
||||
- def_kex = match_filter_allowlist(KEX_CLIENT_KEX, all_kex);
|
||||
- def_key = match_filter_allowlist(KEX_DEFAULT_PK_ALG, all_key);
|
||||
- def_sig = match_filter_allowlist(SSH_ALLOWED_CA_SIGALGS, all_sig);
|
||||
+ def_cipher = match_filter_allowlist((FIPS_mode() ?
|
||||
+ KEX_FIPS_ENCRYPT : KEX_CLIENT_ENCRYPT), all_cipher);
|
||||
+ def_mac = match_filter_allowlist((FIPS_mode() ?
|
||||
+ KEX_FIPS_MAC : KEX_CLIENT_MAC), all_mac);
|
||||
+ def_kex = match_filter_allowlist((FIPS_mode() ?
|
||||
+ KEX_DEFAULT_KEX_FIPS : KEX_CLIENT_KEX), all_kex);
|
||||
+ def_key = match_filter_allowlist((FIPS_mode() ?
|
||||
+ KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG), all_key);
|
||||
+ def_sig = match_filter_allowlist((FIPS_mode() ?
|
||||
+ KEX_FIPS_PK_ALG : SSH_ALLOWED_CA_SIGALGS), all_sig);
|
||||
#define ASSEMBLE(what, defaults, all) \
|
||||
do { \
|
||||
if ((r = kex_assemble_names(&options->what, \
|
||||
diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c
|
||||
index 1fabf99d0..ccb61586e 100644
|
||||
--- a/sandbox-seccomp-filter.c
|
||||
+++ b/sandbox-seccomp-filter.c
|
||||
@@ -230,6 +230,9 @@ static const struct sock_filter preauth_insns[] = {
|
||||
#ifdef __NR_open
|
||||
SC_DENY(__NR_open, EACCES),
|
||||
#endif
|
||||
+#ifdef __NR_socket
|
||||
+ SC_DENY(__NR_socket, EACCES),
|
||||
+#endif
|
||||
#ifdef __NR_openat
|
||||
SC_DENY(__NR_openat, EACCES),
|
||||
#endif
|
||||
diff --git a/servconf.c b/servconf.c
|
||||
index 84891544b..8b708cbf4 100644
|
||||
--- a/servconf.c
|
||||
+++ b/servconf.c
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <limits.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
+#include <openssl/fips.h>
|
||||
#ifdef HAVE_UTIL_H
|
||||
#include <util.h>
|
||||
#endif
|
||||
@@ -247,11 +248,16 @@ assemble_algorithms(ServerOptions *o)
|
||||
all_key = sshkey_alg_list(0, 0, 1, ',');
|
||||
all_sig = sshkey_alg_list(0, 1, 1, ',');
|
||||
/* remove unsupported algos from default lists */
|
||||
- def_cipher = match_filter_allowlist(KEX_SERVER_ENCRYPT, all_cipher);
|
||||
- def_mac = match_filter_allowlist(KEX_SERVER_MAC, all_mac);
|
||||
- def_kex = match_filter_allowlist(KEX_SERVER_KEX, all_kex);
|
||||
- def_key = match_filter_allowlist(KEX_DEFAULT_PK_ALG, all_key);
|
||||
- def_sig = match_filter_allowlist(SSH_ALLOWED_CA_SIGALGS, all_sig);
|
||||
+ def_cipher = match_filter_allowlist((FIPS_mode() ?
|
||||
+ KEX_FIPS_ENCRYPT : KEX_SERVER_ENCRYPT), all_cipher);
|
||||
+ def_mac = match_filter_allowlist((FIPS_mode() ?
|
||||
+ KEX_FIPS_MAC : KEX_SERVER_MAC), all_mac);
|
||||
+ def_kex = match_filter_allowlist((FIPS_mode() ?
|
||||
+ KEX_DEFAULT_KEX_FIPS : KEX_SERVER_KEX), all_kex);
|
||||
+ def_key = match_filter_allowlist((FIPS_mode() ?
|
||||
+ KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG), all_key);
|
||||
+ def_sig = match_filter_allowlist((FIPS_mode() ?
|
||||
+ KEX_FIPS_PK_ALG : SSH_ALLOWED_CA_SIGALGS), all_sig);
|
||||
#define ASSEMBLE(what, defaults, all) \
|
||||
do { \
|
||||
if ((r = kex_assemble_names(&o->what, defaults, all)) != 0) \
|
||||
diff --git a/ssh-ed25519.c b/ssh-ed25519.c
|
||||
index 22d8db026..41942f4e5 100644
|
||||
--- a/ssh-ed25519.c
|
||||
+++ b/ssh-ed25519.c
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
+#include <openssl/fips.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "sshbuf.h"
|
||||
@@ -164,6 +165,10 @@ ssh_ed25519_sign(struct sshkey *key,
|
||||
key->ed25519_sk == NULL ||
|
||||
datalen >= INT_MAX - crypto_sign_ed25519_BYTES)
|
||||
return SSH_ERR_INVALID_ARGUMENT;
|
||||
+ if (FIPS_mode()) {
|
||||
+ logit_f("Ed25519 keys are not allowed in FIPS mode");
|
||||
+ return SSH_ERR_INVALID_ARGUMENT;
|
||||
+ }
|
||||
smlen = slen = datalen + crypto_sign_ed25519_BYTES;
|
||||
if ((sig = malloc(slen)) == NULL)
|
||||
return SSH_ERR_ALLOC_FAIL;
|
||||
@@ -221,6 +226,10 @@ ssh_ed25519_verify(const struct sshkey *key,
|
||||
dlen >= INT_MAX - crypto_sign_ed25519_BYTES ||
|
||||
sig == NULL || siglen == 0)
|
||||
return SSH_ERR_INVALID_ARGUMENT;
|
||||
+ if (FIPS_mode()) {
|
||||
+ logit_f("Ed25519 keys are not allowed in FIPS mode");
|
||||
+ return SSH_ERR_INVALID_ARGUMENT;
|
||||
+ }
|
||||
|
||||
if ((b = sshbuf_from(sig, siglen)) == NULL)
|
||||
return SSH_ERR_ALLOC_FAIL;
|
||||
diff --git a/ssh-gss.h b/ssh-gss.h
|
||||
index a894e23c9..329dc9da0 100644
|
||||
--- a/ssh-gss.h
|
||||
+++ b/ssh-gss.h
|
||||
@@ -88,6 +88,11 @@ extern char **k5users_allowed_cmds;
|
||||
KEX_GSS_GRP14_SHA1_ID "," \
|
||||
KEX_GSS_GEX_SHA1_ID
|
||||
|
||||
+#define GSS_KEX_DEFAULT_KEX_FIPS \
|
||||
+ KEX_GSS_GRP14_SHA256_ID "," \
|
||||
+ KEX_GSS_GRP16_SHA512_ID "," \
|
||||
+ KEX_GSS_NISTP256_SHA256_ID
|
||||
+
|
||||
#include "digest.h" /* SSH_DIGEST_MAX_LENGTH */
|
||||
|
||||
typedef struct {
|
||||
diff --git a/ssh-keygen.c b/ssh-keygen.c
|
||||
index 16cff9473..792aafde0 100644
|
||||
--- a/ssh-keygen.c
|
||||
+++ b/ssh-keygen.c
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#ifdef WITH_OPENSSL
|
||||
#include <openssl/evp.h>
|
||||
+#include <openssl/fips.h>
|
||||
#include <openssl/pem.h>
|
||||
#include "openbsd-compat/openssl-compat.h"
|
||||
#endif
|
||||
@@ -68,6 +69,7 @@
|
||||
#include "cipher.h"
|
||||
|
||||
#define DEFAULT_KEY_TYPE_NAME "ed25519"
|
||||
+#define FIPS_DEFAULT_KEY_TYPE_NAME "rsa"
|
||||
|
||||
/*
|
||||
* Default number of bits in the RSA, DSA and ECDSA keys. These value can be
|
||||
@@ -202,6 +204,12 @@ type_bits_valid(int type, const char *name, u_int32_t *bitsp)
|
||||
#endif
|
||||
}
|
||||
#ifdef WITH_OPENSSL
|
||||
+ if (FIPS_mode()) {
|
||||
+ if (type == KEY_DSA)
|
||||
+ fatal("DSA keys are not allowed in FIPS mode");
|
||||
+ if (type == KEY_ED25519 || type == KEY_ED25519_SK)
|
||||
+ fatal("ED25519 keys are not allowed in FIPS mode");
|
||||
+ }
|
||||
switch (type) {
|
||||
case KEY_DSA:
|
||||
if (*bitsp != 1024)
|
||||
@@ -259,7 +267,7 @@ ask_filename(struct passwd *pw, const char *prompt)
|
||||
char *name = NULL;
|
||||
|
||||
if (key_type_name == NULL)
|
||||
- name = _PATH_SSH_CLIENT_ID_ED25519;
|
||||
+ name = FIPS_mode() ? _PATH_SSH_CLIENT_ID_RSA : _PATH_SSH_CLIENT_ID_ED25519;
|
||||
else {
|
||||
switch (sshkey_type_from_shortname(key_type_name)) {
|
||||
#ifdef WITH_DSA
|
||||
@@ -1144,9 +1152,17 @@ do_gen_all_hostkeys(struct passwd *pw)
|
||||
first = 1;
|
||||
printf("%s: generating new host keys: ", __progname);
|
||||
}
|
||||
+ type = sshkey_type_from_shortname(key_types[i].key_type);
|
||||
+
|
||||
+ /* Skip the keys that are not supported in FIPS mode */
|
||||
+ if (FIPS_mode() && (type == KEY_DSA || type == KEY_ED25519)) {
|
||||
+ logit("Skipping %s key in FIPS mode",
|
||||
+ key_types[i].key_type_display);
|
||||
+ goto next;
|
||||
+ }
|
||||
+
|
||||
printf("%s ", key_types[i].key_type_display);
|
||||
fflush(stdout);
|
||||
- type = sshkey_type_from_shortname(key_types[i].key_type);
|
||||
if ((fd = mkstemp(prv_tmp)) == -1) {
|
||||
error("Could not save your private key in %s: %s",
|
||||
prv_tmp, strerror(errno));
|
||||
@@ -3849,7 +3865,7 @@ main(int argc, char **argv)
|
||||
}
|
||||
|
||||
if (key_type_name == NULL)
|
||||
- key_type_name = DEFAULT_KEY_TYPE_NAME;
|
||||
+ key_type_name = FIPS_mode() ? FIPS_DEFAULT_KEY_TYPE_NAME : DEFAULT_KEY_TYPE_NAME;
|
||||
|
||||
type = sshkey_type_from_shortname(key_type_name);
|
||||
type_bits_valid(type, key_type_name, &bits);
|
||||
diff --git a/ssh-rsa.c b/ssh-rsa.c
|
||||
index 3ad1fddc4..6c2f771a3 100644
|
||||
--- a/ssh-rsa.c
|
||||
+++ b/ssh-rsa.c
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/err.h>
|
||||
+#include <openssl/fips.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
@@ -142,6 +143,8 @@ ssh_rsa_generate(struct sshkey *k, int bits)
|
||||
goto out;
|
||||
}
|
||||
if (EVP_PKEY_keygen(ctx, &res) <= 0 || res == NULL) {
|
||||
+ if (FIPS_mode())
|
||||
+ logit_f("the key length might be unsupported by FIPS mode approved key generation method");
|
||||
ret = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
goto out;
|
||||
}
|
||||
diff --git a/ssh.c b/ssh.c
|
||||
index 98b103c9e..abc8b8439 100644
|
||||
--- a/ssh.c
|
||||
+++ b/ssh.c
|
||||
@@ -78,6 +78,7 @@
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/err.h>
|
||||
#endif
|
||||
+#include <openssl/fips.h>
|
||||
#include "openbsd-compat/openssl-compat.h"
|
||||
#include "openbsd-compat/sys-queue.h"
|
||||
|
||||
@@ -1642,6 +1643,10 @@ main(int ac, char **av)
|
||||
exit(0);
|
||||
}
|
||||
|
||||
+ if (FIPS_mode()) {
|
||||
+ debug("FIPS mode initialized");
|
||||
+ }
|
||||
+
|
||||
/* Expand SecurityKeyProvider if it refers to an environment variable */
|
||||
if (options.sk_provider != NULL && *options.sk_provider == '$' &&
|
||||
strlen(options.sk_provider) > 1) {
|
||||
diff --git a/sshconnect2.c b/sshconnect2.c
|
||||
index 0af15bcc1..3e02f485d 100644
|
||||
--- a/sshconnect2.c
|
||||
+++ b/sshconnect2.c
|
||||
@@ -45,6 +45,8 @@
|
||||
#include <vis.h>
|
||||
#endif
|
||||
|
||||
+#include <openssl/fips.h>
|
||||
+
|
||||
#include "openbsd-compat/sys-queue.h"
|
||||
|
||||
#include "xmalloc.h"
|
||||
@@ -262,6 +264,9 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port,
|
||||
|
||||
#if defined(GSSAPI) && defined(WITH_OPENSSL)
|
||||
if (options.gss_keyex) {
|
||||
+ char * gss_kex_filtered = FIPS_mode() ?
|
||||
+ match_filter_allowlist(options.gss_kex_algorithms, GSS_KEX_DEFAULT_KEX_FIPS) : xstrdup(options.gss_kex_algorithms);
|
||||
+
|
||||
/* Add the GSSAPI mechanisms currently supported on this
|
||||
* client to the key exchange algorithm proposal */
|
||||
orig = myproposal[PROPOSAL_KEX_ALGS];
|
||||
@@ -281,7 +286,9 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port,
|
||||
}
|
||||
|
||||
gss = ssh_gssapi_client_mechanisms(gss_host,
|
||||
- options.gss_client_identity, options.gss_kex_algorithms);
|
||||
+ options.gss_client_identity, gss_kex_filtered);
|
||||
+ free(gss_kex_filtered);
|
||||
+
|
||||
if (gss) {
|
||||
debug("Offering GSSAPI proposal: %s", gss);
|
||||
xasprintf(&myproposal[PROPOSAL_KEX_ALGS],
|
||||
diff --git a/sshd-session.c b/sshd-session.c
|
||||
index a808ac9a6..a67a78391 100644
|
||||
--- a/sshd-session.c
|
||||
+++ b/sshd-session.c
|
||||
@@ -62,6 +62,7 @@
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rand.h>
|
||||
+#include <openssl/fips.h>
|
||||
#include "openbsd-compat/openssl-compat.h"
|
||||
#endif
|
||||
|
||||
diff --git a/sshd.c b/sshd.c
|
||||
index 8a99f0b29..5ff0b5ff0 100644
|
||||
--- a/sshd.c
|
||||
+++ b/sshd.c
|
||||
@@ -52,6 +52,7 @@
|
||||
#endif
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
+#include <syslog.h>
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
@@ -63,6 +64,7 @@
|
||||
#ifdef WITH_OPENSSL
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rand.h>
|
||||
+#include <openssl/fips.h>
|
||||
#include "openbsd-compat/openssl-compat.h"
|
||||
#endif
|
||||
|
||||
@@ -1611,6 +1613,13 @@ main(int ac, char **av)
|
||||
&key, NULL)) != 0 && r != SSH_ERR_SYSTEM_ERROR)
|
||||
do_log2_r(r, ll, "Unable to load host key \"%s\"",
|
||||
options.host_key_files[i]);
|
||||
+ if (FIPS_mode() && key != NULL && (sshkey_type_plain(key->type) == KEY_ED25519_SK
|
||||
+ || sshkey_type_plain(key->type) == KEY_ED25519)) {
|
||||
+ logit_f("sshd: Ed25519 keys are not allowed in FIPS mode, skipping %s", options.host_key_files[i]);
|
||||
+ sshkey_free(key);
|
||||
+ key = NULL;
|
||||
+ continue;
|
||||
+ }
|
||||
if (sshkey_is_sk(key) &&
|
||||
key->sk_flags & SSH_SK_USER_PRESENCE_REQD) {
|
||||
debug("host key %s requires user presence, ignoring",
|
||||
@@ -1830,6 +1839,10 @@ main(int ac, char **av)
|
||||
/* Reinitialize the log (because of the fork above). */
|
||||
log_init(__progname, options.log_level, options.log_facility, log_stderr);
|
||||
|
||||
+ if (FIPS_mode()) {
|
||||
+ debug("FIPS mode initialized");
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* Chdir to the root directory so that the current disk can be
|
||||
* unmounted if desired.
|
||||
diff --git a/sshkey.c b/sshkey.c
|
||||
index 4e41a78c7..ca1cdb642 100644
|
||||
--- a/sshkey.c
|
||||
+++ b/sshkey.c
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pem.h>
|
||||
+#include <openssl/fips.h>
|
||||
#endif
|
||||
|
||||
#include "crypto_api.h"
|
||||
@@ -59,6 +60,7 @@
|
||||
#define SSHKEY_INTERNAL
|
||||
#include "sshkey.h"
|
||||
#include "match.h"
|
||||
+#include "log.h"
|
||||
#include "ssh-sk.h"
|
||||
|
||||
#ifdef WITH_XMSS
|
||||
@@ -408,6 +410,18 @@ sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep)
|
||||
impl = keyimpls[i];
|
||||
if (impl->name == NULL || impl->type == KEY_NULL)
|
||||
continue;
|
||||
+ if (FIPS_mode()) {
|
||||
+ switch (impl->type) {
|
||||
+ case KEY_ED25519:
|
||||
+ case KEY_ED25519_SK:
|
||||
+ case KEY_ED25519_CERT:
|
||||
+ case KEY_ED25519_SK_CERT:
|
||||
+ continue;
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
if (!include_sigonly && impl->sigonly)
|
||||
continue;
|
||||
if ((certs_only && !impl->cert) || (plain_only && impl->cert))
|
||||
@@ -1441,6 +1455,20 @@ sshkey_read(struct sshkey *ret, char **cpp)
|
||||
return SSH_ERR_EC_CURVE_MISMATCH;
|
||||
}
|
||||
|
||||
+ switch (type) {
|
||||
+ case KEY_ED25519:
|
||||
+ case KEY_ED25519_SK:
|
||||
+ case KEY_ED25519_CERT:
|
||||
+ case KEY_ED25519_SK_CERT:
|
||||
+ if (FIPS_mode()) {
|
||||
+ sshkey_free(k);
|
||||
+ logit_f("Ed25519 keys are not allowed in FIPS mode");
|
||||
+ return SSH_ERR_INVALID_ARGUMENT;
|
||||
+ }
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
/* Fill in ret from parsed key */
|
||||
sshkey_free_contents(ret);
|
||||
*ret = *k;
|
||||
@@ -2275,6 +2303,11 @@ sshkey_sign(struct sshkey *key,
|
||||
*lenp = 0;
|
||||
if (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE)
|
||||
return SSH_ERR_INVALID_ARGUMENT;
|
||||
+ if (FIPS_mode() && ((key->type == KEY_ED25519_SK) || (key->type == KEY_ED25519_SK_CERT))) {
|
||||
+ logit_f("Ed25519 keys are not allowed in FIPS mode");
|
||||
+ return SSH_ERR_INVALID_ARGUMENT;
|
||||
+ }
|
||||
+ /* Fallthrough */
|
||||
if ((impl = sshkey_impl_from_key(key)) == NULL)
|
||||
return SSH_ERR_KEY_TYPE_UNKNOWN;
|
||||
if ((r = sshkey_unshield_private(key)) != 0)
|
||||
@@ -2311,6 +2344,10 @@ sshkey_verify(const struct sshkey *key,
|
||||
*detailsp = NULL;
|
||||
if (siglen == 0 || dlen > SSH_KEY_MAX_SIGN_DATA_SIZE)
|
||||
return SSH_ERR_INVALID_ARGUMENT;
|
||||
+ if (FIPS_mode() && ((key->type == KEY_ED25519_SK) || (key->type == KEY_ED25519_SK_CERT))) {
|
||||
+ logit_f("Ed25519 keys are not allowed in FIPS mode");
|
||||
+ return SSH_ERR_INVALID_ARGUMENT;
|
||||
+ }
|
||||
if ((impl = sshkey_impl_from_key(key)) == NULL)
|
||||
return SSH_ERR_KEY_TYPE_UNKNOWN;
|
||||
return impl->funcs->verify(key, sig, siglen, data, dlen,
|
||||
--
|
||||
2.51.0
|
||||
|
||||
47
0043-openssh-8.7p1-ssh-manpage.patch
Normal file
47
0043-openssh-8.7p1-ssh-manpage.patch
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
From 299a602802d7c7d121306eb2aeae1502871a35cb Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:29 +0200
|
||||
Subject: [PATCH 43/50] openssh-8.7p1-ssh-manpage
|
||||
|
||||
---
|
||||
ssh.1 | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ssh.1 b/ssh.1
|
||||
index 6a9fbdc5..755cdef2 100644
|
||||
--- a/ssh.1
|
||||
+++ b/ssh.1
|
||||
@@ -510,12 +510,12 @@ For full details of the options listed below, and their possible values, see
|
||||
.It BatchMode
|
||||
.It BindAddress
|
||||
.It BindInterface
|
||||
-.It CASignatureAlgorithms
|
||||
.It CanonicalDomains
|
||||
.It CanonicalizeFallbackLocal
|
||||
.It CanonicalizeHostname
|
||||
.It CanonicalizeMaxDots
|
||||
.It CanonicalizePermittedCNAMEs
|
||||
+.It CASignatureAlgorithms
|
||||
.It CertificateFile
|
||||
.It ChannelTimeout
|
||||
.It CheckHostIP
|
||||
@@ -528,6 +528,7 @@ For full details of the options listed below, and their possible values, see
|
||||
.It ControlPath
|
||||
.It ControlPersist
|
||||
.It DynamicForward
|
||||
+.It EnableSSHKeysign
|
||||
.It EnableEscapeCommandline
|
||||
.It EnableSSHKeysign
|
||||
.It EscapeChar
|
||||
@@ -588,6 +589,8 @@ For full details of the options listed below, and their possible values, see
|
||||
.It RemoteCommand
|
||||
.It RemoteForward
|
||||
.It RequestTTY
|
||||
+.It RevokedHostKeys
|
||||
+.It SecurityKeyProvider
|
||||
.It RequiredRSASize
|
||||
.It RevokedHostKeys
|
||||
.It SecurityKeyProvider
|
||||
--
|
||||
2.49.0
|
||||
|
||||
133
0044-openssh-8.7p1-negotiate-supported-algs.patch
Normal file
133
0044-openssh-8.7p1-negotiate-supported-algs.patch
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
From 5c92430c08ac392b5b2ace899cc043247c923734 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:29 +0200
|
||||
Subject: [PATCH 44/50] openssh-8.7p1-negotiate-supported-algs
|
||||
|
||||
---
|
||||
regress/hostkey-agent.sh | 32 +++++++++++++++++++++++++-------
|
||||
sshconnect2.c | 17 +++++++++++++++--
|
||||
2 files changed, 40 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/regress/hostkey-agent.sh b/regress/hostkey-agent.sh
|
||||
index 28dcfe17..b9e716dc 100644
|
||||
--- a/regress/hostkey-agent.sh
|
||||
+++ b/regress/hostkey-agent.sh
|
||||
@@ -17,8 +17,21 @@ trace "make CA key"
|
||||
|
||||
${SSHKEYGEN} -qt ed25519 -f $OBJ/agent-ca -N '' || fatal "ssh-keygen CA"
|
||||
|
||||
+PUBKEY_ACCEPTED_ALGOS=`$SSH -G "example.com" | \
|
||||
+ grep -i "PubkeyAcceptedAlgorithms" | cut -d ' ' -f2- | tr "," "|"`
|
||||
+SSH_ACCEPTED_KEYTYPES=`echo "$SSH_KEYTYPES" | egrep "$PUBKEY_ACCEPTED_ALGOS"`
|
||||
+echo $PUBKEY_ACCEPTED_ALGOS | grep "rsa"
|
||||
+r=$?
|
||||
+if [ $r == 0 ]; then
|
||||
+echo $SSH_ACCEPTED_KEYTYPES | grep "rsa"
|
||||
+r=$?
|
||||
+if [ $r -ne 0 ]; then
|
||||
+SSH_ACCEPTED_KEYTYPES="$SSH_ACCEPTED_KEYTYPES ssh-rsa"
|
||||
+fi
|
||||
+fi
|
||||
+
|
||||
trace "load hostkeys"
|
||||
-for k in $SSH_KEYTYPES ; do
|
||||
+for k in $SSH_ACCEPTED_KEYTYPES ; do
|
||||
${SSHKEYGEN} -qt $k -f $OBJ/agent-key.$k -N '' || fatal "ssh-keygen $k"
|
||||
${SSHKEYGEN} -s $OBJ/agent-ca -qh -n localhost-with-alias \
|
||||
-I localhost-with-alias $OBJ/agent-key.$k.pub || \
|
||||
@@ -32,12 +45,16 @@ rm $OBJ/agent-ca # Don't need CA private any more either
|
||||
|
||||
unset SSH_AUTH_SOCK
|
||||
|
||||
-for k in $SSH_KEYTYPES ; do
|
||||
+for k in $SSH_ACCEPTED_KEYTYPES ; do
|
||||
verbose "key type $k"
|
||||
+ hka=$k
|
||||
+ if [ $k = "ssh-rsa" ]; then
|
||||
+ hka="rsa-sha2-512"
|
||||
+ fi
|
||||
cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy
|
||||
- echo "HostKeyAlgorithms $k" >> $OBJ/sshd_proxy
|
||||
+ echo "HostKeyAlgorithms $hka" >> $OBJ/sshd_proxy
|
||||
echo "Hostkey $OBJ/agent-key.${k}" >> $OBJ/sshd_proxy
|
||||
- opts="-oHostKeyAlgorithms=$k -F $OBJ/ssh_proxy"
|
||||
+ opts="-oHostKeyAlgorithms=$hka -F $OBJ/ssh_proxy"
|
||||
( printf 'localhost-with-alias,127.0.0.1,::1 ' ;
|
||||
cat $OBJ/agent-key.$k.pub) > $OBJ/known_hosts
|
||||
SSH_CONNECTION=`${SSH} $opts host 'echo $SSH_CONNECTION'`
|
||||
@@ -50,15 +67,16 @@ for k in $SSH_KEYTYPES ; do
|
||||
done
|
||||
|
||||
SSH_CERTTYPES=`ssh -Q key-sig | grep 'cert-v01@openssh.com' | maybe_filter_sk`
|
||||
+SSH_ACCEPTED_CERTTYPES=`echo "$SSH_CERTTYPES" | egrep "$PUBKEY_ACCEPTED_ALGOS"`
|
||||
|
||||
# Prepare sshd_proxy for certificates.
|
||||
cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy
|
||||
HOSTKEYALGS=""
|
||||
-for k in $SSH_CERTTYPES ; do
|
||||
+for k in $SSH_ACCEPTED_CERTTYPES ; do
|
||||
test -z "$HOSTKEYALGS" || HOSTKEYALGS="${HOSTKEYALGS},"
|
||||
HOSTKEYALGS="${HOSTKEYALGS}${k}"
|
||||
done
|
||||
-for k in $SSH_KEYTYPES ; do
|
||||
+for k in $SSH_ACCEPTED_KEYTYPES ; do
|
||||
echo "Hostkey $OBJ/agent-key.${k}.pub" >> $OBJ/sshd_proxy
|
||||
echo "HostCertificate $OBJ/agent-key.${k}-cert.pub" >> $OBJ/sshd_proxy
|
||||
test -f $OBJ/agent-key.${k}.pub || fatal "no $k key"
|
||||
@@ -70,7 +88,7 @@ echo "HostKeyAlgorithms $HOSTKEYALGS" >> $OBJ/sshd_proxy
|
||||
( printf '@cert-authority localhost-with-alias ' ;
|
||||
cat $OBJ/agent-ca.pub) > $OBJ/known_hosts
|
||||
|
||||
-for k in $SSH_CERTTYPES ; do
|
||||
+for k in $SSH_ACCEPTED_CERTTYPES ; do
|
||||
verbose "cert type $k"
|
||||
opts="-oHostKeyAlgorithms=$k -F $OBJ/ssh_proxy"
|
||||
SSH_CONNECTION=`${SSH} $opts host 'echo $SSH_CONNECTION'`
|
||||
diff --git a/sshconnect2.c b/sshconnect2.c
|
||||
index 14f7671a..ad3f560f 100644
|
||||
--- a/sshconnect2.c
|
||||
+++ b/sshconnect2.c
|
||||
@@ -221,7 +221,7 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port,
|
||||
const struct ssh_conn_info *cinfo)
|
||||
{
|
||||
char *myproposal[PROPOSAL_MAX];
|
||||
- char *all_key, *hkalgs = NULL;
|
||||
+ char *all_key, *hkalgs = NULL, *filtered_algs = NULL;
|
||||
int r, use_known_hosts_order = 0;
|
||||
|
||||
#if defined(GSSAPI) && defined(WITH_OPENSSL)
|
||||
@@ -257,10 +257,22 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port,
|
||||
if (use_known_hosts_order)
|
||||
hkalgs = order_hostkeyalgs(host, hostaddr, port, cinfo);
|
||||
|
||||
+ filtered_algs = hkalgs ? match_filter_allowlist(hkalgs, options.pubkey_accepted_algos)
|
||||
+ : match_filter_allowlist(options.hostkeyalgorithms,
|
||||
+ options.pubkey_accepted_algos);
|
||||
+ if (filtered_algs == NULL) {
|
||||
+ if (hkalgs)
|
||||
+ fatal_f("No match between algorithms for %s (host %s) and pubkey accepted algorithms %s",
|
||||
+ hkalgs, host, options.pubkey_accepted_algos);
|
||||
+ else
|
||||
+ fatal_f("No match between host key algorithms %s and pubkey accepted algorithms %s",
|
||||
+ options.hostkeyalgorithms, options.pubkey_accepted_algos);
|
||||
+ }
|
||||
+
|
||||
kex_proposal_populate_entries(ssh, myproposal,
|
||||
options.kex_algorithms, options.ciphers, options.macs,
|
||||
compression_alg_list(options.compression),
|
||||
- hkalgs ? hkalgs : options.hostkeyalgorithms);
|
||||
+ filtered_algs);
|
||||
|
||||
#if defined(GSSAPI) && defined(WITH_OPENSSL)
|
||||
if (options.gss_keyex) {
|
||||
@@ -304,6 +316,7 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port,
|
||||
#endif
|
||||
|
||||
free(hkalgs);
|
||||
+ free(filtered_algs);
|
||||
|
||||
/* start key exchange */
|
||||
if ((r = kex_setup(ssh, myproposal)) != 0)
|
||||
--
|
||||
2.49.0
|
||||
|
||||
616
0045-openssh-9.0p1-evp-fips-kex.patch
Normal file
616
0045-openssh-9.0p1-evp-fips-kex.patch
Normal file
|
|
@ -0,0 +1,616 @@
|
|||
From be23afbab800c9b5ffea56b3f410a04156c08df2 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:29 +0200
|
||||
Subject: [PATCH 45/50] openssh-9.0p1-evp-fips-kex
|
||||
|
||||
---
|
||||
dh.c | 98 +++++++++++++++++++++++++++++++++-----
|
||||
kex.c | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
kex.h | 6 +++
|
||||
kexdh.c | 52 ++++++++++++++++++--
|
||||
kexecdh.c | 129 ++++++++++++++++++++++++++++++++++++++++----------
|
||||
5 files changed, 382 insertions(+), 42 deletions(-)
|
||||
|
||||
diff --git a/dh.c b/dh.c
|
||||
index 8c9a29fa..ea0a0b09 100644
|
||||
--- a/dh.c
|
||||
+++ b/dh.c
|
||||
@@ -37,6 +37,9 @@
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/dh.h>
|
||||
#include <openssl/fips.h>
|
||||
+#include <openssl/evp.h>
|
||||
+#include <openssl/core_names.h>
|
||||
+#include <openssl/param_build.h>
|
||||
|
||||
#include "dh.h"
|
||||
#include "pathnames.h"
|
||||
@@ -290,10 +293,15 @@ dh_pub_is_valid(const DH *dh, const BIGNUM *dh_pub)
|
||||
int
|
||||
dh_gen_key(DH *dh, int need)
|
||||
{
|
||||
- int pbits;
|
||||
- const BIGNUM *dh_p, *pub_key;
|
||||
+ const BIGNUM *dh_p, *dh_g;
|
||||
+ BIGNUM *pub_key = NULL, *priv_key = NULL;
|
||||
+ EVP_PKEY *pkey = NULL;
|
||||
+ EVP_PKEY_CTX *ctx = NULL;
|
||||
+ OSSL_PARAM_BLD *param_bld = NULL;
|
||||
+ OSSL_PARAM *params = NULL;
|
||||
+ int pbits, r = 0;
|
||||
|
||||
- DH_get0_pqg(dh, &dh_p, NULL, NULL);
|
||||
+ DH_get0_pqg(dh, &dh_p, NULL, &dh_g);
|
||||
|
||||
if (need < 0 || dh_p == NULL ||
|
||||
(pbits = BN_num_bits(dh_p)) <= 0 ||
|
||||
@@ -301,19 +309,85 @@ dh_gen_key(DH *dh, int need)
|
||||
return SSH_ERR_INVALID_ARGUMENT;
|
||||
if (need < 256)
|
||||
need = 256;
|
||||
+
|
||||
+ if ((param_bld = OSSL_PARAM_BLD_new()) == NULL ||
|
||||
+ (ctx = EVP_PKEY_CTX_new_from_name(NULL, "DH", NULL)) == NULL) {
|
||||
+ OSSL_PARAM_BLD_free(param_bld);
|
||||
+ return SSH_ERR_ALLOC_FAIL;
|
||||
+ }
|
||||
+
|
||||
+ if (OSSL_PARAM_BLD_push_BN(param_bld,
|
||||
+ OSSL_PKEY_PARAM_FFC_P, dh_p) != 1 ||
|
||||
+ OSSL_PARAM_BLD_push_BN(param_bld,
|
||||
+ OSSL_PKEY_PARAM_FFC_G, dh_g) != 1) {
|
||||
+ error_f("Could not set p,q,g parameters");
|
||||
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto out;
|
||||
+ }
|
||||
/*
|
||||
* Pollard Rho, Big step/Little Step attacks are O(sqrt(n)),
|
||||
* so double requested need here.
|
||||
*/
|
||||
- if (!DH_set_length(dh, MINIMUM(need * 2, pbits - 1)))
|
||||
- return SSH_ERR_LIBCRYPTO_ERROR;
|
||||
-
|
||||
- if (DH_generate_key(dh) == 0)
|
||||
- return SSH_ERR_LIBCRYPTO_ERROR;
|
||||
- DH_get0_key(dh, &pub_key, NULL);
|
||||
- if (!dh_pub_is_valid(dh, pub_key))
|
||||
- return SSH_ERR_INVALID_FORMAT;
|
||||
- return 0;
|
||||
+ if (OSSL_PARAM_BLD_push_int(param_bld,
|
||||
+ OSSL_PKEY_PARAM_DH_PRIV_LEN,
|
||||
+ MINIMUM(need * 2, pbits - 1)) != 1 ||
|
||||
+ (params = OSSL_PARAM_BLD_to_param(param_bld)) == NULL) {
|
||||
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (EVP_PKEY_fromdata_init(ctx) != 1) {
|
||||
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (EVP_PKEY_fromdata(ctx, &pkey,
|
||||
+ EVP_PKEY_KEY_PARAMETERS, params) != 1) {
|
||||
+ error_f("Failed key generation");
|
||||
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ /* reuse context for key generation */
|
||||
+ EVP_PKEY_CTX_free(ctx);
|
||||
+ ctx = NULL;
|
||||
+
|
||||
+ if ((ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL)) == NULL ||
|
||||
+ EVP_PKEY_keygen_init(ctx) != 1) {
|
||||
+ error_f("Could not create or init context");
|
||||
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (EVP_PKEY_generate(ctx, &pkey) != 1) {
|
||||
+ error_f("Could not generate keys");
|
||||
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (EVP_PKEY_public_check(ctx) != 1) {
|
||||
+ error_f("The public key is incorrect");
|
||||
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PUB_KEY,
|
||||
+ &pub_key) != 1 ||
|
||||
+ EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY,
|
||||
+ &priv_key) != 1 ||
|
||||
+ DH_set0_key(dh, pub_key, priv_key) != 1) {
|
||||
+ error_f("Could not set pub/priv keys to DH struct");
|
||||
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ /* transferred */
|
||||
+ pub_key = NULL;
|
||||
+ priv_key = NULL;
|
||||
+out:
|
||||
+ OSSL_PARAM_free(params);
|
||||
+ OSSL_PARAM_BLD_free(param_bld);
|
||||
+ EVP_PKEY_CTX_free(ctx);
|
||||
+ EVP_PKEY_free(pkey);
|
||||
+ BN_clear_free(pub_key);
|
||||
+ BN_clear_free(priv_key);
|
||||
+ return r;
|
||||
}
|
||||
|
||||
DH *
|
||||
diff --git a/kex.c b/kex.c
|
||||
index 71fbe5cb..ce6a7b81 100644
|
||||
--- a/kex.c
|
||||
+++ b/kex.c
|
||||
@@ -1614,3 +1614,142 @@ kex_exchange_identification(struct ssh *ssh, int timeout_ms,
|
||||
return r;
|
||||
}
|
||||
|
||||
+#ifdef WITH_OPENSSL
|
||||
+/*
|
||||
+ * Creates an EVP_PKEY from the given parameters and keys.
|
||||
+ * The private key can be omitted.
|
||||
+ */
|
||||
+EVP_PKEY *
|
||||
+sshkey_create_evp(OSSL_PARAM_BLD *param_bld, EVP_PKEY_CTX *ctx)
|
||||
+{
|
||||
+ EVP_PKEY *ret = NULL;
|
||||
+ OSSL_PARAM *params = NULL;
|
||||
+ if (param_bld == NULL || ctx == NULL) {
|
||||
+ debug2_f("param_bld or ctx is NULL");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ if ((params = OSSL_PARAM_BLD_to_param(param_bld)) == NULL) {
|
||||
+ debug2_f("Could not build param list");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ if (EVP_PKEY_fromdata_init(ctx) != 1 ||
|
||||
+ EVP_PKEY_fromdata(ctx, &ret, EVP_PKEY_KEYPAIR, params) != 1) {
|
||||
+ debug2_f("EVP_PKEY_fromdata failed");
|
||||
+ OSSL_PARAM_free(params);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+kex_create_evp_ec(EC_KEY *k, int ecdsa_nid, EVP_PKEY **pkey)
|
||||
+{
|
||||
+ OSSL_PARAM_BLD *param_bld = NULL;
|
||||
+ EVP_PKEY_CTX *ctx = NULL;
|
||||
+ BN_CTX *bn_ctx = NULL;
|
||||
+ uint8_t *pub_ser = NULL;
|
||||
+ const char *group_name;
|
||||
+ const EC_POINT *pub = NULL;
|
||||
+ const BIGNUM *priv = NULL;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ if (k == NULL)
|
||||
+ return SSH_ERR_INVALID_ARGUMENT;
|
||||
+ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL ||
|
||||
+ (param_bld = OSSL_PARAM_BLD_new()) == NULL ||
|
||||
+ (bn_ctx = BN_CTX_new()) == NULL) {
|
||||
+ ret = SSH_ERR_ALLOC_FAIL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if ((group_name = OSSL_EC_curve_nid2name(ecdsa_nid)) == NULL ||
|
||||
+ OSSL_PARAM_BLD_push_utf8_string(param_bld,
|
||||
+ OSSL_PKEY_PARAM_GROUP_NAME,
|
||||
+ group_name,
|
||||
+ strlen(group_name)) != 1) {
|
||||
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if ((pub = EC_KEY_get0_public_key(k)) != NULL) {
|
||||
+ const EC_GROUP *group;
|
||||
+ size_t len;
|
||||
+
|
||||
+ group = EC_KEY_get0_group(k);
|
||||
+ len = EC_POINT_point2oct(group, pub,
|
||||
+ POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL);
|
||||
+ if ((pub_ser = malloc(len)) == NULL) {
|
||||
+ ret = SSH_ERR_ALLOC_FAIL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ EC_POINT_point2oct(group,
|
||||
+ pub,
|
||||
+ POINT_CONVERSION_UNCOMPRESSED,
|
||||
+ pub_ser,
|
||||
+ len,
|
||||
+ bn_ctx);
|
||||
+ if (OSSL_PARAM_BLD_push_octet_string(param_bld,
|
||||
+ OSSL_PKEY_PARAM_PUB_KEY,
|
||||
+ pub_ser,
|
||||
+ len) != 1) {
|
||||
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ }
|
||||
+ if ((priv = EC_KEY_get0_private_key(k)) != NULL &&
|
||||
+ OSSL_PARAM_BLD_push_BN(param_bld,
|
||||
+ OSSL_PKEY_PARAM_PRIV_KEY, priv) != 1) {
|
||||
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if ((*pkey = sshkey_create_evp(param_bld, ctx)) == NULL) {
|
||||
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+out:
|
||||
+ OSSL_PARAM_BLD_free(param_bld);
|
||||
+ EVP_PKEY_CTX_free(ctx);
|
||||
+ BN_CTX_free(bn_ctx);
|
||||
+ free(pub_ser);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+kex_create_evp_dh(EVP_PKEY **pkey, const BIGNUM *p, const BIGNUM *q,
|
||||
+ const BIGNUM *g, const BIGNUM *pub, const BIGNUM *priv)
|
||||
+{
|
||||
+ OSSL_PARAM_BLD *param_bld = NULL;
|
||||
+ EVP_PKEY_CTX *ctx = NULL;
|
||||
+ int r = 0;
|
||||
+
|
||||
+ /* create EVP_PKEY-DH key */
|
||||
+ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "DH", NULL)) == NULL ||
|
||||
+ (param_bld = OSSL_PARAM_BLD_new()) == NULL) {
|
||||
+ error_f("EVP_PKEY_CTX or PARAM_BLD init failed");
|
||||
+ r = SSH_ERR_ALLOC_FAIL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_P, p) != 1 ||
|
||||
+ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_Q, q) != 1 ||
|
||||
+ OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_G, g) != 1 ||
|
||||
+ OSSL_PARAM_BLD_push_BN(param_bld,
|
||||
+ OSSL_PKEY_PARAM_PUB_KEY, pub) != 1) {
|
||||
+ error_f("Failed pushing params to OSSL_PARAM_BLD");
|
||||
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (priv != NULL &&
|
||||
+ OSSL_PARAM_BLD_push_BN(param_bld,
|
||||
+ OSSL_PKEY_PARAM_PRIV_KEY, priv) != 1) {
|
||||
+ error_f("Failed pushing private key to OSSL_PARAM_BLD");
|
||||
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if ((*pkey = sshkey_create_evp(param_bld, ctx)) == NULL)
|
||||
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+out:
|
||||
+ OSSL_PARAM_BLD_free(param_bld);
|
||||
+ EVP_PKEY_CTX_free(ctx);
|
||||
+ return r;
|
||||
+}
|
||||
+#endif /* WITH_OPENSSL */
|
||||
diff --git a/kex.h b/kex.h
|
||||
index 6a55aadf..48f3bb87 100644
|
||||
--- a/kex.h
|
||||
+++ b/kex.h
|
||||
@@ -37,6 +37,9 @@
|
||||
# include <openssl/bn.h>
|
||||
# include <openssl/dh.h>
|
||||
# include <openssl/ecdsa.h>
|
||||
+# include <openssl/evp.h>
|
||||
+# include <openssl/core_names.h>
|
||||
+# include <openssl/param_build.h>
|
||||
# ifdef OPENSSL_HAS_ECC
|
||||
# include <openssl/ec.h>
|
||||
# else /* OPENSSL_HAS_ECC */
|
||||
@@ -311,6 +314,9 @@ int kexc25519_shared_key_ext(const u_char key[CURVE25519_SIZE],
|
||||
const u_char pub[CURVE25519_SIZE], struct sshbuf *out, int)
|
||||
__attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE)))
|
||||
__attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE)));
|
||||
+int kex_create_evp_dh(EVP_PKEY **, const BIGNUM *, const BIGNUM *,
|
||||
+ const BIGNUM *, const BIGNUM *, const BIGNUM *);
|
||||
+int kex_create_evp_ec(EC_KEY *k, int ecdsa_nid, EVP_PKEY **pkey);
|
||||
|
||||
#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)
|
||||
void dump_digest(const char *, const u_char *, int);
|
||||
diff --git a/kexdh.c b/kexdh.c
|
||||
index 0faab21b..32e1de51 100644
|
||||
--- a/kexdh.c
|
||||
+++ b/kexdh.c
|
||||
@@ -35,6 +35,10 @@
|
||||
|
||||
#include "openbsd-compat/openssl-compat.h"
|
||||
#include <openssl/dh.h>
|
||||
+#include <openssl/err.h>
|
||||
+#include <openssl/evp.h>
|
||||
+#include <openssl/core_names.h>
|
||||
+#include <openssl/param_build.h>
|
||||
|
||||
#include "sshkey.h"
|
||||
#include "kex.h"
|
||||
@@ -83,9 +87,12 @@ int
|
||||
kex_dh_compute_key(struct kex *kex, BIGNUM *dh_pub, struct sshbuf *out)
|
||||
{
|
||||
BIGNUM *shared_secret = NULL;
|
||||
+ const BIGNUM *pub, *priv, *p, *q, *g;
|
||||
+ EVP_PKEY *pkey = NULL, *dh_pkey = NULL;
|
||||
+ EVP_PKEY_CTX *ctx = NULL;
|
||||
u_char *kbuf = NULL;
|
||||
size_t klen = 0;
|
||||
- int kout, r;
|
||||
+ int r = 0;
|
||||
|
||||
#ifdef DEBUG_KEXDH
|
||||
fprintf(stderr, "dh_pub= ");
|
||||
@@ -100,24 +107,59 @@ kex_dh_compute_key(struct kex *kex, BIGNUM *dh_pub, struct sshbuf *out)
|
||||
r = SSH_ERR_MESSAGE_INCOMPLETE;
|
||||
goto out;
|
||||
}
|
||||
- klen = DH_size(kex->dh);
|
||||
+
|
||||
+ DH_get0_key(kex->dh, &pub, &priv);
|
||||
+ DH_get0_pqg(kex->dh, &p, &q, &g);
|
||||
+ /* import key */
|
||||
+ r = kex_create_evp_dh(&pkey, p, q, g, pub, priv);
|
||||
+ if (r != 0) {
|
||||
+ error_f("Could not create EVP_PKEY for dh");
|
||||
+ ERR_print_errors_fp(stderr);
|
||||
+ goto out;
|
||||
+ }
|
||||
+ /* import peer key
|
||||
+ * the parameters should be the same as with pkey
|
||||
+ */
|
||||
+ r = kex_create_evp_dh(&dh_pkey, p, q, g, dh_pub, NULL);
|
||||
+ if (r != 0) {
|
||||
+ error_f("Could not import peer key for dh");
|
||||
+ ERR_print_errors_fp(stderr);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if ((ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL)) == NULL) {
|
||||
+ error_f("Could not init EVP_PKEY_CTX for dh");
|
||||
+ r = SSH_ERR_ALLOC_FAIL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (EVP_PKEY_derive_init(ctx) != 1 ||
|
||||
+ EVP_PKEY_derive_set_peer(ctx, dh_pkey) != 1 ||
|
||||
+ EVP_PKEY_derive(ctx, NULL, &klen) != 1) {
|
||||
+ error_f("Could not get key size");
|
||||
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto out;
|
||||
+ }
|
||||
if ((kbuf = malloc(klen)) == NULL ||
|
||||
(shared_secret = BN_new()) == NULL) {
|
||||
r = SSH_ERR_ALLOC_FAIL;
|
||||
goto out;
|
||||
}
|
||||
- if ((kout = DH_compute_key(kbuf, dh_pub, kex->dh)) < 0 ||
|
||||
- BN_bin2bn(kbuf, kout, shared_secret) == NULL) {
|
||||
+ if (EVP_PKEY_derive(ctx, kbuf, &klen) != 1 ||
|
||||
+ BN_bin2bn(kbuf, klen, shared_secret) == NULL) {
|
||||
+ error_f("Could not derive key");
|
||||
r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
goto out;
|
||||
}
|
||||
#ifdef DEBUG_KEXDH
|
||||
- dump_digest("shared secret", kbuf, kout);
|
||||
+ dump_digest("shared secret", kbuf, klen);
|
||||
#endif
|
||||
r = sshbuf_put_bignum2(out, shared_secret);
|
||||
out:
|
||||
freezero(kbuf, klen);
|
||||
BN_clear_free(shared_secret);
|
||||
+ EVP_PKEY_free(pkey);
|
||||
+ EVP_PKEY_free(dh_pkey);
|
||||
+ EVP_PKEY_CTX_free(ctx);
|
||||
return r;
|
||||
}
|
||||
|
||||
diff --git a/kexecdh.c b/kexecdh.c
|
||||
index efb2e55a..d92ba54f 100644
|
||||
--- a/kexecdh.c
|
||||
+++ b/kexecdh.c
|
||||
@@ -35,17 +35,57 @@
|
||||
#include <signal.h>
|
||||
|
||||
#include <openssl/ecdh.h>
|
||||
+#include <openssl/evp.h>
|
||||
+#include <openssl/core_names.h>
|
||||
+#include <openssl/param_build.h>
|
||||
+#include <openssl/err.h>
|
||||
|
||||
#include "sshkey.h"
|
||||
#include "kex.h"
|
||||
#include "sshbuf.h"
|
||||
#include "digest.h"
|
||||
#include "ssherr.h"
|
||||
+#include "log.h"
|
||||
|
||||
static int
|
||||
kex_ecdh_dec_key_group(struct kex *, const struct sshbuf *, EC_KEY *key,
|
||||
const EC_GROUP *, struct sshbuf **);
|
||||
|
||||
+static EC_KEY *
|
||||
+generate_ec_keys(int ec_nid)
|
||||
+{
|
||||
+ EC_KEY *client_key = NULL;
|
||||
+ EVP_PKEY *pkey = NULL;
|
||||
+ EVP_PKEY_CTX *ctx = NULL;
|
||||
+ OSSL_PARAM_BLD *param_bld = NULL;
|
||||
+ OSSL_PARAM *params = NULL;
|
||||
+ const char *group_name;
|
||||
+
|
||||
+ if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL ||
|
||||
+ (param_bld = OSSL_PARAM_BLD_new()) == NULL)
|
||||
+ goto out;
|
||||
+ if ((group_name = OSSL_EC_curve_nid2name(ec_nid)) == NULL ||
|
||||
+ OSSL_PARAM_BLD_push_utf8_string(param_bld,
|
||||
+ OSSL_PKEY_PARAM_GROUP_NAME, group_name, 0) != 1 ||
|
||||
+ (params = OSSL_PARAM_BLD_to_param(param_bld)) == NULL) {
|
||||
+ error_f("Could not create OSSL_PARAM");
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (EVP_PKEY_keygen_init(ctx) != 1 ||
|
||||
+ EVP_PKEY_CTX_set_params(ctx, params) != 1 ||
|
||||
+ EVP_PKEY_generate(ctx, &pkey) != 1 ||
|
||||
+ (client_key = EVP_PKEY_get1_EC_KEY(pkey)) == NULL) {
|
||||
+ error_f("Could not generate ec keys");
|
||||
+ goto out;
|
||||
+ }
|
||||
+out:
|
||||
+ EVP_PKEY_free(pkey);
|
||||
+ EVP_PKEY_CTX_free(ctx);
|
||||
+ OSSL_PARAM_BLD_free(param_bld);
|
||||
+ OSSL_PARAM_free(params);
|
||||
+ return client_key;
|
||||
+}
|
||||
+
|
||||
int
|
||||
kex_ecdh_keypair(struct kex *kex)
|
||||
{
|
||||
@@ -55,11 +95,7 @@ kex_ecdh_keypair(struct kex *kex)
|
||||
struct sshbuf *buf = NULL;
|
||||
int r;
|
||||
|
||||
- if ((client_key = EC_KEY_new_by_curve_name(kex->ec_nid)) == NULL) {
|
||||
- r = SSH_ERR_ALLOC_FAIL;
|
||||
- goto out;
|
||||
- }
|
||||
- if (EC_KEY_generate_key(client_key) != 1) {
|
||||
+ if ((client_key = generate_ec_keys(kex->ec_nid)) == NULL) {
|
||||
r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
goto out;
|
||||
}
|
||||
@@ -101,11 +137,7 @@ kex_ecdh_enc(struct kex *kex, const struct sshbuf *client_blob,
|
||||
*server_blobp = NULL;
|
||||
*shared_secretp = NULL;
|
||||
|
||||
- if ((server_key = EC_KEY_new_by_curve_name(kex->ec_nid)) == NULL) {
|
||||
- r = SSH_ERR_ALLOC_FAIL;
|
||||
- goto out;
|
||||
- }
|
||||
- if (EC_KEY_generate_key(server_key) != 1) {
|
||||
+ if ((server_key = generate_ec_keys(kex->ec_nid)) == NULL) {
|
||||
r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
goto out;
|
||||
}
|
||||
@@ -140,11 +172,21 @@ kex_ecdh_dec_key_group(struct kex *kex, const struct sshbuf *ec_blob,
|
||||
{
|
||||
struct sshbuf *buf = NULL;
|
||||
BIGNUM *shared_secret = NULL;
|
||||
- EC_POINT *dh_pub = NULL;
|
||||
- u_char *kbuf = NULL;
|
||||
- size_t klen = 0;
|
||||
+ EVP_PKEY_CTX *ctx = NULL;
|
||||
+ EVP_PKEY *pkey = NULL, *dh_pkey = NULL;
|
||||
+ OSSL_PARAM_BLD *param_bld = NULL;
|
||||
+ OSSL_PARAM *params = NULL;
|
||||
+ u_char *kbuf = NULL, *pub = NULL;
|
||||
+ size_t klen = 0, publen;
|
||||
+ const char *group_name;
|
||||
int r;
|
||||
|
||||
+ /* import EC_KEY to EVP_PKEY */
|
||||
+ if ((r = kex_create_evp_ec(key, kex->ec_nid, &pkey)) != 0) {
|
||||
+ error_f("Could not create EVP_PKEY");
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
*shared_secretp = NULL;
|
||||
|
||||
if ((buf = sshbuf_new()) == NULL) {
|
||||
@@ -153,45 +195,82 @@ kex_ecdh_dec_key_group(struct kex *kex, const struct sshbuf *ec_blob,
|
||||
}
|
||||
if ((r = sshbuf_put_stringb(buf, ec_blob)) != 0)
|
||||
goto out;
|
||||
- if ((dh_pub = EC_POINT_new(group)) == NULL) {
|
||||
+
|
||||
+ /* the public key is in the buffer in octet string UNCOMPRESSED
|
||||
+ * format. See sshbuf_put_ec */
|
||||
+ if ((r = sshbuf_get_string(buf, &pub, &publen)) != 0)
|
||||
+ goto out;
|
||||
+ sshbuf_reset(buf);
|
||||
+ if ((ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL)) == NULL ||
|
||||
+ (param_bld = OSSL_PARAM_BLD_new()) == NULL) {
|
||||
r = SSH_ERR_ALLOC_FAIL;
|
||||
goto out;
|
||||
}
|
||||
- if ((r = sshbuf_get_ec(buf, dh_pub, group)) != 0) {
|
||||
+ if ((group_name = OSSL_EC_curve_nid2name(kex->ec_nid)) == NULL) {
|
||||
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (OSSL_PARAM_BLD_push_octet_string(param_bld,
|
||||
+ OSSL_PKEY_PARAM_PUB_KEY, pub, publen) != 1 ||
|
||||
+ OSSL_PARAM_BLD_push_utf8_string(param_bld,
|
||||
+ OSSL_PKEY_PARAM_GROUP_NAME, group_name, 0) != 1 ||
|
||||
+ (params = OSSL_PARAM_BLD_to_param(param_bld)) == NULL) {
|
||||
+ error_f("Failed to set params for dh_pkey");
|
||||
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (EVP_PKEY_fromdata_init(ctx) != 1 ||
|
||||
+ EVP_PKEY_fromdata(ctx, &dh_pkey,
|
||||
+ EVP_PKEY_PUBLIC_KEY, params) != 1 ||
|
||||
+ EVP_PKEY_public_check(ctx) != 1) {
|
||||
+ error_f("Peer public key import failed");
|
||||
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
goto out;
|
||||
}
|
||||
- sshbuf_reset(buf);
|
||||
|
||||
#ifdef DEBUG_KEXECDH
|
||||
fputs("public key:\n", stderr);
|
||||
- sshkey_dump_ec_point(group, dh_pub);
|
||||
+ EVP_PKEY_print_public_fp(stderr, dh_pkey, 0, NULL);
|
||||
#endif
|
||||
- if (sshkey_ec_validate_public(group, dh_pub) != 0) {
|
||||
- r = SSH_ERR_MESSAGE_INCOMPLETE;
|
||||
+ EVP_PKEY_CTX_free(ctx);
|
||||
+ ctx = NULL;
|
||||
+ if ((ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL)) == NULL ||
|
||||
+ EVP_PKEY_derive_init(ctx) != 1 ||
|
||||
+ EVP_PKEY_derive_set_peer(ctx, dh_pkey) != 1 ||
|
||||
+ EVP_PKEY_derive(ctx, NULL, &klen) != 1) {
|
||||
+ error_f("Failed to get derive information");
|
||||
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
goto out;
|
||||
}
|
||||
- klen = (EC_GROUP_get_degree(group) + 7) / 8;
|
||||
- if ((kbuf = malloc(klen)) == NULL ||
|
||||
- (shared_secret = BN_new()) == NULL) {
|
||||
+ if ((kbuf = malloc(klen)) == NULL) {
|
||||
r = SSH_ERR_ALLOC_FAIL;
|
||||
goto out;
|
||||
}
|
||||
- if (ECDH_compute_key(kbuf, klen, dh_pub, key, NULL) != (int)klen ||
|
||||
- BN_bin2bn(kbuf, klen, shared_secret) == NULL) {
|
||||
+ if (EVP_PKEY_derive(ctx, kbuf, &klen) != 1) {
|
||||
r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
goto out;
|
||||
}
|
||||
#ifdef DEBUG_KEXECDH
|
||||
dump_digest("shared secret", kbuf, klen);
|
||||
#endif
|
||||
+ if ((shared_secret = BN_new()) == NULL ||
|
||||
+ (BN_bin2bn(kbuf, klen, shared_secret) == NULL)) {
|
||||
+ r = SSH_ERR_ALLOC_FAIL;
|
||||
+ goto out;
|
||||
+ }
|
||||
if ((r = sshbuf_put_bignum2(buf, shared_secret)) != 0)
|
||||
goto out;
|
||||
*shared_secretp = buf;
|
||||
buf = NULL;
|
||||
out:
|
||||
- EC_POINT_clear_free(dh_pub);
|
||||
+ EVP_PKEY_CTX_free(ctx);
|
||||
+ EVP_PKEY_free(pkey);
|
||||
+ EVP_PKEY_free(dh_pkey);
|
||||
+ OSSL_PARAM_BLD_free(param_bld);
|
||||
+ OSSL_PARAM_free(params);
|
||||
BN_clear_free(shared_secret);
|
||||
freezero(kbuf, klen);
|
||||
+ freezero(pub, publen);
|
||||
sshbuf_free(buf);
|
||||
return r;
|
||||
}
|
||||
--
|
||||
2.49.0
|
||||
|
||||
334
0046-openssh-8.7p1-nohostsha1proof.patch
Normal file
334
0046-openssh-8.7p1-nohostsha1proof.patch
Normal file
|
|
@ -0,0 +1,334 @@
|
|||
From e4ca3b9dba1cc832a9974493c91207d42e218a68 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:29 +0200
|
||||
Subject: [PATCH 46/50] openssh-8.7p1-nohostsha1proof
|
||||
|
||||
---
|
||||
compat.c | 6 +++++
|
||||
compat.h | 2 +-
|
||||
monitor.c | 27 ++++++++++++++++------
|
||||
regress/unittests/kex/test_kex.c | 3 ++-
|
||||
regress/unittests/sshkey/test_file.c | 3 ++-
|
||||
regress/unittests/sshkey/test_fuzz.c | 3 ++-
|
||||
regress/unittests/sshkey/test_sshkey.c | 32 +++++++++++++++++---------
|
||||
serverloop.c | 6 ++++-
|
||||
ssh-rsa.c | 3 ++-
|
||||
sshconnect2.c | 8 +++++++
|
||||
sshd-session.c | 21 +++++++++++++++++
|
||||
11 files changed, 90 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/compat.c b/compat.c
|
||||
index b59f0bfc..4e611dc3 100644
|
||||
--- a/compat.c
|
||||
+++ b/compat.c
|
||||
@@ -42,6 +42,7 @@ void
|
||||
compat_banner(struct ssh *ssh, const char *version)
|
||||
{
|
||||
int i;
|
||||
+ int forbid_ssh_rsa = 0;
|
||||
static struct {
|
||||
char *pat;
|
||||
int bugs;
|
||||
@@ -125,16 +126,21 @@ compat_banner(struct ssh *ssh, const char *version)
|
||||
};
|
||||
|
||||
/* process table, return first match */
|
||||
+ forbid_ssh_rsa = (ssh->compat & SSH_RH_RSASIGSHA);
|
||||
ssh->compat = 0;
|
||||
for (i = 0; check[i].pat; i++) {
|
||||
if (match_pattern_list(version, check[i].pat, 0) == 1) {
|
||||
debug_f("match: %s pat %s compat 0x%08x",
|
||||
version, check[i].pat, check[i].bugs);
|
||||
ssh->compat = check[i].bugs;
|
||||
+ if (forbid_ssh_rsa)
|
||||
+ ssh->compat |= SSH_RH_RSASIGSHA;
|
||||
return;
|
||||
}
|
||||
}
|
||||
debug_f("no match: %s", version);
|
||||
+ if (forbid_ssh_rsa)
|
||||
+ ssh->compat |= SSH_RH_RSASIGSHA;
|
||||
}
|
||||
|
||||
/* Always returns pointer to allocated memory, caller must free. */
|
||||
diff --git a/compat.h b/compat.h
|
||||
index 1a19060f..2e6db5bf 100644
|
||||
--- a/compat.h
|
||||
+++ b/compat.h
|
||||
@@ -30,7 +30,7 @@
|
||||
#define SSH_BUG_UTF8TTYMODE 0x00000001
|
||||
#define SSH_BUG_SIGTYPE 0x00000002
|
||||
#define SSH_BUG_SIGTYPE74 0x00000004
|
||||
-/* #define unused 0x00000008 */
|
||||
+#define SSH_RH_RSASIGSHA 0x00000008
|
||||
#define SSH_OLD_SESSIONID 0x00000010
|
||||
/* #define unused 0x00000020 */
|
||||
#define SSH_BUG_DEBUG 0x00000040
|
||||
diff --git a/monitor.c b/monitor.c
|
||||
index fbc35782..19cb058e 100644
|
||||
--- a/monitor.c
|
||||
+++ b/monitor.c
|
||||
@@ -747,11 +747,12 @@ mm_answer_sign(struct ssh *ssh, int sock, struct sshbuf *m)
|
||||
struct sshkey *pubkey, *key;
|
||||
struct sshbuf *sigbuf = NULL;
|
||||
u_char *p = NULL, *signature = NULL;
|
||||
- char *alg = NULL;
|
||||
- size_t datlen, siglen;
|
||||
- int r, is_proof = 0, keyid;
|
||||
- u_int compat;
|
||||
+ char *alg = NULL, *effective_alg;
|
||||
+ size_t datlen, siglen, alglen;
|
||||
+ int r, is_proof = 0;
|
||||
+ u_int keyid, compat;
|
||||
const char proof_req[] = "hostkeys-prove-00@openssh.com";
|
||||
+ const char safe_rsa[] = "rsa-sha2-256";
|
||||
|
||||
debug3_f("entering");
|
||||
|
||||
@@ -809,18 +810,30 @@ mm_answer_sign(struct ssh *ssh, int sock, struct sshbuf *m)
|
||||
}
|
||||
|
||||
if ((key = get_hostkey_by_index(keyid)) != NULL) {
|
||||
- if ((r = sshkey_sign(key, &signature, &siglen, p, datlen, alg,
|
||||
+ if (ssh->compat & SSH_RH_RSASIGSHA && strcmp(alg, "ssh-rsa") == 0
|
||||
+ && (sshkey_type_plain(key->type) == KEY_RSA)) {
|
||||
+ effective_alg = safe_rsa;
|
||||
+ } else {
|
||||
+ effective_alg = alg;
|
||||
+ }
|
||||
+ if ((r = sshkey_sign(key, &signature, &siglen, p, datlen, effective_alg,
|
||||
options.sk_provider, NULL, compat)) != 0)
|
||||
fatal_fr(r, "sign");
|
||||
} else if ((key = get_hostkey_public_by_index(keyid, ssh)) != NULL &&
|
||||
auth_sock > 0) {
|
||||
+ if (ssh->compat & SSH_RH_RSASIGSHA && strcmp(alg, "ssh-rsa") == 0
|
||||
+ && (sshkey_type_plain(key->type) == KEY_RSA)) {
|
||||
+ effective_alg = safe_rsa;
|
||||
+ } else {
|
||||
+ effective_alg = alg;
|
||||
+ }
|
||||
if ((r = ssh_agent_sign(auth_sock, key, &signature, &siglen,
|
||||
- p, datlen, alg, compat)) != 0)
|
||||
+ p, datlen, effective_alg, compat)) != 0)
|
||||
fatal_fr(r, "agent sign");
|
||||
} else
|
||||
fatal_f("no hostkey from index %d", keyid);
|
||||
|
||||
- debug3_f("%s %s signature len=%zu", alg,
|
||||
+ debug3_f("%s (effective: %s) %s signature len=%zu", alg, effective_alg,
|
||||
is_proof ? "hostkey proof" : "KEX", siglen);
|
||||
|
||||
sshbuf_reset(m);
|
||||
diff --git a/regress/unittests/kex/test_kex.c b/regress/unittests/kex/test_kex.c
|
||||
index caf8f57f..09016aea 100644
|
||||
--- a/regress/unittests/kex/test_kex.c
|
||||
+++ b/regress/unittests/kex/test_kex.c
|
||||
@@ -97,7 +97,8 @@ do_kex_with_key(char *kex, int keytype, int bits)
|
||||
memcpy(kex_params.proposal, myproposal, sizeof(myproposal));
|
||||
if (kex != NULL)
|
||||
kex_params.proposal[PROPOSAL_KEX_ALGS] = kex;
|
||||
- keyname = strdup(sshkey_ssh_name(private));
|
||||
+ keyname = (strcmp(sshkey_ssh_name(private), "ssh-rsa")) ?
|
||||
+ strdup(sshkey_ssh_name(private)) : strdup("rsa-sha2-256");
|
||||
ASSERT_PTR_NE(keyname, NULL);
|
||||
kex_params.proposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = keyname;
|
||||
ASSERT_INT_EQ(ssh_init(&client, 0, &kex_params), 0);
|
||||
diff --git a/regress/unittests/sshkey/test_file.c b/regress/unittests/sshkey/test_file.c
|
||||
index 3babe604..cc80fe97 100644
|
||||
--- a/regress/unittests/sshkey/test_file.c
|
||||
+++ b/regress/unittests/sshkey/test_file.c
|
||||
@@ -109,6 +109,7 @@ sshkey_file_tests(void)
|
||||
sshkey_free(k2);
|
||||
TEST_DONE();
|
||||
|
||||
+ /* Skip this test, SHA1 signatures are not supported
|
||||
TEST_START("load RSA cert with SHA1 signature");
|
||||
ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1_sha1"), &k2), 0);
|
||||
ASSERT_PTR_NE(k2, NULL);
|
||||
@@ -116,7 +117,7 @@ sshkey_file_tests(void)
|
||||
ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1);
|
||||
ASSERT_STRING_EQ(k2->cert->signature_type, "ssh-rsa");
|
||||
sshkey_free(k2);
|
||||
- TEST_DONE();
|
||||
+ TEST_DONE(); */
|
||||
|
||||
TEST_START("load RSA cert with SHA512 signature");
|
||||
ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1_sha512"), &k2), 0);
|
||||
diff --git a/regress/unittests/sshkey/test_fuzz.c b/regress/unittests/sshkey/test_fuzz.c
|
||||
index 0aff7c9b..951122e1 100644
|
||||
--- a/regress/unittests/sshkey/test_fuzz.c
|
||||
+++ b/regress/unittests/sshkey/test_fuzz.c
|
||||
@@ -338,13 +338,14 @@ sshkey_fuzz_tests(void)
|
||||
TEST_DONE();
|
||||
|
||||
#ifdef WITH_OPENSSL
|
||||
+ /* Skip this test, SHA1 signatures are not supported
|
||||
TEST_START("fuzz RSA sig");
|
||||
buf = load_file("rsa_1");
|
||||
ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
|
||||
sshbuf_free(buf);
|
||||
sig_fuzz(k1, "ssh-rsa");
|
||||
sshkey_free(k1);
|
||||
- TEST_DONE();
|
||||
+ TEST_DONE();*/
|
||||
|
||||
TEST_START("fuzz RSA SHA256 sig");
|
||||
buf = load_file("rsa_1");
|
||||
diff --git a/regress/unittests/sshkey/test_sshkey.c b/regress/unittests/sshkey/test_sshkey.c
|
||||
index 5bf4b65c..6d0a35bb 100644
|
||||
--- a/regress/unittests/sshkey/test_sshkey.c
|
||||
+++ b/regress/unittests/sshkey/test_sshkey.c
|
||||
@@ -61,6 +61,9 @@ build_cert(struct sshbuf *b, struct sshkey *k, const char *type,
|
||||
u_char *sigblob;
|
||||
size_t siglen;
|
||||
|
||||
+ /* ssh-rsa implies SHA1, forbidden in DEFAULT cp */
|
||||
+ int expected = (sig_alg == NULL || strcmp(sig_alg, "ssh-rsa") == 0) ? SSH_ERR_LIBCRYPTO_ERROR : 0;
|
||||
+
|
||||
ca_buf = sshbuf_new();
|
||||
ASSERT_PTR_NE(ca_buf, NULL);
|
||||
ASSERT_INT_EQ(sshkey_putb(ca_key, ca_buf), 0);
|
||||
@@ -102,8 +105,9 @@ build_cert(struct sshbuf *b, struct sshkey *k, const char *type,
|
||||
ASSERT_INT_EQ(sshbuf_put_string(b, NULL, 0), 0); /* reserved */
|
||||
ASSERT_INT_EQ(sshbuf_put_stringb(b, ca_buf), 0); /* signature key */
|
||||
ASSERT_INT_EQ(sshkey_sign(sign_key, &sigblob, &siglen,
|
||||
- sshbuf_ptr(b), sshbuf_len(b), sig_alg, NULL, NULL, 0), 0);
|
||||
- ASSERT_INT_EQ(sshbuf_put_string(b, sigblob, siglen), 0); /* signature */
|
||||
+ sshbuf_ptr(b), sshbuf_len(b), sig_alg, NULL, NULL, 0), expected);
|
||||
+ if (expected == 0)
|
||||
+ ASSERT_INT_EQ(sshbuf_put_string(b, sigblob, siglen), 0); /* signature */
|
||||
|
||||
free(sigblob);
|
||||
sshbuf_free(ca_buf);
|
||||
@@ -120,16 +124,22 @@ signature_test(struct sshkey *k, struct sshkey *bad, const char *sig_alg,
|
||||
{
|
||||
size_t len;
|
||||
u_char *sig;
|
||||
+ /* ssh-rsa implies SHA1, forbidden in DEFAULT cp in RHEL, permitted in Fedora */
|
||||
+ int expected = (sig_alg && strcmp(sig_alg, "ssh-rsa") == 0) ? sshkey_sign(k, &sig, &len, d, l, sig_alg, NULL, NULL, 0) : 0;
|
||||
+ if (k && (sshkey_type_plain(k->type) == KEY_DSA || sshkey_type_plain(k->type) == KEY_DSA_CERT))
|
||||
+ expected = sshkey_sign(k, &sig, &len, d, l, sig_alg, NULL, NULL, 0);
|
||||
|
||||
ASSERT_INT_EQ(sshkey_sign(k, &sig, &len, d, l, sig_alg,
|
||||
- NULL, NULL, 0), 0);
|
||||
- ASSERT_SIZE_T_GT(len, 8);
|
||||
- ASSERT_PTR_NE(sig, NULL);
|
||||
- ASSERT_INT_EQ(sshkey_verify(k, sig, len, d, l, NULL, 0, NULL), 0);
|
||||
- ASSERT_INT_NE(sshkey_verify(bad, sig, len, d, l, NULL, 0, NULL), 0);
|
||||
- /* Fuzz test is more comprehensive, this is just a smoke test */
|
||||
- sig[len - 5] ^= 0x10;
|
||||
- ASSERT_INT_NE(sshkey_verify(k, sig, len, d, l, NULL, 0, NULL), 0);
|
||||
+ NULL, NULL, 0), expected);
|
||||
+ if (expected == 0) {
|
||||
+ ASSERT_SIZE_T_GT(len, 8);
|
||||
+ ASSERT_PTR_NE(sig, NULL);
|
||||
+ ASSERT_INT_EQ(sshkey_verify(k, sig, len, d, l, NULL, 0, NULL), 0);
|
||||
+ ASSERT_INT_NE(sshkey_verify(bad, sig, len, d, l, NULL, 0, NULL), 0);
|
||||
+ /* Fuzz test is more comprehensive, this is just a smoke test */
|
||||
+ sig[len - 5] ^= 0x10;
|
||||
+ ASSERT_INT_NE(sshkey_verify(k, sig, len, d, l, NULL, 0, NULL), 0);
|
||||
+ }
|
||||
free(sig);
|
||||
}
|
||||
|
||||
@@ -526,7 +536,7 @@ sshkey_tests(void)
|
||||
ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2,
|
||||
NULL), 0);
|
||||
k3 = get_private("rsa_1");
|
||||
- build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1, NULL);
|
||||
+ build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1, "rsa-sha2-256");
|
||||
ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k4),
|
||||
SSH_ERR_KEY_CERT_INVALID_SIGN_KEY);
|
||||
ASSERT_PTR_EQ(k4, NULL);
|
||||
diff --git a/serverloop.c b/serverloop.c
|
||||
index 40ddfb04..9c5b1567 100644
|
||||
--- a/serverloop.c
|
||||
+++ b/serverloop.c
|
||||
@@ -80,6 +80,7 @@
|
||||
#include "auth-options.h"
|
||||
#include "serverloop.h"
|
||||
#include "ssherr.h"
|
||||
+#include "compat.h"
|
||||
|
||||
extern ServerOptions options;
|
||||
|
||||
@@ -699,7 +700,10 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp)
|
||||
else if (ssh->kex->flags & KEX_RSA_SHA2_256_SUPPORTED)
|
||||
sigalg = "rsa-sha2-256";
|
||||
}
|
||||
-
|
||||
+ if (ssh->compat & SSH_RH_RSASIGSHA && sigalg == NULL) {
|
||||
+ sigalg = "rsa-sha2-512";
|
||||
+ debug3_f("SHA1 signature is not supported, falling back to %s", sigalg);
|
||||
+ }
|
||||
debug3_f("sign %s key (index %d) using sigalg %s",
|
||||
sshkey_type(key), ndx, sigalg == NULL ? "default" : sigalg);
|
||||
if ((r = sshbuf_put_cstring(sigbuf,
|
||||
diff --git a/ssh-rsa.c b/ssh-rsa.c
|
||||
index 6c2f771a..8dd4ab01 100644
|
||||
--- a/ssh-rsa.c
|
||||
+++ b/ssh-rsa.c
|
||||
@@ -509,7 +509,8 @@ ssh_rsa_verify(const struct sshkey *key,
|
||||
ret = SSH_ERR_INVALID_ARGUMENT;
|
||||
goto out;
|
||||
}
|
||||
- if (hash_alg != want_alg) {
|
||||
+ if (hash_alg != want_alg && want_alg != SSH_DIGEST_SHA1) {
|
||||
+ debug_f("Unexpected digest algorithm: got %d, wanted %d", hash_alg, want_alg);
|
||||
ret = SSH_ERR_SIGNATURE_INVALID;
|
||||
goto out;
|
||||
}
|
||||
diff --git a/sshconnect2.c b/sshconnect2.c
|
||||
index ad3f560f..3941e089 100644
|
||||
--- a/sshconnect2.c
|
||||
+++ b/sshconnect2.c
|
||||
@@ -1434,6 +1434,14 @@ identity_sign(struct identity *id, u_char **sigp, size_t *lenp,
|
||||
retried = 1;
|
||||
goto retry_pin;
|
||||
}
|
||||
+ if ((r == SSH_ERR_LIBCRYPTO_ERROR) && strcmp("ssh-rsa", alg)) {
|
||||
+ char rsa_safe_alg[] = "rsa-sha2-512";
|
||||
+ debug3_f("trying to fallback to algorithm %s", rsa_safe_alg);
|
||||
+
|
||||
+ if ((r = sshkey_sign(sign_key, sigp, lenp, data, datalen,
|
||||
+ rsa_safe_alg, options.sk_provider, pin, compat)) != 0)
|
||||
+ debug_fr(r, "sshkey_sign - RSA fallback");
|
||||
+ }
|
||||
goto out;
|
||||
}
|
||||
|
||||
diff --git a/sshd-session.c b/sshd-session.c
|
||||
index a808ac9a..c3349a8a 100644
|
||||
--- a/sshd-session.c
|
||||
+++ b/sshd-session.c
|
||||
@@ -1316,6 +1316,27 @@ main(int ac, char **av)
|
||||
|
||||
check_ip_options(ssh);
|
||||
|
||||
+ {
|
||||
+ struct sshkey *rsakey = NULL;
|
||||
+ rsakey = get_hostkey_private_by_type(KEY_RSA, 0, ssh);
|
||||
+ if (rsakey == NULL)
|
||||
+ rsakey = get_hostkey_private_by_type(KEY_RSA_CERT, 0, ssh);
|
||||
+
|
||||
+ if (rsakey != NULL) {
|
||||
+ size_t sign_size = 0;
|
||||
+ u_char *tmp = NULL;
|
||||
+ u_char data[] = "Test SHA1 vector";
|
||||
+ int res;
|
||||
+
|
||||
+ res = sshkey_sign(rsakey, &tmp, &sign_size, data, sizeof(data), NULL, NULL, NULL, 0);
|
||||
+ free(tmp);
|
||||
+ if (res == SSH_ERR_LIBCRYPTO_ERROR) {
|
||||
+ verbose_f("SHA1 in signatures is disabled for RSA keys");
|
||||
+ ssh->compat |= SSH_RH_RSASIGSHA;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/* Prepare the channels layer */
|
||||
channel_init_channels(ssh);
|
||||
channel_set_af(ssh, options.address_family);
|
||||
--
|
||||
2.49.0
|
||||
|
||||
25
0047-openssh-9.6p1-pam-rhost.patch
Normal file
25
0047-openssh-9.6p1-pam-rhost.patch
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
From 497de886faaddec60b7ad1013396c7d4f3145968 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:29 +0200
|
||||
Subject: [PATCH 47/50] openssh-9.6p1-pam-rhost
|
||||
|
||||
---
|
||||
auth-pam.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/auth-pam.c b/auth-pam.c
|
||||
index a042c3c8..a321e0d3 100644
|
||||
--- a/auth-pam.c
|
||||
+++ b/auth-pam.c
|
||||
@@ -741,7 +741,7 @@ sshpam_init(struct ssh *ssh, Authctxt *authctxt)
|
||||
sshpam_laddr = get_local_ipaddr(
|
||||
ssh_packet_get_connection_in(ssh));
|
||||
}
|
||||
- if (sshpam_rhost != NULL) {
|
||||
+ if (sshpam_rhost != NULL && strcmp(sshpam_rhost, "UNKNOWN") != 0) {
|
||||
debug("PAM: setting PAM_RHOST to \"%s\"", sshpam_rhost);
|
||||
sshpam_err = pam_set_item(sshpam_handle, PAM_RHOST,
|
||||
sshpam_rhost);
|
||||
--
|
||||
2.49.0
|
||||
|
||||
25
0048-openssh-9.9p1-separate-keysign.patch
Normal file
25
0048-openssh-9.9p1-separate-keysign.patch
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
From b97b1040bc0918fe9be89cdb482d046270e92d9c Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:29 +0200
|
||||
Subject: [PATCH 48/50] openssh-9.9p1-separate-keysign
|
||||
|
||||
---
|
||||
ssh_config.5 | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ssh_config.5 b/ssh_config.5
|
||||
index a43b2a27..9d5da2a6 100644
|
||||
--- a/ssh_config.5
|
||||
+++ b/ssh_config.5
|
||||
@@ -797,7 +797,7 @@ or
|
||||
This option should be placed in the non-hostspecific section.
|
||||
See
|
||||
.Xr ssh-keysign 8
|
||||
-for more information.
|
||||
+for more information. ssh-keysign should be installed explicitly.
|
||||
.It Cm EscapeChar
|
||||
Sets the escape character (default:
|
||||
.Ql ~ ) .
|
||||
--
|
||||
2.49.0
|
||||
|
||||
398
0049-openssh-9.9p1-openssl-mlkem.patch
Normal file
398
0049-openssh-9.9p1-openssl-mlkem.patch
Normal file
|
|
@ -0,0 +1,398 @@
|
|||
From 0a621a2ccb8444e4c6da906b0e112e0522658122 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:29 +0200
|
||||
Subject: [PATCH 49/50] openssh-9.9p1-openssl-mlkem
|
||||
|
||||
---
|
||||
kex-names.c | 20 +++
|
||||
kexmlkem768x25519.c | 291 ++++++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 311 insertions(+)
|
||||
|
||||
diff --git a/kex-names.c b/kex-names.c
|
||||
index cd3902ad..36a953ab 100644
|
||||
--- a/kex-names.c
|
||||
+++ b/kex-names.c
|
||||
@@ -108,6 +108,19 @@ static const struct kexalg gss_kexalgs[] = {
|
||||
{ NULL, 0, -1, -1},
|
||||
};
|
||||
|
||||
+static int is_mlkem768_available()
|
||||
+{
|
||||
+ static int is_fetched = -1;
|
||||
+
|
||||
+ if (is_fetched == -1) {
|
||||
+ EVP_KEM *mlkem768 = EVP_KEM_fetch(NULL, "mlkem768", NULL);
|
||||
+ is_fetched = mlkem768 != NULL ? 1 : 0;
|
||||
+ EVP_KEM_free(mlkem768);
|
||||
+ }
|
||||
+
|
||||
+ return is_fetched;
|
||||
+}
|
||||
+
|
||||
static char *
|
||||
kex_alg_list_internal(char sep, const struct kexalg *algs)
|
||||
{
|
||||
@@ -116,6 +129,9 @@ kex_alg_list_internal(char sep, const struct kexalg *algs)
|
||||
const struct kexalg *k;
|
||||
|
||||
for (k = algs; k->name != NULL; k++) {
|
||||
+ if (strcmp(k->name, KEX_MLKEM768X25519_SHA256) == 0
|
||||
+ && !is_mlkem768_available())
|
||||
+ continue;
|
||||
if (ret != NULL)
|
||||
ret[rlen++] = sep;
|
||||
nlen = strlen(k->name);
|
||||
@@ -147,6 +163,10 @@ kex_alg_by_name(const char *name)
|
||||
{
|
||||
const struct kexalg *k;
|
||||
|
||||
+ if (strcmp(name, KEX_MLKEM768X25519_SHA256) == 0
|
||||
+ && !is_mlkem768_available())
|
||||
+ return NULL;
|
||||
+
|
||||
for (k = kexalgs; k->name != NULL; k++) {
|
||||
if (strcmp(k->name, name) == 0)
|
||||
return k;
|
||||
diff --git a/kexmlkem768x25519.c b/kexmlkem768x25519.c
|
||||
index 2b5d3960..670049dc 100644
|
||||
--- a/kexmlkem768x25519.c
|
||||
+++ b/kexmlkem768x25519.c
|
||||
@@ -48,10 +48,127 @@
|
||||
#ifdef USE_MLKEM768X25519
|
||||
|
||||
#include "libcrux_mlkem768_sha3.h"
|
||||
+#include <openssl/err.h>
|
||||
+#include <openssl/evp.h>
|
||||
+#include <stdio.h>
|
||||
+
|
||||
+static int
|
||||
+mlkem768_keypair_gen(unsigned char *pubkeybuf, unsigned char *privkeybuf)
|
||||
+{
|
||||
+ EVP_PKEY_CTX *ctx = NULL;
|
||||
+ EVP_PKEY *pkey = NULL;
|
||||
+ int ret = SSH_ERR_INTERNAL_ERROR;
|
||||
+ size_t pubkey_size = crypto_kem_mlkem768_PUBLICKEYBYTES, privkey_size = crypto_kem_mlkem768_SECRETKEYBYTES;
|
||||
+
|
||||
+ ctx = EVP_PKEY_CTX_new_from_name(NULL, "mlkem768", NULL);
|
||||
+ if (ctx == NULL) {
|
||||
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ if (EVP_PKEY_keygen_init(ctx) <= 0
|
||||
+ || EVP_PKEY_keygen(ctx, &pkey) <= 0) {
|
||||
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ if (EVP_PKEY_get_raw_public_key(pkey, pubkeybuf, &pubkey_size) <= 0
|
||||
+ || EVP_PKEY_get_raw_private_key(pkey, privkeybuf, &privkey_size) <= 0) {
|
||||
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ if (privkey_size != crypto_kem_mlkem768_SECRETKEYBYTES
|
||||
+ || pubkey_size != crypto_kem_mlkem768_PUBLICKEYBYTES) {
|
||||
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto err;
|
||||
+ }
|
||||
+ ret = 0;
|
||||
+
|
||||
+ err:
|
||||
+ EVP_PKEY_free(pkey);
|
||||
+ EVP_PKEY_CTX_free(ctx);
|
||||
+ if (ret == SSH_ERR_LIBCRYPTO_ERROR)
|
||||
+ ERR_print_errors_fp(stderr);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mlkem768_encap_secret(const u_char *pubkeybuf, u_char *secret, u_char *out)
|
||||
+{
|
||||
+ EVP_PKEY *pkey = NULL;
|
||||
+ EVP_PKEY_CTX *ctx = NULL;
|
||||
+ int r = SSH_ERR_INTERNAL_ERROR;
|
||||
+ size_t outlen = crypto_kem_mlkem768_CIPHERTEXTBYTES,
|
||||
+ secretlen = crypto_kem_mlkem768_BYTES;
|
||||
+
|
||||
+ pkey = EVP_PKEY_new_raw_public_key_ex(NULL, "mlkem768", NULL,
|
||||
+ pubkeybuf, crypto_kem_mlkem768_PUBLICKEYBYTES);
|
||||
+ if (pkey == NULL) {
|
||||
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL);
|
||||
+ if (ctx == NULL
|
||||
+ || EVP_PKEY_encapsulate_init(ctx, NULL) <= 0
|
||||
+ || EVP_PKEY_encapsulate(ctx, out, &outlen, secret, &secretlen) <= 0
|
||||
+ || secretlen != crypto_kem_mlkem768_BYTES
|
||||
+ || outlen != crypto_kem_mlkem768_CIPHERTEXTBYTES) {
|
||||
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto err;
|
||||
+ }
|
||||
+ r = 0;
|
||||
+
|
||||
+ err:
|
||||
+ EVP_PKEY_free(pkey);
|
||||
+ EVP_PKEY_CTX_free(ctx);
|
||||
+ if (r == SSH_ERR_LIBCRYPTO_ERROR)
|
||||
+ ERR_print_errors_fp(stderr);
|
||||
+
|
||||
+ return r;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mlkem768_decap_secret(const u_char *privkeybuf, const u_char *wrapped, u_char *secret)
|
||||
+{
|
||||
+ EVP_PKEY *pkey = NULL;
|
||||
+ EVP_PKEY_CTX *ctx = NULL;
|
||||
+ int r = SSH_ERR_INTERNAL_ERROR;
|
||||
+ size_t wrappedlen = crypto_kem_mlkem768_CIPHERTEXTBYTES,
|
||||
+ secretlen = crypto_kem_mlkem768_BYTES;
|
||||
+
|
||||
+ pkey = EVP_PKEY_new_raw_private_key_ex(NULL, "mlkem768", NULL,
|
||||
+ privkeybuf, crypto_kem_mlkem768_SECRETKEYBYTES);
|
||||
+ if (pkey == NULL) {
|
||||
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL);
|
||||
+ if (ctx == NULL
|
||||
+ || EVP_PKEY_decapsulate_init(ctx, NULL) <= 0
|
||||
+ || EVP_PKEY_decapsulate(ctx, secret, &secretlen, wrapped, wrappedlen) <= 0
|
||||
+ || secretlen != crypto_kem_mlkem768_BYTES) {
|
||||
+ r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
+ goto err;
|
||||
+ }
|
||||
+ r = 0;
|
||||
+
|
||||
+ err:
|
||||
+ EVP_PKEY_free(pkey);
|
||||
+ EVP_PKEY_CTX_free(ctx);
|
||||
+
|
||||
+ if (r == SSH_ERR_LIBCRYPTO_ERROR)
|
||||
+ ERR_print_errors_fp(stderr);
|
||||
+
|
||||
+ return r;
|
||||
+}
|
||||
|
||||
int
|
||||
kex_kem_mlkem768x25519_keypair(struct kex *kex)
|
||||
{
|
||||
+#if 0
|
||||
struct sshbuf *buf = NULL;
|
||||
u_char rnd[LIBCRUX_ML_KEM_KEY_PAIR_PRNG_LEN], *cp = NULL;
|
||||
size_t need;
|
||||
@@ -86,6 +203,36 @@ kex_kem_mlkem768x25519_keypair(struct kex *kex)
|
||||
explicit_bzero(rnd, sizeof(rnd));
|
||||
sshbuf_free(buf);
|
||||
return r;
|
||||
+#else
|
||||
+ struct sshbuf *buf = NULL;
|
||||
+ u_char *cp = NULL;
|
||||
+ size_t need;
|
||||
+ int r = SSH_ERR_INTERNAL_ERROR;
|
||||
+
|
||||
+ if ((buf = sshbuf_new()) == NULL)
|
||||
+ return SSH_ERR_ALLOC_FAIL;
|
||||
+ need = crypto_kem_mlkem768_PUBLICKEYBYTES + CURVE25519_SIZE;
|
||||
+ if ((r = sshbuf_reserve(buf, need, &cp)) != 0)
|
||||
+ goto out;
|
||||
+ if ((r = mlkem768_keypair_gen(cp, kex->mlkem768_client_key)) != 0)
|
||||
+ goto out;
|
||||
+#ifdef DEBUG_KEXECDH
|
||||
+ dump_digest("client public key mlkem768:", cp,
|
||||
+ crypto_kem_mlkem768_PUBLICKEYBYTES);
|
||||
+#endif
|
||||
+ cp += crypto_kem_mlkem768_PUBLICKEYBYTES;
|
||||
+ kexc25519_keygen(kex->c25519_client_key, cp);
|
||||
+#ifdef DEBUG_KEXECDH
|
||||
+ dump_digest("client public key c25519:", cp, CURVE25519_SIZE);
|
||||
+#endif
|
||||
+ /* success */
|
||||
+ r = 0;
|
||||
+ kex->client_pub = buf;
|
||||
+ buf = NULL;
|
||||
+ out:
|
||||
+ sshbuf_free(buf);
|
||||
+ return r;
|
||||
+#endif
|
||||
}
|
||||
|
||||
int
|
||||
@@ -93,6 +240,7 @@ kex_kem_mlkem768x25519_enc(struct kex *kex,
|
||||
const struct sshbuf *client_blob, struct sshbuf **server_blobp,
|
||||
struct sshbuf **shared_secretp)
|
||||
{
|
||||
+#if 0
|
||||
struct sshbuf *server_blob = NULL;
|
||||
struct sshbuf *buf = NULL;
|
||||
const u_char *client_pub;
|
||||
@@ -185,12 +333,97 @@ kex_kem_mlkem768x25519_enc(struct kex *kex,
|
||||
sshbuf_free(server_blob);
|
||||
sshbuf_free(buf);
|
||||
return r;
|
||||
+#else
|
||||
+ struct sshbuf *server_blob = NULL;
|
||||
+ struct sshbuf *buf = NULL;
|
||||
+ const u_char *client_pub;
|
||||
+ u_char server_pub[CURVE25519_SIZE], server_key[CURVE25519_SIZE];
|
||||
+ u_char hash[SSH_DIGEST_MAX_LENGTH];
|
||||
+ size_t need;
|
||||
+ int r = SSH_ERR_INTERNAL_ERROR;
|
||||
+ struct libcrux_mlkem768_enc_result enc; /* FIXME */
|
||||
+
|
||||
+ *server_blobp = NULL;
|
||||
+ *shared_secretp = NULL;
|
||||
+
|
||||
+ /* client_blob contains both KEM and ECDH client pubkeys */
|
||||
+ need = crypto_kem_mlkem768_PUBLICKEYBYTES + CURVE25519_SIZE;
|
||||
+ if (sshbuf_len(client_blob) != need) {
|
||||
+ r = SSH_ERR_SIGNATURE_INVALID;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ client_pub = sshbuf_ptr(client_blob);
|
||||
+#ifdef DEBUG_KEXECDH
|
||||
+ dump_digest("client public key mlkem768:", client_pub,
|
||||
+ crypto_kem_mlkem768_PUBLICKEYBYTES);
|
||||
+ dump_digest("client public key 25519:",
|
||||
+ client_pub + crypto_kem_mlkem768_PUBLICKEYBYTES,
|
||||
+ CURVE25519_SIZE);
|
||||
+#endif
|
||||
+
|
||||
+ /* allocate buffer for concatenation of KEM key and ECDH shared key */
|
||||
+ /* the buffer will be hashed and the result is the shared secret */
|
||||
+ if ((buf = sshbuf_new()) == NULL) {
|
||||
+ r = SSH_ERR_ALLOC_FAIL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ /* allocate space for encrypted KEM key and ECDH pub key */
|
||||
+ if ((server_blob = sshbuf_new()) == NULL) {
|
||||
+ r = SSH_ERR_ALLOC_FAIL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (mlkem768_encap_secret(client_pub, enc.snd, enc.fst.value) != 0)
|
||||
+ goto out;
|
||||
+
|
||||
+ /* generate ECDH key pair, store server pubkey after ciphertext */
|
||||
+ kexc25519_keygen(server_key, server_pub);
|
||||
+ if ((r = sshbuf_put(buf, enc.snd, sizeof(enc.snd))) != 0 ||
|
||||
+ (r = sshbuf_put(server_blob, enc.fst.value, sizeof(enc.fst.value))) != 0 ||
|
||||
+ (r = sshbuf_put(server_blob, server_pub, sizeof(server_pub))) != 0)
|
||||
+ goto out;
|
||||
+ /* append ECDH shared key */
|
||||
+ client_pub += crypto_kem_mlkem768_PUBLICKEYBYTES;
|
||||
+ if ((r = kexc25519_shared_key_ext(server_key, client_pub, buf, 1)) < 0)
|
||||
+ goto out;
|
||||
+ if ((r = ssh_digest_buffer(kex->hash_alg, buf, hash, sizeof(hash))) != 0)
|
||||
+ goto out;
|
||||
+#ifdef DEBUG_KEXECDH
|
||||
+ dump_digest("server public key 25519:", server_pub, CURVE25519_SIZE);
|
||||
+ dump_digest("server cipher text:",
|
||||
+ enc.fst.value, sizeof(enc.fst.value));
|
||||
+ dump_digest("server kem key:", enc.snd, sizeof(enc.snd));
|
||||
+ dump_digest("concatenation of KEM key and ECDH shared key:",
|
||||
+ sshbuf_ptr(buf), sshbuf_len(buf));
|
||||
+#endif
|
||||
+ /* string-encoded hash is resulting shared secret */
|
||||
+ sshbuf_reset(buf);
|
||||
+ if ((r = sshbuf_put_string(buf, hash,
|
||||
+ ssh_digest_bytes(kex->hash_alg))) != 0)
|
||||
+ goto out;
|
||||
+#ifdef DEBUG_KEXECDH
|
||||
+ dump_digest("encoded shared secret:", sshbuf_ptr(buf), sshbuf_len(buf));
|
||||
+#endif
|
||||
+ /* success */
|
||||
+ r = 0;
|
||||
+ *server_blobp = server_blob;
|
||||
+ *shared_secretp = buf;
|
||||
+ server_blob = NULL;
|
||||
+ buf = NULL;
|
||||
+ out:
|
||||
+ explicit_bzero(hash, sizeof(hash));
|
||||
+ explicit_bzero(server_key, sizeof(server_key));
|
||||
+ explicit_bzero(&enc, sizeof(enc));
|
||||
+ sshbuf_free(server_blob);
|
||||
+ sshbuf_free(buf);
|
||||
+ return r;
|
||||
+#endif
|
||||
}
|
||||
|
||||
int
|
||||
kex_kem_mlkem768x25519_dec(struct kex *kex,
|
||||
const struct sshbuf *server_blob, struct sshbuf **shared_secretp)
|
||||
{
|
||||
+#if 0
|
||||
struct sshbuf *buf = NULL;
|
||||
u_char mlkem_key[crypto_kem_mlkem768_BYTES];
|
||||
const u_char *ciphertext, *server_pub;
|
||||
@@ -258,6 +491,64 @@ kex_kem_mlkem768x25519_dec(struct kex *kex,
|
||||
explicit_bzero(mlkem_key, sizeof(mlkem_key));
|
||||
sshbuf_free(buf);
|
||||
return r;
|
||||
+#else
|
||||
+ struct sshbuf *buf = NULL;
|
||||
+ const u_char *ciphertext, *server_pub;
|
||||
+ u_char hash[SSH_DIGEST_MAX_LENGTH];
|
||||
+ u_char decap[crypto_kem_mlkem768_BYTES];
|
||||
+ size_t need;
|
||||
+ int r;
|
||||
+
|
||||
+ *shared_secretp = NULL;
|
||||
+
|
||||
+ need = crypto_kem_mlkem768_CIPHERTEXTBYTES + CURVE25519_SIZE;
|
||||
+ if (sshbuf_len(server_blob) != need) {
|
||||
+ r = SSH_ERR_SIGNATURE_INVALID;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ ciphertext = sshbuf_ptr(server_blob);
|
||||
+ server_pub = ciphertext + crypto_kem_mlkem768_CIPHERTEXTBYTES;
|
||||
+ /* hash concatenation of KEM key and ECDH shared key */
|
||||
+ if ((buf = sshbuf_new()) == NULL) {
|
||||
+ r = SSH_ERR_ALLOC_FAIL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+#ifdef DEBUG_KEXECDH
|
||||
+ dump_digest("server cipher text:", ciphertext, crypto_kem_mlkem768_CIPHERTEXTBYTES);
|
||||
+ dump_digest("server public key c25519:", server_pub, CURVE25519_SIZE);
|
||||
+#endif
|
||||
+ if ((r = mlkem768_decap_secret(kex->mlkem768_client_key, ciphertext, decap)) != 0)
|
||||
+ goto out;
|
||||
+ if ((r = sshbuf_put(buf, decap, sizeof(decap))) != 0)
|
||||
+ goto out;
|
||||
+ if ((r = kexc25519_shared_key_ext(kex->c25519_client_key, server_pub,
|
||||
+ buf, 1)) < 0)
|
||||
+ goto out;
|
||||
+ if ((r = ssh_digest_buffer(kex->hash_alg, buf,
|
||||
+ hash, sizeof(hash))) != 0)
|
||||
+ goto out;
|
||||
+#ifdef DEBUG_KEXECDH
|
||||
+ dump_digest("client kem key:", decap, sizeof(decap));
|
||||
+ dump_digest("concatenation of KEM key and ECDH shared key:",
|
||||
+ sshbuf_ptr(buf), sshbuf_len(buf));
|
||||
+#endif
|
||||
+ sshbuf_reset(buf);
|
||||
+ if ((r = sshbuf_put_string(buf, hash,
|
||||
+ ssh_digest_bytes(kex->hash_alg))) != 0)
|
||||
+ goto out;
|
||||
+#ifdef DEBUG_KEXECDH
|
||||
+ dump_digest("encoded shared secret:", sshbuf_ptr(buf), sshbuf_len(buf));
|
||||
+#endif
|
||||
+ /* success */
|
||||
+ r = 0;
|
||||
+ *shared_secretp = buf;
|
||||
+ buf = NULL;
|
||||
+ out:
|
||||
+ explicit_bzero(hash, sizeof(hash));
|
||||
+ explicit_bzero(decap, sizeof(decap));
|
||||
+ sshbuf_free(buf);
|
||||
+ return r;
|
||||
+#endif
|
||||
}
|
||||
#else /* USE_MLKEM768X25519 */
|
||||
int
|
||||
--
|
||||
2.49.0
|
||||
|
||||
25
0050-openssh-9.9p2-error_processing.patch
Normal file
25
0050-openssh-9.9p2-error_processing.patch
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
From fd32e753ae7f3b314712e6aa8b2bed3c1fca1ef5 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Fri, 16 May 2025 14:53:54 +0200
|
||||
Subject: [PATCH 50/51] openssh-9.9p2-error_processing
|
||||
|
||||
---
|
||||
ssh-agent.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/ssh-agent.c b/ssh-agent.c
|
||||
index 798bf9b6..dfb6ac72 100644
|
||||
--- a/ssh-agent.c
|
||||
+++ b/ssh-agent.c
|
||||
@@ -1377,6 +1377,8 @@ process_add_identity(SocketEntry *e)
|
||||
if ((r = sshkey_private_deserialize(e->request, &k)) != 0 ||
|
||||
k == NULL ||
|
||||
(r = sshbuf_get_cstring(e->request, &comment, NULL)) != 0) {
|
||||
+ if (!r) /* k == NULL */
|
||||
+ r = SSH_ERR_INTERNAL_ERROR;
|
||||
error_fr(r, "parse");
|
||||
goto out;
|
||||
}
|
||||
--
|
||||
2.49.0
|
||||
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
From 4965cdbc1ee1e6a0c665797bb8b944d96d3d411f Mon Sep 17 00:00:00 2001
|
||||
From: Zoltan Fridrich <zfridric@redhat.com>
|
||||
Date: Wed, 16 Apr 2025 15:11:59 +0200
|
||||
Subject: [PATCH 51/53] Provide better error for non-supported private keys
|
||||
|
||||
Signed-off-by: Zoltan Fridrich <zfridric@redhat.com>
|
||||
---
|
||||
sshkey.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/sshkey.c b/sshkey.c
|
||||
index ca1cdb642..aada474e0 100644
|
||||
--- a/sshkey.c
|
||||
+++ b/sshkey.c
|
||||
@@ -3582,6 +3582,9 @@ translate_libcrypto_error(unsigned long pem_err)
|
||||
return SSH_ERR_LIBCRYPTO_ERROR;
|
||||
}
|
||||
case ERR_LIB_ASN1:
|
||||
+#ifdef ERR_LIB_OSSL_DECODER
|
||||
+ case ERR_LIB_OSSL_DECODER:
|
||||
+#endif
|
||||
return SSH_ERR_INVALID_FORMAT;
|
||||
}
|
||||
return SSH_ERR_LIBCRYPTO_ERROR;
|
||||
--
|
||||
2.49.0
|
||||
|
||||
86
0052-Ignore-bad-hostkeys-in-known_hosts-file.patch
Normal file
86
0052-Ignore-bad-hostkeys-in-known_hosts-file.patch
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
From 9ed09ef158a113e21be7b3fefa7c5f932632749b Mon Sep 17 00:00:00 2001
|
||||
From: Zoltan Fridrich <zfridric@redhat.com>
|
||||
Date: Mon, 5 May 2025 11:52:25 +0200
|
||||
Subject: [PATCH 52/53] Ignore bad hostkeys in known_hosts file
|
||||
|
||||
Signed-off-by: Zoltan Fridrich <zfridric@redhat.com>
|
||||
---
|
||||
hostfile.c | 15 +++++++++++++++
|
||||
hostfile.h | 1 +
|
||||
ssh.c | 2 ++
|
||||
3 files changed, 18 insertions(+)
|
||||
|
||||
diff --git a/hostfile.c b/hostfile.c
|
||||
index c5669c703..5c402f501 100644
|
||||
--- a/hostfile.c
|
||||
+++ b/hostfile.c
|
||||
@@ -63,6 +63,14 @@
|
||||
#include "hmac.h"
|
||||
#include "sshbuf.h"
|
||||
|
||||
+static int required_rsa_size = SSH_RSA_MINIMUM_MODULUS_SIZE;
|
||||
+
|
||||
+void
|
||||
+hostfile_set_minimum_rsa_size(int size)
|
||||
+{
|
||||
+ required_rsa_size = size;
|
||||
+}
|
||||
+
|
||||
/* XXX hmac is too easy to dictionary attack; use bcrypt? */
|
||||
|
||||
static int
|
||||
@@ -233,6 +241,7 @@ record_hostkey(struct hostkey_foreach_line *l, void *_ctx)
|
||||
struct load_callback_ctx *ctx = (struct load_callback_ctx *)_ctx;
|
||||
struct hostkeys *hostkeys = ctx->hostkeys;
|
||||
struct hostkey_entry *tmp;
|
||||
+ int r = 0;
|
||||
|
||||
if (l->status == HKF_STATUS_INVALID) {
|
||||
/* XXX make this verbose() in the future */
|
||||
@@ -241,6 +250,12 @@ record_hostkey(struct hostkey_foreach_line *l, void *_ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+ if ((r = sshkey_check_rsa_length(l->key, required_rsa_size)) != 0) {
|
||||
+ debug2_f("%s:%ld: ignoring hostkey: %s",
|
||||
+ l->path, l->linenum, ssh_err(r));
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
debug3_f("found %skey type %s in file %s:%lu",
|
||||
l->marker == MRK_NONE ? "" :
|
||||
(l->marker == MRK_CA ? "ca " : "revoked "),
|
||||
diff --git a/hostfile.h b/hostfile.h
|
||||
index a24a4e329..0e9b1a19a 100644
|
||||
--- a/hostfile.h
|
||||
+++ b/hostfile.h
|
||||
@@ -119,5 +119,6 @@ int hostkeys_foreach_file(const char *path, FILE *f,
|
||||
const char *host, const char *ip, u_int options, u_int note);
|
||||
|
||||
void hostfile_create_user_ssh_dir(const char *, int);
|
||||
+void hostfile_set_minimum_rsa_size(int);
|
||||
|
||||
#endif
|
||||
diff --git a/ssh.c b/ssh.c
|
||||
index abc8b8439..33787a8d4 100644
|
||||
--- a/ssh.c
|
||||
+++ b/ssh.c
|
||||
@@ -110,6 +110,7 @@
|
||||
#include "ssherr.h"
|
||||
#include "myproposal.h"
|
||||
#include "utf8.h"
|
||||
+#include "hostfile.h"
|
||||
|
||||
#ifdef ENABLE_PKCS11
|
||||
#include "ssh-pkcs11.h"
|
||||
@@ -1397,6 +1398,7 @@ main(int ac, char **av)
|
||||
options.update_hostkeys = 0;
|
||||
}
|
||||
}
|
||||
+ hostfile_set_minimum_rsa_size(options.required_rsa_size);
|
||||
if (options.connection_attempts <= 0)
|
||||
fatal("Invalid number of ConnectionAttempts");
|
||||
|
||||
--
|
||||
2.49.0
|
||||
|
||||
450
0053-support-authentication-indicators-in-GSSAPI.patch
Normal file
450
0053-support-authentication-indicators-in-GSSAPI.patch
Normal file
|
|
@ -0,0 +1,450 @@
|
|||
From 5d5a66e96ad03132f65371070f4fa475f10207d9 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
Date: Mon, 10 Jun 2024 23:00:03 +0300
|
||||
Subject: [PATCH] support authentication indicators in GSSAPI
|
||||
|
||||
RFC 6680 defines a set of GSSAPI extensions to handle attributes
|
||||
associated with the GSSAPI names. MIT Kerberos and FreeIPA use
|
||||
name attributes to add information about pre-authentication methods used
|
||||
to acquire the initial Kerberos ticket. The attribute 'auth-indicators'
|
||||
may contain list of strings that KDC has associated with the ticket
|
||||
issuance process.
|
||||
|
||||
Use authentication indicators to authorise or deny access to SSH server.
|
||||
GSSAPIIndicators setting allows to specify a list of possible indicators
|
||||
that a Kerberos ticket presented must or must not contain. More details
|
||||
on the syntax are provided in sshd_config(5) man page.
|
||||
|
||||
Fixes: https://bugzilla.mindrot.org/show_bug.cgi?id=2696
|
||||
|
||||
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
---
|
||||
configure.ac | 1 +
|
||||
gss-serv-krb5.c | 64 +++++++++++++++++++++++++++---
|
||||
gss-serv.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
servconf.c | 15 ++++++-
|
||||
servconf.h | 2 +
|
||||
ssh-gss.h | 7 ++++
|
||||
sshd_config.5 | 44 +++++++++++++++++++++
|
||||
7 files changed, 228 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index d92a85809..2cbe20bf3 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -5004,6 +5004,7 @@ AC_ARG_WITH([kerberos5],
|
||||
AC_CHECK_HEADERS([gssapi.h gssapi/gssapi.h])
|
||||
AC_CHECK_HEADERS([gssapi_krb5.h gssapi/gssapi_krb5.h])
|
||||
AC_CHECK_HEADERS([gssapi_generic.h gssapi/gssapi_generic.h])
|
||||
+ AC_CHECK_HEADERS([gssapi_ext.h gssapi/gssapi_ext.h])
|
||||
|
||||
AC_SEARCH_LIBS([k_hasafs], [kafs], [AC_DEFINE([USE_AFS], [1],
|
||||
[Define this if you want to use libkafs' AFS support])])
|
||||
diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c
|
||||
index 03188d9b3..2c786ef14 100644
|
||||
--- a/gss-serv-krb5.c
|
||||
+++ b/gss-serv-krb5.c
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "log.h"
|
||||
#include "misc.h"
|
||||
#include "servconf.h"
|
||||
+#include "match.h"
|
||||
|
||||
#include "ssh-gss.h"
|
||||
|
||||
@@ -87,6 +88,32 @@ ssh_gssapi_krb5_init(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
+/* Check if any of the indicators in the Kerberos ticket match
|
||||
+ * one of indicators in the list of allowed/denied rules.
|
||||
+ * In case of the match, apply the decision from the rule.
|
||||
+ * In case of no indicator from the ticket matching the rule, deny
|
||||
+ */
|
||||
+
|
||||
+static int
|
||||
+ssh_gssapi_check_indicators(ssh_gssapi_client *client, int *matched)
|
||||
+{
|
||||
+ int ret;
|
||||
+ u_int i;
|
||||
+
|
||||
+ /* Check indicators */
|
||||
+ for (i = 0; client->indicators[i] != NULL; i++) {
|
||||
+ ret = match_pattern_list(client->indicators[i],
|
||||
+ options.gss_indicators, 1);
|
||||
+ /* negative or positive match */
|
||||
+ if (ret != 0) {
|
||||
+ *matched = i;
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+ /* No rule matched */
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/* Check if this user is OK to login. This only works with krb5 - other
|
||||
* GSSAPI mechanisms will need their own.
|
||||
* Returns true if the user is OK to log in, otherwise returns 0
|
||||
@@ -193,7 +220,7 @@ static int
|
||||
ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name)
|
||||
{
|
||||
krb5_principal princ;
|
||||
- int retval;
|
||||
+ int retval, matched;
|
||||
const char *errmsg;
|
||||
int k5login_exists;
|
||||
|
||||
@@ -216,17 +243,42 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name)
|
||||
if (k5login_exists &&
|
||||
ssh_krb5_kuserok(krb_context, princ, name, k5login_exists)) {
|
||||
retval = 1;
|
||||
- logit("Authorized to %s, krb5 principal %s (krb5_kuserok)",
|
||||
- name, (char *)client->displayname.value);
|
||||
+ errmsg = "krb5_kuserok";
|
||||
} else if (ssh_gssapi_krb5_cmdok(princ, client->exportedname.value,
|
||||
name, k5login_exists)) {
|
||||
retval = 1;
|
||||
- logit("Authorized to %s, krb5 principal %s "
|
||||
- "(ssh_gssapi_krb5_cmdok)",
|
||||
- name, (char *)client->displayname.value);
|
||||
+ errmsg = "ssh_gssapi_krb5_cmdok";
|
||||
} else
|
||||
retval = 0;
|
||||
|
||||
+ if ((retval == 1) && (options.gss_indicators != NULL)) {
|
||||
+ /* At this point the configuration enforces presence of indicators
|
||||
+ * so we drop the authorization result again */
|
||||
+ retval = 0;
|
||||
+ if (client->indicators) {
|
||||
+ matched = -1;
|
||||
+ retval = ssh_gssapi_check_indicators(client, &matched);
|
||||
+ if (retval != 0) {
|
||||
+ retval = (retval == 1);
|
||||
+ logit("Ticket contains indicator %s, "
|
||||
+ "krb5 principal %s is %s",
|
||||
+ client->indicators[matched],
|
||||
+ (char *)client->displayname.value,
|
||||
+ retval ? "allowed" : "denied");
|
||||
+ goto cont;
|
||||
+ }
|
||||
+ }
|
||||
+ if (retval == 0) {
|
||||
+ logit("GSSAPI authentication indicators enforced "
|
||||
+ "but not matched. krb5 principal %s denied",
|
||||
+ (char *)client->displayname.value);
|
||||
+ }
|
||||
+ }
|
||||
+cont:
|
||||
+ if (retval == 1) {
|
||||
+ logit("Authorized to %s, krb5 principal %s (%s)",
|
||||
+ name, (char *)client->displayname.value, errmsg);
|
||||
+ }
|
||||
krb5_free_principal(krb_context, princ);
|
||||
return retval;
|
||||
}
|
||||
diff --git a/gss-serv.c b/gss-serv.c
|
||||
index 9d5435eda..5c0491cf1 100644
|
||||
--- a/gss-serv.c
|
||||
+++ b/gss-serv.c
|
||||
@@ -54,7 +54,7 @@ extern ServerOptions options;
|
||||
|
||||
static ssh_gssapi_client gssapi_client =
|
||||
{ GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, GSS_C_NO_CREDENTIAL,
|
||||
- GSS_C_NO_NAME, NULL, {NULL, NULL, NULL, NULL, NULL}, 0, 0};
|
||||
+ GSS_C_NO_NAME, NULL, {NULL, NULL, NULL, NULL, NULL}, 0, 0, NULL};
|
||||
|
||||
ssh_gssapi_mech gssapi_null_mech =
|
||||
{ NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL, NULL};
|
||||
@@ -296,6 +296,92 @@ ssh_gssapi_parse_ename(Gssctxt *ctx, gss_buffer_t ename, gss_buffer_t name)
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
|
||||
+
|
||||
+/* Extract authentication indicators from the Kerberos ticket. Authentication
|
||||
+ * indicators are GSSAPI name attributes for the name "auth-indicators".
|
||||
+ * Multiple indicators might be present in the ticket.
|
||||
+ * Each indicator is a utf8 string. */
|
||||
+
|
||||
+#define AUTH_INDICATORS_TAG "auth-indicators"
|
||||
+
|
||||
+/* Privileged (called from accept_secure_ctx) */
|
||||
+static OM_uint32
|
||||
+ssh_gssapi_getindicators(Gssctxt *ctx, gss_name_t gss_name, ssh_gssapi_client *client)
|
||||
+{
|
||||
+ gss_buffer_set_t attrs = GSS_C_NO_BUFFER_SET;
|
||||
+ gss_buffer_desc value = GSS_C_EMPTY_BUFFER;
|
||||
+ gss_buffer_desc display_value = GSS_C_EMPTY_BUFFER;
|
||||
+ int is_mechname, authenticated, complete, more;
|
||||
+ size_t count, i;
|
||||
+
|
||||
+ ctx->major = gss_inquire_name(&ctx->minor, gss_name,
|
||||
+ &is_mechname, NULL, &attrs);
|
||||
+ if (ctx->major != GSS_S_COMPLETE) {
|
||||
+ return (ctx->major);
|
||||
+ }
|
||||
+
|
||||
+ if (attrs == GSS_C_NO_BUFFER_SET) {
|
||||
+ /* No indicators in the ticket */
|
||||
+ return (0);
|
||||
+ }
|
||||
+
|
||||
+ count = 0;
|
||||
+ for (i = 0; i < attrs->count; i++) {
|
||||
+ /* skip anything but auth-indicators */
|
||||
+ if (((sizeof(AUTH_INDICATORS_TAG) - 1) != attrs->elements[i].length) ||
|
||||
+ strncmp(AUTH_INDICATORS_TAG,
|
||||
+ attrs->elements[i].value,
|
||||
+ sizeof(AUTH_INDICATORS_TAG) - 1) != 0)
|
||||
+ continue;
|
||||
+ count++;
|
||||
+ }
|
||||
+
|
||||
+ if (count == 0) {
|
||||
+ /* No auth-indicators in the ticket */
|
||||
+ (void) gss_release_buffer_set(&ctx->minor, &attrs);
|
||||
+ return (0);
|
||||
+ }
|
||||
+
|
||||
+ client->indicators = recallocarray(NULL, 0, count + 1, sizeof(char*));
|
||||
+ count = 0;
|
||||
+ for (i = 0; i < attrs->count; i++) {
|
||||
+ authenticated = 0;
|
||||
+ complete = 0;
|
||||
+ more = -1;
|
||||
+ /* skip anything but auth-indicators */
|
||||
+ if (((sizeof(AUTH_INDICATORS_TAG) - 1) != attrs->elements[i].length) ||
|
||||
+ strncmp(AUTH_INDICATORS_TAG,
|
||||
+ attrs->elements[i].value,
|
||||
+ sizeof(AUTH_INDICATORS_TAG) - 1) != 0)
|
||||
+ continue;
|
||||
+ /* retrieve all indicators */
|
||||
+ while (more != 0) {
|
||||
+ value.value = NULL;
|
||||
+ display_value.value = NULL;
|
||||
+ ctx->major = gss_get_name_attribute(&ctx->minor, gss_name,
|
||||
+ &attrs->elements[i], &authenticated,
|
||||
+ &complete, &value, &display_value, &more);
|
||||
+ if (ctx->major != GSS_S_COMPLETE) {
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if ((value.value != NULL) && authenticated) {
|
||||
+ client->indicators[count] = xmalloc(value.length + 1);
|
||||
+ memcpy(client->indicators[count], value.value, value.length);
|
||||
+ client->indicators[count][value.length] = '\0';
|
||||
+ count++;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+out:
|
||||
+ (void) gss_release_buffer(&ctx->minor, &value);
|
||||
+ (void) gss_release_buffer(&ctx->minor, &display_value);
|
||||
+ (void) gss_release_buffer_set(&ctx->minor, &attrs);
|
||||
+ return (ctx->major);
|
||||
+}
|
||||
+
|
||||
+
|
||||
/* Extract the client details from a given context. This can only reliably
|
||||
* be called once for a context */
|
||||
|
||||
@@ -385,6 +471,12 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client)
|
||||
}
|
||||
|
||||
gss_release_buffer(&ctx->minor, &ename);
|
||||
+ /* Retrieve authentication indicators, if they exist */
|
||||
+ if ((ctx->major = ssh_gssapi_getindicators(ctx,
|
||||
+ ctx->client, client))) {
|
||||
+ ssh_gssapi_error(ctx);
|
||||
+ return (ctx->major);
|
||||
+ }
|
||||
|
||||
/* We can't copy this structure, so we just move the pointer to it */
|
||||
client->creds = ctx->client_creds;
|
||||
@@ -447,6 +539,7 @@ int
|
||||
ssh_gssapi_userok(char *user, struct passwd *pw, int kex)
|
||||
{
|
||||
OM_uint32 lmin;
|
||||
+ size_t i;
|
||||
|
||||
(void) kex; /* used in privilege separation */
|
||||
|
||||
@@ -465,6 +558,14 @@ ssh_gssapi_userok(char *user, struct passwd *pw, int kex)
|
||||
gss_release_buffer(&lmin, &gssapi_client.displayname);
|
||||
gss_release_buffer(&lmin, &gssapi_client.exportedname);
|
||||
gss_release_cred(&lmin, &gssapi_client.creds);
|
||||
+
|
||||
+ if (gssapi_client.indicators != NULL) {
|
||||
+ for(i = 0; gssapi_client.indicators[i] != NULL; i++) {
|
||||
+ free(gssapi_client.indicators[i]);
|
||||
+ }
|
||||
+ free(gssapi_client.indicators);
|
||||
+ }
|
||||
+
|
||||
explicit_bzero(&gssapi_client,
|
||||
sizeof(ssh_gssapi_client));
|
||||
return 0;
|
||||
diff --git a/servconf.c b/servconf.c
|
||||
index e7e4ad046..aab653244 100644
|
||||
--- a/servconf.c
|
||||
+++ b/servconf.c
|
||||
@@ -147,6 +147,7 @@ initialize_server_options(ServerOptions *options)
|
||||
options->gss_strict_acceptor = -1;
|
||||
options->gss_store_rekey = -1;
|
||||
options->gss_kex_algorithms = NULL;
|
||||
+ options->gss_indicators = NULL;
|
||||
options->use_kuserok = -1;
|
||||
options->enable_k5users = -1;
|
||||
options->password_authentication = -1;
|
||||
@@ -598,7 +599,7 @@ typedef enum {
|
||||
sPerSourcePenalties, sPerSourcePenaltyExemptList,
|
||||
sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
|
||||
sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor,
|
||||
- sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey,
|
||||
+ sGssKeyEx, sGssIndicators, sGssKexAlgorithms, sGssStoreRekey,
|
||||
sAcceptEnv, sSetEnv, sPermitTunnel,
|
||||
sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory,
|
||||
sUsePrivilegeSeparation, sAllowAgentForwarding,
|
||||
@@ -694,6 +695,7 @@ static struct {
|
||||
{ "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL },
|
||||
{ "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL },
|
||||
{ "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL },
|
||||
+ { "gssapiindicators", sGssIndicators, SSHCFG_ALL },
|
||||
#else
|
||||
{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
|
||||
{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
|
||||
@@ -703,6 +705,7 @@ static struct {
|
||||
{ "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL },
|
||||
{ "gssapikexalgorithms", sUnsupported, SSHCFG_GLOBAL },
|
||||
{ "gssapienablek5users", sUnsupported, SSHCFG_ALL },
|
||||
+ { "gssapiindicators", sUnsupported, SSHCFG_ALL },
|
||||
#endif
|
||||
{ "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL },
|
||||
{ "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL },
|
||||
@@ -1730,6 +1733,15 @@ process_server_config_line_depth(ServerOptions *options, char *line,
|
||||
options->gss_kex_algorithms = xstrdup(arg);
|
||||
break;
|
||||
|
||||
+ case sGssIndicators:
|
||||
+ arg = argv_next(&ac, &av);
|
||||
+ if (!arg || *arg == '\0')
|
||||
+ fatal("%s line %d: %s missing argument.",
|
||||
+ filename, linenum, keyword);
|
||||
+ if (options->gss_indicators == NULL)
|
||||
+ options->gss_indicators = xstrdup(arg);
|
||||
+ break;
|
||||
+
|
||||
case sPasswordAuthentication:
|
||||
intptr = &options->password_authentication;
|
||||
goto parse_flag;
|
||||
@@ -3351,6 +3363,7 @@ dump_config(ServerOptions *o)
|
||||
dump_cfg_fmtint(sGssStrictAcceptor, o->gss_strict_acceptor);
|
||||
dump_cfg_fmtint(sGssStoreRekey, o->gss_store_rekey);
|
||||
dump_cfg_string(sGssKexAlgorithms, o->gss_kex_algorithms);
|
||||
+ dump_cfg_string(sGssIndicators, o->gss_indicators);
|
||||
#endif
|
||||
dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
|
||||
dump_cfg_fmtint(sKbdInteractiveAuthentication,
|
||||
diff --git a/servconf.h b/servconf.h
|
||||
index 7c7e5d434..7c41df417 100644
|
||||
--- a/servconf.h
|
||||
+++ b/servconf.h
|
||||
@@ -181,6 +181,7 @@ typedef struct {
|
||||
char **allow_groups;
|
||||
u_int num_deny_groups;
|
||||
char **deny_groups;
|
||||
+ char *gss_indicators;
|
||||
|
||||
u_int num_subsystems;
|
||||
char **subsystem_name;
|
||||
@@ -310,6 +311,7 @@ TAILQ_HEAD(include_list, include_item);
|
||||
M_CP_STROPT(routing_domain); \
|
||||
M_CP_STROPT(permit_user_env_allowlist); \
|
||||
M_CP_STROPT(pam_service_name); \
|
||||
+ M_CP_STROPT(gss_indicators); \
|
||||
M_CP_STRARRAYOPT(authorized_keys_files, num_authkeys_files); \
|
||||
M_CP_STRARRAYOPT(allow_users, num_allow_users); \
|
||||
M_CP_STRARRAYOPT(deny_users, num_deny_users); \
|
||||
diff --git a/ssh-gss.h b/ssh-gss.h
|
||||
index a894e23c9..59cf46d47 100644
|
||||
--- a/ssh-gss.h
|
||||
+++ b/ssh-gss.h
|
||||
@@ -34,6 +34,12 @@
|
||||
#include <gssapi/gssapi.h>
|
||||
#endif
|
||||
|
||||
+#ifdef HAVE_GSSAPI_EXT_H
|
||||
+#include <gssapi_ext.h>
|
||||
+#elif defined(HAVE_GSSAPI_GSSAPI_EXT_H)
|
||||
+#include <gssapi/gssapi_ext.h>
|
||||
+#endif
|
||||
+
|
||||
#ifdef KRB5
|
||||
# ifndef HEIMDAL
|
||||
# ifdef HAVE_GSSAPI_GENERIC_H
|
||||
@@ -107,6 +113,7 @@ typedef struct {
|
||||
ssh_gssapi_ccache store;
|
||||
int used;
|
||||
int updated;
|
||||
+ char **indicators; /* auth indicators */
|
||||
} ssh_gssapi_client;
|
||||
|
||||
typedef struct ssh_gssapi_mech_struct {
|
||||
diff --git a/sshd_config.5 b/sshd_config.5
|
||||
index 583a01cdb..90ab87edd 100644
|
||||
--- a/sshd_config.5
|
||||
+++ b/sshd_config.5
|
||||
@@ -785,6 +785,50 @@ gss-nistp256-sha256-
|
||||
gss-curve25519-sha256-
|
||||
.Ed
|
||||
This option only applies to connections using GSSAPI.
|
||||
+.It Cm GSSAPIIndicators
|
||||
+Specifies whether to accept or deny GSSAPI authenticated access if Kerberos
|
||||
+mechanism is used and Kerberos ticket contains a particular set of
|
||||
+authentication indicators. The values can be specified as a comma-separated list
|
||||
+.Cm [!]name1,[!]name2,... .
|
||||
+When indicator's name is prefixed with !, the authentication indicator 'name'
|
||||
+will deny access to the system. Otherwise, one of non-negated authentication
|
||||
+indicators must be present in the Kerberos ticket to allow access. If
|
||||
+.Cm GSSAPIIndicators
|
||||
+is defined, a Kerberos ticket that has indicators but does not match the
|
||||
+policy will get denial. If at least one indicator is configured, whether for
|
||||
+access or denial, tickets without authentication indicators will be explicitly
|
||||
+rejected.
|
||||
+.Pp
|
||||
+By default systems using MIT Kerberos 1.17 or later will not assign any
|
||||
+indicators. SPAKE and PKINIT methods add authentication indicators
|
||||
+to all successful authentications. The SPAKE pre-authentication method is
|
||||
+preferred over an encrypted timestamp pre-authentication when passwords used to
|
||||
+authenticate user principals. Kerberos KDCs built with Heimdal Kerberos
|
||||
+(including Samba AD DC built with Heimdal) do not add authentication
|
||||
+indicators. However, OpenSSH built against Heimdal Kerberos library is able to
|
||||
+inquire authentication indicators and thus can be used to check for their presence.
|
||||
+.Pp
|
||||
+Indicator name is case-sensitive and depends on the configuration of a
|
||||
+particular Kerberos deployment. Indicators available in MIT Kerberos and
|
||||
+FreeIPA environments:
|
||||
+.Pp
|
||||
+.Bl -tag -width XXXX -offset indent -compact
|
||||
+.It Cm hardened
|
||||
+SPAKE or encrypted timestamp pre-authentication mechanisms in MIT Kerberos and FreeIPA
|
||||
+.It Cm pkinit
|
||||
+smartcard or PKCS11 token-based pre-authentication in MIT Kerberos and FreeIPA
|
||||
+.It Cm radius
|
||||
+pre-authentication based on a RADIUS server in MIT Kerberos and FreeIPA
|
||||
+.It Cm otp
|
||||
+TOTP/HOTP-based two-factor pre-authentication in FreeIPA
|
||||
+.It Cm idp
|
||||
+OAuth2-based pre-authentication in FreeIPA using an external identity provider
|
||||
+and device authorization grant flow
|
||||
+.It Cm passkey
|
||||
+FIDO2-based pre-authentication in FreeIPA, using FIDO2 USB and NFC tokens
|
||||
+.El
|
||||
+.Pp
|
||||
+The default is to not use GSSAPI authentication indicators for access decisions.
|
||||
.It Cm HostbasedAcceptedAlgorithms
|
||||
The default is handled system-wide by
|
||||
.Xr crypto-policies 7 .
|
||||
--
|
||||
2.49.0
|
||||
|
||||
257
1000-openssh-coverity.patch
Normal file
257
1000-openssh-coverity.patch
Normal file
|
|
@ -0,0 +1,257 @@
|
|||
From 24c411970682dc67873c36bac05b4b460d68a628 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||
Date: Thu, 15 May 2025 13:43:29 +0200
|
||||
Subject: [PATCH 50/50] openssh-6.7p1-coverity
|
||||
|
||||
---
|
||||
auth-krb5.c | 2 ++
|
||||
gss-genr.c | 3 ++-
|
||||
krl.c | 3 +++
|
||||
loginrec.c | 2 ++
|
||||
misc.c | 3 +++
|
||||
monitor.c | 4 ++--
|
||||
openbsd-compat/bindresvport.c | 2 +-
|
||||
openbsd-compat/bsd-pselect.c | 8 ++++----
|
||||
readconf.c | 1 +
|
||||
servconf.c | 5 +++--
|
||||
serverloop.c | 2 +-
|
||||
ssh-agent.c | 1 +
|
||||
ssh-keygen.c | 3 +++
|
||||
13 files changed, 28 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/auth-krb5.c b/auth-krb5.c
|
||||
index bae153c9..209a3265 100644
|
||||
--- a/auth-krb5.c
|
||||
+++ b/auth-krb5.c
|
||||
@@ -427,6 +427,7 @@ ssh_krb5_cc_new_unique(krb5_context ctx, krb5_ccache *ccache, int *need_environm
|
||||
umask(old_umask);
|
||||
if (tmpfd == -1) {
|
||||
logit("mkstemp(): %.100s", strerror(oerrno));
|
||||
+ free(ccname);
|
||||
return oerrno;
|
||||
}
|
||||
|
||||
@@ -434,6 +435,7 @@ ssh_krb5_cc_new_unique(krb5_context ctx, krb5_ccache *ccache, int *need_environm
|
||||
oerrno = errno;
|
||||
logit("fchmod(): %.100s", strerror(oerrno));
|
||||
close(tmpfd);
|
||||
+ free(ccname);
|
||||
return oerrno;
|
||||
}
|
||||
/* make sure the KRB5CCNAME is set for non-standard location */
|
||||
diff --git a/gss-genr.c b/gss-genr.c
|
||||
index 3034370c..c357e973 100644
|
||||
--- a/gss-genr.c
|
||||
+++ b/gss-genr.c
|
||||
@@ -168,8 +168,9 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check,
|
||||
enclen = __b64_ntop(digest,
|
||||
ssh_digest_bytes(SSH_DIGEST_MD5), encoded,
|
||||
ssh_digest_bytes(SSH_DIGEST_MD5) * 2);
|
||||
-
|
||||
+#pragma GCC diagnostic ignored "-Wstringop-overflow"
|
||||
cp = strncpy(s, kex, strlen(kex));
|
||||
+#pragma GCC diagnostic pop
|
||||
for ((p = strsep(&cp, ",")); p && *p != '\0';
|
||||
(p = strsep(&cp, ","))) {
|
||||
if (sshbuf_len(buf) != 0 &&
|
||||
diff --git a/krl.c b/krl.c
|
||||
index 0d0f6953..d8517f12 100644
|
||||
--- a/krl.c
|
||||
+++ b/krl.c
|
||||
@@ -1202,6 +1202,7 @@ is_key_revoked(struct ssh_krl *krl, const struct sshkey *key)
|
||||
return r;
|
||||
erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha1s, &rb);
|
||||
free(rb.blob);
|
||||
+ rb.blob = NULL; /* make coverity happy */
|
||||
if (erb != NULL) {
|
||||
KRL_DBG(("revoked by key SHA1"));
|
||||
return SSH_ERR_KEY_REVOKED;
|
||||
@@ -1212,6 +1213,7 @@ is_key_revoked(struct ssh_krl *krl, const struct sshkey *key)
|
||||
return r;
|
||||
erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha256s, &rb);
|
||||
free(rb.blob);
|
||||
+ rb.blob = NULL; /* make coverity happy */
|
||||
if (erb != NULL) {
|
||||
KRL_DBG(("revoked by key SHA256"));
|
||||
return SSH_ERR_KEY_REVOKED;
|
||||
@@ -1223,6 +1225,7 @@ is_key_revoked(struct ssh_krl *krl, const struct sshkey *key)
|
||||
return r;
|
||||
erb = RB_FIND(revoked_blob_tree, &krl->revoked_keys, &rb);
|
||||
free(rb.blob);
|
||||
+ rb.blob = NULL; /* make coverity happy */
|
||||
if (erb != NULL) {
|
||||
KRL_DBG(("revoked by explicit key"));
|
||||
return SSH_ERR_KEY_REVOKED;
|
||||
diff --git a/loginrec.c b/loginrec.c
|
||||
index c4a9bd48..2583612c 100644
|
||||
--- a/loginrec.c
|
||||
+++ b/loginrec.c
|
||||
@@ -683,9 +683,11 @@ construct_utmp(struct logininfo *li,
|
||||
*/
|
||||
|
||||
/* Use strncpy because we don't necessarily want null termination */
|
||||
+ /* coverity[buffer_size_warning : FALSE] */
|
||||
strncpy(ut->ut_name, li->username,
|
||||
MIN_SIZEOF(ut->ut_name, li->username));
|
||||
# ifdef HAVE_HOST_IN_UTMP
|
||||
+ /* coverity[buffer_size_warning : FALSE] */
|
||||
strncpy(ut->ut_host, li->hostname,
|
||||
MIN_SIZEOF(ut->ut_host, li->hostname));
|
||||
# endif
|
||||
diff --git a/misc.c b/misc.c
|
||||
index 09722962..cd71c1b2 100644
|
||||
--- a/misc.c
|
||||
+++ b/misc.c
|
||||
@@ -1556,6 +1556,8 @@ sanitise_stdfd(void)
|
||||
}
|
||||
if (nullfd > STDERR_FILENO)
|
||||
close(nullfd);
|
||||
+ /* coverity[leaked_handle : FALSE]*/
|
||||
+ /* coverity[leaked_handle : FALSE]*/
|
||||
}
|
||||
|
||||
char *
|
||||
@@ -2749,6 +2751,7 @@ stdfd_devnull(int do_stdin, int do_stdout, int do_stderr)
|
||||
}
|
||||
if (devnull > STDERR_FILENO)
|
||||
close(devnull);
|
||||
+ /* coverity[leaked_handle : FALSE]*/
|
||||
return ret;
|
||||
}
|
||||
|
||||
diff --git a/monitor.c b/monitor.c
|
||||
index 19cb058e..58fbac9d 100644
|
||||
--- a/monitor.c
|
||||
+++ b/monitor.c
|
||||
@@ -415,7 +415,7 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor)
|
||||
mm_get_keystate(ssh, pmonitor);
|
||||
|
||||
/* Drain any buffered messages from the child */
|
||||
- while (pmonitor->m_log_recvfd != -1 && monitor_read_log(pmonitor) == 0)
|
||||
+ while (pmonitor->m_log_recvfd >= 0 && monitor_read_log(pmonitor) == 0)
|
||||
;
|
||||
|
||||
if (pmonitor->m_recvfd >= 0)
|
||||
@@ -1813,7 +1813,7 @@ mm_answer_pty(struct ssh *ssh, int sock, struct sshbuf *m)
|
||||
s->ptymaster = s->ptyfd;
|
||||
|
||||
debug3_f("tty %s ptyfd %d", s->tty, s->ttyfd);
|
||||
-
|
||||
+ /* coverity[leaked_handle : FALSE] */
|
||||
return (0);
|
||||
|
||||
error:
|
||||
diff --git a/openbsd-compat/bindresvport.c b/openbsd-compat/bindresvport.c
|
||||
index 346c7fe5..f42792fd 100644
|
||||
--- a/openbsd-compat/bindresvport.c
|
||||
+++ b/openbsd-compat/bindresvport.c
|
||||
@@ -59,7 +59,7 @@ bindresvport_sa(int sd, struct sockaddr *sa)
|
||||
struct sockaddr_in6 *in6;
|
||||
u_int16_t *portp;
|
||||
u_int16_t port;
|
||||
- socklen_t salen;
|
||||
+ socklen_t salen = sizeof(struct sockaddr_storage);
|
||||
int i;
|
||||
|
||||
if (sa == NULL) {
|
||||
diff --git a/openbsd-compat/bsd-pselect.c b/openbsd-compat/bsd-pselect.c
|
||||
index 26bdc3e0..8e2939b9 100644
|
||||
--- a/openbsd-compat/bsd-pselect.c
|
||||
+++ b/openbsd-compat/bsd-pselect.c
|
||||
@@ -85,13 +85,13 @@ pselect_notify_setup(void)
|
||||
static void
|
||||
pselect_notify_parent(void)
|
||||
{
|
||||
- if (notify_pipe[1] != -1)
|
||||
+ if (notify_pipe[1] >= 0)
|
||||
(void)write(notify_pipe[1], "", 1);
|
||||
}
|
||||
static void
|
||||
pselect_notify_prepare(fd_set *readset)
|
||||
{
|
||||
- if (notify_pipe[0] != -1)
|
||||
+ if (notify_pipe[0] >= 0)
|
||||
FD_SET(notify_pipe[0], readset);
|
||||
}
|
||||
static void
|
||||
@@ -99,8 +99,8 @@ pselect_notify_done(fd_set *readset)
|
||||
{
|
||||
char c;
|
||||
|
||||
- if (notify_pipe[0] != -1 && FD_ISSET(notify_pipe[0], readset)) {
|
||||
- while (read(notify_pipe[0], &c, 1) != -1)
|
||||
+ if (notify_pipe[0] >= 0 && FD_ISSET(notify_pipe[0], readset)) {
|
||||
+ while (read(notify_pipe[0], &c, 1) >= 0)
|
||||
debug2_f("reading");
|
||||
FD_CLR(notify_pipe[0], readset);
|
||||
}
|
||||
diff --git a/readconf.c b/readconf.c
|
||||
index ea9d293c..9680c38c 100644
|
||||
--- a/readconf.c
|
||||
+++ b/readconf.c
|
||||
@@ -2164,6 +2164,7 @@ parse_pubkey_algos:
|
||||
} else if (r != 0) {
|
||||
error("%.200s line %d: glob failed for %s.",
|
||||
filename, linenum, arg2);
|
||||
+ free(arg2);
|
||||
goto out;
|
||||
}
|
||||
free(arg2);
|
||||
diff --git a/servconf.c b/servconf.c
|
||||
index 8b708cbf..e7e4ad04 100644
|
||||
--- a/servconf.c
|
||||
+++ b/servconf.c
|
||||
@@ -2293,8 +2293,9 @@ process_server_config_line_depth(ServerOptions *options, char *line,
|
||||
if (*activep && *charptr == NULL) {
|
||||
*charptr = tilde_expand_filename(arg, getuid());
|
||||
/* increase optional counter */
|
||||
- if (intptr != NULL)
|
||||
- *intptr = *intptr + 1;
|
||||
+ /* DEAD CODE intptr is still NULL ;)
|
||||
+ if (intptr != NULL)
|
||||
+ *intptr = *intptr + 1; */
|
||||
}
|
||||
break;
|
||||
|
||||
diff --git a/serverloop.c b/serverloop.c
|
||||
index 9c5b1567..768ee9fa 100644
|
||||
--- a/serverloop.c
|
||||
+++ b/serverloop.c
|
||||
@@ -511,7 +511,7 @@ server_request_tun(struct ssh *ssh)
|
||||
debug_f("invalid tun");
|
||||
goto done;
|
||||
}
|
||||
- if (auth_opts->force_tun_device != -1) {
|
||||
+ if (auth_opts->force_tun_device >= 0) {
|
||||
if (tun != SSH_TUNID_ANY &&
|
||||
auth_opts->force_tun_device != (int)tun)
|
||||
goto done;
|
||||
diff --git a/ssh-agent.c b/ssh-agent.c
|
||||
index 798bf9b6..0e39dff7 100644
|
||||
--- a/ssh-agent.c
|
||||
+++ b/ssh-agent.c
|
||||
@@ -1593,6 +1593,7 @@ sanitize_pkcs11_provider(const char *provider)
|
||||
|
||||
if (pkcs11_uri_parse(provider, uri) != 0) {
|
||||
error("Failed to parse PKCS#11 URI");
|
||||
+ pkcs11_uri_cleanup(uri);
|
||||
return NULL;
|
||||
}
|
||||
/* validate also provider from URI */
|
||||
diff --git a/ssh-keygen.c b/ssh-keygen.c
|
||||
index 792aafde..96b3474d 100644
|
||||
--- a/ssh-keygen.c
|
||||
+++ b/ssh-keygen.c
|
||||
@@ -2424,6 +2424,9 @@ update_krl_from_file(struct passwd *pw, const char *file, int wild_ca,
|
||||
r = ssh_krl_revoke_key_sha256(krl, blob, blen);
|
||||
if (r != 0)
|
||||
fatal_fr(r, "revoke key failed");
|
||||
+ freezero(blob, blen);
|
||||
+ blob = NULL;
|
||||
+ blen = 0;
|
||||
} else {
|
||||
if (strncasecmp(cp, "key:", 4) == 0) {
|
||||
cp += 4;
|
||||
--
|
||||
2.49.0
|
||||
|
||||
2479
2000-openssh-10.0p1-gsissh.patch
Normal file
2479
2000-openssh-10.0p1-gsissh.patch
Normal file
File diff suppressed because it is too large
Load diff
14980
2001-openssh-10.0p1-hpn-18.7.0.patch
Normal file
14980
2001-openssh-10.0p1-hpn-18.7.0.patch
Normal file
File diff suppressed because it is too large
Load diff
2
gsi-openssh-server-systemd-sysusers.conf
Normal file
2
gsi-openssh-server-systemd-sysusers.conf
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#Type Name ID GECOS Home directory Shell
|
||||
u sshd 74 "Privilege-separated SSH" /usr/share/empty.sshd -
|
||||
893
gsi-openssh.spec
893
gsi-openssh.spec
File diff suppressed because it is too large
Load diff
15
gsissh-host-keys-migration.service
Normal file
15
gsissh-host-keys-migration.service
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
[Unit]
|
||||
Description=Update gsissh host key permissions
|
||||
Documentation=https://fedoraproject.org/wiki/Changes/SSHKeySignSuidBit
|
||||
Before=gsisshd.service
|
||||
After=gsissh-keygen.target
|
||||
ConditionPathExists=!/var/lib/.gsissh-host-keys-migration
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=-/usr/libexec/gsissh/ssh-host-keys-migration.sh
|
||||
ExecStart=touch /var/lib/.gsissh-host-keys-migration
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=gsisshd.service
|
||||
36
gsissh-host-keys-migration.sh
Normal file
36
gsissh-host-keys-migration.sh
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#!/usr/bin/bash
|
||||
set -eu -o pipefail
|
||||
# Detect existing non-conforming host keys and perform the permissions migration
|
||||
# https://fedoraproject.org/wiki/Changes/SSHKeySignSuidBit
|
||||
#
|
||||
# Example output looks like:
|
||||
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
# @ WARNING: UNPROTECTED PRIVATE KEY FILE! @
|
||||
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
# Permissions 0640 for '/etc/ssh/ssh_host_rsa_key' are too open.
|
||||
# It is required that your private key files are NOT accessible by others.
|
||||
# This private key will be ignored.
|
||||
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
# @ WARNING: UNPROTECTED PRIVATE KEY FILE! @
|
||||
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
# Permissions 0640 for '/etc/ssh/ssh_host_ecdsa_key' are too open.
|
||||
# It is required that your private key files are NOT accessible by others.
|
||||
# This private key will be ignored.
|
||||
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
# @ WARNING: UNPROTECTED PRIVATE KEY FILE! @
|
||||
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
# Permissions 0640 for '/etc/ssh/ssh_host_ed25519_key' are too open.
|
||||
# It is required that your private key files are NOT accessible by others.
|
||||
# This private key will be ignored.
|
||||
# gsisshd: no hostkeys available -- exiting.
|
||||
#
|
||||
output="$(gsisshd -T 2>&1 || true)" # expected to fail
|
||||
while read line; do
|
||||
if [[ $line =~ ^Permissions\ [0-9]+\ for\ \'(.*)\'\ are\ too\ open. ]]; then
|
||||
keyfile=${BASH_REMATCH[1]}
|
||||
echo $line
|
||||
echo -e "\t-> changing permissions on $keyfile"
|
||||
chmod --verbose g-r $keyfile
|
||||
chown --verbose root:root $keyfile
|
||||
fi
|
||||
done <<< "$output"
|
||||
155
gsisshd-keygen
155
gsisshd-keygen
|
|
@ -1,122 +1,45 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Create the host keys for the gsissh server.
|
||||
#
|
||||
# The creation is controlled by the $AUTOCREATE_SERVER_KEYS environment
|
||||
# variable.
|
||||
AUTOCREATE_SERVER_KEYS=RSAONLY
|
||||
KEYTYPE=$1
|
||||
case $KEYTYPE in
|
||||
"dsa") ;& # disabled in FIPS
|
||||
"ed25519")
|
||||
FIPS=/proc/sys/crypto/fips_enabled
|
||||
if [[ -r "$FIPS" && $(cat $FIPS) == "1" ]]; then
|
||||
exit 0
|
||||
fi ;;
|
||||
"rsa")
|
||||
if [[ ! -z $SSH_RSA_BITS ]]; then
|
||||
SSH_KEYGEN_OPTIONS="-b $SSH_RSA_BITS"
|
||||
fi ;; # always ok
|
||||
"ecdsa")
|
||||
if [[ ! -z $SSH_ECDSA_BITS ]]; then
|
||||
SSH_KEYGEN_OPTIONS="-b $SSH_ECDSA_BITS"
|
||||
fi ;;
|
||||
*) # wrong argument
|
||||
exit 12 ;;
|
||||
esac
|
||||
KEY=/etc/gsissh/ssh_host_${KEYTYPE}_key
|
||||
|
||||
# source function library
|
||||
. /etc/rc.d/init.d/functions
|
||||
|
||||
# Some functions to make the below more readable
|
||||
KEYGEN=/usr/bin/gsissh-keygen
|
||||
RSA1_KEY=/etc/gsissh/ssh_host_key
|
||||
RSA_KEY=/etc/gsissh/ssh_host_rsa_key
|
||||
DSA_KEY=/etc/gsissh/ssh_host_dsa_key
|
||||
ECDSA_KEY=/etc/gsissh/ssh_host_ecdsa_key
|
||||
|
||||
# pull in sysconfig settings
|
||||
[ -f /etc/sysconfig/gsisshd ] && . /etc/sysconfig/gsisshd
|
||||
|
||||
fips_enabled() {
|
||||
if [ -r /proc/sys/crypto/fips_enabled ]; then
|
||||
cat /proc/sys/crypto/fips_enabled
|
||||
else
|
||||
echo 0
|
||||
fi
|
||||
}
|
||||
|
||||
do_rsa1_keygen() {
|
||||
if [ ! -s $RSA1_KEY -a `fips_enabled` -eq 0 ]; then
|
||||
echo -n $"Generating SSH1 RSA host key: "
|
||||
rm -f $RSA1_KEY
|
||||
if test ! -f $RSA1_KEY && $KEYGEN -q -t rsa1 -f $RSA1_KEY -C '' -N '' >&/dev/null; then
|
||||
chgrp ssh_keys $RSA1_KEY
|
||||
chmod 640 $RSA1_KEY
|
||||
chmod 644 $RSA1_KEY.pub
|
||||
if [ -x /sbin/restorecon ]; then
|
||||
/sbin/restorecon $RSA1_KEY.pub
|
||||
fi
|
||||
success $"RSA1 key generation"
|
||||
echo
|
||||
else
|
||||
failure $"RSA1 key generation"
|
||||
echo
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
do_rsa_keygen() {
|
||||
if [ ! -s $RSA_KEY ]; then
|
||||
echo -n $"Generating SSH2 RSA host key: "
|
||||
rm -f $RSA_KEY
|
||||
if test ! -f $RSA_KEY && $KEYGEN -q -t rsa -f $RSA_KEY -C '' -N '' >&/dev/null; then
|
||||
chgrp ssh_keys $RSA_KEY
|
||||
chmod 640 $RSA_KEY
|
||||
chmod 644 $RSA_KEY.pub
|
||||
if [ -x /sbin/restorecon ]; then
|
||||
/sbin/restorecon $RSA_KEY.pub
|
||||
fi
|
||||
success $"RSA key generation"
|
||||
echo
|
||||
else
|
||||
failure $"RSA key generation"
|
||||
echo
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
do_dsa_keygen() {
|
||||
if [ ! -s $DSA_KEY ]; then
|
||||
echo -n $"Generating SSH2 DSA host key: "
|
||||
rm -f $DSA_KEY
|
||||
if test ! -f $DSA_KEY && $KEYGEN -q -t dsa -f $DSA_KEY -C '' -N '' >&/dev/null; then
|
||||
chgrp ssh_keys $DSA_KEY
|
||||
chmod 640 $DSA_KEY
|
||||
chmod 644 $DSA_KEY.pub
|
||||
if [ -x /sbin/restorecon ]; then
|
||||
/sbin/restorecon $DSA_KEY.pub
|
||||
fi
|
||||
success $"DSA key generation"
|
||||
echo
|
||||
else
|
||||
failure $"DSA key generation"
|
||||
echo
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
do_ecdsa_keygen() {
|
||||
if [ ! -s $ECDSA_KEY ]; then
|
||||
echo -n $"Generating SSH2 ECDSA host key: "
|
||||
rm -f $ECDSA_KEY
|
||||
if test ! -f $ECDSA_KEY && $KEYGEN -q -t ecdsa -f $ECDSA_KEY -C '' -N '' >&/dev/null; then
|
||||
chgrp ssh_keys $ECDSA_KEY
|
||||
chmod 600 $ECDSA_KEY
|
||||
chmod 644 $ECDSA_KEY.pub
|
||||
if [ -x /sbin/restorecon ]; then
|
||||
/sbin/restorecon $ECDSA_KEY.pub
|
||||
fi
|
||||
success $"ECDSA key generation"
|
||||
echo
|
||||
else
|
||||
failure $"ECDSA key generation"
|
||||
echo
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Create keys if necessary
|
||||
if [ "x${AUTOCREATE_SERVER_KEYS}" != xNO ]; then
|
||||
do_rsa_keygen
|
||||
if [ "x${AUTOCREATE_SERVER_KEYS}" != xRSAONLY ]; then
|
||||
do_rsa1_keygen
|
||||
do_dsa_keygen
|
||||
do_ecdsa_keygen
|
||||
fi
|
||||
if [[ ! -x $KEYGEN ]]; then
|
||||
exit 13
|
||||
fi
|
||||
|
||||
# remove old keys
|
||||
rm -f $KEY{,.pub}
|
||||
|
||||
# create new keys
|
||||
if ! $KEYGEN -q -t $KEYTYPE $SSH_KEYGEN_OPTIONS -f $KEY -C '' -N '' >&/dev/null; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# sanitize permissions
|
||||
/usr/bin/chmod 600 $KEY
|
||||
/usr/bin/chmod 644 $KEY.pub
|
||||
if [[ -x /usr/sbin/restorecon ]]; then
|
||||
/usr/sbin/restorecon $KEY{,.pub}
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
[Unit]
|
||||
Description=gsissh Server Key Generation
|
||||
ConditionPathExists=|!/etc/gsissh/ssh_host_rsa_key
|
||||
ConditionPathExists=|!/etc/gsissh/ssh_host_dsa_key
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/sbin/gsisshd-keygen
|
||||
Type=oneshot
|
||||
5
gsisshd-keygen.target
Normal file
5
gsisshd-keygen.target
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
[Unit]
|
||||
Wants=gsisshd-keygen@rsa.service
|
||||
Wants=gsisshd-keygen@ecdsa.service
|
||||
Wants=gsisshd-keygen@ed25519.service
|
||||
PartOf=gsisshd.service
|
||||
14
gsisshd-keygen@.service
Normal file
14
gsisshd-keygen@.service
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
[Unit]
|
||||
Description=gsissh %i Server Key Generation
|
||||
ConditionFileNotEmpty=|!/etc/gsissh/ssh_host_%i_key
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
# Set option as empty variable to suppress warnings upon expanding the command line
|
||||
# when the config file under /etc does not exist or is empty.
|
||||
Environment=OPTIONS=
|
||||
EnvironmentFile=-/etc/sysconfig/gsisshd
|
||||
ExecStart=/usr/libexec/gsissh/sshd-keygen %i
|
||||
|
||||
[Install]
|
||||
WantedBy=gsisshd-keygen.target
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
#%PAM-1.0
|
||||
auth required pam_sepermit.so
|
||||
auth substack password-auth
|
||||
auth include postlogin
|
||||
account required pam_sepermit.so
|
||||
account required pam_nologin.so
|
||||
account include password-auth
|
||||
password include password-auth
|
||||
|
|
@ -10,6 +10,8 @@ session required pam_selinux.so close
|
|||
session required pam_loginuid.so
|
||||
# pam_selinux.so open should only be followed by sessions to be executed in the user context
|
||||
session required pam_selinux.so open env_params
|
||||
session required pam_namespace.so
|
||||
session optional pam_keyinit.so force revoke
|
||||
session optional pam_motd.so
|
||||
session include password-auth
|
||||
session include postlogin
|
||||
|
|
|
|||
|
|
@ -1,10 +1,18 @@
|
|||
[Unit]
|
||||
Description=gsissh server daemon
|
||||
After=syslog.target network.target auditd.service
|
||||
Documentation=man:gsisshd(8) man:gsisshd_config(5)
|
||||
After=network.target gsisshd-keygen.target
|
||||
Wants=gsisshd-keygen.target
|
||||
# Migration for Fedora 38 change to remove group ownership for standard host keys
|
||||
# See https://fedoraproject.org/wiki/Changes/SSHKeySignSuidBit
|
||||
Wants=gsissh-host-keys-migration.service
|
||||
|
||||
[Service]
|
||||
EnvironmentFile=/etc/sysconfig/gsisshd
|
||||
ExecStartPre=/usr/sbin/gsisshd-keygen
|
||||
Type=notify
|
||||
# Set option as empty variable to suppress warnings upon expanding the command line
|
||||
# when the config file under /etc does not exist or is empty.
|
||||
Environment=OPTIONS=
|
||||
EnvironmentFile=-/etc/sysconfig/gsisshd
|
||||
ExecStart=/usr/sbin/gsisshd -D $OPTIONS
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
KillMode=process
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
[Unit]
|
||||
Description=gsissh Server Socket
|
||||
Documentation=man:gsisshd(8) man:gsisshd_config(5)
|
||||
Conflicts=gsisshd.service
|
||||
|
||||
[Socket]
|
||||
|
|
|
|||
|
|
@ -1,15 +1,11 @@
|
|||
# Configuration file for the sshd service.
|
||||
# Configuration file for the gsisshd service.
|
||||
|
||||
# The server keys are automatically generated if they ommited
|
||||
# to change the automatic creation uncomment the approprite
|
||||
# line. The default is RSAONLY
|
||||
# The server keys are automatically generated if they are missing.
|
||||
# To change the automatic creation, adjust gsisshd.service options for
|
||||
# example using systemctl enable gsisshd-keygen@dsa.service to allow creation
|
||||
# of DSA key or systemctl mask gsisshd-keygen@rsa.service to disable RSA key
|
||||
# creation.
|
||||
|
||||
# AUTOCREATE_SERVER_KEYS=RSAONLY
|
||||
# AUTOCREATE_SERVER_KEYS=NO
|
||||
# AUTOCREATE_SERVER_KEYS=YES
|
||||
|
||||
# Do not change this option unless you have hardware random
|
||||
# generator and you REALLY know what you are doing
|
||||
|
||||
SSH_USE_STRONG_RNG=0
|
||||
# SSH_USE_STRONG_RNG=1
|
||||
#SSH_RSA_BITS=3072
|
||||
#SSH_ECDSA_BITS=256
|
||||
OPTIONS=""
|
||||
|
|
|
|||
|
|
@ -1,9 +1,18 @@
|
|||
[Unit]
|
||||
Description=gsissh per-connection server daemon
|
||||
Wants=gsisshd-keygen.service
|
||||
After=auditd.service gsisshd-keygen.service
|
||||
Documentation=man:gsisshd(8) man:gsisshd_config(5)
|
||||
Wants=gsisshd-keygen.target
|
||||
After=gsisshd-keygen.target
|
||||
# Migration for Fedora 38 change to remove group ownership for standard host keys
|
||||
# See https://fedoraproject.org/wiki/Changes/SSHKeySignSuidBit
|
||||
Wants=gsissh-host-keys-migration.service
|
||||
|
||||
[Service]
|
||||
# Set option as empty variable to suppress warnings upon expanding the command line
|
||||
# when the config file under /etc does not exist or is empty.
|
||||
Environment=OPTIONS=
|
||||
EnvironmentFile=-/etc/sysconfig/gsisshd
|
||||
ExecStart=-/usr/sbin/gsisshd -i $OPTIONS
|
||||
ExecStart=-/usr/sbin/gsisshd -i $OPTIONS -o "AuthorizedKeysFile ${CREDENTIALS_DIRECTORY}/ssh.ephemeral-authorized_keys-all .ssh/authorized_keys"
|
||||
StandardInput=socket
|
||||
ImportCredential=ssh.ephemeral-authorized_keys-all
|
||||
|
|
|
|||
|
|
@ -1,18 +0,0 @@
|
|||
--- openssh-4.3p2/contrib/gnome-ssh-askpass2.c.grab-info 2006-07-17 15:10:11.000000000 +0200
|
||||
+++ openssh-4.3p2/contrib/gnome-ssh-askpass2.c 2006-07-17 15:25:04.000000000 +0200
|
||||
@@ -65,9 +65,12 @@
|
||||
err = gtk_message_dialog_new(NULL, 0,
|
||||
GTK_MESSAGE_ERROR,
|
||||
GTK_BUTTONS_CLOSE,
|
||||
- "Could not grab %s. "
|
||||
- "A malicious client may be eavesdropping "
|
||||
- "on your session.", what);
|
||||
+ "SSH password dialog could not grab the %s input.\n"
|
||||
+ "This might be caused by application such as screensaver, "
|
||||
+ "however it could also mean that someone may be eavesdropping "
|
||||
+ "on your session.\n"
|
||||
+ "Either close the application which grabs the %s or "
|
||||
+ "log out and log in again to prevent this from happening.", what, what);
|
||||
gtk_window_set_position(GTK_WINDOW(err), GTK_WIN_POS_CENTER);
|
||||
gtk_label_set_line_wrap(GTK_LABEL((GTK_MESSAGE_DIALOG(err))->label),
|
||||
TRUE);
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
diff -up openssh-5.1p1/contrib/gnome-ssh-askpass2.c.progress openssh-5.1p1/contrib/gnome-ssh-askpass2.c
|
||||
--- openssh-5.1p1/contrib/gnome-ssh-askpass2.c.progress 2008-07-23 19:05:26.000000000 +0200
|
||||
+++ openssh-5.1p1/contrib/gnome-ssh-askpass2.c 2008-07-23 19:05:26.000000000 +0200
|
||||
@@ -53,6 +53,7 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <X11/Xlib.h>
|
||||
+#include <glib.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
|
||||
@@ -83,13 +84,24 @@ ok_dialog(GtkWidget *entry, gpointer dia
|
||||
gtk_dialog_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
|
||||
}
|
||||
|
||||
+static void
|
||||
+move_progress(GtkWidget *entry, gpointer progress)
|
||||
+{
|
||||
+ gdouble step;
|
||||
+ g_return_if_fail(GTK_IS_PROGRESS_BAR(progress));
|
||||
+
|
||||
+ step = g_random_double_range(0.03, 0.1);
|
||||
+ gtk_progress_bar_set_pulse_step(GTK_PROGRESS_BAR(progress), step);
|
||||
+ gtk_progress_bar_pulse(GTK_PROGRESS_BAR(progress));
|
||||
+}
|
||||
+
|
||||
static int
|
||||
passphrase_dialog(char *message)
|
||||
{
|
||||
const char *failed;
|
||||
char *passphrase, *local;
|
||||
int result, grab_tries, grab_server, grab_pointer;
|
||||
- GtkWidget *dialog, *entry;
|
||||
+ GtkWidget *dialog, *entry, *progress, *hbox;
|
||||
GdkGrabStatus status;
|
||||
|
||||
grab_server = (getenv("GNOME_SSH_ASKPASS_GRAB_SERVER") != NULL);
|
||||
@@ -102,13 +114,31 @@ passphrase_dialog(char *message)
|
||||
"%s",
|
||||
message);
|
||||
|
||||
+ hbox = gtk_hbox_new(FALSE, 0);
|
||||
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE,
|
||||
+ FALSE, 0);
|
||||
+ gtk_widget_show(hbox);
|
||||
+
|
||||
entry = gtk_entry_new();
|
||||
- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), entry, FALSE,
|
||||
+ gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE,
|
||||
FALSE, 0);
|
||||
+ gtk_entry_set_width_chars(GTK_ENTRY(entry), 2);
|
||||
gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
|
||||
gtk_widget_grab_focus(entry);
|
||||
gtk_widget_show(entry);
|
||||
|
||||
+ hbox = gtk_hbox_new(FALSE, 0);
|
||||
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE,
|
||||
+ FALSE, 8);
|
||||
+ gtk_widget_show(hbox);
|
||||
+
|
||||
+ progress = gtk_progress_bar_new();
|
||||
+
|
||||
+ gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress), "Passphrase length hidden intentionally");
|
||||
+ gtk_box_pack_start(GTK_BOX(hbox), progress, TRUE,
|
||||
+ TRUE, 5);
|
||||
+ gtk_widget_show(progress);
|
||||
+
|
||||
gtk_window_set_title(GTK_WINDOW(dialog), "OpenSSH");
|
||||
gtk_window_set_position (GTK_WINDOW(dialog), GTK_WIN_POS_CENTER);
|
||||
gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE);
|
||||
@@ -119,6 +149,8 @@ passphrase_dialog(char *message)
|
||||
gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
|
||||
g_signal_connect(G_OBJECT(entry), "activate",
|
||||
G_CALLBACK(ok_dialog), dialog);
|
||||
+ g_signal_connect(G_OBJECT(entry), "changed",
|
||||
+ G_CALLBACK(move_progress), progress);
|
||||
|
||||
gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE);
|
||||
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
diff -up openssh-5.1p1/scp.1.manpage openssh-5.1p1/scp.1
|
||||
--- openssh-5.1p1/scp.1.manpage 2008-07-12 09:12:49.000000000 +0200
|
||||
+++ openssh-5.1p1/scp.1 2008-07-23 19:18:15.000000000 +0200
|
||||
@@ -66,6 +66,14 @@ treating file names containing
|
||||
as host specifiers.
|
||||
Copies between two remote hosts are also permitted.
|
||||
.Pp
|
||||
+When copying a source file to a target file which already exists,
|
||||
+.Nm
|
||||
+will replace the contents of the target file (keeping the inode).
|
||||
+.Pp
|
||||
+If the target file does not yet exist, an empty file with the target
|
||||
+file name is created, then filled with the source file contents.
|
||||
+No attempt is made at "near-atomic" transfer using temporary files.
|
||||
+.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl 1
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
diff -up openssh-5.2p1/canohost.c.ip-opts openssh-5.2p1/canohost.c
|
||||
--- openssh-5.2p1/canohost.c.ip-opts 2009-02-14 06:28:21.000000000 +0100
|
||||
+++ openssh-5.2p1/canohost.c 2009-09-01 15:31:29.000000000 +0200
|
||||
@@ -169,12 +169,27 @@ check_ip_options(int sock, char *ipaddr)
|
||||
option_size = sizeof(options);
|
||||
if (getsockopt(sock, ipproto, IP_OPTIONS, options,
|
||||
&option_size) >= 0 && option_size != 0) {
|
||||
- text[0] = '\0';
|
||||
- for (i = 0; i < option_size; i++)
|
||||
- snprintf(text + i*3, sizeof(text) - i*3,
|
||||
- " %2.2x", options[i]);
|
||||
- fatal("Connection from %.100s with IP options:%.800s",
|
||||
- ipaddr, text);
|
||||
+ i = 0;
|
||||
+ do {
|
||||
+ switch (options[i]) {
|
||||
+ case 0:
|
||||
+ case 1:
|
||||
+ ++i;
|
||||
+ break;
|
||||
+ case 131:
|
||||
+ case 137:
|
||||
+ /* Fail, fatally, if we detect either loose or strict
|
||||
+ * source routing options. */
|
||||
+ text[0] = '\0';
|
||||
+ for (i = 0; i < option_size; i++)
|
||||
+ snprintf(text + i*3, sizeof(text) - i*3,
|
||||
+ " %2.2x", options[i]);
|
||||
+ fatal("Connection from %.100s with IP options:%.800s",
|
||||
+ ipaddr, text);
|
||||
+ default:
|
||||
+ i += options[i + 1];
|
||||
+ }
|
||||
+ } while (i < option_size);
|
||||
}
|
||||
#endif /* IP_OPTIONS */
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
diff -up openssh-5.6p1/channels.c.exit-deadlock openssh-5.6p1/channels.c
|
||||
--- openssh-5.6p1/channels.c.exit-deadlock 2010-08-05 15:09:48.000000000 +0200
|
||||
+++ openssh-5.6p1/channels.c 2010-08-23 12:41:43.000000000 +0200
|
||||
@@ -1647,6 +1647,10 @@ channel_handle_wfd(Channel *c, fd_set *r
|
||||
u_int dlen, olen = 0;
|
||||
int len;
|
||||
|
||||
+ if(c->wfd != -1 && buffer_len(&c->output) > 0 && c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
|
||||
+ debug("channel %d: forcing write", c->self);
|
||||
+ FD_SET(c->wfd, writeset);
|
||||
+ }
|
||||
/* Send buffered output data to the socket. */
|
||||
if (c->wfd != -1 &&
|
||||
FD_ISSET(c->wfd, writeset) &&
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
diff -up openssh-5.6p1/channels.c.getaddrinfo openssh-5.6p1/channels.c
|
||||
--- openssh-5.6p1/channels.c.getaddrinfo 2012-02-14 16:12:54.427852524 +0100
|
||||
+++ openssh-5.6p1/channels.c 2012-02-14 16:13:22.818928690 +0100
|
||||
@@ -3275,6 +3275,9 @@ x11_create_display_inet(int x11_display_
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = IPv4or6;
|
||||
hints.ai_flags = x11_use_localhost ? 0: AI_PASSIVE;
|
||||
+#ifdef AI_ADDRCONFIG
|
||||
+ hints.ai_flags |= AI_ADDRCONFIG;
|
||||
+#endif
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
snprintf(strport, sizeof strport, "%d", port);
|
||||
if ((gaierr = getaddrinfo(NULL, strport, &hints, &aitop)) != 0) {
|
||||
diff -up openssh-5.6p1/sshconnect.c.getaddrinfo openssh-5.6p1/sshconnect.c
|
||||
--- openssh-5.6p1/sshconnect.c.getaddrinfo 2012-02-14 16:09:25.057964291 +0100
|
||||
+++ openssh-5.6p1/sshconnect.c 2012-02-14 16:09:25.106047007 +0100
|
||||
@@ -343,6 +343,7 @@ ssh_connect(const char *host, struct soc
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = family;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
+ hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG;
|
||||
snprintf(strport, sizeof strport, "%u", port);
|
||||
if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0)
|
||||
fatal("%s: Could not resolve hostname %.100s: %s", __progname,
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
diff -up openssh-5.8p1/sftp-glob.c.glob openssh-5.8p1/sftp-glob.c
|
||||
--- openssh-5.8p1/sftp-glob.c.glob 2011-03-07 20:17:34.000000000 +0100
|
||||
+++ openssh-5.8p1/sftp-glob.c 2011-03-07 20:18:47.000000000 +0100
|
||||
@@ -145,5 +145,5 @@ remote_glob(struct sftp_conn *conn, cons
|
||||
memset(&cur, 0, sizeof(cur));
|
||||
cur.conn = conn;
|
||||
|
||||
- return(glob(pattern, flags | GLOB_ALTDIRFUNC, errfunc, pglob));
|
||||
+ return(glob(pattern, flags | GLOB_LIMIT | GLOB_ALTDIRFUNC, errfunc, pglob));
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
diff -up openssh-5.8p1/authfile.c.keyperm openssh-5.8p1/authfile.c
|
||||
--- openssh-5.8p1/authfile.c.keyperm 2010-12-01 02:03:39.000000000 +0100
|
||||
+++ openssh-5.8p1/authfile.c 2011-04-21 16:43:36.859648916 +0200
|
||||
@@ -57,6 +57,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
+#include <grp.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "cipher.h"
|
||||
@@ -600,6 +612,13 @@ key_perm_ok(int fd, const char *filename
|
||||
#ifdef HAVE_CYGWIN
|
||||
if (check_ntsec(filename))
|
||||
#endif
|
||||
+ if (st.st_mode & 040) {
|
||||
+ struct group *gr;
|
||||
+
|
||||
+ if ((gr = getgrnam("ssh_keys")) && (st.st_gid == gr->gr_gid))
|
||||
+ st.st_mode &= ~040;
|
||||
+ }
|
||||
+
|
||||
if ((st.st_uid == getuid()) && (st.st_mode & 077) != 0) {
|
||||
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
|
||||
error("@ WARNING: UNPROTECTED PRIVATE KEY FILE! @");
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
diff -up openssh-5.8p1/sshd_config.localdomain openssh-5.8p1/sshd_config
|
||||
--- openssh-5.8p1/sshd_config.localdomain 2011-04-22 11:37:49.273648812 +0200
|
||||
+++ openssh-5.8p1/sshd_config 2011-04-22 11:39:31.758648401 +0200
|
||||
@@ -130,6 +130,10 @@ X11Forwarding yes
|
||||
# override default of no subsystems
|
||||
Subsystem sftp /usr/libexec/sftp-server
|
||||
|
||||
+# Uncomment this if you want to use .local domain
|
||||
+#Host *.local
|
||||
+# CheckHostIP no
|
||||
+
|
||||
# Example of overriding settings on a per-user basis
|
||||
#Match User anoncvs
|
||||
# X11Forwarding no
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
diff -up openssh-5.8p1/packet.c.packet openssh-5.8p1/packet.c
|
||||
--- openssh-5.8p1/packet.c.packet 2011-04-05 13:29:06.998648899 +0200
|
||||
+++ openssh-5.8p1/packet.c 2011-04-05 13:30:32.967648596 +0200
|
||||
@@ -294,6 +294,8 @@ packet_connection_is_on_socket(void)
|
||||
struct sockaddr_storage from, to;
|
||||
socklen_t fromlen, tolen;
|
||||
|
||||
+ if (!active_state)
|
||||
+ return 0;
|
||||
/* filedescriptors in and out are the same, so it's a socket */
|
||||
if (active_state->connection_in == active_state->connection_out)
|
||||
return 1;
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
diff -up openssh-5.8p2/mux.c.remove_stale openssh-5.8p2/mux.c
|
||||
--- openssh-5.8p2/mux.c.remove_stale 2011-01-14 02:01:32.000000000 +0100
|
||||
+++ openssh-5.8p2/mux.c 2011-06-09 15:27:42.556360291 +0200
|
||||
@@ -1867,6 +1867,9 @@ muxclient(const char *path)
|
||||
unlink(path);
|
||||
} else if (errno == ENOENT) {
|
||||
debug("Control socket \"%.100s\" does not exist", path);
|
||||
+ } else if (errno == ECONNREFUSED) {
|
||||
+ debug("Removing stale control socket \"%.100s\"", path);
|
||||
+ unlink(path);
|
||||
} else {
|
||||
error("Control socket connect(%.100s): %s", path,
|
||||
strerror(errno));
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
diff -up openssh-5.8p2/ssh-keyscan.c.sigpipe openssh-5.8p2/ssh-keyscan.c
|
||||
--- openssh-5.8p2/ssh-keyscan.c.sigpipe 2011-08-23 18:30:33.873025916 +0200
|
||||
+++ openssh-5.8p2/ssh-keyscan.c 2011-08-23 18:32:24.574025362 +0200
|
||||
@@ -715,6 +715,8 @@ main(int argc, char **argv)
|
||||
fdlim_set(maxfd);
|
||||
fdcon = xcalloc(maxfd, sizeof(con));
|
||||
|
||||
+ signal(SIGPIPE, SIG_IGN);
|
||||
+
|
||||
read_wait_nfdset = howmany(maxfd, NFDBITS);
|
||||
read_wait = xcalloc(read_wait_nfdset, sizeof(fd_mask));
|
||||
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
diff -up openssh-5.9p1/dns.c.edns openssh-5.9p1/dns.c
|
||||
--- openssh-5.9p1/dns.c.edns 2010-08-31 14:41:14.000000000 +0200
|
||||
+++ openssh-5.9p1/dns.c 2011-09-09 08:05:27.782440497 +0200
|
||||
@@ -177,6 +177,7 @@ verify_host_key_dns(const char *hostname
|
||||
{
|
||||
u_int counter;
|
||||
int result;
|
||||
+ unsigned int rrset_flags = 0;
|
||||
struct rrsetinfo *fingerprints = NULL;
|
||||
|
||||
u_int8_t hostkey_algorithm;
|
||||
@@ -200,8 +201,19 @@ verify_host_key_dns(const char *hostname
|
||||
return -1;
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * Original getrrsetbyname function, found on OpenBSD for example,
|
||||
+ * doesn't accept any flag and prerequisite for obtaining AD bit in
|
||||
+ * DNS response is set by "options edns0" in resolv.conf.
|
||||
+ *
|
||||
+ * Our version is more clever and use RRSET_FORCE_EDNS0 flag.
|
||||
+ */
|
||||
+#ifndef HAVE_GETRRSETBYNAME
|
||||
+ rrset_flags |= RRSET_FORCE_EDNS0;
|
||||
+#endif
|
||||
result = getrrsetbyname(hostname, DNS_RDATACLASS_IN,
|
||||
- DNS_RDATATYPE_SSHFP, 0, &fingerprints);
|
||||
+ DNS_RDATATYPE_SSHFP, rrset_flags, &fingerprints);
|
||||
+
|
||||
if (result) {
|
||||
verbose("DNS lookup error: %s", dns_result_totext(result));
|
||||
return -1;
|
||||
diff -up openssh-5.9p1/openbsd-compat/getrrsetbyname.c.edns openssh-5.9p1/openbsd-compat/getrrsetbyname.c
|
||||
--- openssh-5.9p1/openbsd-compat/getrrsetbyname.c.edns 2009-07-13 03:38:23.000000000 +0200
|
||||
+++ openssh-5.9p1/openbsd-compat/getrrsetbyname.c 2011-09-09 15:03:39.930500801 +0200
|
||||
@@ -209,8 +209,8 @@ getrrsetbyname(const char *hostname, uns
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- /* don't allow flags yet, unimplemented */
|
||||
- if (flags) {
|
||||
+ /* Allow RRSET_FORCE_EDNS0 flag only. */
|
||||
+ if ((flags & ~RRSET_FORCE_EDNS0) != 0) {
|
||||
result = ERRSET_INVAL;
|
||||
goto fail;
|
||||
}
|
||||
@@ -226,9 +226,9 @@ getrrsetbyname(const char *hostname, uns
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifdef RES_USE_DNSSEC
|
||||
- /* turn on DNSSEC if EDNS0 is configured */
|
||||
- if (_resp->options & RES_USE_EDNS0)
|
||||
- _resp->options |= RES_USE_DNSSEC;
|
||||
+ /* turn on DNSSEC if required */
|
||||
+ if (flags & RRSET_FORCE_EDNS0)
|
||||
+ _resp->options |= (RES_USE_EDNS0|RES_USE_DNSSEC);
|
||||
#endif /* RES_USE_DNSEC */
|
||||
|
||||
/* make query */
|
||||
diff -up openssh-5.9p1/openbsd-compat/getrrsetbyname.h.edns openssh-5.9p1/openbsd-compat/getrrsetbyname.h
|
||||
--- openssh-5.9p1/openbsd-compat/getrrsetbyname.h.edns 2007-10-26 08:26:50.000000000 +0200
|
||||
+++ openssh-5.9p1/openbsd-compat/getrrsetbyname.h 2011-09-09 08:05:27.965438689 +0200
|
||||
@@ -72,6 +72,9 @@
|
||||
#ifndef RRSET_VALIDATED
|
||||
# define RRSET_VALIDATED 1
|
||||
#endif
|
||||
+#ifndef RRSET_FORCE_EDNS0
|
||||
+# define RRSET_FORCE_EDNS0 0x0001
|
||||
+#endif
|
||||
|
||||
/*
|
||||
* Return codes for getrrsetbyname()
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
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");
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
diff -up openssh-6.1p1/contrib/Makefile.askpass-ld openssh-6.1p1/contrib/Makefile
|
||||
--- openssh-6.1p1/contrib/Makefile.askpass-ld 2012-05-19 07:24:37.000000000 +0200
|
||||
+++ openssh-6.1p1/contrib/Makefile 2012-09-14 20:35:47.565704718 +0200
|
||||
@@ -4,12 +4,12 @@ all:
|
||||
@echo "Valid targets: gnome-ssh-askpass1 gnome-ssh-askpass2"
|
||||
|
||||
gnome-ssh-askpass1: gnome-ssh-askpass1.c
|
||||
- $(CC) `gnome-config --cflags gnome gnomeui` \
|
||||
+ $(CC) ${CFLAGS} `gnome-config --cflags gnome gnomeui` \
|
||||
gnome-ssh-askpass1.c -o gnome-ssh-askpass1 \
|
||||
`gnome-config --libs gnome gnomeui`
|
||||
|
||||
gnome-ssh-askpass2: gnome-ssh-askpass2.c
|
||||
- $(CC) `$(PKG_CONFIG) --cflags gtk+-2.0` \
|
||||
+ $(CC) ${CFLAGS} `$(PKG_CONFIG) --cflags gtk+-2.0` \
|
||||
gnome-ssh-askpass2.c -o gnome-ssh-askpass2 \
|
||||
`$(PKG_CONFIG) --libs gtk+-2.0 x11`
|
||||
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
diff -up openssh-6.1p1/sshconnect2.c.canohost openssh-6.1p1/sshconnect2.c
|
||||
--- openssh-6.1p1/sshconnect2.c.canohost 2012-10-30 10:52:59.593301692 +0100
|
||||
+++ openssh-6.1p1/sshconnect2.c 2012-10-30 11:01:12.870301632 +0100
|
||||
@@ -699,12 +699,15 @@ userauth_gssapi(Authctxt *authctxt)
|
||||
static u_int mech = 0;
|
||||
OM_uint32 min;
|
||||
int ok = 0;
|
||||
- const char *gss_host;
|
||||
+ const char *gss_host = NULL;
|
||||
|
||||
if (options.gss_server_identity)
|
||||
gss_host = options.gss_server_identity;
|
||||
- else if (options.gss_trust_dns)
|
||||
+ else if (options.gss_trust_dns) {
|
||||
gss_host = get_canonical_hostname(1);
|
||||
+ if ( strcmp( gss_host, "UNKNOWN" ) == 0 )
|
||||
+ gss_host = authctxt->host;
|
||||
+ }
|
||||
else
|
||||
gss_host = authctxt->host;
|
||||
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
diff -up openssh-6.1p1/sshd.c.log-usepam-no openssh-6.1p1/sshd.c
|
||||
--- openssh-6.1p1/sshd.c.log-usepam-no 2012-09-14 20:54:58.000000000 +0200
|
||||
+++ openssh-6.1p1/sshd.c 2012-09-14 20:55:42.289477749 +0200
|
||||
@@ -1617,6 +1617,10 @@ main(int ac, char **av)
|
||||
parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name,
|
||||
&cfg, NULL);
|
||||
|
||||
+ /* 'UsePAM no' is not supported in Fedora */
|
||||
+ if (! options.use_pam)
|
||||
+ logit("WARNING: 'UsePAM no' is not supported in Fedora and may cause several problems.");
|
||||
+
|
||||
seed_rng();
|
||||
|
||||
/* Fill in default values for those options not explicitly set. */
|
||||
diff -up openssh-6.1p1/sshd_config.log-usepam-no openssh-6.1p1/sshd_config
|
||||
--- openssh-6.1p1/sshd_config.log-usepam-no 2012-09-14 20:54:58.514255748 +0200
|
||||
+++ openssh-6.1p1/sshd_config 2012-09-14 20:54:58.551255954 +0200
|
||||
@@ -95,6 +95,8 @@ GSSAPICleanupCredentials yes
|
||||
# If you just want the PAM account and session checks to run without
|
||||
# PAM authentication, then enable this but set PasswordAuthentication
|
||||
# and ChallengeResponseAuthentication to 'no'.
|
||||
+# WARNING: 'UsePAM no' is not supported in Fedora and may cause several
|
||||
+# problems.
|
||||
#UsePAM no
|
||||
UsePAM yes
|
||||
|
||||
|
|
@ -1,271 +0,0 @@
|
|||
diff -up openssh-6.2p1/entropy.c.entropy openssh-6.2p1/entropy.c
|
||||
--- openssh-6.2p1/entropy.c.entropy 2013-03-25 19:31:42.737611051 +0100
|
||||
+++ openssh-6.2p1/entropy.c 2013-03-25 19:31:42.797611433 +0100
|
||||
@@ -237,6 +237,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-6.2p1/openbsd-compat/Makefile.in.entropy openssh-6.2p1/openbsd-compat/Makefile.in
|
||||
--- openssh-6.2p1/openbsd-compat/Makefile.in.entropy 2013-03-25 19:31:42.798611440 +0100
|
||||
+++ openssh-6.2p1/openbsd-compat/Makefile.in 2013-03-25 19:33:02.042116876 +0100
|
||||
@@ -20,7 +20,7 @@ OPENBSD=base64.o basename.o bindresvport
|
||||
|
||||
COMPAT=bsd-arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.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-6.2p1/openbsd-compat/port-linux-prng.c.entropy openssh-6.2p1/openbsd-compat/port-linux-prng.c
|
||||
--- openssh-6.2p1/openbsd-compat/port-linux-prng.c.entropy 2013-03-25 19:31:42.798611440 +0100
|
||||
+++ openssh-6.2p1/openbsd-compat/port-linux-prng.c 2013-03-25 19:31:42.798611440 +0100
|
||||
@@ -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 = 14;
|
||||
+
|
||||
+ if (!env || !strcmp(env, "0"))
|
||||
+ random = "/dev/urandom";
|
||||
+ else if ((ienv = atoi(env)) > randlen)
|
||||
+ 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-6.2p1/ssh-add.0.entropy openssh-6.2p1/ssh-add.0
|
||||
--- openssh-6.2p1/ssh-add.0.entropy 2013-03-22 00:38:29.000000000 +0100
|
||||
+++ openssh-6.2p1/ssh-add.0 2013-03-25 19:31:42.799611446 +0100
|
||||
@@ -82,6 +82,16 @@ ENVIRONMENT
|
||||
Identifies the path of a UNIX-domain socket used to communicate
|
||||
with the agent.
|
||||
|
||||
+ SSH_USE_STRONG_RNG
|
||||
+ The reseeding of the OpenSSL random generator is usually done
|
||||
+ from /dev/urandom. If the SSH_USE_STRONG_RNG environment vari-
|
||||
+ able is set to value other than 0 the OpenSSL random generator is
|
||||
+ reseeded from /dev/random. The number of bytes read is defined
|
||||
+ by the SSH_USE_STRONG_RNG value. Minimum is 14 bytes. This set-
|
||||
+ ting is not recommended on the computers without the hardware
|
||||
+ random generator because insufficient entropy causes the connec-
|
||||
+ tion to be blocked until enough entropy is available.
|
||||
+
|
||||
FILES
|
||||
~/.ssh/identity
|
||||
Contains the protocol version 1 RSA authentication identity of
|
||||
diff -up openssh-6.2p1/ssh-add.1.entropy openssh-6.2p1/ssh-add.1
|
||||
--- openssh-6.2p1/ssh-add.1.entropy 2012-12-07 03:06:13.000000000 +0100
|
||||
+++ openssh-6.2p1/ssh-add.1 2013-03-25 19:31:42.799611446 +0100
|
||||
@@ -160,6 +160,20 @@ to make this work.)
|
||||
Identifies the path of a
|
||||
.Ux Ns -domain
|
||||
socket used to communicate with the agent.
|
||||
+.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 14 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
|
||||
diff -up openssh-6.2p1/ssh-agent.1.entropy openssh-6.2p1/ssh-agent.1
|
||||
--- openssh-6.2p1/ssh-agent.1.entropy 2010-12-01 01:50:35.000000000 +0100
|
||||
+++ openssh-6.2p1/ssh-agent.1 2013-03-25 19:31:42.800611452 +0100
|
||||
@@ -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 14 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-6.2p1/sshd.8.entropy openssh-6.2p1/sshd.8
|
||||
--- openssh-6.2p1/sshd.8.entropy 2013-03-25 19:31:42.752611146 +0100
|
||||
+++ openssh-6.2p1/sshd.8 2013-03-25 19:31:42.800611452 +0100
|
||||
@@ -945,6 +945,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 14 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
|
||||
diff -up openssh-6.2p1/ssh-keygen.1.entropy openssh-6.2p1/ssh-keygen.1
|
||||
--- openssh-6.2p1/ssh-keygen.1.entropy 2013-01-20 12:35:06.000000000 +0100
|
||||
+++ openssh-6.2p1/ssh-keygen.1 2013-03-25 19:31:42.801611459 +0100
|
||||
@@ -806,6 +806,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 14 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-6.2p1/ssh-keysign.8.entropy openssh-6.2p1/ssh-keysign.8
|
||||
--- openssh-6.2p1/ssh-keysign.8.entropy 2010-08-31 14:41:14.000000000 +0200
|
||||
+++ openssh-6.2p1/ssh-keysign.8 2013-03-25 19:31:42.801611459 +0100
|
||||
@@ -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 14 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-6.2p1/ssh.1.entropy openssh-6.2p1/ssh.1
|
||||
--- openssh-6.2p1/ssh.1.entropy 2013-03-25 19:31:42.752611146 +0100
|
||||
+++ openssh-6.2p1/ssh.1 2013-03-25 19:31:42.799611446 +0100
|
||||
@@ -1277,6 +1277,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 14 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
|
||||
|
|
@ -1,158 +0,0 @@
|
|||
diff -up openssh-6.2p1/configure.ac.vendor openssh-6.2p1/configure.ac
|
||||
--- openssh-6.2p1/configure.ac.vendor 2013-03-25 19:34:01.277495179 +0100
|
||||
+++ openssh-6.2p1/configure.ac 2013-03-25 19:34:01.377495818 +0100
|
||||
@@ -4420,6 +4420,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
|
||||
@@ -4681,6 +4687,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-6.2p1/servconf.c.vendor openssh-6.2p1/servconf.c
|
||||
--- openssh-6.2p1/servconf.c.vendor 2013-03-25 19:34:01.197494668 +0100
|
||||
+++ openssh-6.2p1/servconf.c 2013-03-25 19:34:01.379495831 +0100
|
||||
@@ -128,6 +128,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;
|
||||
@@ -287,6 +288,9 @@ fill_default_server_options(ServerOption
|
||||
options->ip_qos_bulk = IPTOS_THROUGHPUT;
|
||||
if (options->version_addendum == NULL)
|
||||
options->version_addendum = xstrdup("");
|
||||
+ if (options->show_patchlevel == -1)
|
||||
+ options->show_patchlevel = 0;
|
||||
+
|
||||
/* Turn privilege separation on by default */
|
||||
if (use_privsep == -1)
|
||||
use_privsep = PRIVSEP_NOSANDBOX;
|
||||
@@ -324,7 +328,7 @@ typedef enum {
|
||||
sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
|
||||
sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
|
||||
sMaxStartups, sMaxAuthTries, sMaxSessions,
|
||||
- sBanner, sUseDNS, sHostbasedAuthentication,
|
||||
+ sBanner, sShowPatchLevel, sUseDNS, sHostbasedAuthentication,
|
||||
sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
|
||||
sClientAliveCountMax, sAuthorizedKeysFile,
|
||||
sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
|
||||
@@ -439,6 +443,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 },
|
||||
@@ -1163,6 +1168,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)
|
||||
@@ -1950,6 +1959,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-6.2p1/servconf.h.vendor openssh-6.2p1/servconf.h
|
||||
--- openssh-6.2p1/servconf.h.vendor 2013-01-09 05:56:45.000000000 +0100
|
||||
+++ openssh-6.2p1/servconf.h 2013-03-25 19:34:01.379495831 +0100
|
||||
@@ -147,6 +147,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-6.2p1/sshd_config.vendor openssh-6.2p1/sshd_config
|
||||
--- openssh-6.2p1/sshd_config.vendor 2013-03-25 19:34:01.380495837 +0100
|
||||
+++ openssh-6.2p1/sshd_config 2013-03-25 19:44:43.471296362 +0100
|
||||
@@ -118,6 +118,7 @@ UsePrivilegeSeparation sandbox # Defaul
|
||||
#Compression delayed
|
||||
#ClientAliveInterval 0
|
||||
#ClientAliveCountMax 3
|
||||
+#ShowPatchLevel no
|
||||
#UseDNS yes
|
||||
#PidFile /var/run/sshd.pid
|
||||
#MaxStartups 10:30:100
|
||||
diff -up openssh-6.2p1/sshd_config.0.vendor openssh-6.2p1/sshd_config.0
|
||||
--- openssh-6.2p1/sshd_config.0.vendor 2013-03-25 19:34:01.361495716 +0100
|
||||
+++ openssh-6.2p1/sshd_config.0 2013-03-25 19:34:01.381495844 +0100
|
||||
@@ -595,6 +595,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-6.2p1/sshd_config.5.vendor openssh-6.2p1/sshd_config.5
|
||||
--- openssh-6.2p1/sshd_config.5.vendor 2013-03-25 19:34:01.362495722 +0100
|
||||
+++ openssh-6.2p1/sshd_config.5 2013-03-25 19:34:01.382495850 +0100
|
||||
@@ -1019,6 +1019,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-6.2p1/sshd.c.vendor openssh-6.2p1/sshd.c
|
||||
--- openssh-6.2p1/sshd.c.vendor 2013-03-25 19:34:01.332495531 +0100
|
||||
+++ openssh-6.2p1/sshd.c 2013-03-25 19:44:11.864112092 +0100
|
||||
@@ -442,7 +442,7 @@ sshd_exchange_identification(int sock_in
|
||||
}
|
||||
|
||||
xasprintf(&server_version_string, "SSH-%d.%d-%.100s%s%s%s",
|
||||
- major, minor, SSH_VERSION,
|
||||
+ major, minor, (options.show_patchlevel == 1) ? SSH_VENDOR_PATCHLEVEL : SSH_VERSION,
|
||||
*options.version_addendum == '\0' ? "" : " ",
|
||||
options.version_addendum, newline);
|
||||
|
||||
@@ -1675,7 +1675,8 @@ main(int ac, char **av)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
- debug("sshd version %s, %s", SSH_VERSION,
|
||||
+ debug("sshd version %s, %s",
|
||||
+ (options.show_patchlevel == 1) ? SSH_VENDOR_PATCHLEVEL : SSH_VERSION,
|
||||
SSLeay_version(SSLEAY_VERSION));
|
||||
|
||||
/* Store privilege separation user for later use if required. */
|
||||
|
|
@ -1,788 +0,0 @@
|
|||
diff -up openssh-6.3p1/auth-pam.c.coverity openssh-6.3p1/auth-pam.c
|
||||
--- openssh-6.3p1/auth-pam.c.coverity 2013-06-02 00:07:32.000000000 +0200
|
||||
+++ openssh-6.3p1/auth-pam.c 2013-10-07 13:20:36.288298063 +0200
|
||||
@@ -216,7 +216,12 @@ pthread_join(sp_pthread_t thread, void *
|
||||
if (sshpam_thread_status != -1)
|
||||
return (sshpam_thread_status);
|
||||
signal(SIGCHLD, sshpam_oldsig);
|
||||
- waitpid(thread, &status, 0);
|
||||
+ while (waitpid(thread, &status, 0) < 0) {
|
||||
+ if (errno == EINTR)
|
||||
+ continue;
|
||||
+ fatal("%s: waitpid: %s", __func__,
|
||||
+ strerror(errno));
|
||||
+ }
|
||||
return (status);
|
||||
}
|
||||
#endif
|
||||
diff -up openssh-6.3p1/channels.c.coverity openssh-6.3p1/channels.c
|
||||
--- openssh-6.3p1/channels.c.coverity 2013-09-13 08:19:31.000000000 +0200
|
||||
+++ openssh-6.3p1/channels.c 2013-10-07 13:20:36.289298058 +0200
|
||||
@@ -233,11 +233,11 @@ channel_register_fds(Channel *c, int rfd
|
||||
channel_max_fd = MAX(channel_max_fd, wfd);
|
||||
channel_max_fd = MAX(channel_max_fd, efd);
|
||||
|
||||
- if (rfd != -1)
|
||||
+ if (rfd >= 0)
|
||||
fcntl(rfd, F_SETFD, FD_CLOEXEC);
|
||||
- if (wfd != -1 && wfd != rfd)
|
||||
+ if (wfd >= 0 && wfd != rfd)
|
||||
fcntl(wfd, F_SETFD, FD_CLOEXEC);
|
||||
- if (efd != -1 && efd != rfd && efd != wfd)
|
||||
+ if (efd >= 0 && efd != rfd && efd != wfd)
|
||||
fcntl(efd, F_SETFD, FD_CLOEXEC);
|
||||
|
||||
c->rfd = rfd;
|
||||
@@ -255,11 +255,11 @@ channel_register_fds(Channel *c, int rfd
|
||||
|
||||
/* enable nonblocking mode */
|
||||
if (nonblock) {
|
||||
- if (rfd != -1)
|
||||
+ if (rfd >= 0)
|
||||
set_nonblock(rfd);
|
||||
- if (wfd != -1)
|
||||
+ if (wfd >= 0)
|
||||
set_nonblock(wfd);
|
||||
- if (efd != -1)
|
||||
+ if (efd >= 0)
|
||||
set_nonblock(efd);
|
||||
}
|
||||
}
|
||||
diff -up openssh-6.3p1/clientloop.c.coverity openssh-6.3p1/clientloop.c
|
||||
--- openssh-6.3p1/clientloop.c.coverity 2013-06-10 05:07:12.000000000 +0200
|
||||
+++ openssh-6.3p1/clientloop.c 2013-10-07 13:20:36.289298058 +0200
|
||||
@@ -2068,14 +2068,15 @@ client_input_global_request(int type, u_
|
||||
char *rtype;
|
||||
int want_reply;
|
||||
int success = 0;
|
||||
+/* success is still 0 the packet is allways SSH2_MSG_REQUEST_FAILURE, isn't it? */
|
||||
|
||||
rtype = packet_get_string(NULL);
|
||||
want_reply = packet_get_char();
|
||||
debug("client_input_global_request: rtype %s want_reply %d",
|
||||
rtype, want_reply);
|
||||
if (want_reply) {
|
||||
- packet_start(success ?
|
||||
- SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE);
|
||||
+ packet_start(/*success ?
|
||||
+ SSH2_MSG_REQUEST_SUCCESS :*/ SSH2_MSG_REQUEST_FAILURE);
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
}
|
||||
diff -up openssh-6.3p1/key.c.coverity openssh-6.3p1/key.c
|
||||
--- openssh-6.3p1/key.c.coverity 2013-06-01 23:41:51.000000000 +0200
|
||||
+++ openssh-6.3p1/key.c 2013-10-07 13:20:36.290298054 +0200
|
||||
@@ -807,8 +807,10 @@ key_read(Key *ret, char **cpp)
|
||||
success = 1;
|
||||
/*XXXX*/
|
||||
key_free(k);
|
||||
+/*XXXX
|
||||
if (success != 1)
|
||||
break;
|
||||
+XXXX*/
|
||||
/* advance cp: skip whitespace and data */
|
||||
while (*cp == ' ' || *cp == '\t')
|
||||
cp++;
|
||||
diff -up openssh-6.3p1/monitor.c.coverity openssh-6.3p1/monitor.c
|
||||
--- openssh-6.3p1/monitor.c.coverity 2013-07-20 05:21:53.000000000 +0200
|
||||
+++ openssh-6.3p1/monitor.c 2013-10-07 13:54:36.761314042 +0200
|
||||
@@ -449,7 +449,7 @@ monitor_child_preauth(Authctxt *_authctx
|
||||
mm_get_keystate(pmonitor);
|
||||
|
||||
/* Drain any buffered messages from the child */
|
||||
- while (pmonitor->m_log_recvfd != -1 && monitor_read_log(pmonitor) == 0)
|
||||
+ while (pmonitor->m_log_recvfd >= 0 && monitor_read_log(pmonitor) == 0)
|
||||
;
|
||||
|
||||
close(pmonitor->m_sendfd);
|
||||
@@ -1202,6 +1202,10 @@ mm_answer_keyallowed(int sock, Buffer *m
|
||||
break;
|
||||
}
|
||||
}
|
||||
+
|
||||
+ debug3("%s: key %p is %s",
|
||||
+ __func__, key, allowed ? "allowed" : "not allowed");
|
||||
+
|
||||
if (key != NULL)
|
||||
key_free(key);
|
||||
|
||||
@@ -1223,9 +1227,6 @@ mm_answer_keyallowed(int sock, Buffer *m
|
||||
free(chost);
|
||||
}
|
||||
|
||||
- debug3("%s: key %p is %s",
|
||||
- __func__, key, allowed ? "allowed" : "not allowed");
|
||||
-
|
||||
buffer_clear(m);
|
||||
buffer_put_int(m, allowed);
|
||||
buffer_put_int(m, forced_command != NULL);
|
||||
diff -up openssh-6.3p1/monitor_wrap.c.coverity openssh-6.3p1/monitor_wrap.c
|
||||
--- openssh-6.3p1/monitor_wrap.c.coverity 2013-06-02 00:07:32.000000000 +0200
|
||||
+++ openssh-6.3p1/monitor_wrap.c 2013-10-07 13:20:36.291298049 +0200
|
||||
@@ -710,10 +710,10 @@ mm_pty_allocate(int *ptyfd, int *ttyfd,
|
||||
if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 ||
|
||||
(tmp2 = dup(pmonitor->m_recvfd)) == -1) {
|
||||
error("%s: cannot allocate fds for pty", __func__);
|
||||
- if (tmp1 > 0)
|
||||
+ if (tmp1 >= 0)
|
||||
close(tmp1);
|
||||
- if (tmp2 > 0)
|
||||
- close(tmp2);
|
||||
+ /*DEAD CODE if (tmp2 >= 0)
|
||||
+ close(tmp2);*/
|
||||
return 0;
|
||||
}
|
||||
close(tmp1);
|
||||
diff -up openssh-6.3p1/openbsd-compat/bindresvport.c.coverity openssh-6.3p1/openbsd-compat/bindresvport.c
|
||||
--- openssh-6.3p1/openbsd-compat/bindresvport.c.coverity 2010-12-03 00:50:26.000000000 +0100
|
||||
+++ openssh-6.3p1/openbsd-compat/bindresvport.c 2013-10-07 13:20:36.291298049 +0200
|
||||
@@ -58,7 +58,7 @@ bindresvport_sa(int sd, struct sockaddr
|
||||
struct sockaddr_in6 *in6;
|
||||
u_int16_t *portp;
|
||||
u_int16_t port;
|
||||
- socklen_t salen;
|
||||
+ socklen_t salen = sizeof(struct sockaddr_storage);
|
||||
int i;
|
||||
|
||||
if (sa == NULL) {
|
||||
diff -up openssh-6.3p1/packet.c.coverity openssh-6.3p1/packet.c
|
||||
--- openssh-6.3p1/packet.c.coverity 2013-07-18 08:12:45.000000000 +0200
|
||||
+++ openssh-6.3p1/packet.c 2013-10-07 13:20:36.291298049 +0200
|
||||
@@ -1199,6 +1199,7 @@ packet_read_poll1(void)
|
||||
case DEATTACK_DETECTED:
|
||||
packet_disconnect("crc32 compensation attack: "
|
||||
"network attack detected");
|
||||
+ break;
|
||||
case DEATTACK_DOS_DETECTED:
|
||||
packet_disconnect("deattack denial of "
|
||||
"service detected");
|
||||
diff -up openssh-6.3p1/progressmeter.c.coverity openssh-6.3p1/progressmeter.c
|
||||
--- openssh-6.3p1/progressmeter.c.coverity 2013-06-02 15:46:24.000000000 +0200
|
||||
+++ openssh-6.3p1/progressmeter.c 2013-10-07 13:42:32.377850691 +0200
|
||||
@@ -65,7 +65,7 @@ static void update_progress_meter(int);
|
||||
|
||||
static time_t start; /* start progress */
|
||||
static time_t last_update; /* last progress update */
|
||||
-static char *file; /* name of the file being transferred */
|
||||
+static const char *file; /* name of the file being transferred */
|
||||
static off_t end_pos; /* ending position of transfer */
|
||||
static off_t cur_pos; /* transfer position as of last refresh */
|
||||
static volatile off_t *counter; /* progress counter */
|
||||
@@ -247,7 +247,7 @@ update_progress_meter(int ignore)
|
||||
}
|
||||
|
||||
void
|
||||
-start_progress_meter(char *f, off_t filesize, off_t *ctr)
|
||||
+start_progress_meter(const char *f, off_t filesize, off_t *ctr)
|
||||
{
|
||||
start = last_update = monotime();
|
||||
file = f;
|
||||
diff -up openssh-6.3p1/progressmeter.h.coverity openssh-6.3p1/progressmeter.h
|
||||
--- openssh-6.3p1/progressmeter.h.coverity 2006-03-26 05:30:02.000000000 +0200
|
||||
+++ openssh-6.3p1/progressmeter.h 2013-10-07 13:20:36.292298044 +0200
|
||||
@@ -23,5 +23,5 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
-void start_progress_meter(char *, off_t, off_t *);
|
||||
+void start_progress_meter(const char *, off_t, off_t *);
|
||||
void stop_progress_meter(void);
|
||||
diff -up openssh-6.3p1/scp.c.coverity openssh-6.3p1/scp.c
|
||||
--- openssh-6.3p1/scp.c.coverity 2013-07-18 08:11:25.000000000 +0200
|
||||
+++ openssh-6.3p1/scp.c 2013-10-07 13:20:36.292298044 +0200
|
||||
@@ -155,7 +155,7 @@ killchild(int signo)
|
||||
{
|
||||
if (do_cmd_pid > 1) {
|
||||
kill(do_cmd_pid, signo ? signo : SIGTERM);
|
||||
- waitpid(do_cmd_pid, NULL, 0);
|
||||
+ (void) waitpid(do_cmd_pid, NULL, 0);
|
||||
}
|
||||
|
||||
if (signo)
|
||||
diff -up openssh-6.3p1/servconf.c.coverity openssh-6.3p1/servconf.c
|
||||
--- openssh-6.3p1/servconf.c.coverity 2013-07-20 05:21:53.000000000 +0200
|
||||
+++ openssh-6.3p1/servconf.c 2013-10-07 13:20:36.293298039 +0200
|
||||
@@ -1323,7 +1323,7 @@ process_server_config_line(ServerOptions
|
||||
fatal("%s line %d: Missing subsystem name.",
|
||||
filename, linenum);
|
||||
if (!*activep) {
|
||||
- arg = strdelim(&cp);
|
||||
+ /*arg =*/ (void) strdelim(&cp);
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < options->num_subsystems; i++)
|
||||
@@ -1414,8 +1414,9 @@ process_server_config_line(ServerOptions
|
||||
if (*activep && *charptr == NULL) {
|
||||
*charptr = tilde_expand_filename(arg, getuid());
|
||||
/* increase optional counter */
|
||||
- if (intptr != NULL)
|
||||
- *intptr = *intptr + 1;
|
||||
+ /* DEAD CODE intptr is still NULL ;)
|
||||
+ if (intptr != NULL)
|
||||
+ *intptr = *intptr + 1; */
|
||||
}
|
||||
break;
|
||||
|
||||
diff -up openssh-6.3p1/serverloop.c.coverity openssh-6.3p1/serverloop.c
|
||||
--- openssh-6.3p1/serverloop.c.coverity 2013-07-18 08:12:45.000000000 +0200
|
||||
+++ openssh-6.3p1/serverloop.c 2013-10-07 13:43:36.620537138 +0200
|
||||
@@ -147,13 +147,13 @@ notify_setup(void)
|
||||
static void
|
||||
notify_parent(void)
|
||||
{
|
||||
- if (notify_pipe[1] != -1)
|
||||
+ if (notify_pipe[1] >= 0)
|
||||
(void)write(notify_pipe[1], "", 1);
|
||||
}
|
||||
static void
|
||||
notify_prepare(fd_set *readset)
|
||||
{
|
||||
- if (notify_pipe[0] != -1)
|
||||
+ if (notify_pipe[0] >= 0)
|
||||
FD_SET(notify_pipe[0], readset);
|
||||
}
|
||||
static void
|
||||
@@ -161,8 +161,8 @@ notify_done(fd_set *readset)
|
||||
{
|
||||
char c;
|
||||
|
||||
- if (notify_pipe[0] != -1 && FD_ISSET(notify_pipe[0], readset))
|
||||
- while (read(notify_pipe[0], &c, 1) != -1)
|
||||
+ if (notify_pipe[0] >= 0 && FD_ISSET(notify_pipe[0], readset))
|
||||
+ while (read(notify_pipe[0], &c, 1) >= 0)
|
||||
debug2("notify_done: reading");
|
||||
}
|
||||
|
||||
@@ -336,7 +336,7 @@ wait_until_can_do_something(fd_set **rea
|
||||
* If we have buffered data, try to write some of that data
|
||||
* to the program.
|
||||
*/
|
||||
- if (fdin != -1 && buffer_len(&stdin_buffer) > 0)
|
||||
+ if (fdin >= 0 && buffer_len(&stdin_buffer) > 0)
|
||||
FD_SET(fdin, *writesetp);
|
||||
}
|
||||
notify_prepare(*readsetp);
|
||||
@@ -476,7 +476,7 @@ process_output(fd_set *writeset)
|
||||
int len;
|
||||
|
||||
/* Write buffered data to program stdin. */
|
||||
- if (!compat20 && fdin != -1 && FD_ISSET(fdin, writeset)) {
|
||||
+ if (!compat20 && fdin >= 0 && FD_ISSET(fdin, writeset)) {
|
||||
data = buffer_ptr(&stdin_buffer);
|
||||
dlen = buffer_len(&stdin_buffer);
|
||||
len = write(fdin, data, dlen);
|
||||
@@ -589,7 +589,7 @@ server_loop(pid_t pid, int fdin_arg, int
|
||||
set_nonblock(fdin);
|
||||
set_nonblock(fdout);
|
||||
/* we don't have stderr for interactive terminal sessions, see below */
|
||||
- if (fderr != -1)
|
||||
+ if (fderr >= 0)
|
||||
set_nonblock(fderr);
|
||||
|
||||
if (!(datafellows & SSH_BUG_IGNOREMSG) && isatty(fdin))
|
||||
@@ -613,7 +613,7 @@ server_loop(pid_t pid, int fdin_arg, int
|
||||
max_fd = MAX(connection_in, connection_out);
|
||||
max_fd = MAX(max_fd, fdin);
|
||||
max_fd = MAX(max_fd, fdout);
|
||||
- if (fderr != -1)
|
||||
+ if (fderr >= 0)
|
||||
max_fd = MAX(max_fd, fderr);
|
||||
#endif
|
||||
|
||||
@@ -643,7 +643,7 @@ server_loop(pid_t pid, int fdin_arg, int
|
||||
* If we have received eof, and there is no more pending
|
||||
* input data, cause a real eof by closing fdin.
|
||||
*/
|
||||
- if (stdin_eof && fdin != -1 && buffer_len(&stdin_buffer) == 0) {
|
||||
+ if (stdin_eof && fdin >= 0 && buffer_len(&stdin_buffer) == 0) {
|
||||
if (fdin != fdout)
|
||||
close(fdin);
|
||||
else
|
||||
@@ -739,15 +739,15 @@ server_loop(pid_t pid, int fdin_arg, int
|
||||
buffer_free(&stderr_buffer);
|
||||
|
||||
/* Close the file descriptors. */
|
||||
- if (fdout != -1)
|
||||
+ if (fdout >= 0)
|
||||
close(fdout);
|
||||
fdout = -1;
|
||||
fdout_eof = 1;
|
||||
- if (fderr != -1)
|
||||
+ if (fderr >= 0)
|
||||
close(fderr);
|
||||
fderr = -1;
|
||||
fderr_eof = 1;
|
||||
- if (fdin != -1)
|
||||
+ if (fdin >= 0)
|
||||
close(fdin);
|
||||
fdin = -1;
|
||||
|
||||
@@ -946,7 +946,7 @@ server_input_window_size(int type, u_int
|
||||
|
||||
debug("Window change received.");
|
||||
packet_check_eom();
|
||||
- if (fdin != -1)
|
||||
+ if (fdin >= 0)
|
||||
pty_change_window_size(fdin, row, col, xpixel, ypixel);
|
||||
}
|
||||
|
||||
@@ -1006,7 +1006,7 @@ server_request_tun(void)
|
||||
}
|
||||
|
||||
tun = packet_get_int();
|
||||
- if (forced_tun_device != -1) {
|
||||
+ if (forced_tun_device >= 0) {
|
||||
if (tun != SSH_TUNID_ANY && forced_tun_device != tun)
|
||||
goto done;
|
||||
tun = forced_tun_device;
|
||||
diff -up openssh-6.3p1/sftp-client.c.coverity openssh-6.3p1/sftp-client.c
|
||||
--- openssh-6.3p1/sftp-client.c.coverity 2013-07-26 00:40:00.000000000 +0200
|
||||
+++ openssh-6.3p1/sftp-client.c 2013-10-07 13:48:45.885027420 +0200
|
||||
@@ -149,7 +149,7 @@ get_msg(struct sftp_conn *conn, Buffer *
|
||||
}
|
||||
|
||||
static void
|
||||
-send_string_request(struct sftp_conn *conn, u_int id, u_int code, char *s,
|
||||
+send_string_request(struct sftp_conn *conn, u_int id, u_int code, const char *s,
|
||||
u_int len)
|
||||
{
|
||||
Buffer msg;
|
||||
@@ -165,7 +165,7 @@ send_string_request(struct sftp_conn *co
|
||||
|
||||
static void
|
||||
send_string_attrs_request(struct sftp_conn *conn, u_int id, u_int code,
|
||||
- char *s, u_int len, Attrib *a)
|
||||
+ const char *s, u_int len, Attrib *a)
|
||||
{
|
||||
Buffer msg;
|
||||
|
||||
@@ -422,7 +422,7 @@ sftp_proto_version(struct sftp_conn *con
|
||||
}
|
||||
|
||||
int
|
||||
-do_close(struct sftp_conn *conn, char *handle, u_int handle_len)
|
||||
+do_close(struct sftp_conn *conn, const char *handle, u_int handle_len)
|
||||
{
|
||||
u_int id, status;
|
||||
Buffer msg;
|
||||
@@ -447,7 +447,7 @@ do_close(struct sftp_conn *conn, char *h
|
||||
|
||||
|
||||
static int
|
||||
-do_lsreaddir(struct sftp_conn *conn, char *path, int printflag,
|
||||
+do_lsreaddir(struct sftp_conn *conn, const char *path, int printflag,
|
||||
SFTP_DIRENT ***dir)
|
||||
{
|
||||
Buffer msg;
|
||||
@@ -572,7 +572,7 @@ do_lsreaddir(struct sftp_conn *conn, cha
|
||||
}
|
||||
|
||||
int
|
||||
-do_readdir(struct sftp_conn *conn, char *path, SFTP_DIRENT ***dir)
|
||||
+do_readdir(struct sftp_conn *conn, const char *path, SFTP_DIRENT ***dir)
|
||||
{
|
||||
return(do_lsreaddir(conn, path, 0, dir));
|
||||
}
|
||||
@@ -590,7 +590,7 @@ void free_sftp_dirents(SFTP_DIRENT **s)
|
||||
}
|
||||
|
||||
int
|
||||
-do_rm(struct sftp_conn *conn, char *path)
|
||||
+do_rm(struct sftp_conn *conn, const char *path)
|
||||
{
|
||||
u_int status, id;
|
||||
|
||||
@@ -605,7 +605,7 @@ do_rm(struct sftp_conn *conn, char *path
|
||||
}
|
||||
|
||||
int
|
||||
-do_mkdir(struct sftp_conn *conn, char *path, Attrib *a, int printflag)
|
||||
+do_mkdir(struct sftp_conn *conn, const char *path, Attrib *a, int printflag)
|
||||
{
|
||||
u_int status, id;
|
||||
|
||||
@@ -621,7 +621,7 @@ do_mkdir(struct sftp_conn *conn, char *p
|
||||
}
|
||||
|
||||
int
|
||||
-do_rmdir(struct sftp_conn *conn, char *path)
|
||||
+do_rmdir(struct sftp_conn *conn, const char *path)
|
||||
{
|
||||
u_int status, id;
|
||||
|
||||
@@ -637,7 +637,7 @@ do_rmdir(struct sftp_conn *conn, char *p
|
||||
}
|
||||
|
||||
Attrib *
|
||||
-do_stat(struct sftp_conn *conn, char *path, int quiet)
|
||||
+do_stat(struct sftp_conn *conn, const char *path, int quiet)
|
||||
{
|
||||
u_int id;
|
||||
|
||||
@@ -651,7 +651,7 @@ do_stat(struct sftp_conn *conn, char *pa
|
||||
}
|
||||
|
||||
Attrib *
|
||||
-do_lstat(struct sftp_conn *conn, char *path, int quiet)
|
||||
+do_lstat(struct sftp_conn *conn, const char *path, int quiet)
|
||||
{
|
||||
u_int id;
|
||||
|
||||
@@ -685,7 +685,7 @@ do_fstat(struct sftp_conn *conn, char *h
|
||||
#endif
|
||||
|
||||
int
|
||||
-do_setstat(struct sftp_conn *conn, char *path, Attrib *a)
|
||||
+do_setstat(struct sftp_conn *conn, const char *path, Attrib *a)
|
||||
{
|
||||
u_int status, id;
|
||||
|
||||
@@ -702,7 +702,7 @@ do_setstat(struct sftp_conn *conn, char
|
||||
}
|
||||
|
||||
int
|
||||
-do_fsetstat(struct sftp_conn *conn, char *handle, u_int handle_len,
|
||||
+do_fsetstat(struct sftp_conn *conn, const char *handle, u_int handle_len,
|
||||
Attrib *a)
|
||||
{
|
||||
u_int status, id;
|
||||
@@ -719,7 +719,7 @@ do_fsetstat(struct sftp_conn *conn, char
|
||||
}
|
||||
|
||||
char *
|
||||
-do_realpath(struct sftp_conn *conn, char *path)
|
||||
+do_realpath(struct sftp_conn *conn, const char *path)
|
||||
{
|
||||
Buffer msg;
|
||||
u_int type, expected_id, count, id;
|
||||
@@ -768,7 +768,7 @@ do_realpath(struct sftp_conn *conn, char
|
||||
}
|
||||
|
||||
int
|
||||
-do_rename(struct sftp_conn *conn, char *oldpath, char *newpath)
|
||||
+do_rename(struct sftp_conn *conn, const char *oldpath, const char *newpath)
|
||||
{
|
||||
Buffer msg;
|
||||
u_int status, id;
|
||||
@@ -802,7 +802,7 @@ do_rename(struct sftp_conn *conn, char *
|
||||
}
|
||||
|
||||
int
|
||||
-do_hardlink(struct sftp_conn *conn, char *oldpath, char *newpath)
|
||||
+do_hardlink(struct sftp_conn *conn, const char *oldpath, const char *newpath)
|
||||
{
|
||||
Buffer msg;
|
||||
u_int status, id;
|
||||
@@ -835,7 +835,7 @@ do_hardlink(struct sftp_conn *conn, char
|
||||
}
|
||||
|
||||
int
|
||||
-do_symlink(struct sftp_conn *conn, char *oldpath, char *newpath)
|
||||
+do_symlink(struct sftp_conn *conn, const char *oldpath, const char *newpath)
|
||||
{
|
||||
Buffer msg;
|
||||
u_int status, id;
|
||||
@@ -987,7 +987,7 @@ send_read_request(struct sftp_conn *conn
|
||||
}
|
||||
|
||||
int
|
||||
-do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
|
||||
+do_download(struct sftp_conn *conn, const char *remote_path, const char *local_path,
|
||||
Attrib *a, int pflag, int resume)
|
||||
{
|
||||
Attrib junk;
|
||||
@@ -1255,7 +1255,7 @@ do_download(struct sftp_conn *conn, char
|
||||
}
|
||||
|
||||
static int
|
||||
-download_dir_internal(struct sftp_conn *conn, char *src, char *dst,
|
||||
+download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
|
||||
Attrib *dirattrib, int pflag, int printflag, int depth, int resume)
|
||||
{
|
||||
int i, ret = 0;
|
||||
@@ -1345,7 +1345,7 @@ download_dir_internal(struct sftp_conn *
|
||||
}
|
||||
|
||||
int
|
||||
-download_dir(struct sftp_conn *conn, char *src, char *dst,
|
||||
+download_dir(struct sftp_conn *conn, const char *src, const char *dst,
|
||||
Attrib *dirattrib, int pflag, int printflag, int resume)
|
||||
{
|
||||
char *src_canon;
|
||||
@@ -1363,7 +1363,7 @@ download_dir(struct sftp_conn *conn, cha
|
||||
}
|
||||
|
||||
int
|
||||
-do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
|
||||
+do_upload(struct sftp_conn *conn, const char *local_path, const char *remote_path,
|
||||
int pflag)
|
||||
{
|
||||
int local_fd;
|
||||
@@ -1548,7 +1548,7 @@ do_upload(struct sftp_conn *conn, char *
|
||||
}
|
||||
|
||||
static int
|
||||
-upload_dir_internal(struct sftp_conn *conn, char *src, char *dst,
|
||||
+upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
|
||||
int pflag, int printflag, int depth)
|
||||
{
|
||||
int ret = 0, status;
|
||||
@@ -1639,7 +1639,7 @@ upload_dir_internal(struct sftp_conn *co
|
||||
}
|
||||
|
||||
int
|
||||
-upload_dir(struct sftp_conn *conn, char *src, char *dst, int printflag,
|
||||
+upload_dir(struct sftp_conn *conn, const char *src, const char *dst, int printflag,
|
||||
int pflag)
|
||||
{
|
||||
char *dst_canon;
|
||||
@@ -1656,7 +1656,7 @@ upload_dir(struct sftp_conn *conn, char
|
||||
}
|
||||
|
||||
char *
|
||||
-path_append(char *p1, char *p2)
|
||||
+path_append(const char *p1, const char *p2)
|
||||
{
|
||||
char *ret;
|
||||
size_t len = strlen(p1) + strlen(p2) + 2;
|
||||
diff -up openssh-6.3p1/sftp-client.h.coverity openssh-6.3p1/sftp-client.h
|
||||
--- openssh-6.3p1/sftp-client.h.coverity 2013-07-25 03:56:52.000000000 +0200
|
||||
+++ openssh-6.3p1/sftp-client.h 2013-10-07 13:45:10.108080813 +0200
|
||||
@@ -56,49 +56,49 @@ struct sftp_conn *do_init(int, int, u_in
|
||||
u_int sftp_proto_version(struct sftp_conn *);
|
||||
|
||||
/* Close file referred to by 'handle' */
|
||||
-int do_close(struct sftp_conn *, char *, u_int);
|
||||
+int do_close(struct sftp_conn *, const char *, u_int);
|
||||
|
||||
/* Read contents of 'path' to NULL-terminated array 'dir' */
|
||||
-int do_readdir(struct sftp_conn *, char *, SFTP_DIRENT ***);
|
||||
+int do_readdir(struct sftp_conn *, const char *, SFTP_DIRENT ***);
|
||||
|
||||
/* Frees a NULL-terminated array of SFTP_DIRENTs (eg. from do_readdir) */
|
||||
void free_sftp_dirents(SFTP_DIRENT **);
|
||||
|
||||
/* Delete file 'path' */
|
||||
-int do_rm(struct sftp_conn *, char *);
|
||||
+int do_rm(struct sftp_conn *, const char *);
|
||||
|
||||
/* Create directory 'path' */
|
||||
-int do_mkdir(struct sftp_conn *, char *, Attrib *, int);
|
||||
+int do_mkdir(struct sftp_conn *, const char *, Attrib *, int);
|
||||
|
||||
/* Remove directory 'path' */
|
||||
-int do_rmdir(struct sftp_conn *, char *);
|
||||
+int do_rmdir(struct sftp_conn *, const char *);
|
||||
|
||||
/* Get file attributes of 'path' (follows symlinks) */
|
||||
-Attrib *do_stat(struct sftp_conn *, char *, int);
|
||||
+Attrib *do_stat(struct sftp_conn *, const char *, int);
|
||||
|
||||
/* Get file attributes of 'path' (does not follow symlinks) */
|
||||
-Attrib *do_lstat(struct sftp_conn *, char *, int);
|
||||
+Attrib *do_lstat(struct sftp_conn *, const char *, int);
|
||||
|
||||
/* Set file attributes of 'path' */
|
||||
-int do_setstat(struct sftp_conn *, char *, Attrib *);
|
||||
+int do_setstat(struct sftp_conn *, const char *, Attrib *);
|
||||
|
||||
/* Set file attributes of open file 'handle' */
|
||||
-int do_fsetstat(struct sftp_conn *, char *, u_int, Attrib *);
|
||||
+int do_fsetstat(struct sftp_conn *, const char *, u_int, Attrib *);
|
||||
|
||||
/* Canonicalise 'path' - caller must free result */
|
||||
-char *do_realpath(struct sftp_conn *, char *);
|
||||
+char *do_realpath(struct sftp_conn *, const char *);
|
||||
|
||||
/* Get statistics for filesystem hosting file at "path" */
|
||||
int do_statvfs(struct sftp_conn *, const char *, struct sftp_statvfs *, int);
|
||||
|
||||
/* Rename 'oldpath' to 'newpath' */
|
||||
-int do_rename(struct sftp_conn *, char *, char *);
|
||||
+int do_rename(struct sftp_conn *, const char *, const char *);
|
||||
|
||||
/* Link 'oldpath' to 'newpath' */
|
||||
-int do_hardlink(struct sftp_conn *, char *, char *);
|
||||
+int do_hardlink(struct sftp_conn *, const char *, const char *);
|
||||
|
||||
-/* Rename 'oldpath' to 'newpath' */
|
||||
-int do_symlink(struct sftp_conn *, char *, char *);
|
||||
+/* Symlink 'oldpath' to 'newpath' */
|
||||
+int do_symlink(struct sftp_conn *, const char *, const char *);
|
||||
|
||||
/* XXX: add callbacks to do_download/do_upload so we can do progress meter */
|
||||
|
||||
@@ -106,27 +106,27 @@ int do_symlink(struct sftp_conn *, char
|
||||
* Download 'remote_path' to 'local_path'. Preserve permissions and times
|
||||
* if 'pflag' is set
|
||||
*/
|
||||
-int do_download(struct sftp_conn *, char *, char *, Attrib *, int, int);
|
||||
+int do_download(struct sftp_conn *, const char *, const char *, Attrib *, int, int);
|
||||
|
||||
/*
|
||||
* Recursively download 'remote_directory' to 'local_directory'. Preserve
|
||||
* times if 'pflag' is set
|
||||
*/
|
||||
-int download_dir(struct sftp_conn *, char *, char *, Attrib *, int, int, int);
|
||||
+int download_dir(struct sftp_conn *, const char *, const char *, Attrib *, int, int, int);
|
||||
|
||||
/*
|
||||
* Upload 'local_path' to 'remote_path'. Preserve permissions and times
|
||||
* if 'pflag' is set
|
||||
*/
|
||||
-int do_upload(struct sftp_conn *, char *, char *, int);
|
||||
+int do_upload(struct sftp_conn *, const char *, const char *, int);
|
||||
|
||||
/*
|
||||
* Recursively upload 'local_directory' to 'remote_directory'. Preserve
|
||||
* times if 'pflag' is set
|
||||
*/
|
||||
-int upload_dir(struct sftp_conn *, char *, char *, int, int);
|
||||
+int upload_dir(struct sftp_conn *, const char *, const char *, int, int);
|
||||
|
||||
/* Concatenate paths, taking care of slashes. Caller must free result. */
|
||||
-char *path_append(char *, char *);
|
||||
+char *path_append(const char *, const char *);
|
||||
|
||||
#endif
|
||||
diff -up openssh-6.3p1/sftp.c.coverity openssh-6.3p1/sftp.c
|
||||
--- openssh-6.3p1/sftp.c.coverity 2013-07-25 03:56:52.000000000 +0200
|
||||
+++ openssh-6.3p1/sftp.c 2013-10-07 13:49:47.322727449 +0200
|
||||
@@ -213,7 +213,7 @@ killchild(int signo)
|
||||
{
|
||||
if (sshpid > 1) {
|
||||
kill(sshpid, SIGTERM);
|
||||
- waitpid(sshpid, NULL, 0);
|
||||
+ (void) waitpid(sshpid, NULL, 0);
|
||||
}
|
||||
|
||||
_exit(1);
|
||||
@@ -324,7 +324,7 @@ local_do_ls(const char *args)
|
||||
|
||||
/* Strip one path (usually the pwd) from the start of another */
|
||||
static char *
|
||||
-path_strip(char *path, char *strip)
|
||||
+path_strip(const char *path, const char *strip)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
@@ -342,7 +342,7 @@ path_strip(char *path, char *strip)
|
||||
}
|
||||
|
||||
static char *
|
||||
-make_absolute(char *p, char *pwd)
|
||||
+make_absolute(char *p, const char *pwd)
|
||||
{
|
||||
char *abs_str;
|
||||
|
||||
@@ -493,7 +493,7 @@ parse_df_flags(const char *cmd, char **a
|
||||
}
|
||||
|
||||
static int
|
||||
-is_dir(char *path)
|
||||
+is_dir(const char *path)
|
||||
{
|
||||
struct stat sb;
|
||||
|
||||
@@ -505,7 +505,7 @@ is_dir(char *path)
|
||||
}
|
||||
|
||||
static int
|
||||
-remote_is_dir(struct sftp_conn *conn, char *path)
|
||||
+remote_is_dir(struct sftp_conn *conn, const char *path)
|
||||
{
|
||||
Attrib *a;
|
||||
|
||||
@@ -519,7 +519,7 @@ remote_is_dir(struct sftp_conn *conn, ch
|
||||
|
||||
/* Check whether path returned from glob(..., GLOB_MARK, ...) is a directory */
|
||||
static int
|
||||
-pathname_is_dir(char *pathname)
|
||||
+pathname_is_dir(const char *pathname)
|
||||
{
|
||||
size_t l = strlen(pathname);
|
||||
|
||||
@@ -527,7 +527,7 @@ pathname_is_dir(char *pathname)
|
||||
}
|
||||
|
||||
static int
|
||||
-process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd,
|
||||
+process_get(struct sftp_conn *conn, const char *src, const char *dst, const char *pwd,
|
||||
int pflag, int rflag, int resume)
|
||||
{
|
||||
char *abs_src = NULL;
|
||||
@@ -605,7 +605,7 @@ out:
|
||||
}
|
||||
|
||||
static int
|
||||
-process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd,
|
||||
+process_put(struct sftp_conn *conn, const char *src, const char *dst, const char *pwd,
|
||||
int pflag, int rflag)
|
||||
{
|
||||
char *tmp_dst = NULL;
|
||||
@@ -709,7 +709,7 @@ sdirent_comp(const void *aa, const void
|
||||
|
||||
/* sftp ls.1 replacement for directories */
|
||||
static int
|
||||
-do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag)
|
||||
+do_ls_dir(struct sftp_conn *conn, const char *path, const char *strip_path, int lflag)
|
||||
{
|
||||
int n;
|
||||
u_int c = 1, colspace = 0, columns = 1;
|
||||
@@ -794,7 +794,7 @@ do_ls_dir(struct sftp_conn *conn, char *
|
||||
|
||||
/* sftp ls.1 replacement which handles path globs */
|
||||
static int
|
||||
-do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path,
|
||||
+do_globbed_ls(struct sftp_conn *conn, const char *path, const char *strip_path,
|
||||
int lflag)
|
||||
{
|
||||
char *fname, *lname;
|
||||
@@ -875,7 +875,7 @@ do_globbed_ls(struct sftp_conn *conn, ch
|
||||
}
|
||||
|
||||
static int
|
||||
-do_df(struct sftp_conn *conn, char *path, int hflag, int iflag)
|
||||
+do_df(struct sftp_conn *conn, const char *path, int hflag, int iflag)
|
||||
{
|
||||
struct sftp_statvfs st;
|
||||
char s_used[FMT_SCALED_STRSIZE];
|
||||
diff -up openssh-6.3p1/ssh-agent.c.coverity openssh-6.3p1/ssh-agent.c
|
||||
--- openssh-6.3p1/ssh-agent.c.coverity 2013-07-20 05:22:49.000000000 +0200
|
||||
+++ openssh-6.3p1/ssh-agent.c 2013-10-07 13:20:36.296298024 +0200
|
||||
@@ -1143,8 +1143,8 @@ main(int ac, char **av)
|
||||
sanitise_stdfd();
|
||||
|
||||
/* drop */
|
||||
- setegid(getgid());
|
||||
- setgid(getgid());
|
||||
+ (void) setegid(getgid());
|
||||
+ (void) setgid(getgid());
|
||||
|
||||
#if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE)
|
||||
/* Disable ptrace on Linux without sgid bit */
|
||||
diff -up openssh-6.3p1/sshd.c.coverity openssh-6.3p1/sshd.c
|
||||
--- openssh-6.3p1/sshd.c.coverity 2013-07-20 05:21:53.000000000 +0200
|
||||
+++ openssh-6.3p1/sshd.c 2013-10-07 13:20:36.296298024 +0200
|
||||
@@ -699,8 +699,10 @@ privsep_preauth(Authctxt *authctxt)
|
||||
if (getuid() == 0 || geteuid() == 0)
|
||||
privsep_preauth_child();
|
||||
setproctitle("%s", "[net]");
|
||||
- if (box != NULL)
|
||||
+ if (box != NULL) {
|
||||
ssh_sandbox_child(box);
|
||||
+ free(box);
|
||||
+ }
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1345,6 +1347,9 @@ server_accept_loop(int *sock_in, int *so
|
||||
if (num_listen_socks < 0)
|
||||
break;
|
||||
}
|
||||
+
|
||||
+ if (fdset != NULL)
|
||||
+ free(fdset);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,250 +0,0 @@
|
|||
diff -up openssh-6.2p1/ctr-cavstest.c.ctr-cavs openssh-6.2p1/ctr-cavstest.c
|
||||
--- openssh-6.2p1/ctr-cavstest.c.ctr-cavs 2013-03-25 21:35:52.512586671 +0100
|
||||
+++ openssh-6.2p1/ctr-cavstest.c 2013-03-25 21:35:52.512586671 +0100
|
||||
@@ -0,0 +1,208 @@
|
||||
+/*
|
||||
+ *
|
||||
+ * invocation (all of the following are equal):
|
||||
+ * ./ctr-cavstest --algo aes128-ctr --key 987212980144b6a632e864031f52dacc --mode encrypt --data a6deca405eef2e8e4609abf3c3ccf4a6
|
||||
+ * ./ctr-cavstest --algo aes128-ctr --key 987212980144b6a632e864031f52dacc --mode encrypt --data a6deca405eef2e8e4609abf3c3ccf4a6 --iv 00000000000000000000000000000000
|
||||
+ * echo -n a6deca405eef2e8e4609abf3c3ccf4a6 | ./ctr-cavstest --algo aes128-ctr --key 987212980144b6a632e864031f52dacc --mode encrypt
|
||||
+ */
|
||||
+
|
||||
+#include "includes.h"
|
||||
+
|
||||
+#include <sys/types.h>
|
||||
+#include <sys/param.h>
|
||||
+#include <stdarg.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+#include <ctype.h>
|
||||
+
|
||||
+#include "xmalloc.h"
|
||||
+#include "log.h"
|
||||
+#include "cipher.h"
|
||||
+
|
||||
+/* compatibility with old or broken OpenSSL versions */
|
||||
+#include "openbsd-compat/openssl-compat.h"
|
||||
+
|
||||
+void usage(void) {
|
||||
+ fprintf(stderr, "Usage: ctr-cavstest --algo <ssh-crypto-algorithm>\n"
|
||||
+ " --key <hexadecimal-key> --mode <encrypt|decrypt>\n"
|
||||
+ " [--iv <hexadecimal-iv>] --data <hexadecimal-data>\n\n"
|
||||
+ "Hexadecimal output is printed to stdout.\n"
|
||||
+ "Hexadecimal input data can be alternatively read from stdin.\n");
|
||||
+ exit(1);
|
||||
+}
|
||||
+
|
||||
+void *fromhex(char *hex, size_t *len)
|
||||
+{
|
||||
+ unsigned char *bin;
|
||||
+ char *p;
|
||||
+ size_t n = 0;
|
||||
+ int shift = 4;
|
||||
+ unsigned char out = 0;
|
||||
+ unsigned char *optr;
|
||||
+
|
||||
+ bin = xmalloc(strlen(hex)/2);
|
||||
+ optr = bin;
|
||||
+
|
||||
+ for (p = hex; *p != '\0'; ++p) {
|
||||
+ unsigned char c;
|
||||
+
|
||||
+ c = *p;
|
||||
+ if (isspace(c))
|
||||
+ continue;
|
||||
+
|
||||
+ if (c >= '0' && c <= '9') {
|
||||
+ c = c - '0';
|
||||
+ } else if (c >= 'A' && c <= 'F') {
|
||||
+ c = c - 'A' + 10;
|
||||
+ } else if (c >= 'a' && c <= 'f') {
|
||||
+ c = c - 'a' + 10;
|
||||
+ } else {
|
||||
+ /* truncate on nonhex cipher */
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ out |= c << shift;
|
||||
+ shift = (shift + 4) % 8;
|
||||
+
|
||||
+ if (shift) {
|
||||
+ *(optr++) = out;
|
||||
+ out = 0;
|
||||
+ ++n;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ *len = n;
|
||||
+ return bin;
|
||||
+}
|
||||
+
|
||||
+#define READ_CHUNK 4096
|
||||
+#define MAX_READ_SIZE 1024*1024*100
|
||||
+char *read_stdin(void)
|
||||
+{
|
||||
+ char *buf;
|
||||
+ size_t n, total = 0;
|
||||
+
|
||||
+ buf = xmalloc(READ_CHUNK);
|
||||
+
|
||||
+ do {
|
||||
+ n = fread(buf + total, 1, READ_CHUNK, stdin);
|
||||
+ if (n < READ_CHUNK) /* terminate on short read */
|
||||
+ break;
|
||||
+
|
||||
+ total += n;
|
||||
+ buf = xrealloc(buf, total + READ_CHUNK, 1);
|
||||
+ } while(total < MAX_READ_SIZE);
|
||||
+ return buf;
|
||||
+}
|
||||
+
|
||||
+int main (int argc, char *argv[])
|
||||
+{
|
||||
+
|
||||
+ Cipher *c;
|
||||
+ CipherContext cc;
|
||||
+ char *algo = "aes128-ctr";
|
||||
+ char *hexkey = NULL;
|
||||
+ char *hexiv = "00000000000000000000000000000000";
|
||||
+ char *hexdata = NULL;
|
||||
+ char *p;
|
||||
+ int i;
|
||||
+ int encrypt = 1;
|
||||
+ void *key;
|
||||
+ size_t keylen;
|
||||
+ void *iv;
|
||||
+ size_t ivlen;
|
||||
+ void *data;
|
||||
+ size_t datalen;
|
||||
+ void *outdata;
|
||||
+
|
||||
+ for (i = 1; i < argc; ++i) {
|
||||
+ if (strcmp(argv[i], "--algo") == 0) {
|
||||
+ algo = argv[++i];
|
||||
+ } else if (strcmp(argv[i], "--key") == 0) {
|
||||
+ hexkey = argv[++i];
|
||||
+ } else if (strcmp(argv[i], "--mode") == 0) {
|
||||
+ ++i;
|
||||
+ if (argv[i] == NULL) {
|
||||
+ usage();
|
||||
+ }
|
||||
+ if (strncmp(argv[i], "enc", 3) == 0) {
|
||||
+ encrypt = 1;
|
||||
+ } else if (strncmp(argv[i], "dec", 3) == 0) {
|
||||
+ encrypt = 0;
|
||||
+ } else {
|
||||
+ usage();
|
||||
+ }
|
||||
+ } else if (strcmp(argv[i], "--iv") == 0) {
|
||||
+ hexiv = argv[++i];
|
||||
+ } else if (strcmp(argv[i], "--data") == 0) {
|
||||
+ hexdata = argv[++i];
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (hexkey == NULL || algo == NULL) {
|
||||
+ usage();
|
||||
+ }
|
||||
+
|
||||
+ SSLeay_add_all_algorithms();
|
||||
+
|
||||
+ c = cipher_by_name(algo);
|
||||
+ if (c == NULL) {
|
||||
+ fprintf(stderr, "Error: unknown algorithm\n");
|
||||
+ return 2;
|
||||
+ }
|
||||
+
|
||||
+ if (hexdata == NULL) {
|
||||
+ hexdata = read_stdin();
|
||||
+ } else {
|
||||
+ hexdata = xstrdup(hexdata);
|
||||
+ }
|
||||
+
|
||||
+ key = fromhex(hexkey, &keylen);
|
||||
+
|
||||
+ if (keylen != 16 && keylen != 24 && keylen == 32) {
|
||||
+ fprintf(stderr, "Error: unsupported key length\n");
|
||||
+ return 2;
|
||||
+ }
|
||||
+
|
||||
+ iv = fromhex(hexiv, &ivlen);
|
||||
+
|
||||
+ if (ivlen != 16) {
|
||||
+ fprintf(stderr, "Error: unsupported iv length\n");
|
||||
+ return 2;
|
||||
+ }
|
||||
+
|
||||
+ data = fromhex(hexdata, &datalen);
|
||||
+
|
||||
+ if (data == NULL || datalen == 0) {
|
||||
+ fprintf(stderr, "Error: no data to encrypt/decrypt\n");
|
||||
+ return 2;
|
||||
+ }
|
||||
+
|
||||
+ cipher_init(&cc, c, key, keylen, iv, ivlen, encrypt);
|
||||
+
|
||||
+ free(key);
|
||||
+ free(iv);
|
||||
+
|
||||
+ outdata = malloc(datalen);
|
||||
+ if(outdata == NULL) {
|
||||
+ fprintf(stderr, "Error: memory allocation failure\n");
|
||||
+ return 2;
|
||||
+ }
|
||||
+
|
||||
+ cipher_crypt(&cc, outdata, data, datalen, 0, 0);
|
||||
+
|
||||
+ free(data);
|
||||
+
|
||||
+ cipher_cleanup(&cc);
|
||||
+
|
||||
+ for (p = outdata; datalen > 0; ++p, --datalen) {
|
||||
+ printf("%02X", (unsigned char)*p);
|
||||
+ }
|
||||
+
|
||||
+ free(outdata);
|
||||
+
|
||||
+ printf("\n");
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
diff -up openssh-6.2p1/Makefile.in.ctr-cavs openssh-6.2p1/Makefile.in
|
||||
--- openssh-6.2p1/Makefile.in.ctr-cavs 2013-03-25 21:35:52.451586280 +0100
|
||||
+++ openssh-6.2p1/Makefile.in 2013-03-25 21:37:14.956114584 +0100
|
||||
@@ -28,6 +28,7 @@ SSH_KEYSIGN=$(libexecdir)/ssh-keysign
|
||||
SSH_LDAP_HELPER=$(libexecdir)/ssh-ldap-helper
|
||||
SSH_LDAP_WRAPPER=$(libexecdir)/ssh-ldap-wrapper
|
||||
SSH_KEYCAT=$(libexecdir)/ssh-keycat
|
||||
+CTR_CAVSTEST=$(libexecdir)/ctr-cavstest
|
||||
SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper
|
||||
PRIVSEP_PATH=@PRIVSEP_PATH@
|
||||
SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@
|
||||
@@ -65,7 +66,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) ssh-keycat$(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) ctr-cavstest$(EXEEXT)
|
||||
|
||||
LIBSSH_OBJS=authfd.o authfile.o bufaux.o bufbn.o buffer.o \
|
||||
canohost.o channels.o cipher.o cipher-aes.o \
|
||||
@@ -174,6 +175,9 @@ ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) l
|
||||
ssh-keycat$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keycat.o
|
||||
$(LD) -o $@ ssh-keycat.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(SSHDLIBS)
|
||||
|
||||
+ctr-cavstest$(EXEEXT): $(LIBCOMPAT) libssh.a ctr-cavstest.o
|
||||
+ $(LD) -o $@ ctr-cavstest.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS)
|
||||
+
|
||||
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 -lfipscheck $(LIBS)
|
||||
|
||||
@@ -281,6 +285,7 @@ install-files:
|
||||
$(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) ctr-cavstest$(EXEEXT) $(DESTDIR)$(libexecdir)/ctr-cavstest$(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
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
diff -up openssh-5.9p1/cipher-ctr.c.ctr-evp openssh-5.9p1/cipher-ctr.c
|
||||
--- openssh-5.9p1/cipher-ctr.c.ctr-evp 2012-01-11 09:24:06.000000000 +0100
|
||||
+++ openssh-5.9p1/cipher-ctr.c 2012-01-11 15:54:04.675956600 +0100
|
||||
@@ -38,7 +38,7 @@ void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, in
|
||||
|
||||
struct ssh_aes_ctr_ctx
|
||||
{
|
||||
- AES_KEY aes_ctx;
|
||||
+ EVP_CIPHER_CTX ecbctx;
|
||||
u_char aes_counter[AES_BLOCK_SIZE];
|
||||
};
|
||||
|
||||
@@ -63,21 +63,42 @@ ssh_aes_ctr(EVP_CIPHER_CTX *ctx, u_char
|
||||
{
|
||||
struct ssh_aes_ctr_ctx *c;
|
||||
size_t n = 0;
|
||||
- u_char buf[AES_BLOCK_SIZE];
|
||||
+ u_char ctrbuf[AES_BLOCK_SIZE*256];
|
||||
+ u_char buf[AES_BLOCK_SIZE*256];
|
||||
|
||||
if (len == 0)
|
||||
return (1);
|
||||
if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL)
|
||||
return (0);
|
||||
|
||||
- while ((len--) > 0) {
|
||||
+ for (; len > 0; len -= sizeof(u_int)) {
|
||||
+ u_int r,a,b;
|
||||
+
|
||||
if (n == 0) {
|
||||
- AES_encrypt(c->aes_counter, buf, &c->aes_ctx);
|
||||
- ssh_ctr_inc(c->aes_counter, AES_BLOCK_SIZE);
|
||||
+ int outl, i, buflen;
|
||||
+
|
||||
+ buflen = MIN(len, sizeof(ctrbuf));
|
||||
+
|
||||
+ for(i = 0; i < buflen; i += AES_BLOCK_SIZE) {
|
||||
+ memcpy(&ctrbuf[i], c->aes_counter, AES_BLOCK_SIZE);
|
||||
+ ssh_ctr_inc(c->aes_counter, AES_BLOCK_SIZE);
|
||||
+ }
|
||||
+
|
||||
+ EVP_EncryptUpdate(&c->ecbctx, buf, &outl,
|
||||
+ ctrbuf, buflen);
|
||||
}
|
||||
- *(dest++) = *(src++) ^ buf[n];
|
||||
- n = (n + 1) % AES_BLOCK_SIZE;
|
||||
+
|
||||
+ memcpy(&a, src, sizeof(a));
|
||||
+ memcpy(&b, &buf[n], sizeof(b));
|
||||
+ r = a ^ b;
|
||||
+ memcpy(dest, &r, sizeof(r));
|
||||
+ src += sizeof(a);
|
||||
+ dest += sizeof(r);
|
||||
+
|
||||
+ n = (n + sizeof(b)) % sizeof(buf);
|
||||
}
|
||||
+ memset(ctrbuf, '\0', sizeof(ctrbuf));
|
||||
+ memset(buf, '\0', sizeof(buf));
|
||||
return (1);
|
||||
}
|
||||
|
||||
@@ -91,9 +112,28 @@ ssh_aes_ctr_init(EVP_CIPHER_CTX *ctx, co
|
||||
c = xmalloc(sizeof(*c));
|
||||
EVP_CIPHER_CTX_set_app_data(ctx, c);
|
||||
}
|
||||
- if (key != NULL)
|
||||
- AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
|
||||
- &c->aes_ctx);
|
||||
+
|
||||
+ EVP_CIPHER_CTX_init(&c->ecbctx);
|
||||
+
|
||||
+ if (key != NULL) {
|
||||
+ const EVP_CIPHER *cipher;
|
||||
+ switch(EVP_CIPHER_CTX_key_length(ctx)*8) {
|
||||
+ case 128:
|
||||
+ cipher = EVP_aes_128_ecb();
|
||||
+ break;
|
||||
+ case 192:
|
||||
+ cipher = EVP_aes_192_ecb();
|
||||
+ break;
|
||||
+ case 256:
|
||||
+ cipher = EVP_aes_256_ecb();
|
||||
+ break;
|
||||
+ default:
|
||||
+ fatal("ssh_aes_ctr_init: wrong aes key length");
|
||||
+ }
|
||||
+ if(!EVP_EncryptInit_ex(&c->ecbctx, cipher, NULL, key, NULL))
|
||||
+ fatal("ssh_aes_ctr_init: cannot initialize aes encryption");
|
||||
+ EVP_CIPHER_CTX_set_padding(&c->ecbctx, 0);
|
||||
+ }
|
||||
if (iv != NULL)
|
||||
memcpy(c->aes_counter, iv, AES_BLOCK_SIZE);
|
||||
return (1);
|
||||
@@ -105,6 +145,7 @@ ssh_aes_ctr_cleanup(EVP_CIPHER_CTX *ctx)
|
||||
struct ssh_aes_ctr_ctx *c;
|
||||
|
||||
if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
|
||||
+ EVP_CIPHER_CTX_cleanup(&c->ecbctx);
|
||||
memset(c, 0, sizeof(*c));
|
||||
free(c);
|
||||
EVP_CIPHER_CTX_set_app_data(ctx, NULL);
|
||||
|
|
@ -1,406 +0,0 @@
|
|||
diff -up openssh-6.3p1/auth-rsa.c.fingerprint openssh-6.3p1/auth-rsa.c
|
||||
diff -up openssh-6.3p1/auth.c.fingerprint openssh-6.3p1/auth.c
|
||||
--- openssh-6.3p1/auth.c.fingerprint 2013-10-07 14:02:36.998968153 +0200
|
||||
+++ openssh-6.3p1/auth.c 2013-10-07 15:42:05.243812405 +0200
|
||||
@@ -685,9 +685,10 @@ auth_key_is_revoked(Key *key)
|
||||
case 1:
|
||||
revoked:
|
||||
/* Key revoked */
|
||||
- key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
|
||||
+ key_fp = key_selected_fingerprint(key, SSH_FP_HEX);
|
||||
error("WARNING: authentication attempt with a revoked "
|
||||
- "%s key %s ", key_type(key), key_fp);
|
||||
+ "%s key %s%s ", key_type(key),
|
||||
+ key_fingerprint_prefix(), key_fp);
|
||||
free(key_fp);
|
||||
return 1;
|
||||
}
|
||||
diff -up openssh-6.3p1/auth2-hostbased.c.fingerprint openssh-6.3p1/auth2-hostbased.c
|
||||
--- openssh-6.3p1/auth2-hostbased.c.fingerprint 2013-10-07 14:02:36.998968153 +0200
|
||||
+++ openssh-6.3p1/auth2-hostbased.c 2013-10-07 15:43:49.747355927 +0200
|
||||
@@ -200,16 +200,18 @@ hostbased_key_allowed(struct passwd *pw,
|
||||
|
||||
if (host_status == HOST_OK) {
|
||||
if (key_is_cert(key)) {
|
||||
- fp = key_fingerprint(key->cert->signature_key,
|
||||
- SSH_FP_MD5, SSH_FP_HEX);
|
||||
+ fp = key_selected_fingerprint(key->cert->signature_key,
|
||||
+ SSH_FP_HEX);
|
||||
verbose("Accepted certificate ID \"%s\" signed by "
|
||||
- "%s CA %s from %s@%s", key->cert->key_id,
|
||||
- key_type(key->cert->signature_key), fp,
|
||||
+ "%s CA %s%s from %s@%s", key->cert->key_id,
|
||||
+ key_type(key->cert->signature_key),
|
||||
+ key_fingerprint_prefix(), fp,
|
||||
cuser, lookup);
|
||||
} else {
|
||||
- fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
|
||||
- verbose("Accepted %s public key %s from %s@%s",
|
||||
- key_type(key), fp, cuser, lookup);
|
||||
+ fp = key_selected_fingerprint(key, SSH_FP_HEX);
|
||||
+ verbose("Accepted %s public key %s%s from %s@%s",
|
||||
+ key_type(key), key_fingerprint_prefix(),
|
||||
+ fp, cuser, lookup);
|
||||
}
|
||||
free(fp);
|
||||
}
|
||||
diff -up openssh-6.3p1/auth2-pubkey.c.fingerprint openssh-6.3p1/auth2-pubkey.c
|
||||
--- openssh-6.3p1/auth2-pubkey.c.fingerprint 2013-07-18 08:10:10.000000000 +0200
|
||||
+++ openssh-6.3p1/auth2-pubkey.c 2013-10-07 15:50:44.617495624 +0200
|
||||
@@ -359,10 +359,10 @@ check_authkeys_file(FILE *f, char *file,
|
||||
continue;
|
||||
if (!key_is_cert_authority)
|
||||
continue;
|
||||
- fp = key_fingerprint(found, SSH_FP_MD5,
|
||||
- SSH_FP_HEX);
|
||||
- debug("matching CA found: file %s, line %lu, %s %s",
|
||||
- file, linenum, key_type(found), fp);
|
||||
+ fp = key_selected_fingerprint(found, SSH_FP_HEX);
|
||||
+ debug("matching CA found: file %s, line %lu, %s %s%s",
|
||||
+ file, linenum, key_type(found),
|
||||
+ key_fingerprint_prefix(), fp);
|
||||
/*
|
||||
* If the user has specified a list of principals as
|
||||
* a key option, then prefer that list to matching
|
||||
@@ -400,9 +400,9 @@ check_authkeys_file(FILE *f, char *file,
|
||||
if (key_is_cert_authority)
|
||||
continue;
|
||||
found_key = 1;
|
||||
- fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
|
||||
- debug("matching key found: file %s, line %lu %s %s",
|
||||
- file, linenum, key_type(found), fp);
|
||||
+ fp = key_selected_fingerprint(found, SSH_FP_HEX);
|
||||
+ verbose("Found matching %s key: %s%s",
|
||||
+ key_type(found), key_fingerprint_prefix(), fp);
|
||||
free(fp);
|
||||
break;
|
||||
}
|
||||
@@ -425,13 +425,13 @@ user_cert_trusted_ca(struct passwd *pw,
|
||||
if (!key_is_cert(key) || options.trusted_user_ca_keys == NULL)
|
||||
return 0;
|
||||
|
||||
- ca_fp = key_fingerprint(key->cert->signature_key,
|
||||
- SSH_FP_MD5, SSH_FP_HEX);
|
||||
+ ca_fp = key_selected_fingerprint(key->cert->signature_key, SSH_FP_HEX);
|
||||
|
||||
if (key_in_file(key->cert->signature_key,
|
||||
options.trusted_user_ca_keys, 1) != 1) {
|
||||
- debug2("%s: CA %s %s is not listed in %s", __func__,
|
||||
- key_type(key->cert->signature_key), ca_fp,
|
||||
+ debug2("%s: CA %s%s %s is not listed in %s", __func__,
|
||||
+ key_type(key->cert->signature_key),
|
||||
+ key_fingerprint_prefix(), ca_fp,
|
||||
options.trusted_user_ca_keys);
|
||||
goto out;
|
||||
}
|
||||
diff -up openssh-6.3p1/key.c.fingerprint openssh-6.3p1/key.c
|
||||
--- openssh-6.3p1/key.c.fingerprint 2013-10-07 14:02:36.971968285 +0200
|
||||
+++ openssh-6.3p1/key.c 2013-10-07 14:02:36.999968148 +0200
|
||||
@@ -598,6 +598,34 @@ key_fingerprint(const Key *k, enum fp_ty
|
||||
return retval;
|
||||
}
|
||||
|
||||
+enum fp_type
|
||||
+key_fingerprint_selection(void)
|
||||
+{
|
||||
+ static enum fp_type rv;
|
||||
+ static char rv_defined = 0;
|
||||
+ char *env;
|
||||
+
|
||||
+ if (!rv_defined) {
|
||||
+ env = getenv("SSH_FINGERPRINT_TYPE");
|
||||
+ rv = (env && !strcmp (env, "sha")) ?
|
||||
+ SSH_FP_SHA1 : SSH_FP_MD5;
|
||||
+ rv_defined = 1;
|
||||
+ }
|
||||
+ return rv;
|
||||
+}
|
||||
+
|
||||
+char *
|
||||
+key_selected_fingerprint(Key *k, enum fp_rep dgst_rep)
|
||||
+{
|
||||
+ return key_fingerprint(k, key_fingerprint_selection(), dgst_rep);
|
||||
+}
|
||||
+
|
||||
+char *
|
||||
+key_fingerprint_prefix(void)
|
||||
+{
|
||||
+ return key_fingerprint_selection() == SSH_FP_SHA1 ? "sha1:" : "";
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Reads a multiple-precision integer in decimal from the buffer, and advances
|
||||
* the pointer. The integer must already be initialized. This function is
|
||||
diff -up openssh-6.3p1/key.h.fingerprint openssh-6.3p1/key.h
|
||||
--- openssh-6.3p1/key.h.fingerprint 2013-10-07 14:02:36.999968148 +0200
|
||||
+++ openssh-6.3p1/key.h 2013-10-07 15:44:17.574233450 +0200
|
||||
@@ -97,6 +97,9 @@ int key_equal_public(const Key *, cons
|
||||
int key_equal(const Key *, const Key *);
|
||||
char *key_fingerprint(const Key *, enum fp_type, enum fp_rep);
|
||||
u_char *key_fingerprint_raw(const Key *, enum fp_type, u_int *);
|
||||
+enum fp_type key_fingerprint_selection(void);
|
||||
+char *key_selected_fingerprint(Key *, enum fp_rep);
|
||||
+char *key_fingerprint_prefix(void);
|
||||
const char *key_type(const Key *);
|
||||
const char *key_cert_type(const Key *);
|
||||
int key_write(const Key *, FILE *);
|
||||
diff -up openssh-6.3p1/ssh-add.c.fingerprint openssh-6.3p1/ssh-add.c
|
||||
--- openssh-6.3p1/ssh-add.c.fingerprint 2013-10-07 14:02:37.000968143 +0200
|
||||
+++ openssh-6.3p1/ssh-add.c 2013-10-07 14:44:57.466515766 +0200
|
||||
@@ -326,10 +326,10 @@ list_identities(AuthenticationConnection
|
||||
key = ssh_get_next_identity(ac, &comment, version)) {
|
||||
had_identities = 1;
|
||||
if (do_fp) {
|
||||
- fp = key_fingerprint(key, SSH_FP_MD5,
|
||||
- SSH_FP_HEX);
|
||||
- printf("%d %s %s (%s)\n",
|
||||
- key_size(key), fp, comment, key_type(key));
|
||||
+ fp = key_selected_fingerprint(key, SSH_FP_HEX);
|
||||
+ printf("%d %s%s %s (%s)\n",
|
||||
+ key_size(key), key_fingerprint_prefix(),
|
||||
+ fp, comment, key_type(key));
|
||||
free(fp);
|
||||
} else {
|
||||
if (!key_write(key, stdout))
|
||||
diff -up openssh-6.3p1/ssh-agent.c.fingerprint openssh-6.3p1/ssh-agent.c
|
||||
--- openssh-6.3p1/ssh-agent.c.fingerprint 2013-10-07 14:02:37.000968143 +0200
|
||||
+++ openssh-6.3p1/ssh-agent.c 2013-10-07 15:41:11.627044336 +0200
|
||||
@@ -198,9 +198,9 @@ confirm_key(Identity *id)
|
||||
char *p;
|
||||
int ret = -1;
|
||||
|
||||
- p = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX);
|
||||
- if (ask_permission("Allow use of key %s?\nKey fingerprint %s.",
|
||||
- id->comment, p))
|
||||
+ p = key_selected_fingerprint(id->key, SSH_FP_HEX);
|
||||
+ if (ask_permission("Allow use of key %s?\nKey fingerprint %s%s.",
|
||||
+ id->comment, key_fingerprint_prefix(), p))
|
||||
ret = 0;
|
||||
free(p);
|
||||
|
||||
diff -up openssh-6.3p1/ssh-keygen.c.fingerprint openssh-6.3p1/ssh-keygen.c
|
||||
--- openssh-6.3p1/ssh-keygen.c.fingerprint 2013-07-20 05:22:32.000000000 +0200
|
||||
+++ openssh-6.3p1/ssh-keygen.c 2013-10-07 14:25:52.864145038 +0200
|
||||
@@ -767,13 +767,14 @@ do_fingerprint(struct passwd *pw)
|
||||
{
|
||||
FILE *f;
|
||||
Key *public;
|
||||
- char *comment = NULL, *cp, *ep, line[16*1024], *fp, *ra;
|
||||
+ char *comment = NULL, *cp, *ep, line[16*1024], *fp, *ra, *pfx;
|
||||
int i, skip = 0, num = 0, invalid = 1;
|
||||
enum fp_rep rep;
|
||||
enum fp_type fptype;
|
||||
struct stat st;
|
||||
|
||||
- fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5;
|
||||
+ fptype = print_bubblebabble ? SSH_FP_SHA1 : key_fingerprint_selection();
|
||||
+ pfx = print_bubblebabble ? "" : key_fingerprint_prefix();
|
||||
rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX;
|
||||
|
||||
if (!have_identity)
|
||||
@@ -785,8 +786,8 @@ do_fingerprint(struct passwd *pw)
|
||||
public = key_load_public(identity_file, &comment);
|
||||
if (public != NULL) {
|
||||
fp = key_fingerprint(public, fptype, rep);
|
||||
- ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART);
|
||||
- printf("%u %s %s (%s)\n", key_size(public), fp, comment,
|
||||
+ ra = key_selected_fingerprint(public, SSH_FP_RANDOMART);
|
||||
+ printf("%u %s%s %s (%s)\n", key_size(public), pfx, fp, comment,
|
||||
key_type(public));
|
||||
if (log_level >= SYSLOG_LEVEL_VERBOSE)
|
||||
printf("%s\n", ra);
|
||||
@@ -851,8 +852,8 @@ do_fingerprint(struct passwd *pw)
|
||||
}
|
||||
comment = *cp ? cp : comment;
|
||||
fp = key_fingerprint(public, fptype, rep);
|
||||
- ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART);
|
||||
- printf("%u %s %s (%s)\n", key_size(public), fp,
|
||||
+ ra = key_selected_fingerprint(public, SSH_FP_RANDOMART);
|
||||
+ printf("%u %s%s %s (%s)\n", key_size(public), pfx, fp,
|
||||
comment ? comment : "no comment", key_type(public));
|
||||
if (log_level >= SYSLOG_LEVEL_VERBOSE)
|
||||
printf("%s\n", ra);
|
||||
@@ -970,13 +971,15 @@ printhost(FILE *f, const char *name, Key
|
||||
if (print_fingerprint) {
|
||||
enum fp_rep rep;
|
||||
enum fp_type fptype;
|
||||
- char *fp, *ra;
|
||||
+ char *fp, *ra, *pfx;
|
||||
|
||||
- fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5;
|
||||
+ fptype = print_bubblebabble ? SSH_FP_SHA1 : key_fingerprint_selection();
|
||||
+ pfx = print_bubblebabble ? "" : key_fingerprint_prefix();
|
||||
rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX;
|
||||
+
|
||||
fp = key_fingerprint(public, fptype, rep);
|
||||
- ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART);
|
||||
- printf("%u %s %s (%s)\n", key_size(public), fp, name,
|
||||
+ ra = key_selected_fingerprint(public, SSH_FP_RANDOMART);
|
||||
+ printf("%u %s%s %s (%s)\n", key_size(public), pfx, fp, name,
|
||||
key_type(public));
|
||||
if (log_level >= SYSLOG_LEVEL_VERBOSE)
|
||||
printf("%s\n", ra);
|
||||
@@ -1855,16 +1858,17 @@ do_show_cert(struct passwd *pw)
|
||||
fatal("%s is not a certificate", identity_file);
|
||||
v00 = key->type == KEY_RSA_CERT_V00 || key->type == KEY_DSA_CERT_V00;
|
||||
|
||||
- key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
|
||||
- ca_fp = key_fingerprint(key->cert->signature_key,
|
||||
- SSH_FP_MD5, SSH_FP_HEX);
|
||||
+ key_fp = key_selected_fingerprint(key, SSH_FP_HEX);
|
||||
+ ca_fp = key_selected_fingerprint(key->cert->signature_key, SSH_FP_HEX);
|
||||
|
||||
printf("%s:\n", identity_file);
|
||||
printf(" Type: %s %s certificate\n", key_ssh_name(key),
|
||||
key_cert_type(key));
|
||||
- printf(" Public key: %s %s\n", key_type(key), key_fp);
|
||||
- printf(" Signing CA: %s %s\n",
|
||||
- key_type(key->cert->signature_key), ca_fp);
|
||||
+ printf(" Public key: %s %s%s\n", key_type(key),
|
||||
+ key_fingerprint_prefix(), key_fp);
|
||||
+ printf(" Signing CA: %s %s%s\n",
|
||||
+ key_type(key->cert->signature_key),
|
||||
+ key_fingerprint_prefix(), ca_fp);
|
||||
printf(" Key ID: \"%s\"\n", key->cert->key_id);
|
||||
if (!v00) {
|
||||
printf(" Serial: %llu\n",
|
||||
@@ -2655,13 +2659,12 @@ passphrase_again:
|
||||
fclose(f);
|
||||
|
||||
if (!quiet) {
|
||||
- char *fp = key_fingerprint(public, SSH_FP_MD5, SSH_FP_HEX);
|
||||
- char *ra = key_fingerprint(public, SSH_FP_MD5,
|
||||
- SSH_FP_RANDOMART);
|
||||
+ char *fp = key_selected_fingerprint(public, SSH_FP_HEX);
|
||||
+ char *ra = key_selected_fingerprint(public, SSH_FP_RANDOMART);
|
||||
printf("Your public key has been saved in %s.\n",
|
||||
identity_file);
|
||||
printf("The key fingerprint is:\n");
|
||||
- printf("%s %s\n", fp, comment);
|
||||
+ printf("%s%s %s\n", key_fingerprint_prefix(), fp, comment);
|
||||
printf("The key's randomart image is:\n");
|
||||
printf("%s\n", ra);
|
||||
free(ra);
|
||||
diff -up openssh-6.3p1/sshconnect.c.fingerprint openssh-6.3p1/sshconnect.c
|
||||
--- openssh-6.3p1/sshconnect.c.fingerprint 2013-06-01 23:31:19.000000000 +0200
|
||||
+++ openssh-6.3p1/sshconnect.c 2013-10-07 14:43:54.859822036 +0200
|
||||
@@ -830,10 +830,10 @@ check_host_key(char *hostname, struct so
|
||||
"key for IP address '%.128s' to the list "
|
||||
"of known hosts.", type, ip);
|
||||
} else if (options.visual_host_key) {
|
||||
- fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
|
||||
- ra = key_fingerprint(host_key, SSH_FP_MD5,
|
||||
- SSH_FP_RANDOMART);
|
||||
- logit("Host key fingerprint is %s\n%s\n", fp, ra);
|
||||
+ fp = key_selected_fingerprint(host_key, SSH_FP_HEX);
|
||||
+ ra = key_selected_fingerprint(host_key, SSH_FP_RANDOMART);
|
||||
+ logit("Host key fingerprint is %s%s\n%s\n",
|
||||
+ key_fingerprint_prefix(), fp, ra);
|
||||
free(ra);
|
||||
free(fp);
|
||||
}
|
||||
@@ -871,9 +871,8 @@ check_host_key(char *hostname, struct so
|
||||
else
|
||||
snprintf(msg1, sizeof(msg1), ".");
|
||||
/* The default */
|
||||
- fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
|
||||
- ra = key_fingerprint(host_key, SSH_FP_MD5,
|
||||
- SSH_FP_RANDOMART);
|
||||
+ fp = key_selected_fingerprint(host_key, SSH_FP_HEX);
|
||||
+ ra = key_selected_fingerprint(host_key, SSH_FP_RANDOMART);
|
||||
msg2[0] = '\0';
|
||||
if (options.verify_host_key_dns) {
|
||||
if (matching_host_key_dns)
|
||||
@@ -888,10 +887,11 @@ check_host_key(char *hostname, struct so
|
||||
snprintf(msg, sizeof(msg),
|
||||
"The authenticity of host '%.200s (%s)' can't be "
|
||||
"established%s\n"
|
||||
- "%s key fingerprint is %s.%s%s\n%s"
|
||||
+ "%s key fingerprint is %s%s.%s%s\n%s"
|
||||
"Are you sure you want to continue connecting "
|
||||
"(yes/no)? ",
|
||||
- host, ip, msg1, type, fp,
|
||||
+ host, ip, msg1, type,
|
||||
+ key_fingerprint_prefix(), fp,
|
||||
options.visual_host_key ? "\n" : "",
|
||||
options.visual_host_key ? ra : "",
|
||||
msg2);
|
||||
@@ -1136,8 +1136,9 @@ verify_host_key(char *host, struct socka
|
||||
int flags = 0;
|
||||
char *fp;
|
||||
|
||||
- fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
|
||||
- debug("Server host key: %s %s", key_type(host_key), fp);
|
||||
+ fp = key_selected_fingerprint(host_key, SSH_FP_HEX);
|
||||
+ debug("Server host key: %s %s%s", key_type(host_key),
|
||||
+ key_fingerprint_prefix(), fp);
|
||||
free(fp);
|
||||
|
||||
/* XXX certs are not yet supported for DNS */
|
||||
@@ -1238,14 +1239,15 @@ show_other_keys(struct hostkeys *hostkey
|
||||
continue;
|
||||
if (!lookup_key_in_hostkeys_by_type(hostkeys, type[i], &found))
|
||||
continue;
|
||||
- fp = key_fingerprint(found->key, SSH_FP_MD5, SSH_FP_HEX);
|
||||
- ra = key_fingerprint(found->key, SSH_FP_MD5, SSH_FP_RANDOMART);
|
||||
+ fp = key_selected_fingerprint(found->key, SSH_FP_HEX);
|
||||
+ ra = key_selected_fingerprint(found->key, SSH_FP_RANDOMART);
|
||||
logit("WARNING: %s key found for host %s\n"
|
||||
"in %s:%lu\n"
|
||||
- "%s key fingerprint %s.",
|
||||
+ "%s key fingerprint %s%s.",
|
||||
key_type(found->key),
|
||||
found->host, found->file, found->line,
|
||||
- key_type(found->key), fp);
|
||||
+ key_type(found->key),
|
||||
+ key_fingerprint_prefix(), fp);
|
||||
if (options.visual_host_key)
|
||||
logit("%s", ra);
|
||||
free(ra);
|
||||
@@ -1260,7 +1262,7 @@ warn_changed_key(Key *host_key)
|
||||
{
|
||||
char *fp;
|
||||
|
||||
- fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
|
||||
+ fp = key_selected_fingerprint(host_key, SSH_FP_HEX);
|
||||
|
||||
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
|
||||
error("@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @");
|
||||
@@ -1268,8 +1270,8 @@ warn_changed_key(Key *host_key)
|
||||
error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!");
|
||||
error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!");
|
||||
error("It is also possible that a host key has just been changed.");
|
||||
- error("The fingerprint for the %s key sent by the remote host is\n%s.",
|
||||
- key_type(host_key), fp);
|
||||
+ error("The fingerprint for the %s key sent by the remote host is\n%s%s.",
|
||||
+ key_type(host_key),key_fingerprint_prefix(), fp);
|
||||
error("Please contact your system administrator.");
|
||||
|
||||
free(fp);
|
||||
diff -up openssh-6.3p1/sshconnect2.c.fingerprint openssh-6.3p1/sshconnect2.c
|
||||
--- openssh-6.3p1/sshconnect2.c.fingerprint 2013-10-07 14:02:37.001968139 +0200
|
||||
+++ openssh-6.3p1/sshconnect2.c 2013-10-07 15:20:09.403234714 +0200
|
||||
@@ -590,8 +590,9 @@ input_userauth_pk_ok(int type, u_int32_t
|
||||
key->type, pktype);
|
||||
goto done;
|
||||
}
|
||||
- fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
|
||||
- debug2("input_userauth_pk_ok: fp %s", fp);
|
||||
+ fp = key_selected_fingerprint(key, SSH_FP_HEX);
|
||||
+ debug2("input_userauth_pk_ok: fp %s%s",
|
||||
+ key_fingerprint_prefix(), fp);
|
||||
free(fp);
|
||||
|
||||
/*
|
||||
@@ -1202,8 +1203,9 @@ sign_and_send_pubkey(Authctxt *authctxt,
|
||||
int have_sig = 1;
|
||||
char *fp;
|
||||
|
||||
- fp = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX);
|
||||
- debug3("sign_and_send_pubkey: %s %s", key_type(id->key), fp);
|
||||
+ fp = key_selected_fingerprint(id->key, SSH_FP_HEX);
|
||||
+ debug3("sign_and_send_pubkey: %s %s%s", key_type(id->key),
|
||||
+ key_fingerprint_prefix(), fp);
|
||||
free(fp);
|
||||
|
||||
if (key_to_blob(id->key, &blob, &bloblen) == 0) {
|
||||
|
|
@ -1,607 +0,0 @@
|
|||
diff -up openssh-6.3p1/Makefile.in.fips openssh-6.3p1/Makefile.in
|
||||
--- openssh-6.3p1/Makefile.in.fips 2013-10-11 22:24:32.850031186 +0200
|
||||
+++ openssh-6.3p1/Makefile.in 2013-10-11 22:24:32.870031092 +0200
|
||||
@@ -147,25 +147,25 @@ libssh.a: $(LIBSSH_OBJS)
|
||||
$(RANLIB) $@
|
||||
|
||||
ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS)
|
||||
- $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHLIBS) $(LIBS) $(GSSLIBS)
|
||||
+ $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(SSHLIBS) $(LIBS) $(GSSLIBS)
|
||||
|
||||
sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS)
|
||||
- $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS)
|
||||
+ $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS)
|
||||
|
||||
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)
|
||||
@@ -177,7 +177,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-6.3p1/auth-rsa.c.fips openssh-6.3p1/auth-rsa.c
|
||||
--- openssh-6.3p1/auth-rsa.c.fips 2013-10-24 15:43:46.019999906 +0200
|
||||
+++ openssh-6.3p1/auth-rsa.c 2013-10-24 15:44:09.262890686 +0200
|
||||
@@ -240,7 +240,7 @@ rsa_key_allowed_in_file(struct passwd *p
|
||||
"actual %d vs. announced %d.",
|
||||
file, linenum, BN_num_bits(key->rsa->n), bits);
|
||||
|
||||
- fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
|
||||
+ fp = key_fingerprint(key, FIPS_mode() ? SSH_FP_SHA1 : SSH_FP_MD5, SSH_FP_HEX);
|
||||
debug("matching key found: file %s, line %lu %s %s",
|
||||
file, linenum, key_type(key), fp);
|
||||
free(fp);
|
||||
diff -up openssh-6.3p1/auth2-pubkey.c.fips openssh-6.3p1/auth2-pubkey.c
|
||||
--- openssh-6.3p1/auth2-pubkey.c.fips 2013-10-24 15:39:05.008319990 +0200
|
||||
+++ openssh-6.3p1/auth2-pubkey.c 2013-10-24 15:39:05.029319892 +0200
|
||||
@@ -209,7 +209,7 @@ pubkey_auth_info(Authctxt *authctxt, con
|
||||
|
||||
if (key_is_cert(key)) {
|
||||
fp = key_fingerprint(key->cert->signature_key,
|
||||
- SSH_FP_MD5, SSH_FP_HEX);
|
||||
+ FIPS_mode() ? SSH_FP_SHA1 : SSH_FP_MD5, SSH_FP_HEX);
|
||||
auth_info(authctxt, "%s ID %s (serial %llu) CA %s %s%s%s",
|
||||
key_type(key), key->cert->key_id,
|
||||
(unsigned long long)key->cert->serial,
|
||||
@@ -217,7 +217,7 @@ pubkey_auth_info(Authctxt *authctxt, con
|
||||
extra == NULL ? "" : ", ", extra == NULL ? "" : extra);
|
||||
free(fp);
|
||||
} else {
|
||||
- fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
|
||||
+ fp = key_fingerprint(key, FIPS_mode() ? SSH_FP_SHA1 : SSH_FP_MD5, SSH_FP_HEX);
|
||||
auth_info(authctxt, "%s %s%s%s", key_type(key), fp,
|
||||
extra == NULL ? "" : ", ", extra == NULL ? "" : extra);
|
||||
free(fp);
|
||||
diff -up openssh-6.3p1/authfile.c.fips openssh-6.3p1/authfile.c
|
||||
--- openssh-6.3p1/authfile.c.fips 2013-10-11 22:24:32.857031153 +0200
|
||||
+++ openssh-6.3p1/authfile.c 2013-10-11 22:24:32.870031092 +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), 0, 0);
|
||||
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(©), 0, 0);
|
||||
cipher_cleanup(&ciphercontext);
|
||||
diff -up openssh-6.3p1/cipher-ctr.c.fips openssh-6.3p1/cipher-ctr.c
|
||||
--- openssh-6.3p1/cipher-ctr.c.fips 2013-06-02 00:07:32.000000000 +0200
|
||||
+++ openssh-6.3p1/cipher-ctr.c 2013-10-11 22:24:32.870031092 +0200
|
||||
@@ -138,7 +138,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-6.3p1/cipher.c.fips openssh-6.3p1/cipher.c
|
||||
--- openssh-6.3p1/cipher.c.fips 2013-10-11 22:24:32.820031327 +0200
|
||||
+++ openssh-6.3p1/cipher.c 2013-10-11 22:24:32.871031087 +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,27 @@ static const struct Cipher ciphers[] = {
|
||||
{ NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL }
|
||||
};
|
||||
|
||||
+static const struct Cipher fips_ciphers[] = {
|
||||
+ { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null },
|
||||
+ { "des", SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc },
|
||||
+ { "3des", SSH_CIPHER_3DES, 8, 16, 0, 0, 0, 1, evp_ssh1_3des },
|
||||
+ { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc },
|
||||
+ { "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 1, EVP_aes_128_cbc },
|
||||
+ { "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 1, EVP_aes_192_cbc },
|
||||
+ { "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc },
|
||||
+ { "rijndael-cbc@lysator.liu.se",
|
||||
+ SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc },
|
||||
+ { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 0, EVP_aes_128_ctr },
|
||||
+ { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 0, EVP_aes_192_ctr },
|
||||
+ { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 0, EVP_aes_256_ctr },
|
||||
+#ifdef OPENSSL_HAVE_EVPGCM
|
||||
+ { "aes128-gcm@openssh.com",
|
||||
+ SSH_CIPHER_SSH2, 16, 16, 12, 16, 0, 0, EVP_aes_128_gcm },
|
||||
+ { "aes256-gcm@openssh.com",
|
||||
+ SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm },
|
||||
+#endif
|
||||
+ { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL }
|
||||
+};
|
||||
/*--*/
|
||||
|
||||
/* Returns a comma-separated list of supported ciphers. */
|
||||
@@ -96,7 +118,7 @@ cipher_alg_list(void)
|
||||
size_t nlen, rlen = 0;
|
||||
const Cipher *c;
|
||||
|
||||
- for (c = ciphers; c->name != NULL; c++) {
|
||||
+ for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++) {
|
||||
if (c->number != SSH_CIPHER_SSH2)
|
||||
continue;
|
||||
if (ret != NULL)
|
||||
@@ -161,7 +183,7 @@ const Cipher *
|
||||
cipher_by_name(const char *name)
|
||||
{
|
||||
const 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;
|
||||
@@ -171,7 +193,7 @@ const Cipher *
|
||||
cipher_by_number(int id)
|
||||
{
|
||||
const 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;
|
||||
@@ -215,7 +237,7 @@ cipher_number(const char *name)
|
||||
const 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;
|
||||
@@ -374,14 +396,15 @@ cipher_cleanup(CipherContext *cc)
|
||||
* passphrase and using the resulting 16 bytes as the key.
|
||||
*/
|
||||
|
||||
-void
|
||||
+int
|
||||
cipher_set_key_string(CipherContext *cc, const 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);
|
||||
|
||||
@@ -389,6 +412,7 @@ cipher_set_key_string(CipherContext *cc,
|
||||
|
||||
memset(digest, 0, sizeof(digest));
|
||||
memset(&md, 0, sizeof(md));
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
diff -up openssh-6.3p1/cipher.h.fips openssh-6.3p1/cipher.h
|
||||
--- openssh-6.3p1/cipher.h.fips 2013-10-11 22:24:32.820031327 +0200
|
||||
+++ openssh-6.3p1/cipher.h 2013-10-11 22:24:32.871031087 +0200
|
||||
@@ -92,7 +92,7 @@ void cipher_init(CipherContext *, const
|
||||
void cipher_crypt(CipherContext *, u_char *, const u_char *,
|
||||
u_int, u_int, u_int);
|
||||
void cipher_cleanup(CipherContext *);
|
||||
-void cipher_set_key_string(CipherContext *, const Cipher *, const char *, int);
|
||||
+int cipher_set_key_string(CipherContext *, const Cipher *, const char *, int);
|
||||
u_int cipher_blocksize(const Cipher *);
|
||||
u_int cipher_keylen(const Cipher *);
|
||||
u_int cipher_authlen(const Cipher *);
|
||||
diff -up openssh-6.3p1/key.c.fips openssh-6.3p1/key.c
|
||||
--- openssh-6.3p1/key.c.fips 2013-10-11 22:24:32.821031322 +0200
|
||||
+++ openssh-6.3p1/key.c 2013-10-11 22:24:32.871031087 +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>
|
||||
@@ -606,9 +607,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-6.3p1/mac.c.fips openssh-6.3p1/mac.c
|
||||
--- openssh-6.3p1/mac.c.fips 2013-10-11 22:24:32.821031322 +0200
|
||||
+++ openssh-6.3p1/mac.c 2013-10-11 22:25:35.394737186 +0200
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <openssl/hmac.h>
|
||||
+#include <openssl/fips.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
@@ -60,7 +61,7 @@ struct macalg {
|
||||
int etm; /* Encrypt-then-MAC */
|
||||
};
|
||||
|
||||
-static const struct macalg macs[] = {
|
||||
+static const struct macalg all_macs[] = {
|
||||
/* Encrypt-and-MAC (encrypt-and-authenticate) variants */
|
||||
{ "hmac-sha1", SSH_EVP, EVP_sha1, 0, 0, 0, 0 },
|
||||
{ "hmac-sha1-96", SSH_EVP, EVP_sha1, 96, 0, 0, 0 },
|
||||
@@ -91,6 +92,18 @@ static const struct macalg macs[] = {
|
||||
{ NULL, 0, NULL, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
+static const struct macalg fips_macs[] = {
|
||||
+ { "hmac-sha1", SSH_EVP, EVP_sha1, 0, 0, 0, 0 },
|
||||
+ { "hmac-sha1-etm@openssh.com", SSH_EVP, EVP_sha1, 0, 0, 0, 1 },
|
||||
+#ifdef HAVE_EVP_SHA256
|
||||
+ { "hmac-sha2-256", SSH_EVP, EVP_sha256, 0, 0, 0, 0 },
|
||||
+ { "hmac-sha2-512", SSH_EVP, EVP_sha512, 0, 0, 0, 0 },
|
||||
+ { "hmac-sha2-256-etm@openssh.com", SSH_EVP, EVP_sha256, 0, 0, 0, 1 },
|
||||
+ { "hmac-sha2-512-etm@openssh.com", SSH_EVP, EVP_sha512, 0, 0, 0, 1 },
|
||||
+#endif
|
||||
+ { NULL, 0, NULL, 0, 0, 0, 0 }
|
||||
+};
|
||||
+
|
||||
/* Returns a comma-separated list of supported MACs. */
|
||||
char *
|
||||
mac_alg_list(void)
|
||||
@@ -99,7 +112,7 @@ mac_alg_list(void)
|
||||
size_t nlen, rlen = 0;
|
||||
const struct macalg *m;
|
||||
|
||||
- for (m = macs; m->name != NULL; m++) {
|
||||
+ for (m = FIPS_mode() ? fips_macs : all_macs; m->name != NULL; m++) {
|
||||
if (ret != NULL)
|
||||
ret[rlen++] = '\n';
|
||||
nlen = strlen(m->name);
|
||||
@@ -136,7 +149,7 @@ mac_setup(Mac *mac, char *name)
|
||||
{
|
||||
const struct macalg *m;
|
||||
|
||||
- for (m = macs; m->name != NULL; m++) {
|
||||
+ for (m = FIPS_mode() ? fips_macs : all_macs; m->name != NULL; m++) {
|
||||
if (strcmp(name, m->name) != 0)
|
||||
continue;
|
||||
if (mac != NULL)
|
||||
diff -up openssh-6.3p1/myproposal.h.fips openssh-6.3p1/myproposal.h
|
||||
--- openssh-6.3p1/myproposal.h.fips 2013-06-11 04:10:02.000000000 +0200
|
||||
+++ openssh-6.3p1/myproposal.h 2013-10-11 22:24:32.872031082 +0200
|
||||
@@ -114,6 +114,19 @@
|
||||
#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"
|
||||
+#ifdef HAVE_EVP_SHA256
|
||||
+#define KEX_FIPS_MAC \
|
||||
+ "hmac-sha1," \
|
||||
+ "hmac-sha2-256," \
|
||||
+ "hmac-sha2-512"
|
||||
+#else
|
||||
+#define KEX_FIPS_MAC \
|
||||
+ "hmac-sha1"
|
||||
+#endif
|
||||
|
||||
static char *myproposal[PROPOSAL_MAX] = {
|
||||
KEX_DEFAULT_KEX,
|
||||
diff -up openssh-6.3p1/openbsd-compat/bsd-arc4random.c.fips openssh-6.3p1/openbsd-compat/bsd-arc4random.c
|
||||
--- openssh-6.3p1/openbsd-compat/bsd-arc4random.c.fips 2010-03-25 22:52:02.000000000 +0100
|
||||
+++ openssh-6.3p1/openbsd-compat/bsd-arc4random.c 2013-10-11 22:24:32.872031082 +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-6.3p1/ssh-keygen.c.fips openssh-6.3p1/ssh-keygen.c
|
||||
--- openssh-6.3p1/ssh-keygen.c.fips 2013-10-24 15:45:06.055623916 +0200
|
||||
+++ openssh-6.3p1/ssh-keygen.c 2013-10-24 15:45:36.906478986 +0200
|
||||
@@ -730,7 +730,7 @@ do_download(struct passwd *pw)
|
||||
enum fp_type fptype;
|
||||
char *fp, *ra;
|
||||
|
||||
- fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5;
|
||||
+ fptype = print_bubblebabble ? SSH_FP_SHA1 : (FIPS_mode() ? SSH_FP_SHA1 : SSH_FP_MD5);
|
||||
rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX;
|
||||
|
||||
pkcs11_init(0);
|
||||
@@ -740,7 +740,7 @@ do_download(struct passwd *pw)
|
||||
for (i = 0; i < nkeys; i++) {
|
||||
if (print_fingerprint) {
|
||||
fp = key_fingerprint(keys[i], fptype, rep);
|
||||
- ra = key_fingerprint(keys[i], SSH_FP_MD5,
|
||||
+ ra = key_fingerprint(keys[i], FIPS_mode() ? SSH_FP_SHA1 : SSH_FP_MD5,
|
||||
SSH_FP_RANDOMART);
|
||||
printf("%u %s %s (PKCS11 key)\n", key_size(keys[i]),
|
||||
fp, key_type(keys[i]));
|
||||
diff -up openssh-6.3p1/ssh.c.fips openssh-6.3p1/ssh.c
|
||||
--- openssh-6.3p1/ssh.c.fips 2013-07-25 03:55:53.000000000 +0200
|
||||
+++ openssh-6.3p1/ssh.c 2013-10-11 22:24:32.872031082 +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,13 @@ main(int ac, char **av)
|
||||
sanitise_stdfd();
|
||||
|
||||
__progname = ssh_get_progname(av[0]);
|
||||
+ SSLeay_add_all_algorithms();
|
||||
+ if (access("/etc/system-fips", F_OK) == 0)
|
||||
+ if (! FIPSCHECK_verify(NULL, NULL))
|
||||
+ if (FIPS_mode())
|
||||
+ fatal("FIPS integrity verification test failed.");
|
||||
+ else
|
||||
+ logit("FIPS integrity verification test failed.");
|
||||
|
||||
#ifndef HAVE_SETPROCTITLE
|
||||
/* Prepare for later setproctitle emulation */
|
||||
@@ -330,6 +339,9 @@ main(int ac, char **av)
|
||||
"ACD:E:F:I:KL:MNO:PQ:R: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':
|
||||
@@ -647,7 +659,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. */
|
||||
@@ -748,6 +759,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);
|
||||
|
||||
@@ -816,6 +831,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-6.3p1/sshconnect2.c.fips openssh-6.3p1/sshconnect2.c
|
||||
--- openssh-6.3p1/sshconnect2.c.fips 2013-10-11 22:24:32.810031374 +0200
|
||||
+++ openssh-6.3p1/sshconnect2.c 2013-10-11 22:24:32.873031077 +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-6.3p1/sshd.c.fips openssh-6.3p1/sshd.c
|
||||
--- openssh-6.3p1/sshd.c.fips 2013-10-11 22:24:32.842031223 +0200
|
||||
+++ openssh-6.3p1/sshd.c 2013-10-11 22:24:32.873031077 +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
|
||||
@@ -1450,6 +1452,14 @@ main(int ac, char **av)
|
||||
#endif
|
||||
__progname = ssh_get_progname(av[0]);
|
||||
|
||||
+ SSLeay_add_all_algorithms();
|
||||
+ if (access("/etc/system-fips", F_OK) == 0)
|
||||
+ if (! FIPSCHECK_verify(NULL, NULL))
|
||||
+ if (FIPS_mode())
|
||||
+ fatal("FIPS integrity verification test failed.");
|
||||
+ else
|
||||
+ logit("FIPS integrity verification test failed.");
|
||||
+
|
||||
/* Save argv. Duplicate so setproctitle emulation doesn't clobber it */
|
||||
saved_argc = ac;
|
||||
rexec_argc = ac;
|
||||
@@ -1601,8 +1611,6 @@ main(int ac, char **av)
|
||||
else
|
||||
closefrom(REEXEC_DEVCRYPTO_RESERVED_FD);
|
||||
|
||||
- OpenSSL_add_all_algorithms();
|
||||
-
|
||||
/* If requested, redirect the logs to the specified logfile. */
|
||||
if (logfile != NULL) {
|
||||
log_redirect_stderr_to(logfile);
|
||||
@@ -1773,6 +1781,10 @@ main(int ac, char **av)
|
||||
debug("private host key: #%d type %d %s", i, keytype,
|
||||
key_type(key ? key : pubkey));
|
||||
}
|
||||
+ 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;
|
||||
@@ -1936,6 +1948,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. */
|
||||
if (chdir("/") == -1)
|
||||
@@ -2498,6 +2514,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]);
|
||||
@@ -2507,6 +2526,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] =
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,65 +0,0 @@
|
|||
diff -U0 openssh-6.3p1/ChangeLog.df openssh-6.3p1/ChangeLog
|
||||
--- openssh-6.3p1/ChangeLog.df 2013-10-23 22:38:03.476272461 +0200
|
||||
+++ openssh-6.3p1/ChangeLog 2013-10-23 22:39:46.051788366 +0200
|
||||
@@ -0,0 +1,8 @@
|
||||
+20131010
|
||||
+ - dtucker@cvs.openbsd.org 2013/10/08 11:42:13
|
||||
+ [dh.c dh.h]
|
||||
+ Increase the size of the Diffie-Hellman groups requested for a each
|
||||
+ symmetric key size. New values from NIST Special Publication 800-57 with
|
||||
+ the upper limit specified by RFC4419. Pointed out by Peter Backes, ok
|
||||
+ djm@.
|
||||
+
|
||||
diff -up openssh-6.3p1/dh.c.df openssh-6.3p1/dh.c
|
||||
--- openssh-6.3p1/dh.c.df 2013-07-18 08:12:07.000000000 +0200
|
||||
+++ openssh-6.3p1/dh.c 2013-10-23 22:38:03.476272461 +0200
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: dh.c,v 1.51 2013/07/02 12:31:43 markus Exp $ */
|
||||
+/* $OpenBSD: dh.c,v 1.52 2013/10/08 11:42:13 dtucker Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Niels Provos. All rights reserved.
|
||||
*
|
||||
@@ -352,17 +352,20 @@ dh_new_group14(void)
|
||||
|
||||
/*
|
||||
* Estimates the group order for a Diffie-Hellman group that has an
|
||||
- * attack complexity approximately the same as O(2**bits). Estimate
|
||||
- * with: O(exp(1.9223 * (ln q)^(1/3) (ln ln q)^(2/3)))
|
||||
+ * attack complexity approximately the same as O(2**bits).
|
||||
+ * Values from NIST Special Publication 800-57: Recommendation for Key
|
||||
+ * Management Part 1 (rev 3) limited by the recommended maximum value
|
||||
+ * from RFC4419 section 3.
|
||||
*/
|
||||
|
||||
int
|
||||
dh_estimate(int bits)
|
||||
{
|
||||
-
|
||||
+ if (bits <= 112)
|
||||
+ return 2048;
|
||||
if (bits <= 128)
|
||||
- return (1024); /* O(2**86) */
|
||||
+ return 3072;
|
||||
if (bits <= 192)
|
||||
- return (2048); /* O(2**116) */
|
||||
- return (4096); /* O(2**156) */
|
||||
+ return 7680;
|
||||
+ return 8192;
|
||||
}
|
||||
diff -up openssh-6.3p1/dh.h.df openssh-6.3p1/dh.h
|
||||
--- openssh-6.3p1/dh.h.df 2008-06-29 14:47:04.000000000 +0200
|
||||
+++ openssh-6.3p1/dh.h 2013-10-23 22:38:03.476272461 +0200
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: dh.h,v 1.10 2008/06/26 09:19:40 djm Exp $ */
|
||||
+/* $OpenBSD: dh.h,v 1.11 2013/10/08 11:42:13 dtucker Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Niels Provos. All rights reserved.
|
||||
@@ -43,6 +43,7 @@ int dh_pub_is_valid(DH *, BIGNUM *);
|
||||
|
||||
int dh_estimate(int);
|
||||
|
||||
+/* Min and max values from RFC4419. */
|
||||
#define DH_GRP_MIN 1024
|
||||
#define DH_GRP_MAX 8192
|
||||
|
||||
|
|
@ -1,247 +0,0 @@
|
|||
diff -up openssh-6.3p1/auth-krb5.c.ccache_name openssh-6.3p1/auth-krb5.c
|
||||
--- openssh-6.3p1/auth-krb5.c.ccache_name 2013-10-23 22:03:52.322950759 +0200
|
||||
+++ openssh-6.3p1/auth-krb5.c 2013-10-23 22:04:24.295799873 +0200
|
||||
@@ -50,7 +50,9 @@
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
+#include <sys/stat.h>
|
||||
#include <krb5.h>
|
||||
+#include <profile.h>
|
||||
|
||||
extern ServerOptions options;
|
||||
|
||||
@@ -91,6 +93,7 @@ auth_krb5_password(Authctxt *authctxt, c
|
||||
#endif
|
||||
krb5_error_code problem;
|
||||
krb5_ccache ccache = NULL;
|
||||
+ const char *ccache_type;
|
||||
int len;
|
||||
char *client, *platform_client;
|
||||
const char *errmsg;
|
||||
@@ -191,12 +194,30 @@ auth_krb5_password(Authctxt *authctxt, c
|
||||
goto out;
|
||||
#endif
|
||||
|
||||
+ ccache_type = krb5_cc_get_type(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
|
||||
authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
|
||||
|
||||
- len = strlen(authctxt->krb5_ticket_file) + 6;
|
||||
+ if (authctxt->krb5_ticket_file[0] == ':')
|
||||
+ authctxt->krb5_ticket_file++;
|
||||
+
|
||||
+ len = strlen(authctxt->krb5_ticket_file) + strlen(ccache_type);
|
||||
authctxt->krb5_ccname = xmalloc(len);
|
||||
- snprintf(authctxt->krb5_ccname, len, "FILE:%s",
|
||||
+
|
||||
+#ifdef USE_CCAPI
|
||||
+ snprintf(authctxt->krb5_ccname, len, "API:%s",
|
||||
authctxt->krb5_ticket_file);
|
||||
+#else
|
||||
+ snprintf(authctxt->krb5_ccname, len, "%s:%s",
|
||||
+ ccache_type, authctxt->krb5_ticket_file);
|
||||
+#endif
|
||||
+
|
||||
+ if (strcmp(ccache_type, "DIR") == 0) {
|
||||
+ char *p;
|
||||
+ p = strrchr(authctxt->krb5_ccname, '/');
|
||||
+ if (p)
|
||||
+ *p = '\0';
|
||||
+ }
|
||||
+
|
||||
|
||||
#ifdef USE_PAM
|
||||
if (options.use_pam)
|
||||
@@ -235,10 +256,34 @@ auth_krb5_password(Authctxt *authctxt, c
|
||||
void
|
||||
krb5_cleanup_proc(Authctxt *authctxt)
|
||||
{
|
||||
+ struct stat krb5_ccname_stat;
|
||||
+ char krb5_ccname[128], *krb5_ccname_dir_start, *krb5_ccname_dir_end;
|
||||
+
|
||||
debug("krb5_cleanup_proc called");
|
||||
if (authctxt->krb5_fwd_ccache) {
|
||||
krb5_cc_destroy(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
|
||||
authctxt->krb5_fwd_ccache = NULL;
|
||||
+
|
||||
+ strncpy(krb5_ccname, authctxt->krb5_ccname, sizeof(krb5_ccname) - 10);
|
||||
+ krb5_ccname_dir_start = strchr(krb5_ccname, ':') + 1;
|
||||
+ *krb5_ccname_dir_start++ = '\0';
|
||||
+ if (strcmp(krb5_ccname, "DIR") == 0) {
|
||||
+
|
||||
+ strcat(krb5_ccname_dir_start, "/primary");
|
||||
+
|
||||
+ if (stat(krb5_ccname_dir_start, &krb5_ccname_stat) == 0) {
|
||||
+ if (unlink(krb5_ccname_dir_start) == 0) {
|
||||
+ krb5_ccname_dir_end = strrchr(krb5_ccname_dir_start, '/');
|
||||
+ *krb5_ccname_dir_end = '\0';
|
||||
+ if (rmdir(krb5_ccname_dir_start) == -1)
|
||||
+ debug("cache dir '%s' remove failed: %s", krb5_ccname_dir_start, strerror(errno));
|
||||
+ }
|
||||
+ else
|
||||
+ debug("cache primary file '%s', remove failed: %s",
|
||||
+ krb5_ccname_dir_start, strerror(errno)
|
||||
+ );
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
if (authctxt->krb5_user) {
|
||||
krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user);
|
||||
@@ -250,34 +295,139 @@ krb5_cleanup_proc(Authctxt *authctxt)
|
||||
}
|
||||
}
|
||||
|
||||
+int
|
||||
+ssh_asprintf_append(char **dsc, const char *fmt, ...) {
|
||||
+ char *src, *old;
|
||||
+ va_list ap;
|
||||
+ int i;
|
||||
+
|
||||
+ va_start(ap, fmt);
|
||||
+ i = vasprintf(&src, fmt, ap);
|
||||
+ va_end(ap);
|
||||
+
|
||||
+ if (i == -1 || src == NULL)
|
||||
+ return -1;
|
||||
+
|
||||
+ old = *dsc;
|
||||
+
|
||||
+ i = asprintf(dsc, "%s%s", *dsc, src);
|
||||
+ if (i == -1 || src == NULL) {
|
||||
+ free(src);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ free(old);
|
||||
+ free(src);
|
||||
+
|
||||
+ return i;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+ssh_krb5_expand_template(char **result, const char *template) {
|
||||
+ char *p_n, *p_o, *r, *tmp_template;
|
||||
+
|
||||
+ if (template == NULL)
|
||||
+ return -1;
|
||||
+
|
||||
+ tmp_template = p_n = p_o = xstrdup(template);
|
||||
+ r = xstrdup("");
|
||||
+
|
||||
+ while ((p_n = strstr(p_o, "%{")) != NULL) {
|
||||
+
|
||||
+ *p_n++ = '\0';
|
||||
+ if (ssh_asprintf_append(&r, "%s", p_o) == -1)
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ if (strncmp(p_n, "{uid}", 5) == 0 || strncmp(p_n, "{euid}", 6) == 0 ||
|
||||
+ strncmp(p_n, "{USERID}", 8) == 0) {
|
||||
+ p_o = strchr(p_n, '}') + 1;
|
||||
+ if (ssh_asprintf_append(&r, "%d", geteuid()) == -1)
|
||||
+ goto cleanup;
|
||||
+ continue;
|
||||
+ }
|
||||
+ else if (strncmp(p_n, "{TEMP}", 6) == 0) {
|
||||
+ p_o = strchr(p_n, '}') + 1;
|
||||
+ if (ssh_asprintf_append(&r, "/tmp") == -1)
|
||||
+ goto cleanup;
|
||||
+ continue;
|
||||
+ } else {
|
||||
+ p_o = strchr(p_n, '}') + 1;
|
||||
+ p_o = '\0';
|
||||
+ debug("%s: unsupported token %s in %s", __func__, p_n, template);
|
||||
+ /* unknown token, fallback to the default */
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (ssh_asprintf_append(&r, "%s", p_o) == -1)
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ *result = r;
|
||||
+ free(tmp_template);
|
||||
+ return 0;
|
||||
+
|
||||
+cleanup:
|
||||
+ free(r);
|
||||
+ free(tmp_template);
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+krb5_error_code
|
||||
+ssh_krb5_get_cctemplate(krb5_context ctx, char **ccname) {
|
||||
+ profile_t p;
|
||||
+ int ret = 0;
|
||||
+ char *value = NULL;
|
||||
+
|
||||
+ ret = krb5_get_profile(ctx, &p);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = profile_get_string(p, "libdefaults", "default_ccache_name", NULL, NULL, &value);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = ssh_krb5_expand_template(ccname, value);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
#ifndef HEIMDAL
|
||||
krb5_error_code
|
||||
ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) {
|
||||
int tmpfd, ret, oerrno;
|
||||
- char ccname[40];
|
||||
+ char *ccname;
|
||||
+#ifdef USE_CCAPI
|
||||
+ char cctemplate[] = "API:krb5cc_%d";
|
||||
+#else
|
||||
mode_t old_umask;
|
||||
+ char cctemplate[] = "FILE:/tmp/krb5cc_%d_XXXXXXXXXX";
|
||||
|
||||
- ret = snprintf(ccname, sizeof(ccname),
|
||||
- "FILE:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid());
|
||||
- if (ret < 0 || (size_t)ret >= sizeof(ccname))
|
||||
- return ENOMEM;
|
||||
-
|
||||
- old_umask = umask(0177);
|
||||
- tmpfd = mkstemp(ccname + strlen("FILE:"));
|
||||
- oerrno = errno;
|
||||
- umask(old_umask);
|
||||
- if (tmpfd == -1) {
|
||||
- logit("mkstemp(): %.100s", strerror(oerrno));
|
||||
- return oerrno;
|
||||
- }
|
||||
+#endif
|
||||
+
|
||||
+ ret = ssh_krb5_get_cctemplate(ctx, &ccname);
|
||||
|
||||
- if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) {
|
||||
+ if (ret) {
|
||||
+ ret = asprintf(&ccname, cctemplate, geteuid());
|
||||
+ if (ret == -1)
|
||||
+ return ENOMEM;
|
||||
+ old_umask = umask(0177);
|
||||
+ tmpfd = mkstemp(ccname + strlen("FILE:"));
|
||||
oerrno = errno;
|
||||
- logit("fchmod(): %.100s", strerror(oerrno));
|
||||
+ umask(old_umask);
|
||||
+ if (tmpfd == -1) {
|
||||
+ logit("mkstemp(): %.100s", strerror(oerrno));
|
||||
+ return oerrno;
|
||||
+ }
|
||||
+
|
||||
+ if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) {
|
||||
+ oerrno = errno;
|
||||
+ logit("fchmod(): %.100s", strerror(oerrno));
|
||||
+ close(tmpfd);
|
||||
+ return oerrno;
|
||||
+ }
|
||||
close(tmpfd);
|
||||
- return oerrno;
|
||||
}
|
||||
- close(tmpfd);
|
||||
+ debug("%s: Setting ccname to %s", __func__, ccname);
|
||||
|
||||
return (krb5_cc_resolve(ctx, ccname, ccache));
|
||||
}
|
||||
|
|
@ -1,167 +0,0 @@
|
|||
diff -up openssh-6.3p1/auth-krb5.c.kuserok openssh-6.3p1/auth-krb5.c
|
||||
--- openssh-6.3p1/auth-krb5.c.kuserok 2013-10-11 21:41:42.889087613 +0200
|
||||
+++ openssh-6.3p1/auth-krb5.c 2013-10-11 21:41:42.905087537 +0200
|
||||
@@ -55,6 +55,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)
|
||||
{
|
||||
@@ -159,7 +173,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-6.3p1/gss-serv-krb5.c.kuserok openssh-6.3p1/gss-serv-krb5.c
|
||||
--- openssh-6.3p1/gss-serv-krb5.c.kuserok 2013-10-11 21:41:42.901087556 +0200
|
||||
+++ openssh-6.3p1/gss-serv-krb5.c 2013-10-11 21:46:42.898673597 +0200
|
||||
@@ -67,6 +67,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 */
|
||||
|
||||
@@ -116,7 +117,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, name) && k5login_exists) {
|
||||
+ if (ssh_krb5_kuserok(krb_context, princ, name) && k5login_exists) {
|
||||
retval = 1;
|
||||
logit("Authorized to %s, krb5 principal %s (krb5_kuserok)",
|
||||
name, (char *)client->displayname.value);
|
||||
diff -up openssh-6.3p1/servconf.c.kuserok openssh-6.3p1/servconf.c
|
||||
--- openssh-6.3p1/servconf.c.kuserok 2013-10-11 21:41:42.896087580 +0200
|
||||
+++ openssh-6.3p1/servconf.c 2013-10-11 21:48:24.664194016 +0200
|
||||
@@ -157,6 +157,7 @@ initialize_server_options(ServerOptions
|
||||
options->ip_qos_interactive = -1;
|
||||
options->ip_qos_bulk = -1;
|
||||
options->version_addendum = NULL;
|
||||
+ options->use_kuserok = -1;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -310,6 +311,8 @@ fill_default_server_options(ServerOption
|
||||
options->version_addendum = xstrdup("");
|
||||
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)
|
||||
@@ -336,7 +339,7 @@ typedef enum {
|
||||
sPermitRootLogin, sLogFacility, sLogLevel,
|
||||
sRhostsRSAAuthentication, sRSAAuthentication,
|
||||
sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
|
||||
- sKerberosGetAFSToken,
|
||||
+ sKerberosGetAFSToken, sKerberosUseKuserok,
|
||||
sKerberosTgtPassing, sChallengeResponseAuthentication,
|
||||
sPasswordAuthentication, sKbdInteractiveAuthentication,
|
||||
sListenAddress, sAddressFamily,
|
||||
@@ -409,11 +412,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 },
|
||||
@@ -1515,6 +1520,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')
|
||||
@@ -1815,6 +1824,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);
|
||||
M_CP_INTOPT(rekey_limit);
|
||||
M_CP_INTOPT(rekey_interval);
|
||||
|
||||
@@ -2055,6 +2065,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-6.3p1/servconf.h.kuserok openssh-6.3p1/servconf.h
|
||||
--- openssh-6.3p1/servconf.h.kuserok 2013-10-11 21:41:42.896087580 +0200
|
||||
+++ openssh-6.3p1/servconf.h 2013-10-11 21:41:42.907087528 +0200
|
||||
@@ -174,6 +174,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-6.3p1/sshd_config.5.kuserok openssh-6.3p1/sshd_config.5
|
||||
--- openssh-6.3p1/sshd_config.5.kuserok 2013-10-11 21:41:42.898087571 +0200
|
||||
+++ openssh-6.3p1/sshd_config.5 2013-10-11 21:41:42.907087528 +0200
|
||||
@@ -675,6 +675,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.
|
||||
@@ -833,6 +837,7 @@ Available keywords are
|
||||
.Cm HostbasedUsesNameFromPacketOnly ,
|
||||
.Cm KbdInteractiveAuthentication ,
|
||||
.Cm KerberosAuthentication ,
|
||||
+.Cm KerberosUseKuserok ,
|
||||
.Cm MaxAuthTries ,
|
||||
.Cm MaxSessions ,
|
||||
.Cm PasswordAuthentication ,
|
||||
diff -up openssh-6.3p1/sshd_config.kuserok openssh-6.3p1/sshd_config
|
||||
--- openssh-6.3p1/sshd_config.kuserok 2013-10-11 21:41:42.898087571 +0200
|
||||
+++ openssh-6.3p1/sshd_config 2013-10-11 21:41:42.907087528 +0200
|
||||
@@ -86,6 +86,7 @@ ChallengeResponseAuthentication no
|
||||
#KerberosOrLocalPasswd yes
|
||||
#KerberosTicketCleanup yes
|
||||
#KerberosGetAFSToken no
|
||||
+#KerberosUseKuserok yes
|
||||
|
||||
# GSSAPI options
|
||||
#GSSAPIAuthentication no
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,104 +0,0 @@
|
|||
diff -up openssh-6.3p1/openbsd-compat/port-linux.c.privsep-selinux openssh-6.3p1/openbsd-compat/port-linux.c
|
||||
--- openssh-6.3p1/openbsd-compat/port-linux.c.privsep-selinux 2013-10-10 14:58:20.634762245 +0200
|
||||
+++ openssh-6.3p1/openbsd-compat/port-linux.c 2013-10-10 15:13:57.864306950 +0200
|
||||
@@ -503,6 +503,25 @@ ssh_selinux_change_context(const char *n
|
||||
free(newctx);
|
||||
}
|
||||
|
||||
+void
|
||||
+ssh_selinux_copy_context(void)
|
||||
+{
|
||||
+ security_context_t *ctx;
|
||||
+
|
||||
+ if (!ssh_selinux_enabled())
|
||||
+ return;
|
||||
+
|
||||
+ if (getexeccon((security_context_t *)&ctx) != 0) {
|
||||
+ logit("%s: getcon failed with %s", __func__, strerror (errno));
|
||||
+ return;
|
||||
+ }
|
||||
+ if (ctx != NULL) {
|
||||
+ if (setcon(ctx) != 0)
|
||||
+ logit("%s: setcon failed with %s", __func__, strerror (errno));
|
||||
+ freecon(ctx);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
#endif /* WITH_SELINUX */
|
||||
|
||||
#ifdef LINUX_OOM_ADJUST
|
||||
diff -up openssh-6.3p1/openbsd-compat/port-linux.h.privsep-selinux openssh-6.3p1/openbsd-compat/port-linux.h
|
||||
--- openssh-6.3p1/openbsd-compat/port-linux.h.privsep-selinux 2011-01-25 02:16:18.000000000 +0100
|
||||
+++ openssh-6.3p1/openbsd-compat/port-linux.h 2013-10-10 14:58:20.634762245 +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_copy_context(void);
|
||||
void ssh_selinux_setfscreatecon(const char *);
|
||||
#endif
|
||||
|
||||
diff -up openssh-6.3p1/session.c.privsep-selinux openssh-6.3p1/session.c
|
||||
--- openssh-6.3p1/session.c.privsep-selinux 2013-10-10 14:58:20.617762326 +0200
|
||||
+++ openssh-6.3p1/session.c 2013-10-10 15:13:16.520503590 +0200
|
||||
@@ -1522,6 +1522,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_copy_context();
|
||||
+#endif
|
||||
safely_chroot(chroot_path, pw->pw_uid);
|
||||
free(tmp);
|
||||
free(chroot_path);
|
||||
@@ -1544,6 +1547,12 @@ do_setusercontext(struct passwd *pw)
|
||||
/* Permanently switch to the desired uid. */
|
||||
permanently_set_uid(pw);
|
||||
#endif
|
||||
+
|
||||
+#ifdef WITH_SELINUX
|
||||
+ if (options.chroot_directory == NULL ||
|
||||
+ strcasecmp(options.chroot_directory, "none") == 0)
|
||||
+ ssh_selinux_copy_context();
|
||||
+#endif
|
||||
} else if (options.chroot_directory != NULL &&
|
||||
strcasecmp(options.chroot_directory, "none") != 0) {
|
||||
fatal("server lacks privileges to chroot to ChrootDirectory");
|
||||
@@ -1808,9 +1817,6 @@ do_child(Session *s, const char *command
|
||||
argv[i] = NULL;
|
||||
optind = optreset = 1;
|
||||
__progname = argv[0];
|
||||
-#ifdef WITH_SELINUX
|
||||
- ssh_selinux_change_context("sftpd_t");
|
||||
-#endif
|
||||
exit(sftp_server_main(i, argv, s->pw));
|
||||
}
|
||||
|
||||
diff -up openssh-6.3p1/sshd.c.privsep-selinux openssh-6.3p1/sshd.c
|
||||
--- openssh-6.3p1/sshd.c.privsep-selinux 2013-10-10 14:58:20.632762255 +0200
|
||||
+++ openssh-6.3p1/sshd.c 2013-10-10 14:58:20.635762241 +0200
|
||||
@@ -668,6 +668,10 @@ privsep_preauth_child(void)
|
||||
/* Demote the private keys to public keys. */
|
||||
demote_sensitive_data();
|
||||
|
||||
+#ifdef WITH_SELINUX
|
||||
+ ssh_selinux_change_context("sshd_net_t");
|
||||
+#endif
|
||||
+
|
||||
/* Change our root directory */
|
||||
if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1)
|
||||
fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR,
|
||||
@@ -811,6 +815,13 @@ privsep_postauth(Authctxt *authctxt)
|
||||
do_setusercontext(authctxt->pw);
|
||||
|
||||
skip:
|
||||
+#ifdef WITH_SELINUX
|
||||
+ /* switch SELinux content for root too */
|
||||
+ if (authctxt->pw->pw_uid == 0) {
|
||||
+ ssh_selinux_copy_context();
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
/* It is safe now to apply the key state */
|
||||
monitor_apply_keystate(pmonitor);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue