diff options
author | Colin Watson <cjwatson@debian.org> | 2019-06-05 06:41:44 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2019-06-09 22:09:07 +0100 |
commit | 865a97e05b6aab1619e1c8eeb33ccb8f9a9e48d3 (patch) | |
tree | 7bb2128eb663180bacfabca88f26d26bf0733824 /debian | |
parent | ba627ba172d6649919baedff5ba2789610da382a (diff) | |
parent | 7d50f9e5be88179325983a1f58c9d51bb58f025a (diff) |
New upstream release (8.0p1)
Diffstat (limited to 'debian')
39 files changed, 2039 insertions, 2228 deletions
diff --git a/debian/.git-dpm b/debian/.git-dpm index 65e73673d..46a4f4209 100644 --- a/debian/.git-dpm +++ b/debian/.git-dpm | |||
@@ -1,11 +1,12 @@ | |||
1 | # see git-dpm(1) from git-dpm package | 1 | # see git-dpm(1) from git-dpm package |
2 | 6b56cd57db9061296231f14d537f1ebaf25e8877 | 2 | 7d50f9e5be88179325983a1f58c9d51bb58f025a |
3 | 6b56cd57db9061296231f14d537f1ebaf25e8877 | 3 | 7d50f9e5be88179325983a1f58c9d51bb58f025a |
4 | 3d246f10429fc9a37b98eabef94fe8dc7c61002b | 4 | 102062f825fb26a74295a1c089c00c4c4c76b68a |
5 | 3d246f10429fc9a37b98eabef94fe8dc7c61002b | 5 | 102062f825fb26a74295a1c089c00c4c4c76b68a |
6 | openssh_7.9p1.orig.tar.gz | 6 | openssh_8.0p1.orig.tar.gz |
7 | 993aceedea8ecabb1d0dd7293508a361891c4eaa | 7 | 756dbb99193f9541c9206a667eaa27b0fa184a4f |
8 | 1565384 | 8 | 1597697 |
9 | debianTag="debian/%e%%%V" | 9 | debianTag="debian/%e%%%V" |
10 | patchedTag="patched/%e%%%V" | 10 | patchedTag="patched/%e%%%V" |
11 | upstreamTag="upstream/%U" | 11 | upstreamTag="upstream/%U" |
12 | signature:a287987d9d505aaa8a89e693920f14b9b9e27a5f:683:openssh_8.0p1.orig.tar.gz.asc | ||
diff --git a/debian/NEWS b/debian/NEWS index c0a535cf2..c8d01545f 100644 --- a/debian/NEWS +++ b/debian/NEWS | |||
@@ -1,3 +1,17 @@ | |||
1 | openssh (1:8.0p1-1) unstable; urgency=medium | ||
2 | |||
3 | OpenSSH 8.0 includes a number of changes that may affect existing | ||
4 | configurations: | ||
5 | |||
6 | * sshd(8): Remove support for obsolete "host/port" syntax. | ||
7 | Slash-separated host/port was added in 2001 as an alternative to | ||
8 | host:port syntax for the benefit of IPv6 users. These days there are | ||
9 | established standards for this like [::1]:22 and the slash syntax is | ||
10 | easily mistaken for CIDR notation, which OpenSSH supports for some | ||
11 | things. Remove the slash notation from ListenAddress and PermitOpen. | ||
12 | |||
13 | -- Colin Watson <cjwatson@debian.org> Wed, 05 Jun 2019 07:09:47 +0100 | ||
14 | |||
1 | openssh (1:7.9p1-1) unstable; urgency=medium | 15 | openssh (1:7.9p1-1) unstable; urgency=medium |
2 | 16 | ||
3 | OpenSSH 7.9 includes a number of changes that may affect existing | 17 | OpenSSH 7.9 includes a number of changes that may affect existing |
diff --git a/debian/changelog b/debian/changelog index 8b18f3506..c272f8fc8 100644 --- a/debian/changelog +++ b/debian/changelog | |||
@@ -1,3 +1,129 @@ | |||
1 | openssh (1:8.0p1-1) UNRELEASED; urgency=medium | ||
2 | |||
3 | * New upstream release (https://www.openssh.com/txt/release-8.0, closes: | ||
4 | #927792): | ||
5 | - ssh(1), ssh-agent(1), ssh-add(1): Add support for ECDSA keys in | ||
6 | PKCS#11 tokens (LP: #1665695). | ||
7 | - ssh(1), sshd(8): Add experimental quantum-computing resistant key | ||
8 | exchange method, based on a combination of Streamlined NTRU Prime | ||
9 | 4591^761 and X25519. | ||
10 | - ssh-keygen(1): Increase the default RSA key size to 3072 bits, | ||
11 | following NIST Special Publication 800-57's guidance for a 128-bit | ||
12 | equivalent symmetric security level (LP: #1445625). | ||
13 | - ssh(1): Allow "PKCS11Provider=none" to override later instances of the | ||
14 | PKCS11Provider directive in ssh_config. | ||
15 | - sshd(8): Add a log message for situations where a connection is | ||
16 | dropped for attempting to run a command but a sshd_config | ||
17 | ForceCommand=internal-sftp restriction is in effect. | ||
18 | - ssh(1): When prompting whether to record a new host key, accept the | ||
19 | key fingerprint as a synonym for "yes". This allows the user to paste | ||
20 | a fingerprint obtained out of band at the prompt and have the client | ||
21 | do the comparison for you. | ||
22 | - ssh-keygen(1): When signing multiple certificates on a single | ||
23 | command-line invocation, allow automatically incrementing the | ||
24 | certificate serial number. | ||
25 | - scp(1), sftp(1): Accept -J option as an alias to ProxyJump on the scp | ||
26 | and sftp command-lines. | ||
27 | - ssh-agent(1), ssh-pkcs11-helper(8), ssh-add(1): Accept "-v" | ||
28 | command-line flags to increase the verbosity of output; pass verbose | ||
29 | flags though to subprocesses, such as ssh-pkcs11-helper started from | ||
30 | ssh-agent. | ||
31 | - ssh-add(1): Add a "-T" option to allowing testing whether keys in an | ||
32 | agent are usable by performing a signature and a verification. | ||
33 | - sftp-server(8): Add a "lsetstat@openssh.com" protocol extension that | ||
34 | replicates the functionality of the existing SSH2_FXP_SETSTAT | ||
35 | operation but does not follow symlinks. | ||
36 | - sftp(1): Add "-h" flag to chown/chgrp/chmod commands to request they | ||
37 | do not follow symlinks. | ||
38 | - sshd(8): Expose $SSH_CONNECTION in the PAM environment. This makes | ||
39 | the connection 4-tuple available to PAM modules that wish to use it in | ||
40 | decision-making. | ||
41 | - sshd(8): Add a ssh_config "Match final" predicate. Matches in same | ||
42 | pass as "Match canonical" but doesn't require hostname | ||
43 | canonicalisation be enabled. | ||
44 | - sftp(1): Support a prefix of '@' to suppress echo of sftp batch | ||
45 | commands. | ||
46 | - ssh-keygen(1): When printing certificate contents using "ssh-keygen | ||
47 | -Lf /path/certificate", include the algorithm that the CA used to sign | ||
48 | the cert. | ||
49 | - sshd(8): Fix authentication failures when sshd_config contains | ||
50 | "AuthenticationMethods any" inside a Match block that overrides a more | ||
51 | restrictive default. | ||
52 | - sshd(8): Avoid sending duplicate keepalives when ClientAliveCount is | ||
53 | enabled. | ||
54 | - sshd(8): Fix two race conditions related to SIGHUP daemon restart. | ||
55 | Remnant file descriptors in recently-forked child processes could | ||
56 | block the parent sshd's attempt to listen(2) to the configured | ||
57 | addresses. Also, the restarting parent sshd could exit before any | ||
58 | child processes that were awaiting their re-execution state had | ||
59 | completed reading it, leaving them in a fallback path. | ||
60 | - ssh(1): Fix stdout potentially being redirected to /dev/null when | ||
61 | ProxyCommand=- was in use. | ||
62 | - sshd(8): Avoid sending SIGPIPE to child processes if they attempt to | ||
63 | write to stderr after their parent processes have exited. | ||
64 | - ssh(1): Fix bad interaction between the ssh_config ConnectTimeout and | ||
65 | ConnectionAttempts directives - connection attempts after the first | ||
66 | were ignoring the requested timeout (LP: #1798049). | ||
67 | - ssh-keyscan(1): Return a non-zero exit status if no keys were found | ||
68 | (closes: #374980, LP: #1661745). | ||
69 | - scp(1): Sanitize scp filenames to allow UTF-8 characters without | ||
70 | terminal control sequences. | ||
71 | - sshd(8): Fix confusion between ClientAliveInterval and time-based | ||
72 | RekeyLimit that could cause connections to be incorrectly closed. | ||
73 | - ssh(1), ssh-add(1): Correct some bugs in PKCS#11 token PIN handling at | ||
74 | initial token login. The attempt to read the PIN could be skipped in | ||
75 | some cases, particularly on devices with integrated PIN readers. This | ||
76 | would lead to an inability to retrieve keys from these tokens. | ||
77 | - ssh(1), ssh-add(1): Support keys on PKCS#11 tokens that set the | ||
78 | CKA_ALWAYS_AUTHENTICATE flag by requring a fresh login after the | ||
79 | C_SignInit operation. | ||
80 | - ssh(1): Improve documentation for ProxyJump/-J, clarifying that local | ||
81 | configuration does not apply to jump hosts. | ||
82 | - ssh-keygen(1): Clarify manual - ssh-keygen -e only writes public keys, | ||
83 | not private. | ||
84 | - ssh(1), sshd(8): be more strict in processing protocol banners, | ||
85 | allowing \r characters only immediately before \n. | ||
86 | - Various: fix a number of memory leaks. | ||
87 | - scp(1), sftp(1): fix calculation of initial bandwidth limits. Account | ||
88 | for bytes written before the timer starts and adjust the schedule on | ||
89 | which recalculations are performed. Avoids an initial burst of | ||
90 | traffic and yields more accurate bandwidth limits. | ||
91 | - sshd(8): Only consider the ext-info-c extension during the initial key | ||
92 | eschange. It shouldn't be sent in subsequent ones, but if it is | ||
93 | present we should ignore it. This prevents sshd from sending a | ||
94 | SSH_MSG_EXT_INFO for REKEX for these buggy clients. | ||
95 | - ssh-keygen(1): Clarify manual that ssh-keygen -F (find host in | ||
96 | authorized_keys) and -R (remove host from authorized_keys) options may | ||
97 | accept either a bare hostname or a [hostname]:port combo. | ||
98 | - ssh(1): Don't attempt to connect to empty SSH_AUTH_SOCK. | ||
99 | - sshd(8): Silence error messages when sshd fails to load some of the | ||
100 | default host keys. Failure to load an explicitly-configured hostkey | ||
101 | is still an error, and failure to load any host key is still fatal. | ||
102 | - ssh(1): Redirect stderr of ProxyCommands to /dev/null when ssh is | ||
103 | started with ControlPersist; prevents random ProxyCommand output from | ||
104 | interfering with session output. | ||
105 | - ssh(1): The ssh client was keeping a redundant ssh-agent socket | ||
106 | (leftover from authentication) around for the life of the connection. | ||
107 | - sshd(8): Fix bug in HostbasedAcceptedKeyTypes and | ||
108 | PubkeyAcceptedKeyTypes options. If only RSA-SHA2 signature types were | ||
109 | specified, then authentication would always fail for RSA keys as the | ||
110 | monitor checks only the base key (not the signature algorithm) type | ||
111 | against *AcceptedKeyTypes. | ||
112 | - ssh(1): Request correct signature types from ssh-agent when | ||
113 | certificate keys and RSA-SHA2 signatures are in use. | ||
114 | - sshd(8): Don't set $MAIL if UsePAM=yes as PAM typically specifies the | ||
115 | user environment if it's enabled (closes: #189920, #532754). | ||
116 | * Mostly resynced GSSAPI key exchange patch with Fedora. Major changes: | ||
117 | - Support selection of GSSAPI key exchange algorithms. | ||
118 | - Support GSSAPI key exchange methods with DH and SHA2. | ||
119 | - Support GSSAPI key exchange using ECDH and SHA2. | ||
120 | - Make sure the Kerberos tickets are cleaned up with the user context. | ||
121 | - Enable gssapi-keyex authentication without gssapi-with-mic. | ||
122 | - Allow querying for GSSAPI key exchange algorithms from ssh (-Q | ||
123 | kex-gss). | ||
124 | |||
125 | -- Colin Watson <cjwatson@debian.org> Wed, 05 Jun 2019 07:09:47 +0100 | ||
126 | |||
1 | openssh (1:7.9p1-10) unstable; urgency=medium | 127 | openssh (1:7.9p1-10) unstable; urgency=medium |
2 | 128 | ||
3 | * Temporarily revert IPQoS defaults to pre-7.8 values until issues with | 129 | * Temporarily revert IPQoS defaults to pre-7.8 values until issues with |
diff --git a/debian/openssh-client.docs b/debian/openssh-client.docs index d80ec1262..11aa99402 100644 --- a/debian/openssh-client.docs +++ b/debian/openssh-client.docs | |||
@@ -1,4 +1,3 @@ | |||
1 | ChangeLog.gssapi | ||
2 | OVERVIEW | 1 | OVERVIEW |
3 | README | 2 | README |
4 | README.dns | 3 | README.dns |
diff --git a/debian/patches/authorized-keys-man-symlink.patch b/debian/patches/authorized-keys-man-symlink.patch index c895e63db..3e5fac6e1 100644 --- a/debian/patches/authorized-keys-man-symlink.patch +++ b/debian/patches/authorized-keys-man-symlink.patch | |||
@@ -1,4 +1,4 @@ | |||
1 | From 67a6cbb29f77920718884e783238f4a00fe64001 Mon Sep 17 00:00:00 2001 | 1 | From f9a76ef65bfb6c17d613ab3db2bf39db5087adfc Mon Sep 17 00:00:00 2001 |
2 | From: Tomas Pospisek <tpo_deb@sourcepole.ch> | 2 | From: Tomas Pospisek <tpo_deb@sourcepole.ch> |
3 | Date: Sun, 9 Feb 2014 16:10:07 +0000 | 3 | Date: Sun, 9 Feb 2014 16:10:07 +0000 |
4 | Subject: Install authorized_keys(5) as a symlink to sshd(8) | 4 | Subject: Install authorized_keys(5) as a symlink to sshd(8) |
@@ -13,10 +13,10 @@ Patch-Name: authorized-keys-man-symlink.patch | |||
13 | 1 file changed, 1 insertion(+) | 13 | 1 file changed, 1 insertion(+) |
14 | 14 | ||
15 | diff --git a/Makefile.in b/Makefile.in | 15 | diff --git a/Makefile.in b/Makefile.in |
16 | index 70050ffb6..ee166114d 100644 | 16 | index c31821acc..0960a6a03 100644 |
17 | --- a/Makefile.in | 17 | --- a/Makefile.in |
18 | +++ b/Makefile.in | 18 | +++ b/Makefile.in |
19 | @@ -356,6 +356,7 @@ install-files: | 19 | @@ -357,6 +357,7 @@ install-files: |
20 | $(INSTALL) -m 644 sshd_config.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/sshd_config.5 | 20 | $(INSTALL) -m 644 sshd_config.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/sshd_config.5 |
21 | $(INSTALL) -m 644 ssh_config.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/ssh_config.5 | 21 | $(INSTALL) -m 644 ssh_config.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/ssh_config.5 |
22 | $(INSTALL) -m 644 sshd.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sshd.8 | 22 | $(INSTALL) -m 644 sshd.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sshd.8 |
diff --git a/debian/patches/check-filenames-in-scp-client.patch b/debian/patches/check-filenames-in-scp-client.patch deleted file mode 100644 index 519358ce6..000000000 --- a/debian/patches/check-filenames-in-scp-client.patch +++ /dev/null | |||
@@ -1,187 +0,0 @@ | |||
1 | From 125924e47db3713a85a70e0f8d6c23818d2ea054 Mon Sep 17 00:00:00 2001 | ||
2 | From: "djm@openbsd.org" <djm@openbsd.org> | ||
3 | Date: Sat, 26 Jan 2019 22:41:28 +0000 | ||
4 | Subject: upstream: check in scp client that filenames sent during | ||
5 | |||
6 | remote->local directory copies satisfy the wildcard specified by the user. | ||
7 | |||
8 | This checking provides some protection against a malicious server | ||
9 | sending unexpected filenames, but it comes at a risk of rejecting wanted | ||
10 | files due to differences between client and server wildcard expansion rules. | ||
11 | |||
12 | For this reason, this also adds a new -T flag to disable the check. | ||
13 | |||
14 | reported by Harry Sintonen | ||
15 | fix approach suggested by markus@; | ||
16 | has been in snaps for ~1wk courtesy deraadt@ | ||
17 | |||
18 | OpenBSD-Commit-ID: 00f44b50d2be8e321973f3c6d014260f8f7a8eda | ||
19 | |||
20 | CVE-2019-6111 | ||
21 | |||
22 | Origin: backport, https://anongit.mindrot.org/openssh.git/commit/?id=391ffc4b9d31fa1f4ad566499fef9176ff8a07dc | ||
23 | Last-Update: 2019-02-08 | ||
24 | |||
25 | Patch-Name: check-filenames-in-scp-client.patch | ||
26 | --- | ||
27 | scp.1 | 12 +++++++++++- | ||
28 | scp.c | 37 +++++++++++++++++++++++++++++-------- | ||
29 | 2 files changed, 40 insertions(+), 9 deletions(-) | ||
30 | |||
31 | diff --git a/scp.1 b/scp.1 | ||
32 | index 0e5cc1b2d..397e77091 100644 | ||
33 | --- a/scp.1 | ||
34 | +++ b/scp.1 | ||
35 | @@ -18,7 +18,7 @@ | ||
36 | .Nd secure copy (remote file copy program) | ||
37 | .Sh SYNOPSIS | ||
38 | .Nm scp | ||
39 | -.Op Fl 346BCpqrv | ||
40 | +.Op Fl 346BCpqrTv | ||
41 | .Op Fl c Ar cipher | ||
42 | .Op Fl F Ar ssh_config | ||
43 | .Op Fl i Ar identity_file | ||
44 | @@ -208,6 +208,16 @@ to use for the encrypted connection. | ||
45 | The program must understand | ||
46 | .Xr ssh 1 | ||
47 | options. | ||
48 | +.It Fl T | ||
49 | +Disable strict filename checking. | ||
50 | +By default when copying files from a remote host to a local directory | ||
51 | +.Nm | ||
52 | +checks that the received filenames match those requested on the command-line | ||
53 | +to prevent the remote end from sending unexpected or unwanted files. | ||
54 | +Because of differences in how various operating systems and shells interpret | ||
55 | +filename wildcards, these checks may cause wanted files to be rejected. | ||
56 | +This option disables these checks at the expense of fully trusting that | ||
57 | +the server will not send unexpected filenames. | ||
58 | .It Fl v | ||
59 | Verbose mode. | ||
60 | Causes | ||
61 | diff --git a/scp.c b/scp.c | ||
62 | index 1971c80cd..035037bcc 100644 | ||
63 | --- a/scp.c | ||
64 | +++ b/scp.c | ||
65 | @@ -94,6 +94,7 @@ | ||
66 | #include <dirent.h> | ||
67 | #include <errno.h> | ||
68 | #include <fcntl.h> | ||
69 | +#include <fnmatch.h> | ||
70 | #include <limits.h> | ||
71 | #include <locale.h> | ||
72 | #include <pwd.h> | ||
73 | @@ -383,14 +384,14 @@ void verifydir(char *); | ||
74 | struct passwd *pwd; | ||
75 | uid_t userid; | ||
76 | int errs, remin, remout; | ||
77 | -int pflag, iamremote, iamrecursive, targetshouldbedirectory; | ||
78 | +int Tflag, pflag, iamremote, iamrecursive, targetshouldbedirectory; | ||
79 | |||
80 | #define CMDNEEDS 64 | ||
81 | char cmd[CMDNEEDS]; /* must hold "rcp -r -p -d\0" */ | ||
82 | |||
83 | int response(void); | ||
84 | void rsource(char *, struct stat *); | ||
85 | -void sink(int, char *[]); | ||
86 | +void sink(int, char *[], const char *); | ||
87 | void source(int, char *[]); | ||
88 | void tolocal(int, char *[]); | ||
89 | void toremote(int, char *[]); | ||
90 | @@ -429,8 +430,9 @@ main(int argc, char **argv) | ||
91 | addargs(&args, "-oRemoteCommand=none"); | ||
92 | addargs(&args, "-oRequestTTY=no"); | ||
93 | |||
94 | - fflag = tflag = 0; | ||
95 | - while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q12346S:o:F:")) != -1) | ||
96 | + fflag = Tflag = tflag = 0; | ||
97 | + while ((ch = getopt(argc, argv, | ||
98 | + "dfl:prtTvBCc:i:P:q12346S:o:F:")) != -1) { | ||
99 | switch (ch) { | ||
100 | /* User-visible flags. */ | ||
101 | case '1': | ||
102 | @@ -509,9 +511,13 @@ main(int argc, char **argv) | ||
103 | setmode(0, O_BINARY); | ||
104 | #endif | ||
105 | break; | ||
106 | + case 'T': | ||
107 | + Tflag = 1; | ||
108 | + break; | ||
109 | default: | ||
110 | usage(); | ||
111 | } | ||
112 | + } | ||
113 | argc -= optind; | ||
114 | argv += optind; | ||
115 | |||
116 | @@ -542,7 +548,7 @@ main(int argc, char **argv) | ||
117 | } | ||
118 | if (tflag) { | ||
119 | /* Receive data. */ | ||
120 | - sink(argc, argv); | ||
121 | + sink(argc, argv, NULL); | ||
122 | exit(errs != 0); | ||
123 | } | ||
124 | if (argc < 2) | ||
125 | @@ -800,7 +806,7 @@ tolocal(int argc, char **argv) | ||
126 | continue; | ||
127 | } | ||
128 | free(bp); | ||
129 | - sink(1, argv + argc - 1); | ||
130 | + sink(1, argv + argc - 1, src); | ||
131 | (void) close(remin); | ||
132 | remin = remout = -1; | ||
133 | } | ||
134 | @@ -976,7 +982,7 @@ rsource(char *name, struct stat *statp) | ||
135 | (sizeof(type) != 4 && sizeof(type) != 8)) | ||
136 | |||
137 | void | ||
138 | -sink(int argc, char **argv) | ||
139 | +sink(int argc, char **argv, const char *src) | ||
140 | { | ||
141 | static BUF buffer; | ||
142 | struct stat stb; | ||
143 | @@ -992,6 +998,7 @@ sink(int argc, char **argv) | ||
144 | unsigned long long ull; | ||
145 | int setimes, targisdir, wrerrno = 0; | ||
146 | char ch, *cp, *np, *targ, *why, *vect[1], buf[2048], visbuf[2048]; | ||
147 | + char *src_copy = NULL, *restrict_pattern = NULL; | ||
148 | struct timeval tv[2]; | ||
149 | |||
150 | #define atime tv[0] | ||
151 | @@ -1016,6 +1023,17 @@ sink(int argc, char **argv) | ||
152 | (void) atomicio(vwrite, remout, "", 1); | ||
153 | if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode)) | ||
154 | targisdir = 1; | ||
155 | + if (src != NULL && !iamrecursive && !Tflag) { | ||
156 | + /* | ||
157 | + * Prepare to try to restrict incoming filenames to match | ||
158 | + * the requested destination file glob. | ||
159 | + */ | ||
160 | + if ((src_copy = strdup(src)) == NULL) | ||
161 | + fatal("strdup failed"); | ||
162 | + if ((restrict_pattern = strrchr(src_copy, '/')) != NULL) { | ||
163 | + *restrict_pattern++ = '\0'; | ||
164 | + } | ||
165 | + } | ||
166 | for (first = 1;; first = 0) { | ||
167 | cp = buf; | ||
168 | if (atomicio(read, remin, cp, 1) != 1) | ||
169 | @@ -1120,6 +1138,9 @@ sink(int argc, char **argv) | ||
170 | run_err("error: unexpected filename: %s", cp); | ||
171 | exit(1); | ||
172 | } | ||
173 | + if (restrict_pattern != NULL && | ||
174 | + fnmatch(restrict_pattern, cp, 0) != 0) | ||
175 | + SCREWUP("filename does not match request"); | ||
176 | if (targisdir) { | ||
177 | static char *namebuf; | ||
178 | static size_t cursize; | ||
179 | @@ -1157,7 +1178,7 @@ sink(int argc, char **argv) | ||
180 | goto bad; | ||
181 | } | ||
182 | vect[0] = xstrdup(np); | ||
183 | - sink(1, vect); | ||
184 | + sink(1, vect, src); | ||
185 | if (setimes) { | ||
186 | setimes = 0; | ||
187 | if (utimes(vect[0], tv) < 0) | ||
diff --git a/debian/patches/conch-old-privkey-format.patch b/debian/patches/conch-old-privkey-format.patch index 90bb3e995..40fe32898 100644 --- a/debian/patches/conch-old-privkey-format.patch +++ b/debian/patches/conch-old-privkey-format.patch | |||
@@ -1,4 +1,4 @@ | |||
1 | From 1d2a55436d4b556269f42ad5f7e16608b5a8ed74 Mon Sep 17 00:00:00 2001 | 1 | From 9c01e0ae9889c05bfe68b2f1f1c5e5019e63ff0b Mon Sep 17 00:00:00 2001 |
2 | From: Colin Watson <cjwatson@debian.org> | 2 | From: Colin Watson <cjwatson@debian.org> |
3 | Date: Thu, 30 Aug 2018 00:58:56 +0100 | 3 | Date: Thu, 30 Aug 2018 00:58:56 +0100 |
4 | Subject: Work around conch interoperability failure | 4 | Subject: Work around conch interoperability failure |
@@ -18,7 +18,7 @@ Patch-Name: conch-old-privkey-format.patch | |||
18 | 3 files changed, 16 insertions(+), 3 deletions(-) | 18 | 3 files changed, 16 insertions(+), 3 deletions(-) |
19 | 19 | ||
20 | diff --git a/regress/Makefile b/regress/Makefile | 20 | diff --git a/regress/Makefile b/regress/Makefile |
21 | index 647b4a049..6e462a4f6 100644 | 21 | index 925edf71a..6fdfcc8ca 100644 |
22 | --- a/regress/Makefile | 22 | --- a/regress/Makefile |
23 | +++ b/regress/Makefile | 23 | +++ b/regress/Makefile |
24 | @@ -110,8 +110,9 @@ CLEANFILES= *.core actual agent-key.* authorized_keys_${USERNAME} \ | 24 | @@ -110,8 +110,9 @@ CLEANFILES= *.core actual agent-key.* authorized_keys_${USERNAME} \ |
@@ -47,10 +47,10 @@ index 199d863a0..c7df19fd4 100644 | |||
47 | 127.0.0.1 "cat ${DATA}" 2>/dev/null | cat > ${COPY} | 47 | 127.0.0.1 "cat ${DATA}" 2>/dev/null | cat > ${COPY} |
48 | if [ $? -ne 0 ]; then | 48 | if [ $? -ne 0 ]; then |
49 | diff --git a/regress/test-exec.sh b/regress/test-exec.sh | 49 | diff --git a/regress/test-exec.sh b/regress/test-exec.sh |
50 | index 40d46e3cd..1bbd47f25 100644 | 50 | index b8e2009de..08338121b 100644 |
51 | --- a/regress/test-exec.sh | 51 | --- a/regress/test-exec.sh |
52 | +++ b/regress/test-exec.sh | 52 | +++ b/regress/test-exec.sh |
53 | @@ -504,6 +504,18 @@ REGRESS_INTEROP_CONCH=no | 53 | @@ -500,6 +500,18 @@ REGRESS_INTEROP_CONCH=no |
54 | if test -x "$CONCH" ; then | 54 | if test -x "$CONCH" ; then |
55 | REGRESS_INTEROP_CONCH=yes | 55 | REGRESS_INTEROP_CONCH=yes |
56 | fi | 56 | fi |
diff --git a/debian/patches/debian-banner.patch b/debian/patches/debian-banner.patch index 7963b03ed..61e58e553 100644 --- a/debian/patches/debian-banner.patch +++ b/debian/patches/debian-banner.patch | |||
@@ -1,4 +1,4 @@ | |||
1 | From a18385c6866da4d69f46b64626ae5d60b4cf4a66 Mon Sep 17 00:00:00 2001 | 1 | From 085c44daefaee16df97e1b2a0967b2140cc86de0 Mon Sep 17 00:00:00 2001 |
2 | From: Kees Cook <kees@debian.org> | 2 | From: Kees Cook <kees@debian.org> |
3 | Date: Sun, 9 Feb 2014 16:10:06 +0000 | 3 | Date: Sun, 9 Feb 2014 16:10:06 +0000 |
4 | Subject: Add DebianBanner server configuration option | 4 | Subject: Add DebianBanner server configuration option |
@@ -8,21 +8,60 @@ initial protocol handshake, for those scared by package-versioning.patch. | |||
8 | 8 | ||
9 | Bug-Debian: http://bugs.debian.org/562048 | 9 | Bug-Debian: http://bugs.debian.org/562048 |
10 | Forwarded: not-needed | 10 | Forwarded: not-needed |
11 | Last-Update: 2018-10-19 | 11 | Last-Update: 2019-06-05 |
12 | 12 | ||
13 | Patch-Name: debian-banner.patch | 13 | Patch-Name: debian-banner.patch |
14 | --- | 14 | --- |
15 | kex.c | 5 +++-- | ||
16 | kex.h | 2 +- | ||
15 | servconf.c | 9 +++++++++ | 17 | servconf.c | 9 +++++++++ |
16 | servconf.h | 2 ++ | 18 | servconf.h | 2 ++ |
19 | sshconnect.c | 2 +- | ||
17 | sshd.c | 3 ++- | 20 | sshd.c | 3 ++- |
18 | sshd_config.5 | 5 +++++ | 21 | sshd_config.5 | 5 +++++ |
19 | 4 files changed, 18 insertions(+), 1 deletion(-) | 22 | 7 files changed, 23 insertions(+), 5 deletions(-) |
20 | 23 | ||
24 | diff --git a/kex.c b/kex.c | ||
25 | index be354206d..bbb7a2340 100644 | ||
26 | --- a/kex.c | ||
27 | +++ b/kex.c | ||
28 | @@ -1168,7 +1168,7 @@ send_error(struct ssh *ssh, char *msg) | ||
29 | */ | ||
30 | int | ||
31 | kex_exchange_identification(struct ssh *ssh, int timeout_ms, | ||
32 | - const char *version_addendum) | ||
33 | + int debian_banner, const char *version_addendum) | ||
34 | { | ||
35 | int remote_major, remote_minor, mismatch; | ||
36 | size_t len, i, n; | ||
37 | @@ -1186,7 +1186,8 @@ kex_exchange_identification(struct ssh *ssh, int timeout_ms, | ||
38 | if (version_addendum != NULL && *version_addendum == '\0') | ||
39 | version_addendum = NULL; | ||
40 | if ((r = sshbuf_putf(our_version, "SSH-%d.%d-%.100s%s%s\r\n", | ||
41 | - PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_RELEASE, | ||
42 | + PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, | ||
43 | + debian_banner ? SSH_RELEASE : SSH_RELEASE_MINIMUM, | ||
44 | version_addendum == NULL ? "" : " ", | ||
45 | version_addendum == NULL ? "" : version_addendum)) != 0) { | ||
46 | error("%s: sshbuf_putf: %s", __func__, ssh_err(r)); | ||
47 | diff --git a/kex.h b/kex.h | ||
48 | index 2d5f1d4ed..39f67bbc1 100644 | ||
49 | --- a/kex.h | ||
50 | +++ b/kex.h | ||
51 | @@ -195,7 +195,7 @@ char *kex_names_cat(const char *, const char *); | ||
52 | int kex_assemble_names(char **, const char *, const char *); | ||
53 | int kex_gss_names_valid(const char *); | ||
54 | |||
55 | -int kex_exchange_identification(struct ssh *, int, const char *); | ||
56 | +int kex_exchange_identification(struct ssh *, int, int, const char *); | ||
57 | |||
58 | struct kex *kex_new(void); | ||
59 | int kex_ready(struct ssh *, char *[PROPOSAL_MAX]); | ||
21 | diff --git a/servconf.c b/servconf.c | 60 | diff --git a/servconf.c b/servconf.c |
22 | index 6caf1db38..c5dd617ef 100644 | 61 | index c01e0690e..8d2bced52 100644 |
23 | --- a/servconf.c | 62 | --- a/servconf.c |
24 | +++ b/servconf.c | 63 | +++ b/servconf.c |
25 | @@ -182,6 +182,7 @@ initialize_server_options(ServerOptions *options) | 64 | @@ -184,6 +184,7 @@ initialize_server_options(ServerOptions *options) |
26 | options->fingerprint_hash = -1; | 65 | options->fingerprint_hash = -1; |
27 | options->disable_forwarding = -1; | 66 | options->disable_forwarding = -1; |
28 | options->expose_userauth_info = -1; | 67 | options->expose_userauth_info = -1; |
@@ -30,7 +69,7 @@ index 6caf1db38..c5dd617ef 100644 | |||
30 | } | 69 | } |
31 | 70 | ||
32 | /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ | 71 | /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ |
33 | @@ -417,6 +418,8 @@ fill_default_server_options(ServerOptions *options) | 72 | @@ -437,6 +438,8 @@ fill_default_server_options(ServerOptions *options) |
34 | options->disable_forwarding = 0; | 73 | options->disable_forwarding = 0; |
35 | if (options->expose_userauth_info == -1) | 74 | if (options->expose_userauth_info == -1) |
36 | options->expose_userauth_info = 0; | 75 | options->expose_userauth_info = 0; |
@@ -39,7 +78,7 @@ index 6caf1db38..c5dd617ef 100644 | |||
39 | 78 | ||
40 | assemble_algorithms(options); | 79 | assemble_algorithms(options); |
41 | 80 | ||
42 | @@ -504,6 +507,7 @@ typedef enum { | 81 | @@ -523,6 +526,7 @@ typedef enum { |
43 | sStreamLocalBindMask, sStreamLocalBindUnlink, | 82 | sStreamLocalBindMask, sStreamLocalBindUnlink, |
44 | sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding, | 83 | sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding, |
45 | sExposeAuthInfo, sRDomain, | 84 | sExposeAuthInfo, sRDomain, |
@@ -47,7 +86,7 @@ index 6caf1db38..c5dd617ef 100644 | |||
47 | sDeprecated, sIgnore, sUnsupported | 86 | sDeprecated, sIgnore, sUnsupported |
48 | } ServerOpCodes; | 87 | } ServerOpCodes; |
49 | 88 | ||
50 | @@ -661,6 +665,7 @@ static struct { | 89 | @@ -682,6 +686,7 @@ static struct { |
51 | { "exposeauthinfo", sExposeAuthInfo, SSHCFG_ALL }, | 90 | { "exposeauthinfo", sExposeAuthInfo, SSHCFG_ALL }, |
52 | { "rdomain", sRDomain, SSHCFG_ALL }, | 91 | { "rdomain", sRDomain, SSHCFG_ALL }, |
53 | { "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL }, | 92 | { "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL }, |
@@ -55,7 +94,7 @@ index 6caf1db38..c5dd617ef 100644 | |||
55 | { NULL, sBadOption, 0 } | 94 | { NULL, sBadOption, 0 } |
56 | }; | 95 | }; |
57 | 96 | ||
58 | @@ -2173,6 +2178,10 @@ process_server_config_line(ServerOptions *options, char *line, | 97 | @@ -2211,6 +2216,10 @@ process_server_config_line(ServerOptions *options, char *line, |
59 | *charptr = xstrdup(arg); | 98 | *charptr = xstrdup(arg); |
60 | break; | 99 | break; |
61 | 100 | ||
@@ -67,10 +106,10 @@ index 6caf1db38..c5dd617ef 100644 | |||
67 | case sIgnore: | 106 | case sIgnore: |
68 | case sUnsupported: | 107 | case sUnsupported: |
69 | diff --git a/servconf.h b/servconf.h | 108 | diff --git a/servconf.h b/servconf.h |
70 | index 3b76da816..4e3c54042 100644 | 109 | index a476d5220..986093ffa 100644 |
71 | --- a/servconf.h | 110 | --- a/servconf.h |
72 | +++ b/servconf.h | 111 | +++ b/servconf.h |
73 | @@ -212,6 +212,8 @@ typedef struct { | 112 | @@ -214,6 +214,8 @@ typedef struct { |
74 | int fingerprint_hash; | 113 | int fingerprint_hash; |
75 | int expose_userauth_info; | 114 | int expose_userauth_info; |
76 | u_int64_t timing_secret; | 115 | u_int64_t timing_secret; |
@@ -79,22 +118,35 @@ index 3b76da816..4e3c54042 100644 | |||
79 | } ServerOptions; | 118 | } ServerOptions; |
80 | 119 | ||
81 | /* Information about the incoming connection as used by Match */ | 120 | /* Information about the incoming connection as used by Match */ |
121 | diff --git a/sshconnect.c b/sshconnect.c | ||
122 | index 0b6f6af4b..1183ffe0e 100644 | ||
123 | --- a/sshconnect.c | ||
124 | +++ b/sshconnect.c | ||
125 | @@ -1287,7 +1287,7 @@ ssh_login(struct ssh *ssh, Sensitive *sensitive, const char *orighost, | ||
126 | lowercase(host); | ||
127 | |||
128 | /* Exchange protocol version identification strings with the server. */ | ||
129 | - if (kex_exchange_identification(ssh, timeout_ms, NULL) != 0) | ||
130 | + if (kex_exchange_identification(ssh, timeout_ms, 1, NULL) != 0) | ||
131 | cleanup_exit(255); /* error already logged */ | ||
132 | |||
133 | /* Put the connection into non-blocking mode. */ | ||
82 | diff --git a/sshd.c b/sshd.c | 134 | diff --git a/sshd.c b/sshd.c |
83 | index 9481272fc..d7e77d343 100644 | 135 | index e3e96426e..1e7ece588 100644 |
84 | --- a/sshd.c | 136 | --- a/sshd.c |
85 | +++ b/sshd.c | 137 | +++ b/sshd.c |
86 | @@ -384,7 +384,8 @@ sshd_exchange_identification(struct ssh *ssh, int sock_in, int sock_out) | 138 | @@ -2160,7 +2160,8 @@ main(int ac, char **av) |
87 | char remote_version[256]; /* Must be at least as big as buf. */ | 139 | if (!debug_flag) |
140 | alarm(options.login_grace_time); | ||
88 | 141 | ||
89 | xasprintf(&server_version_string, "SSH-%d.%d-%.100s%s%s\r\n", | 142 | - if (kex_exchange_identification(ssh, -1, options.version_addendum) != 0) |
90 | - PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_RELEASE, | 143 | + if (kex_exchange_identification(ssh, -1, options.debian_banner, |
91 | + PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, | 144 | + options.version_addendum) != 0) |
92 | + options.debian_banner ? SSH_RELEASE : SSH_RELEASE_MINIMUM, | 145 | cleanup_exit(255); /* error already logged */ |
93 | *options.version_addendum == '\0' ? "" : " ", | ||
94 | options.version_addendum); | ||
95 | 146 | ||
147 | ssh_packet_set_nonblocking(ssh); | ||
96 | diff --git a/sshd_config.5 b/sshd_config.5 | 148 | diff --git a/sshd_config.5 b/sshd_config.5 |
97 | index e7e55dd71..37e6be38f 100644 | 149 | index 2ef671d1b..addea54a0 100644 |
98 | --- a/sshd_config.5 | 150 | --- a/sshd_config.5 |
99 | +++ b/sshd_config.5 | 151 | +++ b/sshd_config.5 |
100 | @@ -543,6 +543,11 @@ or | 152 | @@ -543,6 +543,11 @@ or |
diff --git a/debian/patches/debian-config.patch b/debian/patches/debian-config.patch index 4866d52ad..0d47f6706 100644 --- a/debian/patches/debian-config.patch +++ b/debian/patches/debian-config.patch | |||
@@ -1,4 +1,4 @@ | |||
1 | From a433d9baa031d7136a8cf3e3807ebff83a3a8634 Mon Sep 17 00:00:00 2001 | 1 | From ebd590550bb09fe129b103994d53143788683d05 Mon Sep 17 00:00:00 2001 |
2 | From: Colin Watson <cjwatson@debian.org> | 2 | From: Colin Watson <cjwatson@debian.org> |
3 | Date: Sun, 9 Feb 2014 16:10:18 +0000 | 3 | Date: Sun, 9 Feb 2014 16:10:18 +0000 |
4 | Subject: Various Debian-specific configuration changes | 4 | Subject: Various Debian-specific configuration changes |
@@ -39,10 +39,10 @@ Patch-Name: debian-config.patch | |||
39 | 6 files changed, 77 insertions(+), 9 deletions(-) | 39 | 6 files changed, 77 insertions(+), 9 deletions(-) |
40 | 40 | ||
41 | diff --git a/readconf.c b/readconf.c | 41 | diff --git a/readconf.c b/readconf.c |
42 | index 6b01f20d2..661b8bf40 100644 | 42 | index cd60007f8..f35bde6e6 100644 |
43 | --- a/readconf.c | 43 | --- a/readconf.c |
44 | +++ b/readconf.c | 44 | +++ b/readconf.c |
45 | @@ -2000,7 +2000,7 @@ fill_default_options(Options * options) | 45 | @@ -2028,7 +2028,7 @@ fill_default_options(Options * options) |
46 | if (options->forward_x11 == -1) | 46 | if (options->forward_x11 == -1) |
47 | options->forward_x11 = 0; | 47 | options->forward_x11 = 0; |
48 | if (options->forward_x11_trusted == -1) | 48 | if (options->forward_x11_trusted == -1) |
@@ -52,10 +52,10 @@ index 6b01f20d2..661b8bf40 100644 | |||
52 | options->forward_x11_timeout = 1200; | 52 | options->forward_x11_timeout = 1200; |
53 | /* | 53 | /* |
54 | diff --git a/ssh.1 b/ssh.1 | 54 | diff --git a/ssh.1 b/ssh.1 |
55 | index ad1ed0f86..1bcc8edab 100644 | 55 | index 8d2b08a29..4e298cb56 100644 |
56 | --- a/ssh.1 | 56 | --- a/ssh.1 |
57 | +++ b/ssh.1 | 57 | +++ b/ssh.1 |
58 | @@ -782,6 +782,16 @@ directive in | 58 | @@ -795,6 +795,16 @@ directive in |
59 | .Xr ssh_config 5 | 59 | .Xr ssh_config 5 |
60 | for more information. | 60 | for more information. |
61 | .Pp | 61 | .Pp |
@@ -72,7 +72,7 @@ index ad1ed0f86..1bcc8edab 100644 | |||
72 | .It Fl x | 72 | .It Fl x |
73 | Disables X11 forwarding. | 73 | Disables X11 forwarding. |
74 | .Pp | 74 | .Pp |
75 | @@ -790,6 +800,17 @@ Enables trusted X11 forwarding. | 75 | @@ -803,6 +813,17 @@ Enables trusted X11 forwarding. |
76 | Trusted X11 forwardings are not subjected to the X11 SECURITY extension | 76 | Trusted X11 forwardings are not subjected to the X11 SECURITY extension |
77 | controls. | 77 | controls. |
78 | .Pp | 78 | .Pp |
@@ -91,7 +91,7 @@ index ad1ed0f86..1bcc8edab 100644 | |||
91 | Send log information using the | 91 | Send log information using the |
92 | .Xr syslog 3 | 92 | .Xr syslog 3 |
93 | diff --git a/ssh_config b/ssh_config | 93 | diff --git a/ssh_config b/ssh_config |
94 | index bcb9f153d..1b676fb2c 100644 | 94 | index 1ff999b68..6dd6ecf87 100644 |
95 | --- a/ssh_config | 95 | --- a/ssh_config |
96 | +++ b/ssh_config | 96 | +++ b/ssh_config |
97 | @@ -17,9 +17,10 @@ | 97 | @@ -17,9 +17,10 @@ |
@@ -106,7 +106,7 @@ index bcb9f153d..1b676fb2c 100644 | |||
106 | # PasswordAuthentication yes | 106 | # PasswordAuthentication yes |
107 | # HostbasedAuthentication no | 107 | # HostbasedAuthentication no |
108 | # GSSAPIAuthentication no | 108 | # GSSAPIAuthentication no |
109 | @@ -46,3 +47,6 @@ | 109 | @@ -45,3 +46,6 @@ |
110 | # VisualHostKey no | 110 | # VisualHostKey no |
111 | # ProxyCommand ssh -q -W %h:%p gateway.example.com | 111 | # ProxyCommand ssh -q -W %h:%p gateway.example.com |
112 | # RekeyLimit 1G 1h | 112 | # RekeyLimit 1G 1h |
@@ -114,7 +114,7 @@ index bcb9f153d..1b676fb2c 100644 | |||
114 | + HashKnownHosts yes | 114 | + HashKnownHosts yes |
115 | + GSSAPIAuthentication yes | 115 | + GSSAPIAuthentication yes |
116 | diff --git a/ssh_config.5 b/ssh_config.5 | 116 | diff --git a/ssh_config.5 b/ssh_config.5 |
117 | index a91355726..1a8e24bd1 100644 | 117 | index 39535c4f8..a27631ae9 100644 |
118 | --- a/ssh_config.5 | 118 | --- a/ssh_config.5 |
119 | +++ b/ssh_config.5 | 119 | +++ b/ssh_config.5 |
120 | @@ -71,6 +71,22 @@ Since the first obtained value for each parameter is used, more | 120 | @@ -71,6 +71,22 @@ Since the first obtained value for each parameter is used, more |
@@ -140,7 +140,7 @@ index a91355726..1a8e24bd1 100644 | |||
140 | The file contains keyword-argument pairs, one per line. | 140 | The file contains keyword-argument pairs, one per line. |
141 | Lines starting with | 141 | Lines starting with |
142 | .Ql # | 142 | .Ql # |
143 | @@ -699,11 +715,12 @@ elapsed. | 143 | @@ -717,11 +733,12 @@ elapsed. |
144 | .It Cm ForwardX11Trusted | 144 | .It Cm ForwardX11Trusted |
145 | If this option is set to | 145 | If this option is set to |
146 | .Cm yes , | 146 | .Cm yes , |
@@ -204,7 +204,7 @@ index 2c48105f8..ed8272f6d 100644 | |||
204 | # Example of overriding settings on a per-user basis | 204 | # Example of overriding settings on a per-user basis |
205 | #Match User anoncvs | 205 | #Match User anoncvs |
206 | diff --git a/sshd_config.5 b/sshd_config.5 | 206 | diff --git a/sshd_config.5 b/sshd_config.5 |
207 | index 23f71fd1d..ba50a30f1 100644 | 207 | index f995e4ab0..c0c4ebd66 100644 |
208 | --- a/sshd_config.5 | 208 | --- a/sshd_config.5 |
209 | +++ b/sshd_config.5 | 209 | +++ b/sshd_config.5 |
210 | @@ -56,6 +56,28 @@ Arguments may optionally be enclosed in double quotes | 210 | @@ -56,6 +56,28 @@ Arguments may optionally be enclosed in double quotes |
diff --git a/debian/patches/dnssec-sshfp.patch b/debian/patches/dnssec-sshfp.patch index e2acdf1a2..6879e11ba 100644 --- a/debian/patches/dnssec-sshfp.patch +++ b/debian/patches/dnssec-sshfp.patch | |||
@@ -1,4 +1,4 @@ | |||
1 | From 0ee33d93c5c7a5fbb8b027aa24e7c9668125fda9 Mon Sep 17 00:00:00 2001 | 1 | From 13a16baaf467fae5d507cdb17e3bc753639bca4f Mon Sep 17 00:00:00 2001 |
2 | From: Colin Watson <cjwatson@debian.org> | 2 | From: Colin Watson <cjwatson@debian.org> |
3 | Date: Sun, 9 Feb 2014 16:10:01 +0000 | 3 | Date: Sun, 9 Feb 2014 16:10:01 +0000 |
4 | Subject: Force use of DNSSEC even if "options edns0" isn't in resolv.conf | 4 | Subject: Force use of DNSSEC even if "options edns0" isn't in resolv.conf |
diff --git a/debian/patches/doc-hash-tab-completion.patch b/debian/patches/doc-hash-tab-completion.patch index c6bc43299..60ded7c30 100644 --- a/debian/patches/doc-hash-tab-completion.patch +++ b/debian/patches/doc-hash-tab-completion.patch | |||
@@ -1,4 +1,4 @@ | |||
1 | From 1d0c41a7e0b2426733ddb598248d0488c9c00a8b Mon Sep 17 00:00:00 2001 | 1 | From 099b0bdc57b9a21842c457d83ff9488fa814c9c4 Mon Sep 17 00:00:00 2001 |
2 | From: Colin Watson <cjwatson@debian.org> | 2 | From: Colin Watson <cjwatson@debian.org> |
3 | Date: Sun, 9 Feb 2014 16:10:11 +0000 | 3 | Date: Sun, 9 Feb 2014 16:10:11 +0000 |
4 | Subject: Document that HashKnownHosts may break tab-completion | 4 | Subject: Document that HashKnownHosts may break tab-completion |
@@ -13,10 +13,10 @@ Patch-Name: doc-hash-tab-completion.patch | |||
13 | 1 file changed, 3 insertions(+) | 13 | 1 file changed, 3 insertions(+) |
14 | 14 | ||
15 | diff --git a/ssh_config.5 b/ssh_config.5 | 15 | diff --git a/ssh_config.5 b/ssh_config.5 |
16 | index 7d55fa820..a91355726 100644 | 16 | index bd1e9311d..39535c4f8 100644 |
17 | --- a/ssh_config.5 | 17 | --- a/ssh_config.5 |
18 | +++ b/ssh_config.5 | 18 | +++ b/ssh_config.5 |
19 | @@ -793,6 +793,9 @@ Note that existing names and addresses in known hosts files | 19 | @@ -836,6 +836,9 @@ Note that existing names and addresses in known hosts files |
20 | will not be converted automatically, | 20 | will not be converted automatically, |
21 | but may be manually hashed using | 21 | but may be manually hashed using |
22 | .Xr ssh-keygen 1 . | 22 | .Xr ssh-keygen 1 . |
diff --git a/debian/patches/fix-key-type-check.patch b/debian/patches/fix-key-type-check.patch deleted file mode 100644 index 846df5768..000000000 --- a/debian/patches/fix-key-type-check.patch +++ /dev/null | |||
@@ -1,88 +0,0 @@ | |||
1 | From 5e021158aa22cc64da4fca1618ee0bfd2d031049 Mon Sep 17 00:00:00 2001 | ||
2 | From: "djm@openbsd.org" <djm@openbsd.org> | ||
3 | Date: Fri, 16 Nov 2018 02:43:56 +0000 | ||
4 | Subject: upstream: fix bug in HostbasedAcceptedKeyTypes and | ||
5 | |||
6 | PubkeyAcceptedKeyTypes options. If only RSA-SHA2 siganture types were | ||
7 | specified, then authentication would always fail for RSA keys as the monitor | ||
8 | checks only the base key (not the signature algorithm) type against | ||
9 | *AcceptedKeyTypes. bz#2746; reported by Jakub Jelen; ok dtucker | ||
10 | |||
11 | OpenBSD-Commit-ID: 117bc3dc54578dbdb515a1d3732988cb5b00461b | ||
12 | |||
13 | Origin: upstream, https://anongit.mindrot.org/openssh.git/commit/?id=cd9467318b56e6e93ff9575c906ff8350af9b8a2 | ||
14 | Last-Update: 2019-02-28 | ||
15 | |||
16 | Patch-Name: fix-key-type-check.patch | ||
17 | --- | ||
18 | monitor.c | 39 ++++++++++++++++++++++++++++++++++----- | ||
19 | 1 file changed, 34 insertions(+), 5 deletions(-) | ||
20 | |||
21 | diff --git a/monitor.c b/monitor.c | ||
22 | index 08fddabd7..037d6d333 100644 | ||
23 | --- a/monitor.c | ||
24 | +++ b/monitor.c | ||
25 | @@ -1,4 +1,4 @@ | ||
26 | -/* $OpenBSD: monitor.c,v 1.186 2018/07/20 03:46:34 djm Exp $ */ | ||
27 | +/* $OpenBSD: monitor.c,v 1.188 2018/11/16 02:43:56 djm Exp $ */ | ||
28 | /* | ||
29 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> | ||
30 | * Copyright 2002 Markus Friedl <markus@openbsd.org> | ||
31 | @@ -892,6 +892,35 @@ mm_answer_authrole(int sock, struct sshbuf *m) | ||
32 | return (0); | ||
33 | } | ||
34 | |||
35 | +/* | ||
36 | + * Check that the key type appears in the supplied pattern list, ignoring | ||
37 | + * mismatches in the signature algorithm. (Signature algorithm checks are | ||
38 | + * performed in the unprivileged authentication code). | ||
39 | + * Returns 1 on success, 0 otherwise. | ||
40 | + */ | ||
41 | +static int | ||
42 | +key_base_type_match(const char *method, const struct sshkey *key, | ||
43 | + const char *list) | ||
44 | +{ | ||
45 | + char *s, *l, *ol = xstrdup(list); | ||
46 | + int found = 0; | ||
47 | + | ||
48 | + l = ol; | ||
49 | + for ((s = strsep(&l, ",")); s && *s != '\0'; (s = strsep(&l, ","))) { | ||
50 | + if (sshkey_type_from_name(s) == key->type) { | ||
51 | + found = 1; | ||
52 | + break; | ||
53 | + } | ||
54 | + } | ||
55 | + if (!found) { | ||
56 | + error("%s key type %s is not in permitted list %s", method, | ||
57 | + sshkey_ssh_name(key), list); | ||
58 | + } | ||
59 | + | ||
60 | + free(ol); | ||
61 | + return found; | ||
62 | +} | ||
63 | + | ||
64 | int | ||
65 | mm_answer_authpassword(int sock, struct sshbuf *m) | ||
66 | { | ||
67 | @@ -1197,8 +1226,8 @@ mm_answer_keyallowed(int sock, struct sshbuf *m) | ||
68 | break; | ||
69 | if (auth2_key_already_used(authctxt, key)) | ||
70 | break; | ||
71 | - if (match_pattern_list(sshkey_ssh_name(key), | ||
72 | - options.pubkey_key_types, 0) != 1) | ||
73 | + if (!key_base_type_match(auth_method, key, | ||
74 | + options.pubkey_key_types)) | ||
75 | break; | ||
76 | allowed = user_key_allowed(ssh, authctxt->pw, key, | ||
77 | pubkey_auth_attempt, &opts); | ||
78 | @@ -1209,8 +1238,8 @@ mm_answer_keyallowed(int sock, struct sshbuf *m) | ||
79 | break; | ||
80 | if (auth2_key_already_used(authctxt, key)) | ||
81 | break; | ||
82 | - if (match_pattern_list(sshkey_ssh_name(key), | ||
83 | - options.hostbased_key_types, 0) != 1) | ||
84 | + if (!key_base_type_match(auth_method, key, | ||
85 | + options.hostbased_key_types)) | ||
86 | break; | ||
87 | allowed = hostbased_key_allowed(authctxt->pw, | ||
88 | cuser, chost, key); | ||
diff --git a/debian/patches/gnome-ssh-askpass2-icon.patch b/debian/patches/gnome-ssh-askpass2-icon.patch index b6d4f1239..35f3327df 100644 --- a/debian/patches/gnome-ssh-askpass2-icon.patch +++ b/debian/patches/gnome-ssh-askpass2-icon.patch | |||
@@ -1,4 +1,4 @@ | |||
1 | From df56506f727e37c13346259bdcd5975e257a259d Mon Sep 17 00:00:00 2001 | 1 | From 601332e5cc1198d6dabddc8168249a81c5dc822a Mon Sep 17 00:00:00 2001 |
2 | From: Vincent Untz <vuntz@ubuntu.com> | 2 | From: Vincent Untz <vuntz@ubuntu.com> |
3 | Date: Sun, 9 Feb 2014 16:10:16 +0000 | 3 | Date: Sun, 9 Feb 2014 16:10:16 +0000 |
4 | Subject: Give the ssh-askpass-gnome window a default icon | 4 | Subject: Give the ssh-askpass-gnome window a default icon |
diff --git a/debian/patches/gssapi.patch b/debian/patches/gssapi.patch index f62bf6672..45d131d27 100644 --- a/debian/patches/gssapi.patch +++ b/debian/patches/gssapi.patch | |||
@@ -1,4 +1,4 @@ | |||
1 | From 72b1d308e6400194ef6e4e7dd45bfa48fa39b5e6 Mon Sep 17 00:00:00 2001 | 1 | From 7ce79be85036c4b36937f1b1ba85f6094068412c Mon Sep 17 00:00:00 2001 |
2 | From: Simon Wilkinson <simon@sxw.org.uk> | 2 | From: Simon Wilkinson <simon@sxw.org.uk> |
3 | Date: Sun, 9 Feb 2014 16:09:48 +0000 | 3 | Date: Sun, 9 Feb 2014 16:09:48 +0000 |
4 | Subject: GSSAPI key exchange support | 4 | Subject: GSSAPI key exchange support |
@@ -16,185 +16,69 @@ have it merged into the main openssh package rather than having separate | |||
16 | -krb5 packages (as we used to have). It seems to have a generally good | 16 | -krb5 packages (as we used to have). It seems to have a generally good |
17 | security history. | 17 | security history. |
18 | 18 | ||
19 | Origin: other, https://github.com/openssh-gsskex/openssh-gsskex/commits/debian/master | ||
19 | Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1242 | 20 | Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1242 |
20 | Last-Updated: 2018-10-20 | 21 | Last-Updated: 2019-06-05 |
21 | 22 | ||
22 | Patch-Name: gssapi.patch | 23 | Patch-Name: gssapi.patch |
23 | --- | 24 | --- |
24 | ChangeLog.gssapi | 113 ++++++++++++++++ | 25 | Makefile.in | 3 +- |
25 | Makefile.in | 3 +- | 26 | auth-krb5.c | 17 +- |
26 | auth-krb5.c | 17 ++- | 27 | auth.c | 96 +------- |
27 | auth.c | 96 +------------ | 28 | auth2-gss.c | 56 ++++- |
28 | auth2-gss.c | 54 +++++++- | 29 | auth2.c | 2 + |
29 | auth2.c | 2 + | 30 | canohost.c | 93 ++++++++ |
30 | canohost.c | 93 +++++++++++++ | 31 | canohost.h | 3 + |
31 | canohost.h | 3 + | 32 | clientloop.c | 15 +- |
32 | clientloop.c | 15 ++- | 33 | configure.ac | 24 ++ |
33 | config.h.in | 6 + | 34 | gss-genr.c | 300 +++++++++++++++++++++++- |
34 | configure.ac | 24 ++++ | 35 | gss-serv-krb5.c | 85 ++++++- |
35 | gss-genr.c | 280 +++++++++++++++++++++++++++++++++++++- | 36 | gss-serv.c | 186 +++++++++++++-- |
36 | gss-serv-krb5.c | 85 +++++++++++- | 37 | hmac.c | 1 + |
37 | gss-serv.c | 184 +++++++++++++++++++++++-- | 38 | kex.c | 66 +++++- |
38 | kex.c | 19 +++ | 39 | kex.h | 29 +++ |
39 | kex.h | 14 ++ | 40 | kexdh.c | 10 + |
40 | kexgssc.c | 341 +++++++++++++++++++++++++++++++++++++++++++++++ | 41 | kexgen.c | 2 +- |
41 | kexgsss.c | 300 +++++++++++++++++++++++++++++++++++++++++ | 42 | kexgssc.c | 606 ++++++++++++++++++++++++++++++++++++++++++++++++ |
42 | monitor.c | 122 +++++++++++++++-- | 43 | kexgsss.c | 474 +++++++++++++++++++++++++++++++++++++ |
43 | monitor.h | 3 + | 44 | mac.c | 1 + |
44 | monitor_wrap.c | 53 +++++++- | 45 | monitor.c | 139 ++++++++++- |
45 | monitor_wrap.h | 4 +- | 46 | monitor.h | 2 + |
46 | opacket.c | 2 +- | 47 | monitor_wrap.c | 57 ++++- |
47 | opacket.h | 2 +- | 48 | monitor_wrap.h | 4 +- |
48 | readconf.c | 43 ++++++ | 49 | readconf.c | 70 ++++++ |
49 | readconf.h | 5 + | 50 | readconf.h | 6 + |
50 | servconf.c | 26 ++++ | 51 | servconf.c | 47 ++++ |
51 | servconf.h | 2 + | 52 | servconf.h | 3 + |
52 | ssh-gss.h | 41 +++++- | 53 | session.c | 10 +- |
53 | ssh_config | 2 + | 54 | ssh-gss.h | 50 +++- |
54 | ssh_config.5 | 32 +++++ | 55 | ssh.1 | 8 + |
55 | sshconnect2.c | 133 +++++++++++++++++- | 56 | ssh.c | 4 +- |
56 | sshd.c | 110 +++++++++++++++ | 57 | ssh_config | 2 + |
57 | sshd_config | 2 + | 58 | ssh_config.5 | 57 +++++ |
58 | sshd_config.5 | 10 ++ | 59 | sshconnect2.c | 140 ++++++++++- |
59 | sshkey.c | 3 +- | 60 | sshd.c | 120 +++++++++- |
60 | sshkey.h | 1 + | 61 | sshd_config | 2 + |
61 | 37 files changed, 2099 insertions(+), 146 deletions(-) | 62 | sshd_config.5 | 30 +++ |
62 | create mode 100644 ChangeLog.gssapi | 63 | sshkey.c | 3 +- |
64 | sshkey.h | 1 + | ||
65 | 40 files changed, 2664 insertions(+), 160 deletions(-) | ||
63 | create mode 100644 kexgssc.c | 66 | create mode 100644 kexgssc.c |
64 | create mode 100644 kexgsss.c | 67 | create mode 100644 kexgsss.c |
65 | 68 | ||
66 | diff --git a/ChangeLog.gssapi b/ChangeLog.gssapi | ||
67 | new file mode 100644 | ||
68 | index 000000000..f117a336a | ||
69 | --- /dev/null | ||
70 | +++ b/ChangeLog.gssapi | ||
71 | @@ -0,0 +1,113 @@ | ||
72 | +20110101 | ||
73 | + - Finally update for OpenSSH 5.6p1 | ||
74 | + - Add GSSAPIServerIdentity option from Jim Basney | ||
75 | + | ||
76 | +20100308 | ||
77 | + - [ Makefile.in, key.c, key.h ] | ||
78 | + Updates for OpenSSH 5.4p1 | ||
79 | + - [ servconf.c ] | ||
80 | + Include GSSAPI options in the sshd -T configuration dump, and flag | ||
81 | + some older configuration options as being unsupported. Thanks to Colin | ||
82 | + Watson. | ||
83 | + - | ||
84 | + | ||
85 | +20100124 | ||
86 | + - [ sshconnect2.c ] | ||
87 | + Adapt to deal with additional element in Authmethod structure. Thanks to | ||
88 | + Colin Watson | ||
89 | + | ||
90 | +20090615 | ||
91 | + - [ gss-genr.c gss-serv.c kexgssc.c kexgsss.c monitor.c sshconnect2.c | ||
92 | + sshd.c ] | ||
93 | + Fix issues identified by Greg Hudson following a code review | ||
94 | + Check return value of gss_indicate_mechs | ||
95 | + Protect GSSAPI calls in monitor, so they can only be used if enabled | ||
96 | + Check return values of bignum functions in key exchange | ||
97 | + Use BN_clear_free to clear other side's DH value | ||
98 | + Make ssh_gssapi_id_kex more robust | ||
99 | + Only configure kex table pointers if GSSAPI is enabled | ||
100 | + Don't leak mechanism list, or gss mechanism list | ||
101 | + Cast data.length before printing | ||
102 | + If serverkey isn't provided, use an empty string, rather than NULL | ||
103 | + | ||
104 | +20090201 | ||
105 | + - [ gss-genr.c gss-serv.c kex.h kexgssc.c readconf.c readconf.h ssh-gss.h | ||
106 | + ssh_config.5 sshconnet2.c ] | ||
107 | + Add support for the GSSAPIClientIdentity option, which allows the user | ||
108 | + to specify which GSSAPI identity to use to contact a given server | ||
109 | + | ||
110 | +20080404 | ||
111 | + - [ gss-serv.c ] | ||
112 | + Add code to actually implement GSSAPIStrictAcceptCheck, which had somehow | ||
113 | + been omitted from a previous version of this patch. Reported by Borislav | ||
114 | + Stoichkov | ||
115 | + | ||
116 | +20070317 | ||
117 | + - [ gss-serv-krb5.c ] | ||
118 | + Remove C99ism, where new_ccname was being declared in the middle of a | ||
119 | + function | ||
120 | + | ||
121 | +20061220 | ||
122 | + - [ servconf.c ] | ||
123 | + Make default for GSSAPIStrictAcceptorCheck be Yes, to match previous, and | ||
124 | + documented, behaviour. Reported by Dan Watson. | ||
125 | + | ||
126 | +20060910 | ||
127 | + - [ gss-genr.c kexgssc.c kexgsss.c kex.h monitor.c sshconnect2.c sshd.c | ||
128 | + ssh-gss.h ] | ||
129 | + add support for gss-group14-sha1 key exchange mechanisms | ||
130 | + - [ gss-serv.c servconf.c servconf.h sshd_config sshd_config.5 ] | ||
131 | + Add GSSAPIStrictAcceptorCheck option to allow the disabling of | ||
132 | + acceptor principal checking on multi-homed machines. | ||
133 | + <Bugzilla #928> | ||
134 | + - [ sshd_config ssh_config ] | ||
135 | + Add settings for GSSAPIKeyExchange and GSSAPITrustDNS to the sample | ||
136 | + configuration files | ||
137 | + - [ kexgss.c kegsss.c sshconnect2.c sshd.c ] | ||
138 | + Code cleanup. Replace strlen/xmalloc/snprintf sequences with xasprintf() | ||
139 | + Limit length of error messages displayed by client | ||
140 | + | ||
141 | +20060909 | ||
142 | + - [ gss-genr.c gss-serv.c ] | ||
143 | + move ssh_gssapi_acquire_cred() and ssh_gssapi_server_ctx to be server | ||
144 | + only, where they belong | ||
145 | + <Bugzilla #1225> | ||
146 | + | ||
147 | +20060829 | ||
148 | + - [ gss-serv-krb5.c ] | ||
149 | + Fix CCAPI credentials cache name when creating KRB5CCNAME environment | ||
150 | + variable | ||
151 | + | ||
152 | +20060828 | ||
153 | + - [ gss-genr.c ] | ||
154 | + Avoid Heimdal context freeing problem | ||
155 | + <Fixed upstream 20060829> | ||
156 | + | ||
157 | +20060818 | ||
158 | + - [ gss-genr.c ssh-gss.h sshconnect2.c ] | ||
159 | + Make sure that SPENGO is disabled | ||
160 | + <Bugzilla #1218 - Fixed upstream 20060818> | ||
161 | + | ||
162 | +20060421 | ||
163 | + - [ gssgenr.c, sshconnect2.c ] | ||
164 | + a few type changes (signed versus unsigned, int versus size_t) to | ||
165 | + fix compiler errors/warnings | ||
166 | + (from jbasney AT ncsa.uiuc.edu) | ||
167 | + - [ kexgssc.c, sshconnect2.c ] | ||
168 | + fix uninitialized variable warnings | ||
169 | + (from jbasney AT ncsa.uiuc.edu) | ||
170 | + - [ gssgenr.c ] | ||
171 | + pass oid to gss_display_status (helpful when using GSSAPI mechglue) | ||
172 | + (from jbasney AT ncsa.uiuc.edu) | ||
173 | + <Bugzilla #1220 > | ||
174 | + - [ gss-serv-krb5.c ] | ||
175 | + #ifdef HAVE_GSSAPI_KRB5 should be #ifdef HAVE_GSSAPI_KRB5_H | ||
176 | + (from jbasney AT ncsa.uiuc.edu) | ||
177 | + <Fixed upstream 20060304> | ||
178 | + - [ readconf.c, readconf.h, ssh_config.5, sshconnect2.c | ||
179 | + add client-side GssapiKeyExchange option | ||
180 | + (from jbasney AT ncsa.uiuc.edu) | ||
181 | + - [ sshconnect2.c ] | ||
182 | + add support for GssapiTrustDns option for gssapi-with-mic | ||
183 | + (from jbasney AT ncsa.uiuc.edu) | ||
184 | + <gssapi-with-mic support is Bugzilla #1008> | ||
185 | diff --git a/Makefile.in b/Makefile.in | 69 | diff --git a/Makefile.in b/Makefile.in |
186 | index 126b2c742..70050ffb6 100644 | 70 | index 6f001bb36..c31821acc 100644 |
187 | --- a/Makefile.in | 71 | --- a/Makefile.in |
188 | +++ b/Makefile.in | 72 | +++ b/Makefile.in |
189 | @@ -100,6 +100,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ | 73 | @@ -100,6 +100,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ |
190 | kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ | 74 | kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ |
191 | kexdhc.o kexgexc.o kexecdhc.o kexc25519c.o \ | 75 | kexgexc.o kexgexs.o \ |
192 | kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o \ | 76 | sntrup4591761.o kexsntrup4591761x25519.o kexgen.o \ |
193 | + kexgssc.o \ | 77 | + kexgssc.o \ |
194 | platform-pledge.o platform-tracing.o platform-misc.o | 78 | platform-pledge.o platform-tracing.o platform-misc.o |
195 | 79 | ||
196 | SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ | 80 | |
197 | @@ -113,7 +114,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o \ | 81 | @@ -114,7 +115,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o \ |
198 | auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ | 82 | auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ |
199 | auth2-none.o auth2-passwd.o auth2-pubkey.o \ | 83 | auth2-none.o auth2-passwd.o auth2-pubkey.o \ |
200 | monitor.o monitor_wrap.o auth-krb5.o \ | 84 | monitor.o monitor_wrap.o auth-krb5.o \ |
@@ -255,7 +139,7 @@ index 3096f1c8e..204752e1b 100644 | |||
255 | return (krb5_cc_resolve(ctx, ccname, ccache)); | 139 | return (krb5_cc_resolve(ctx, ccname, ccache)); |
256 | } | 140 | } |
257 | diff --git a/auth.c b/auth.c | 141 | diff --git a/auth.c b/auth.c |
258 | index 3ca3762cc..d8e6b4a3d 100644 | 142 | index 8696f258e..f7a23afba 100644 |
259 | --- a/auth.c | 143 | --- a/auth.c |
260 | +++ b/auth.c | 144 | +++ b/auth.c |
261 | @@ -399,7 +399,8 @@ auth_root_allowed(struct ssh *ssh, const char *method) | 145 | @@ -399,7 +399,8 @@ auth_root_allowed(struct ssh *ssh, const char *method) |
@@ -268,7 +152,7 @@ index 3ca3762cc..d8e6b4a3d 100644 | |||
268 | return 1; | 152 | return 1; |
269 | break; | 153 | break; |
270 | case PERMIT_FORCED_ONLY: | 154 | case PERMIT_FORCED_ONLY: |
271 | @@ -737,99 +738,6 @@ fakepw(void) | 155 | @@ -723,99 +724,6 @@ fakepw(void) |
272 | return (&fake); | 156 | return (&fake); |
273 | } | 157 | } |
274 | 158 | ||
@@ -369,7 +253,7 @@ index 3ca3762cc..d8e6b4a3d 100644 | |||
369 | * Return the canonical name of the host in the other side of the current | 253 | * Return the canonical name of the host in the other side of the current |
370 | * connection. The host name is cached, so it is efficient to call this | 254 | * connection. The host name is cached, so it is efficient to call this |
371 | diff --git a/auth2-gss.c b/auth2-gss.c | 255 | diff --git a/auth2-gss.c b/auth2-gss.c |
372 | index 9351e0428..1f12bb113 100644 | 256 | index 9351e0428..d6446c0cf 100644 |
373 | --- a/auth2-gss.c | 257 | --- a/auth2-gss.c |
374 | +++ b/auth2-gss.c | 258 | +++ b/auth2-gss.c |
375 | @@ -1,7 +1,7 @@ | 259 | @@ -1,7 +1,7 @@ |
@@ -381,11 +265,11 @@ index 9351e0428..1f12bb113 100644 | |||
381 | * | 265 | * |
382 | * Redistribution and use in source and binary forms, with or without | 266 | * Redistribution and use in source and binary forms, with or without |
383 | * modification, are permitted provided that the following conditions | 267 | * modification, are permitted provided that the following conditions |
384 | @@ -54,6 +54,46 @@ static int input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh); | 268 | @@ -54,6 +54,48 @@ static int input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh); |
385 | static int input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh); | 269 | static int input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh); |
386 | static int input_gssapi_errtok(int, u_int32_t, struct ssh *); | 270 | static int input_gssapi_errtok(int, u_int32_t, struct ssh *); |
387 | 271 | ||
388 | +/* | 272 | +/* |
389 | + * The 'gssapi_keyex' userauth mechanism. | 273 | + * The 'gssapi_keyex' userauth mechanism. |
390 | + */ | 274 | + */ |
391 | +static int | 275 | +static int |
@@ -393,7 +277,7 @@ index 9351e0428..1f12bb113 100644 | |||
393 | +{ | 277 | +{ |
394 | + Authctxt *authctxt = ssh->authctxt; | 278 | + Authctxt *authctxt = ssh->authctxt; |
395 | + int r, authenticated = 0; | 279 | + int r, authenticated = 0; |
396 | + struct sshbuf *b; | 280 | + struct sshbuf *b = NULL; |
397 | + gss_buffer_desc mic, gssbuf; | 281 | + gss_buffer_desc mic, gssbuf; |
398 | + u_char *p; | 282 | + u_char *p; |
399 | + size_t len; | 283 | + size_t len; |
@@ -401,8 +285,10 @@ index 9351e0428..1f12bb113 100644 | |||
401 | + if ((r = sshpkt_get_string(ssh, &p, &len)) != 0 || | 285 | + if ((r = sshpkt_get_string(ssh, &p, &len)) != 0 || |
402 | + (r = sshpkt_get_end(ssh)) != 0) | 286 | + (r = sshpkt_get_end(ssh)) != 0) |
403 | + fatal("%s: %s", __func__, ssh_err(r)); | 287 | + fatal("%s: %s", __func__, ssh_err(r)); |
288 | + | ||
404 | + if ((b = sshbuf_new()) == NULL) | 289 | + if ((b = sshbuf_new()) == NULL) |
405 | + fatal("%s: sshbuf_new failed", __func__); | 290 | + fatal("%s: sshbuf_new failed", __func__); |
291 | + | ||
406 | + mic.value = p; | 292 | + mic.value = p; |
407 | + mic.length = len; | 293 | + mic.length = len; |
408 | + | 294 | + |
@@ -414,11 +300,11 @@ index 9351e0428..1f12bb113 100644 | |||
414 | + gssbuf.length = sshbuf_len(b); | 300 | + gssbuf.length = sshbuf_len(b); |
415 | + | 301 | + |
416 | + /* gss_kex_context is NULL with privsep, so we can't check it here */ | 302 | + /* gss_kex_context is NULL with privsep, so we can't check it here */ |
417 | + if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gss_kex_context, | 303 | + if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gss_kex_context, |
418 | + &gssbuf, &mic)))) | 304 | + &gssbuf, &mic)))) |
419 | + authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, | 305 | + authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, |
420 | + authctxt->pw)); | 306 | + authctxt->pw, 1)); |
421 | + | 307 | + |
422 | + sshbuf_free(b); | 308 | + sshbuf_free(b); |
423 | + free(mic.value); | 309 | + free(mic.value); |
424 | + | 310 | + |
@@ -428,27 +314,27 @@ index 9351e0428..1f12bb113 100644 | |||
428 | /* | 314 | /* |
429 | * We only support those mechanisms that we know about (ie ones that we know | 315 | * We only support those mechanisms that we know about (ie ones that we know |
430 | * how to check local user kuserok and the like) | 316 | * how to check local user kuserok and the like) |
431 | @@ -260,7 +300,8 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh) | 317 | @@ -260,7 +302,8 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh) |
432 | if ((r = sshpkt_get_end(ssh)) != 0) | 318 | if ((r = sshpkt_get_end(ssh)) != 0) |
433 | fatal("%s: %s", __func__, ssh_err(r)); | 319 | fatal("%s: %s", __func__, ssh_err(r)); |
434 | 320 | ||
435 | - authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); | 321 | - authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); |
436 | + authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, | 322 | + authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, |
437 | + authctxt->pw)); | 323 | + authctxt->pw, 1)); |
438 | 324 | ||
439 | if ((!use_privsep || mm_is_monitor()) && | 325 | if ((!use_privsep || mm_is_monitor()) && |
440 | (displayname = ssh_gssapi_displayname()) != NULL) | 326 | (displayname = ssh_gssapi_displayname()) != NULL) |
441 | @@ -306,7 +347,8 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) | 327 | @@ -306,7 +349,8 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) |
442 | gssbuf.length = sshbuf_len(b); | 328 | gssbuf.length = sshbuf_len(b); |
443 | 329 | ||
444 | if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))) | 330 | if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))) |
445 | - authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); | 331 | - authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); |
446 | + authenticated = | 332 | + authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, |
447 | + PRIVSEP(ssh_gssapi_userok(authctxt->user, authctxt->pw)); | 333 | + authctxt->pw, 0)); |
448 | else | 334 | else |
449 | logit("GSSAPI MIC check failed"); | 335 | logit("GSSAPI MIC check failed"); |
450 | 336 | ||
451 | @@ -326,6 +368,12 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) | 337 | @@ -326,6 +370,12 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) |
452 | return 0; | 338 | return 0; |
453 | } | 339 | } |
454 | 340 | ||
@@ -462,10 +348,10 @@ index 9351e0428..1f12bb113 100644 | |||
462 | "gssapi-with-mic", | 348 | "gssapi-with-mic", |
463 | userauth_gssapi, | 349 | userauth_gssapi, |
464 | diff --git a/auth2.c b/auth2.c | 350 | diff --git a/auth2.c b/auth2.c |
465 | index 4d19957a6..a77742819 100644 | 351 | index 16ae1a363..7417eafa4 100644 |
466 | --- a/auth2.c | 352 | --- a/auth2.c |
467 | +++ b/auth2.c | 353 | +++ b/auth2.c |
468 | @@ -74,6 +74,7 @@ extern Authmethod method_passwd; | 354 | @@ -75,6 +75,7 @@ extern Authmethod method_passwd; |
469 | extern Authmethod method_kbdint; | 355 | extern Authmethod method_kbdint; |
470 | extern Authmethod method_hostbased; | 356 | extern Authmethod method_hostbased; |
471 | #ifdef GSSAPI | 357 | #ifdef GSSAPI |
@@ -473,7 +359,7 @@ index 4d19957a6..a77742819 100644 | |||
473 | extern Authmethod method_gssapi; | 359 | extern Authmethod method_gssapi; |
474 | #endif | 360 | #endif |
475 | 361 | ||
476 | @@ -81,6 +82,7 @@ Authmethod *authmethods[] = { | 362 | @@ -82,6 +83,7 @@ Authmethod *authmethods[] = { |
477 | &method_none, | 363 | &method_none, |
478 | &method_pubkey, | 364 | &method_pubkey, |
479 | #ifdef GSSAPI | 365 | #ifdef GSSAPI |
@@ -600,7 +486,7 @@ index 26d62855a..0cadc9f18 100644 | |||
600 | int get_peer_port(int); | 486 | int get_peer_port(int); |
601 | char *get_local_ipaddr(int); | 487 | char *get_local_ipaddr(int); |
602 | diff --git a/clientloop.c b/clientloop.c | 488 | diff --git a/clientloop.c b/clientloop.c |
603 | index 8d312cdaa..1464634b0 100644 | 489 | index 086c0dfe8..9b90c64f3 100644 |
604 | --- a/clientloop.c | 490 | --- a/clientloop.c |
605 | +++ b/clientloop.c | 491 | +++ b/clientloop.c |
606 | @@ -112,6 +112,10 @@ | 492 | @@ -112,6 +112,10 @@ |
@@ -614,7 +500,7 @@ index 8d312cdaa..1464634b0 100644 | |||
614 | /* import options */ | 500 | /* import options */ |
615 | extern Options options; | 501 | extern Options options; |
616 | 502 | ||
617 | @@ -1370,9 +1374,18 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, | 503 | @@ -1374,9 +1378,18 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, |
618 | break; | 504 | break; |
619 | 505 | ||
620 | /* Do channel operations unless rekeying in progress. */ | 506 | /* Do channel operations unless rekeying in progress. */ |
@@ -632,37 +518,13 @@ index 8d312cdaa..1464634b0 100644 | |||
632 | + } | 518 | + } |
633 | + | 519 | + |
634 | /* Buffer input from the connection. */ | 520 | /* Buffer input from the connection. */ |
635 | client_process_net_input(readset); | 521 | client_process_net_input(ssh, readset); |
636 | |||
637 | diff --git a/config.h.in b/config.h.in | ||
638 | index 91b65db8f..209760c7c 100644 | ||
639 | --- a/config.h.in | ||
640 | +++ b/config.h.in | ||
641 | @@ -1845,6 +1845,9 @@ | ||
642 | /* Use btmp to log bad logins */ | ||
643 | #undef USE_BTMP | ||
644 | |||
645 | +/* platform uses an in-memory credentials cache */ | ||
646 | +#undef USE_CCAPI | ||
647 | + | ||
648 | /* Use libedit for sftp */ | ||
649 | #undef USE_LIBEDIT | ||
650 | |||
651 | @@ -1860,6 +1863,9 @@ | ||
652 | /* Use PIPES instead of a socketpair() */ | ||
653 | #undef USE_PIPES | ||
654 | |||
655 | +/* platform has the Security Authorization Session API */ | ||
656 | +#undef USE_SECURITY_SESSION_API | ||
657 | + | ||
658 | /* Define if you have Solaris privileges */ | ||
659 | #undef USE_SOLARIS_PRIVS | ||
660 | 522 | ||
661 | diff --git a/configure.ac b/configure.ac | 523 | diff --git a/configure.ac b/configure.ac |
662 | index 7379ab358..023e7cc55 100644 | 524 | index 30be6c182..2869f7042 100644 |
663 | --- a/configure.ac | 525 | --- a/configure.ac |
664 | +++ b/configure.ac | 526 | +++ b/configure.ac |
665 | @@ -664,6 +664,30 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) | 527 | @@ -665,6 +665,30 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) |
666 | [Use tunnel device compatibility to OpenBSD]) | 528 | [Use tunnel device compatibility to OpenBSD]) |
667 | AC_DEFINE([SSH_TUN_PREPEND_AF], [1], | 529 | AC_DEFINE([SSH_TUN_PREPEND_AF], [1], |
668 | [Prepend the address family to IP tunnel traffic]) | 530 | [Prepend the address family to IP tunnel traffic]) |
@@ -670,7 +532,7 @@ index 7379ab358..023e7cc55 100644 | |||
670 | + AC_TRY_COMPILE([#include <Security/AuthSession.h>], | 532 | + AC_TRY_COMPILE([#include <Security/AuthSession.h>], |
671 | + [SessionCreate(0, 0);], | 533 | + [SessionCreate(0, 0);], |
672 | + [ac_cv_use_security_session_api="yes" | 534 | + [ac_cv_use_security_session_api="yes" |
673 | + AC_DEFINE([USE_SECURITY_SESSION_API], [1], | 535 | + AC_DEFINE([USE_SECURITY_SESSION_API], [1], |
674 | + [platform has the Security Authorization Session API]) | 536 | + [platform has the Security Authorization Session API]) |
675 | + LIBS="$LIBS -framework Security" | 537 | + LIBS="$LIBS -framework Security" |
676 | + AC_MSG_RESULT([yes])], | 538 | + AC_MSG_RESULT([yes])], |
@@ -681,7 +543,7 @@ index 7379ab358..023e7cc55 100644 | |||
681 | + [#include <Kerberos/Kerberos.h>], | 543 | + [#include <Kerberos/Kerberos.h>], |
682 | + [cc_context_t c; | 544 | + [cc_context_t c; |
683 | + (void) cc_initialize (&c, 0, NULL, NULL);], | 545 | + (void) cc_initialize (&c, 0, NULL, NULL);], |
684 | + [AC_DEFINE([USE_CCAPI], [1], | 546 | + [AC_DEFINE([USE_CCAPI], [1], |
685 | + [platform uses an in-memory credentials cache]) | 547 | + [platform uses an in-memory credentials cache]) |
686 | + LIBS="$LIBS -framework Security" | 548 | + LIBS="$LIBS -framework Security" |
687 | + AC_MSG_RESULT([yes]) | 549 | + AC_MSG_RESULT([yes]) |
@@ -694,7 +556,7 @@ index 7379ab358..023e7cc55 100644 | |||
694 | AC_CHECK_DECL([AU_IPv4], [], | 556 | AC_CHECK_DECL([AU_IPv4], [], |
695 | AC_DEFINE([AU_IPv4], [0], [System only supports IPv4 audit records]) | 557 | AC_DEFINE([AU_IPv4], [0], [System only supports IPv4 audit records]) |
696 | diff --git a/gss-genr.c b/gss-genr.c | 558 | diff --git a/gss-genr.c b/gss-genr.c |
697 | index d56257b4a..491e62cee 100644 | 559 | index d56257b4a..763a63ffa 100644 |
698 | --- a/gss-genr.c | 560 | --- a/gss-genr.c |
699 | +++ b/gss-genr.c | 561 | +++ b/gss-genr.c |
700 | @@ -1,7 +1,7 @@ | 562 | @@ -1,7 +1,7 @@ |
@@ -706,16 +568,15 @@ index d56257b4a..491e62cee 100644 | |||
706 | * | 568 | * |
707 | * Redistribution and use in source and binary forms, with or without | 569 | * Redistribution and use in source and binary forms, with or without |
708 | * modification, are permitted provided that the following conditions | 570 | * modification, are permitted provided that the following conditions |
709 | @@ -39,14 +39,37 @@ | 571 | @@ -41,12 +41,36 @@ |
710 | #include "xmalloc.h" | ||
711 | #include "ssherr.h" | ||
712 | #include "sshbuf.h" | 572 | #include "sshbuf.h" |
713 | +#include "sshkey.h" | ||
714 | #include "log.h" | 573 | #include "log.h" |
715 | #include "ssh2.h" | 574 | #include "ssh2.h" |
716 | +#include "cipher.h" | 575 | +#include "cipher.h" |
576 | +#include "sshkey.h" | ||
717 | +#include "kex.h" | 577 | +#include "kex.h" |
718 | +#include "digest.h" | 578 | +#include "digest.h" |
579 | +#include "packet.h" | ||
719 | 580 | ||
720 | #include "ssh-gss.h" | 581 | #include "ssh-gss.h" |
721 | 582 | ||
@@ -736,7 +597,7 @@ index d56257b4a..491e62cee 100644 | |||
736 | + | 597 | + |
737 | +static ssh_gss_kex_mapping *gss_enc2oid = NULL; | 598 | +static ssh_gss_kex_mapping *gss_enc2oid = NULL; |
738 | + | 599 | + |
739 | +int | 600 | +int |
740 | +ssh_gssapi_oid_table_ok(void) { | 601 | +ssh_gssapi_oid_table_ok(void) { |
741 | + return (gss_enc2oid != NULL); | 602 | + return (gss_enc2oid != NULL); |
742 | +} | 603 | +} |
@@ -744,10 +605,25 @@ index d56257b4a..491e62cee 100644 | |||
744 | /* sshbuf_get for gss_buffer_desc */ | 605 | /* sshbuf_get for gss_buffer_desc */ |
745 | int | 606 | int |
746 | ssh_gssapi_get_buffer_desc(struct sshbuf *b, gss_buffer_desc *g) | 607 | ssh_gssapi_get_buffer_desc(struct sshbuf *b, gss_buffer_desc *g) |
747 | @@ -62,6 +85,143 @@ ssh_gssapi_get_buffer_desc(struct sshbuf *b, gss_buffer_desc *g) | 608 | @@ -62,6 +86,162 @@ ssh_gssapi_get_buffer_desc(struct sshbuf *b, gss_buffer_desc *g) |
748 | return 0; | 609 | return 0; |
749 | } | 610 | } |
750 | 611 | ||
612 | +/* sshpkt_get of gss_buffer_desc */ | ||
613 | +int | ||
614 | +ssh_gssapi_sshpkt_get_buffer_desc(struct ssh *ssh, gss_buffer_desc *g) | ||
615 | +{ | ||
616 | + int r; | ||
617 | + u_char *p; | ||
618 | + size_t len; | ||
619 | + | ||
620 | + if ((r = sshpkt_get_string(ssh, &p, &len)) != 0) | ||
621 | + return r; | ||
622 | + g->value = p; | ||
623 | + g->length = len; | ||
624 | + return 0; | ||
625 | +} | ||
626 | + | ||
751 | +/* | 627 | +/* |
752 | + * Return a list of the gss-group1-sha1 mechanisms supported by this program | 628 | + * Return a list of the gss-group1-sha1 mechanisms supported by this program |
753 | + * | 629 | + * |
@@ -756,27 +632,30 @@ index d56257b4a..491e62cee 100644 | |||
756 | + */ | 632 | + */ |
757 | + | 633 | + |
758 | +char * | 634 | +char * |
759 | +ssh_gssapi_client_mechanisms(const char *host, const char *client) { | 635 | +ssh_gssapi_client_mechanisms(const char *host, const char *client, |
760 | + gss_OID_set gss_supported; | 636 | + const char *kex) { |
637 | + gss_OID_set gss_supported = NULL; | ||
761 | + OM_uint32 min_status; | 638 | + OM_uint32 min_status; |
762 | + | 639 | + |
763 | + if (GSS_ERROR(gss_indicate_mechs(&min_status, &gss_supported))) | 640 | + if (GSS_ERROR(gss_indicate_mechs(&min_status, &gss_supported))) |
764 | + return NULL; | 641 | + return NULL; |
765 | + | 642 | + |
766 | + return(ssh_gssapi_kex_mechs(gss_supported, ssh_gssapi_check_mechanism, | 643 | + return ssh_gssapi_kex_mechs(gss_supported, ssh_gssapi_check_mechanism, |
767 | + host, client)); | 644 | + host, client, kex); |
768 | +} | 645 | +} |
769 | + | 646 | + |
770 | +char * | 647 | +char * |
771 | +ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check, | 648 | +ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check, |
772 | + const char *host, const char *client) { | 649 | + const char *host, const char *client, const char *kex) { |
773 | + struct sshbuf *buf; | 650 | + struct sshbuf *buf = NULL; |
774 | + size_t i; | 651 | + size_t i; |
775 | + int r, oidpos, enclen; | 652 | + int r = SSH_ERR_ALLOC_FAIL; |
653 | + int oidpos, enclen; | ||
776 | + char *mechs, *encoded; | 654 | + char *mechs, *encoded; |
777 | + u_char digest[SSH_DIGEST_MAX_LENGTH]; | 655 | + u_char digest[SSH_DIGEST_MAX_LENGTH]; |
778 | + char deroid[2]; | 656 | + char deroid[2]; |
779 | + struct ssh_digest_ctx *md; | 657 | + struct ssh_digest_ctx *md = NULL; |
658 | + char *s, *cp, *p; | ||
780 | + | 659 | + |
781 | + if (gss_enc2oid != NULL) { | 660 | + if (gss_enc2oid != NULL) { |
782 | + for (i = 0; gss_enc2oid[i].encoded != NULL; i++) | 661 | + for (i = 0; gss_enc2oid[i].encoded != NULL; i++) |
@@ -791,6 +670,7 @@ index d56257b4a..491e62cee 100644 | |||
791 | + fatal("%s: sshbuf_new failed", __func__); | 670 | + fatal("%s: sshbuf_new failed", __func__); |
792 | + | 671 | + |
793 | + oidpos = 0; | 672 | + oidpos = 0; |
673 | + s = cp = xstrdup(kex); | ||
794 | + for (i = 0; i < gss_supported->count; i++) { | 674 | + for (i = 0; i < gss_supported->count; i++) { |
795 | + if (gss_supported->elements[i].length < 128 && | 675 | + if (gss_supported->elements[i].length < 128 && |
796 | + (*check)(NULL, &(gss_supported->elements[i]), host, client)) { | 676 | + (*check)(NULL, &(gss_supported->elements[i]), host, client)) { |
@@ -799,12 +679,15 @@ index d56257b4a..491e62cee 100644 | |||
799 | + deroid[1] = gss_supported->elements[i].length; | 679 | + deroid[1] = gss_supported->elements[i].length; |
800 | + | 680 | + |
801 | + if ((md = ssh_digest_start(SSH_DIGEST_MD5)) == NULL || | 681 | + if ((md = ssh_digest_start(SSH_DIGEST_MD5)) == NULL || |
802 | + ssh_digest_update(md, deroid, 2) != 0 || | 682 | + (r = ssh_digest_update(md, deroid, 2)) != 0 || |
803 | + ssh_digest_update(md, | 683 | + (r = ssh_digest_update(md, |
804 | + gss_supported->elements[i].elements, | 684 | + gss_supported->elements[i].elements, |
805 | + gss_supported->elements[i].length) != 0 || | 685 | + gss_supported->elements[i].length)) != 0 || |
806 | + ssh_digest_final(md, digest, sizeof(digest)) != 0) | 686 | + (r = ssh_digest_final(md, digest, sizeof(digest))) != 0) |
807 | + fatal("%s: digest failed", __func__); | 687 | + fatal("%s: digest failed: %s", __func__, |
688 | + ssh_err(r)); | ||
689 | + ssh_digest_free(md); | ||
690 | + md = NULL; | ||
808 | + | 691 | + |
809 | + encoded = xmalloc(ssh_digest_bytes(SSH_DIGEST_MD5) | 692 | + encoded = xmalloc(ssh_digest_bytes(SSH_DIGEST_MD5) |
810 | + * 2); | 693 | + * 2); |
@@ -812,69 +695,66 @@ index d56257b4a..491e62cee 100644 | |||
812 | + ssh_digest_bytes(SSH_DIGEST_MD5), encoded, | 695 | + ssh_digest_bytes(SSH_DIGEST_MD5), encoded, |
813 | + ssh_digest_bytes(SSH_DIGEST_MD5) * 2); | 696 | + ssh_digest_bytes(SSH_DIGEST_MD5) * 2); |
814 | + | 697 | + |
815 | + if (oidpos != 0) { | 698 | + cp = strncpy(s, kex, strlen(kex)); |
816 | + if ((r = sshbuf_put_u8(buf, ',')) != 0) | 699 | + for ((p = strsep(&cp, ",")); p && *p != '\0'; |
817 | + fatal("%s: buffer error: %s", | 700 | + (p = strsep(&cp, ","))) { |
701 | + if (sshbuf_len(buf) != 0 && | ||
702 | + (r = sshbuf_put_u8(buf, ',')) != 0) | ||
703 | + fatal("%s: sshbuf_put_u8 error: %s", | ||
704 | + __func__, ssh_err(r)); | ||
705 | + if ((r = sshbuf_put(buf, p, strlen(p))) != 0 || | ||
706 | + (r = sshbuf_put(buf, encoded, enclen)) != 0) | ||
707 | + fatal("%s: sshbuf_put error: %s", | ||
818 | + __func__, ssh_err(r)); | 708 | + __func__, ssh_err(r)); |
819 | + } | 709 | + } |
820 | + | 710 | + |
821 | + if ((r = sshbuf_put(buf, KEX_GSS_GEX_SHA1_ID, | ||
822 | + sizeof(KEX_GSS_GEX_SHA1_ID) - 1)) != 0 || | ||
823 | + (r = sshbuf_put(buf, encoded, enclen)) != 0 || | ||
824 | + (r = sshbuf_put_u8(buf, ',')) != 0 || | ||
825 | + (r = sshbuf_put(buf, KEX_GSS_GRP1_SHA1_ID, | ||
826 | + sizeof(KEX_GSS_GRP1_SHA1_ID) - 1)) != 0 || | ||
827 | + (r = sshbuf_put(buf, encoded, enclen)) != 0 || | ||
828 | + (r = sshbuf_put_u8(buf, ',')) != 0 || | ||
829 | + (r = sshbuf_put(buf, KEX_GSS_GRP14_SHA1_ID, | ||
830 | + sizeof(KEX_GSS_GRP14_SHA1_ID) - 1)) != 0 || | ||
831 | + (r = sshbuf_put(buf, encoded, enclen)) != 0) | ||
832 | + fatal("%s: buffer error: %s", | ||
833 | + __func__, ssh_err(r)); | ||
834 | + | ||
835 | + gss_enc2oid[oidpos].oid = &(gss_supported->elements[i]); | 711 | + gss_enc2oid[oidpos].oid = &(gss_supported->elements[i]); |
836 | + gss_enc2oid[oidpos].encoded = encoded; | 712 | + gss_enc2oid[oidpos].encoded = encoded; |
837 | + oidpos++; | 713 | + oidpos++; |
838 | + } | 714 | + } |
839 | + } | 715 | + } |
716 | + free(s); | ||
840 | + gss_enc2oid[oidpos].oid = NULL; | 717 | + gss_enc2oid[oidpos].oid = NULL; |
841 | + gss_enc2oid[oidpos].encoded = NULL; | 718 | + gss_enc2oid[oidpos].encoded = NULL; |
842 | + | 719 | + |
843 | + if ((mechs = sshbuf_dup_string(buf)) == NULL) | 720 | + if ((mechs = sshbuf_dup_string(buf)) == NULL) |
844 | + fatal("%s: sshbuf_dup_string failed", __func__); | 721 | + fatal("%s: sshbuf_dup_string failed", __func__); |
845 | + | 722 | + |
723 | + sshbuf_free(buf); | ||
724 | + | ||
846 | + if (strlen(mechs) == 0) { | 725 | + if (strlen(mechs) == 0) { |
847 | + free(mechs); | 726 | + free(mechs); |
848 | + mechs = NULL; | 727 | + mechs = NULL; |
849 | + } | 728 | + } |
850 | + | 729 | + |
851 | + return (mechs); | 730 | + return (mechs); |
852 | +} | 731 | +} |
853 | + | 732 | + |
854 | +gss_OID | 733 | +gss_OID |
855 | +ssh_gssapi_id_kex(Gssctxt *ctx, char *name, int kex_type) { | 734 | +ssh_gssapi_id_kex(Gssctxt *ctx, char *name, int kex_type) { |
856 | + int i = 0; | 735 | + int i = 0; |
857 | + | 736 | + |
858 | + switch (kex_type) { | 737 | +#define SKIP_KEX_NAME(type) \ |
859 | + case KEX_GSS_GRP1_SHA1: | 738 | + case type: \ |
860 | + if (strlen(name) < sizeof(KEX_GSS_GRP1_SHA1_ID)) | 739 | + if (strlen(name) < sizeof(type##_ID)) \ |
861 | + return GSS_C_NO_OID; | 740 | + return GSS_C_NO_OID; \ |
862 | + name += sizeof(KEX_GSS_GRP1_SHA1_ID) - 1; | 741 | + name += sizeof(type##_ID) - 1; \ |
863 | + break; | ||
864 | + case KEX_GSS_GRP14_SHA1: | ||
865 | + if (strlen(name) < sizeof(KEX_GSS_GRP14_SHA1_ID)) | ||
866 | + return GSS_C_NO_OID; | ||
867 | + name += sizeof(KEX_GSS_GRP14_SHA1_ID) - 1; | ||
868 | + break; | ||
869 | + case KEX_GSS_GEX_SHA1: | ||
870 | + if (strlen(name) < sizeof(KEX_GSS_GEX_SHA1_ID)) | ||
871 | + return GSS_C_NO_OID; | ||
872 | + name += sizeof(KEX_GSS_GEX_SHA1_ID) - 1; | ||
873 | + break; | 742 | + break; |
743 | + | ||
744 | + switch (kex_type) { | ||
745 | + SKIP_KEX_NAME(KEX_GSS_GRP1_SHA1) | ||
746 | + SKIP_KEX_NAME(KEX_GSS_GRP14_SHA1) | ||
747 | + SKIP_KEX_NAME(KEX_GSS_GRP14_SHA256) | ||
748 | + SKIP_KEX_NAME(KEX_GSS_GRP16_SHA512) | ||
749 | + SKIP_KEX_NAME(KEX_GSS_GEX_SHA1) | ||
750 | + SKIP_KEX_NAME(KEX_GSS_NISTP256_SHA256) | ||
751 | + SKIP_KEX_NAME(KEX_GSS_C25519_SHA256) | ||
874 | + default: | 752 | + default: |
875 | + return GSS_C_NO_OID; | 753 | + return GSS_C_NO_OID; |
876 | + } | 754 | + } |
877 | + | 755 | + |
756 | +#undef SKIP_KEX_NAME | ||
757 | + | ||
878 | + while (gss_enc2oid[i].encoded != NULL && | 758 | + while (gss_enc2oid[i].encoded != NULL && |
879 | + strcmp(name, gss_enc2oid[i].encoded) != 0) | 759 | + strcmp(name, gss_enc2oid[i].encoded) != 0) |
880 | + i++; | 760 | + i++; |
@@ -888,7 +768,7 @@ index d56257b4a..491e62cee 100644 | |||
888 | /* Check that the OID in a data stream matches that in the context */ | 768 | /* Check that the OID in a data stream matches that in the context */ |
889 | int | 769 | int |
890 | ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len) | 770 | ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len) |
891 | @@ -218,7 +378,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int deleg_creds, gss_buffer_desc *recv_tok, | 771 | @@ -218,7 +398,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int deleg_creds, gss_buffer_desc *recv_tok, |
892 | } | 772 | } |
893 | 773 | ||
894 | ctx->major = gss_init_sec_context(&ctx->minor, | 774 | ctx->major = gss_init_sec_context(&ctx->minor, |
@@ -897,7 +777,7 @@ index d56257b4a..491e62cee 100644 | |||
897 | GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | deleg_flag, | 777 | GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | deleg_flag, |
898 | 0, NULL, recv_tok, NULL, send_tok, flags, NULL); | 778 | 0, NULL, recv_tok, NULL, send_tok, flags, NULL); |
899 | 779 | ||
900 | @@ -247,9 +407,43 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host) | 780 | @@ -247,9 +427,43 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host) |
901 | return (ctx->major); | 781 | return (ctx->major); |
902 | } | 782 | } |
903 | 783 | ||
@@ -919,8 +799,8 @@ index d56257b4a..491e62cee 100644 | |||
919 | + GSS_C_NT_USER_NAME, &gssname); | 799 | + GSS_C_NT_USER_NAME, &gssname); |
920 | + | 800 | + |
921 | + if (!ctx->major) | 801 | + if (!ctx->major) |
922 | + ctx->major = gss_acquire_cred(&ctx->minor, | 802 | + ctx->major = gss_acquire_cred(&ctx->minor, |
923 | + gssname, 0, oidset, GSS_C_INITIATE, | 803 | + gssname, 0, oidset, GSS_C_INITIATE, |
924 | + &ctx->client_creds, NULL, NULL); | 804 | + &ctx->client_creds, NULL, NULL); |
925 | + | 805 | + |
926 | + gss_release_name(&status, &gssname); | 806 | + gss_release_name(&status, &gssname); |
@@ -935,13 +815,13 @@ index d56257b4a..491e62cee 100644 | |||
935 | OM_uint32 | 815 | OM_uint32 |
936 | ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash) | 816 | ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash) |
937 | { | 817 | { |
938 | + if (ctx == NULL) | 818 | + if (ctx == NULL) |
939 | + return -1; | 819 | + return -1; |
940 | + | 820 | + |
941 | if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context, | 821 | if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context, |
942 | GSS_C_QOP_DEFAULT, buffer, hash))) | 822 | GSS_C_QOP_DEFAULT, buffer, hash))) |
943 | ssh_gssapi_error(ctx); | 823 | ssh_gssapi_error(ctx); |
944 | @@ -257,6 +451,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash) | 824 | @@ -257,6 +471,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash) |
945 | return (ctx->major); | 825 | return (ctx->major); |
946 | } | 826 | } |
947 | 827 | ||
@@ -961,12 +841,12 @@ index d56257b4a..491e62cee 100644 | |||
961 | void | 841 | void |
962 | ssh_gssapi_buildmic(struct sshbuf *b, const char *user, const char *service, | 842 | ssh_gssapi_buildmic(struct sshbuf *b, const char *user, const char *service, |
963 | const char *context) | 843 | const char *context) |
964 | @@ -273,11 +480,16 @@ ssh_gssapi_buildmic(struct sshbuf *b, const char *user, const char *service, | 844 | @@ -273,11 +500,16 @@ ssh_gssapi_buildmic(struct sshbuf *b, const char *user, const char *service, |
965 | } | 845 | } |
966 | 846 | ||
967 | int | 847 | int |
968 | -ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) | 848 | -ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) |
969 | +ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host, | 849 | +ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host, |
970 | + const char *client) | 850 | + const char *client) |
971 | { | 851 | { |
972 | gss_buffer_desc token = GSS_C_EMPTY_BUFFER; | 852 | gss_buffer_desc token = GSS_C_EMPTY_BUFFER; |
@@ -979,7 +859,7 @@ index d56257b4a..491e62cee 100644 | |||
979 | 859 | ||
980 | /* RFC 4462 says we MUST NOT do SPNEGO */ | 860 | /* RFC 4462 says we MUST NOT do SPNEGO */ |
981 | if (oid->length == spnego_oid.length && | 861 | if (oid->length == spnego_oid.length && |
982 | @@ -287,6 +499,10 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) | 862 | @@ -287,6 +519,10 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) |
983 | ssh_gssapi_build_ctx(ctx); | 863 | ssh_gssapi_build_ctx(ctx); |
984 | ssh_gssapi_set_oid(*ctx, oid); | 864 | ssh_gssapi_set_oid(*ctx, oid); |
985 | major = ssh_gssapi_import_name(*ctx, host); | 865 | major = ssh_gssapi_import_name(*ctx, host); |
@@ -990,12 +870,12 @@ index d56257b4a..491e62cee 100644 | |||
990 | if (!GSS_ERROR(major)) { | 870 | if (!GSS_ERROR(major)) { |
991 | major = ssh_gssapi_init_ctx(*ctx, 0, GSS_C_NO_BUFFER, &token, | 871 | major = ssh_gssapi_init_ctx(*ctx, 0, GSS_C_NO_BUFFER, &token, |
992 | NULL); | 872 | NULL); |
993 | @@ -296,10 +512,66 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) | 873 | @@ -296,10 +532,66 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) |
994 | GSS_C_NO_BUFFER); | 874 | GSS_C_NO_BUFFER); |
995 | } | 875 | } |
996 | 876 | ||
997 | - if (GSS_ERROR(major)) | 877 | - if (GSS_ERROR(major)) |
998 | + if (GSS_ERROR(major) || intctx != NULL) | 878 | + if (GSS_ERROR(major) || intctx != NULL) |
999 | ssh_gssapi_delete_ctx(ctx); | 879 | ssh_gssapi_delete_ctx(ctx); |
1000 | 880 | ||
1001 | return (!GSS_ERROR(major)); | 881 | return (!GSS_ERROR(major)); |
@@ -1010,7 +890,7 @@ index d56257b4a..491e62cee 100644 | |||
1010 | + static OM_uint32 last_call = 0; | 890 | + static OM_uint32 last_call = 0; |
1011 | + OM_uint32 lifetime, now, major, minor; | 891 | + OM_uint32 lifetime, now, major, minor; |
1012 | + int equal; | 892 | + int equal; |
1013 | + | 893 | + |
1014 | + now = time(NULL); | 894 | + now = time(NULL); |
1015 | + | 895 | + |
1016 | + if (ctxt) { | 896 | + if (ctxt) { |
@@ -1038,8 +918,8 @@ index d56257b4a..491e62cee 100644 | |||
1038 | + | 918 | + |
1039 | + if (saved_mech == GSS_C_NO_OID) | 919 | + if (saved_mech == GSS_C_NO_OID) |
1040 | + return 0; | 920 | + return 0; |
1041 | + | 921 | + |
1042 | + major = gss_inquire_cred(&minor, GSS_C_NO_CREDENTIAL, | 922 | + major = gss_inquire_cred(&minor, GSS_C_NO_CREDENTIAL, |
1043 | + &name, &lifetime, NULL, NULL); | 923 | + &name, &lifetime, NULL, NULL); |
1044 | + if (major == GSS_S_CREDENTIALS_EXPIRED) | 924 | + if (major == GSS_S_CREDENTIALS_EXPIRED) |
1045 | + return 0; | 925 | + return 0; |
@@ -1059,7 +939,7 @@ index d56257b4a..491e62cee 100644 | |||
1059 | + | 939 | + |
1060 | #endif /* GSSAPI */ | 940 | #endif /* GSSAPI */ |
1061 | diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c | 941 | diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c |
1062 | index a151bc1e4..90f8692f5 100644 | 942 | index a151bc1e4..ef9beb67c 100644 |
1063 | --- a/gss-serv-krb5.c | 943 | --- a/gss-serv-krb5.c |
1064 | +++ b/gss-serv-krb5.c | 944 | +++ b/gss-serv-krb5.c |
1065 | @@ -1,7 +1,7 @@ | 945 | @@ -1,7 +1,7 @@ |
@@ -1107,7 +987,7 @@ index a151bc1e4..90f8692f5 100644 | |||
1107 | } | 987 | } |
1108 | 988 | ||
1109 | +int | 989 | +int |
1110 | +ssh_gssapi_krb5_updatecreds(ssh_gssapi_ccache *store, | 990 | +ssh_gssapi_krb5_updatecreds(ssh_gssapi_ccache *store, |
1111 | + ssh_gssapi_client *client) | 991 | + ssh_gssapi_client *client) |
1112 | +{ | 992 | +{ |
1113 | + krb5_ccache ccache = NULL; | 993 | + krb5_ccache ccache = NULL; |
@@ -1116,14 +996,14 @@ index a151bc1e4..90f8692f5 100644 | |||
1116 | + krb5_error_code problem; | 996 | + krb5_error_code problem; |
1117 | + OM_uint32 maj_status, min_status; | 997 | + OM_uint32 maj_status, min_status; |
1118 | + | 998 | + |
1119 | + if ((problem = krb5_cc_resolve(krb_context, store->envval, &ccache))) { | 999 | + if ((problem = krb5_cc_resolve(krb_context, store->envval, &ccache))) { |
1120 | + logit("krb5_cc_resolve(): %.100s", | 1000 | + logit("krb5_cc_resolve(): %.100s", |
1121 | + krb5_get_err_text(krb_context, problem)); | 1001 | + krb5_get_err_text(krb_context, problem)); |
1122 | + return 0; | 1002 | + return 0; |
1123 | + } | 1003 | + } |
1124 | + | 1004 | + |
1125 | + /* Find out who the principal in this cache is */ | 1005 | + /* Find out who the principal in this cache is */ |
1126 | + if ((problem = krb5_cc_get_principal(krb_context, ccache, | 1006 | + if ((problem = krb5_cc_get_principal(krb_context, ccache, |
1127 | + &principal))) { | 1007 | + &principal))) { |
1128 | + logit("krb5_cc_get_principal(): %.100s", | 1008 | + logit("krb5_cc_get_principal(): %.100s", |
1129 | + krb5_get_err_text(krb_context, problem)); | 1009 | + krb5_get_err_text(krb_context, problem)); |
@@ -1185,7 +1065,7 @@ index a151bc1e4..90f8692f5 100644 | |||
1185 | 1065 | ||
1186 | #endif /* KRB5 */ | 1066 | #endif /* KRB5 */ |
1187 | diff --git a/gss-serv.c b/gss-serv.c | 1067 | diff --git a/gss-serv.c b/gss-serv.c |
1188 | index ab3a15f0f..6c087a1b1 100644 | 1068 | index ab3a15f0f..1d47870e7 100644 |
1189 | --- a/gss-serv.c | 1069 | --- a/gss-serv.c |
1190 | +++ b/gss-serv.c | 1070 | +++ b/gss-serv.c |
1191 | @@ -1,7 +1,7 @@ | 1071 | @@ -1,7 +1,7 @@ |
@@ -1197,7 +1077,7 @@ index ab3a15f0f..6c087a1b1 100644 | |||
1197 | * | 1077 | * |
1198 | * Redistribution and use in source and binary forms, with or without | 1078 | * Redistribution and use in source and binary forms, with or without |
1199 | * modification, are permitted provided that the following conditions | 1079 | * modification, are permitted provided that the following conditions |
1200 | @@ -44,17 +44,22 @@ | 1080 | @@ -44,17 +44,19 @@ |
1201 | #include "session.h" | 1081 | #include "session.h" |
1202 | #include "misc.h" | 1082 | #include "misc.h" |
1203 | #include "servconf.h" | 1083 | #include "servconf.h" |
@@ -1205,16 +1085,14 @@ index ab3a15f0f..6c087a1b1 100644 | |||
1205 | 1085 | ||
1206 | #include "ssh-gss.h" | 1086 | #include "ssh-gss.h" |
1207 | +#include "monitor_wrap.h" | 1087 | +#include "monitor_wrap.h" |
1208 | + | ||
1209 | +extern ServerOptions options; | ||
1210 | 1088 | ||
1211 | extern ServerOptions options; | 1089 | extern ServerOptions options; |
1212 | 1090 | ||
1213 | static ssh_gssapi_client gssapi_client = | 1091 | static ssh_gssapi_client gssapi_client = |
1214 | { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, | 1092 | - { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, |
1215 | - GSS_C_NO_CREDENTIAL, NULL, {NULL, NULL, NULL, NULL}}; | 1093 | - GSS_C_NO_CREDENTIAL, NULL, {NULL, NULL, NULL, NULL}}; |
1216 | + GSS_C_NO_CREDENTIAL, GSS_C_NO_NAME, NULL, | 1094 | + { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, GSS_C_NO_CREDENTIAL, |
1217 | + {NULL, NULL, NULL, NULL, NULL}, 0, 0}; | 1095 | + GSS_C_NO_NAME, NULL, {NULL, NULL, NULL, NULL, NULL}, 0, 0}; |
1218 | 1096 | ||
1219 | ssh_gssapi_mech gssapi_null_mech = | 1097 | ssh_gssapi_mech gssapi_null_mech = |
1220 | - { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL}; | 1098 | - { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL}; |
@@ -1222,7 +1100,7 @@ index ab3a15f0f..6c087a1b1 100644 | |||
1222 | 1100 | ||
1223 | #ifdef KRB5 | 1101 | #ifdef KRB5 |
1224 | extern ssh_gssapi_mech gssapi_kerberos_mech; | 1102 | extern ssh_gssapi_mech gssapi_kerberos_mech; |
1225 | @@ -140,6 +145,28 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) | 1103 | @@ -140,6 +142,29 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) |
1226 | return (ssh_gssapi_acquire_cred(*ctx)); | 1104 | return (ssh_gssapi_acquire_cred(*ctx)); |
1227 | } | 1105 | } |
1228 | 1106 | ||
@@ -1232,7 +1110,8 @@ index ab3a15f0f..6c087a1b1 100644 | |||
1232 | + if (supported_oids == NULL) | 1110 | + if (supported_oids == NULL) |
1233 | + ssh_gssapi_prepare_supported_oids(); | 1111 | + ssh_gssapi_prepare_supported_oids(); |
1234 | + return (ssh_gssapi_kex_mechs(supported_oids, | 1112 | + return (ssh_gssapi_kex_mechs(supported_oids, |
1235 | + &ssh_gssapi_server_check_mech, NULL, NULL)); | 1113 | + &ssh_gssapi_server_check_mech, NULL, NULL, |
1114 | + options.gss_kex_algorithms)); | ||
1236 | +} | 1115 | +} |
1237 | + | 1116 | + |
1238 | +/* Unprivileged */ | 1117 | +/* Unprivileged */ |
@@ -1241,7 +1120,7 @@ index ab3a15f0f..6c087a1b1 100644 | |||
1241 | + const char *dummy) { | 1120 | + const char *dummy) { |
1242 | + Gssctxt *ctx = NULL; | 1121 | + Gssctxt *ctx = NULL; |
1243 | + int res; | 1122 | + int res; |
1244 | + | 1123 | + |
1245 | + res = !GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctx, oid))); | 1124 | + res = !GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctx, oid))); |
1246 | + ssh_gssapi_delete_ctx(&ctx); | 1125 | + ssh_gssapi_delete_ctx(&ctx); |
1247 | + | 1126 | + |
@@ -1251,7 +1130,7 @@ index ab3a15f0f..6c087a1b1 100644 | |||
1251 | /* Unprivileged */ | 1130 | /* Unprivileged */ |
1252 | void | 1131 | void |
1253 | ssh_gssapi_supported_oids(gss_OID_set *oidset) | 1132 | ssh_gssapi_supported_oids(gss_OID_set *oidset) |
1254 | @@ -150,7 +177,9 @@ ssh_gssapi_supported_oids(gss_OID_set *oidset) | 1133 | @@ -150,7 +175,9 @@ ssh_gssapi_supported_oids(gss_OID_set *oidset) |
1255 | gss_OID_set supported; | 1134 | gss_OID_set supported; |
1256 | 1135 | ||
1257 | gss_create_empty_oid_set(&min_status, oidset); | 1136 | gss_create_empty_oid_set(&min_status, oidset); |
@@ -1262,7 +1141,7 @@ index ab3a15f0f..6c087a1b1 100644 | |||
1262 | 1141 | ||
1263 | while (supported_mechs[i]->name != NULL) { | 1142 | while (supported_mechs[i]->name != NULL) { |
1264 | if (GSS_ERROR(gss_test_oid_set_member(&min_status, | 1143 | if (GSS_ERROR(gss_test_oid_set_member(&min_status, |
1265 | @@ -276,8 +305,48 @@ OM_uint32 | 1144 | @@ -276,8 +303,48 @@ OM_uint32 |
1266 | ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) | 1145 | ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) |
1267 | { | 1146 | { |
1268 | int i = 0; | 1147 | int i = 0; |
@@ -1278,21 +1157,21 @@ index ab3a15f0f..6c087a1b1 100644 | |||
1278 | + return GSS_S_COMPLETE; | 1157 | + return GSS_S_COMPLETE; |
1279 | + } | 1158 | + } |
1280 | + | 1159 | + |
1281 | + if ((ctx->major = gss_inquire_cred_by_mech(&ctx->minor, | 1160 | + if ((ctx->major = gss_inquire_cred_by_mech(&ctx->minor, |
1282 | + ctx->client_creds, ctx->oid, &new_name, | 1161 | + ctx->client_creds, ctx->oid, &new_name, |
1283 | + NULL, NULL, NULL))) { | 1162 | + NULL, NULL, NULL))) { |
1284 | + ssh_gssapi_error(ctx); | 1163 | + ssh_gssapi_error(ctx); |
1285 | + return (ctx->major); | 1164 | + return (ctx->major); |
1286 | + } | 1165 | + } |
1287 | + | 1166 | + |
1288 | + ctx->major = gss_compare_name(&ctx->minor, client->name, | 1167 | + ctx->major = gss_compare_name(&ctx->minor, client->name, |
1289 | + new_name, &equal); | 1168 | + new_name, &equal); |
1290 | + | 1169 | + |
1291 | + if (GSS_ERROR(ctx->major)) { | 1170 | + if (GSS_ERROR(ctx->major)) { |
1292 | + ssh_gssapi_error(ctx); | 1171 | + ssh_gssapi_error(ctx); |
1293 | + return (ctx->major); | 1172 | + return (ctx->major); |
1294 | + } | 1173 | + } |
1295 | + | 1174 | + |
1296 | + if (!equal) { | 1175 | + if (!equal) { |
1297 | + debug("Rekeyed credentials have different name"); | 1176 | + debug("Rekeyed credentials have different name"); |
1298 | + return GSS_S_COMPLETE; | 1177 | + return GSS_S_COMPLETE; |
@@ -1305,14 +1184,14 @@ index ab3a15f0f..6c087a1b1 100644 | |||
1305 | + gss_release_cred(&ctx->minor, &client->creds); | 1184 | + gss_release_cred(&ctx->minor, &client->creds); |
1306 | + client->name = new_name; | 1185 | + client->name = new_name; |
1307 | + client->creds = ctx->client_creds; | 1186 | + client->creds = ctx->client_creds; |
1308 | + ctx->client_creds = GSS_C_NO_CREDENTIAL; | 1187 | + ctx->client_creds = GSS_C_NO_CREDENTIAL; |
1309 | + client->updated = 1; | 1188 | + client->updated = 1; |
1310 | + return GSS_S_COMPLETE; | 1189 | + return GSS_S_COMPLETE; |
1311 | + } | 1190 | + } |
1312 | 1191 | ||
1313 | client->mech = NULL; | 1192 | client->mech = NULL; |
1314 | 1193 | ||
1315 | @@ -292,6 +361,13 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) | 1194 | @@ -292,6 +359,13 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) |
1316 | if (client->mech == NULL) | 1195 | if (client->mech == NULL) |
1317 | return GSS_S_FAILURE; | 1196 | return GSS_S_FAILURE; |
1318 | 1197 | ||
@@ -1326,7 +1205,7 @@ index ab3a15f0f..6c087a1b1 100644 | |||
1326 | if ((ctx->major = gss_display_name(&ctx->minor, ctx->client, | 1205 | if ((ctx->major = gss_display_name(&ctx->minor, ctx->client, |
1327 | &client->displayname, NULL))) { | 1206 | &client->displayname, NULL))) { |
1328 | ssh_gssapi_error(ctx); | 1207 | ssh_gssapi_error(ctx); |
1329 | @@ -309,6 +385,8 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) | 1208 | @@ -309,6 +383,8 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) |
1330 | return (ctx->major); | 1209 | return (ctx->major); |
1331 | } | 1210 | } |
1332 | 1211 | ||
@@ -1335,16 +1214,20 @@ index ab3a15f0f..6c087a1b1 100644 | |||
1335 | /* We can't copy this structure, so we just move the pointer to it */ | 1214 | /* We can't copy this structure, so we just move the pointer to it */ |
1336 | client->creds = ctx->client_creds; | 1215 | client->creds = ctx->client_creds; |
1337 | ctx->client_creds = GSS_C_NO_CREDENTIAL; | 1216 | ctx->client_creds = GSS_C_NO_CREDENTIAL; |
1338 | @@ -356,7 +434,7 @@ ssh_gssapi_do_child(char ***envp, u_int *envsizep) | 1217 | @@ -356,19 +432,23 @@ ssh_gssapi_do_child(char ***envp, u_int *envsizep) |
1339 | 1218 | ||
1340 | /* Privileged */ | 1219 | /* Privileged */ |
1341 | int | 1220 | int |
1342 | -ssh_gssapi_userok(char *user) | 1221 | -ssh_gssapi_userok(char *user) |
1343 | +ssh_gssapi_userok(char *user, struct passwd *pw) | 1222 | +ssh_gssapi_userok(char *user, struct passwd *pw, int kex) |
1344 | { | 1223 | { |
1345 | OM_uint32 lmin; | 1224 | OM_uint32 lmin; |
1346 | 1225 | ||
1347 | @@ -366,9 +444,11 @@ ssh_gssapi_userok(char *user) | 1226 | + (void) kex; /* used in privilege separation */ |
1227 | + | ||
1228 | if (gssapi_client.exportedname.length == 0 || | ||
1229 | gssapi_client.exportedname.value == NULL) { | ||
1230 | debug("No suitable client data"); | ||
1348 | return 0; | 1231 | return 0; |
1349 | } | 1232 | } |
1350 | if (gssapi_client.mech && gssapi_client.mech->userok) | 1233 | if (gssapi_client.mech && gssapi_client.mech->userok) |
@@ -1365,7 +1248,7 @@ index ab3a15f0f..6c087a1b1 100644 | |||
1365 | -/* Privileged */ | 1248 | -/* Privileged */ |
1366 | -OM_uint32 | 1249 | -OM_uint32 |
1367 | -ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) | 1250 | -ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) |
1368 | +/* These bits are only used for rekeying. The unpriviledged child is running | 1251 | +/* These bits are only used for rekeying. The unpriviledged child is running |
1369 | + * as the user, the monitor is root. | 1252 | + * as the user, the monitor is root. |
1370 | + * | 1253 | + * |
1371 | + * In the child, we want to : | 1254 | + * In the child, we want to : |
@@ -1376,7 +1259,7 @@ index ab3a15f0f..6c087a1b1 100644 | |||
1376 | +/* Stuff for PAM */ | 1259 | +/* Stuff for PAM */ |
1377 | + | 1260 | + |
1378 | +#ifdef USE_PAM | 1261 | +#ifdef USE_PAM |
1379 | +static int ssh_gssapi_simple_conv(int n, const struct pam_message **msg, | 1262 | +static int ssh_gssapi_simple_conv(int n, const struct pam_message **msg, |
1380 | + struct pam_response **resp, void *data) | 1263 | + struct pam_response **resp, void *data) |
1381 | { | 1264 | { |
1382 | - ctx->major = gss_verify_mic(&ctx->minor, ctx->context, | 1265 | - ctx->major = gss_verify_mic(&ctx->minor, ctx->context, |
@@ -1389,18 +1272,18 @@ index ab3a15f0f..6c087a1b1 100644 | |||
1389 | +void | 1272 | +void |
1390 | +ssh_gssapi_rekey_creds(void) { | 1273 | +ssh_gssapi_rekey_creds(void) { |
1391 | + int ok; | 1274 | + int ok; |
1392 | + int ret; | ||
1393 | +#ifdef USE_PAM | 1275 | +#ifdef USE_PAM |
1276 | + int ret; | ||
1394 | + pam_handle_t *pamh = NULL; | 1277 | + pam_handle_t *pamh = NULL; |
1395 | + struct pam_conv pamconv = {ssh_gssapi_simple_conv, NULL}; | 1278 | + struct pam_conv pamconv = {ssh_gssapi_simple_conv, NULL}; |
1396 | + char *envstr; | 1279 | + char *envstr; |
1397 | +#endif | 1280 | +#endif |
1398 | + | 1281 | + |
1399 | + if (gssapi_client.store.filename == NULL && | 1282 | + if (gssapi_client.store.filename == NULL && |
1400 | + gssapi_client.store.envval == NULL && | 1283 | + gssapi_client.store.envval == NULL && |
1401 | + gssapi_client.store.envvar == NULL) | 1284 | + gssapi_client.store.envvar == NULL) |
1402 | + return; | 1285 | + return; |
1403 | + | 1286 | + |
1404 | + ok = PRIVSEP(ssh_gssapi_update_creds(&gssapi_client.store)); | 1287 | + ok = PRIVSEP(ssh_gssapi_update_creds(&gssapi_client.store)); |
1405 | + | 1288 | + |
1406 | + if (!ok) | 1289 | + if (!ok) |
@@ -1423,7 +1306,7 @@ index ab3a15f0f..6c087a1b1 100644 | |||
1423 | + if (ret) | 1306 | + if (ret) |
1424 | + return; | 1307 | + return; |
1425 | + | 1308 | + |
1426 | + xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, | 1309 | + xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, |
1427 | + gssapi_client.store.envval); | 1310 | + gssapi_client.store.envval); |
1428 | + | 1311 | + |
1429 | + ret = pam_putenv(pamh, envstr); | 1312 | + ret = pam_putenv(pamh, envstr); |
@@ -1433,7 +1316,7 @@ index ab3a15f0f..6c087a1b1 100644 | |||
1433 | +#endif | 1316 | +#endif |
1434 | +} | 1317 | +} |
1435 | + | 1318 | + |
1436 | +int | 1319 | +int |
1437 | +ssh_gssapi_update_creds(ssh_gssapi_ccache *store) { | 1320 | +ssh_gssapi_update_creds(ssh_gssapi_ccache *store) { |
1438 | + int ok = 0; | 1321 | + int ok = 0; |
1439 | + | 1322 | + |
@@ -1455,11 +1338,29 @@ index ab3a15f0f..6c087a1b1 100644 | |||
1455 | } | 1338 | } |
1456 | 1339 | ||
1457 | /* Privileged */ | 1340 | /* Privileged */ |
1341 | diff --git a/hmac.c b/hmac.c | ||
1342 | index 1c879640c..a29f32c5c 100644 | ||
1343 | --- a/hmac.c | ||
1344 | +++ b/hmac.c | ||
1345 | @@ -19,6 +19,7 @@ | ||
1346 | |||
1347 | #include <sys/types.h> | ||
1348 | #include <string.h> | ||
1349 | +#include <stdlib.h> | ||
1350 | |||
1351 | #include "sshbuf.h" | ||
1352 | #include "digest.h" | ||
1458 | diff --git a/kex.c b/kex.c | 1353 | diff --git a/kex.c b/kex.c |
1459 | index 25f9f66f6..fb5bfaea5 100644 | 1354 | index 34808b5c3..a2a4794e8 100644 |
1460 | --- a/kex.c | 1355 | --- a/kex.c |
1461 | +++ b/kex.c | 1356 | +++ b/kex.c |
1462 | @@ -54,6 +54,10 @@ | 1357 | @@ -55,11 +55,16 @@ |
1358 | #include "misc.h" | ||
1359 | #include "dispatch.h" | ||
1360 | #include "monitor.h" | ||
1361 | +#include "xmalloc.h" | ||
1362 | |||
1363 | #include "ssherr.h" | ||
1463 | #include "sshbuf.h" | 1364 | #include "sshbuf.h" |
1464 | #include "digest.h" | 1365 | #include "digest.h" |
1465 | 1366 | ||
@@ -1470,57 +1371,129 @@ index 25f9f66f6..fb5bfaea5 100644 | |||
1470 | /* prototype */ | 1371 | /* prototype */ |
1471 | static int kex_choose_conf(struct ssh *); | 1372 | static int kex_choose_conf(struct ssh *); |
1472 | static int kex_input_newkeys(int, u_int32_t, struct ssh *); | 1373 | static int kex_input_newkeys(int, u_int32_t, struct ssh *); |
1473 | @@ -105,6 +109,14 @@ static const struct kexalg kexalgs[] = { | 1374 | @@ -113,15 +118,28 @@ static const struct kexalg kexalgs[] = { |
1474 | #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ | 1375 | #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ |
1475 | { NULL, -1, -1, -1}, | 1376 | { NULL, -1, -1, -1}, |
1476 | }; | 1377 | }; |
1477 | +static const struct kexalg kexalg_prefixes[] = { | 1378 | +static const struct kexalg gss_kexalgs[] = { |
1478 | +#ifdef GSSAPI | 1379 | +#ifdef GSSAPI |
1479 | + { KEX_GSS_GEX_SHA1_ID, KEX_GSS_GEX_SHA1, 0, SSH_DIGEST_SHA1 }, | 1380 | + { KEX_GSS_GEX_SHA1_ID, KEX_GSS_GEX_SHA1, 0, SSH_DIGEST_SHA1 }, |
1480 | + { KEX_GSS_GRP1_SHA1_ID, KEX_GSS_GRP1_SHA1, 0, SSH_DIGEST_SHA1 }, | 1381 | + { KEX_GSS_GRP1_SHA1_ID, KEX_GSS_GRP1_SHA1, 0, SSH_DIGEST_SHA1 }, |
1481 | + { KEX_GSS_GRP14_SHA1_ID, KEX_GSS_GRP14_SHA1, 0, SSH_DIGEST_SHA1 }, | 1382 | + { KEX_GSS_GRP14_SHA1_ID, KEX_GSS_GRP14_SHA1, 0, SSH_DIGEST_SHA1 }, |
1383 | + { KEX_GSS_GRP14_SHA256_ID, KEX_GSS_GRP14_SHA256, 0, SSH_DIGEST_SHA256 }, | ||
1384 | + { KEX_GSS_GRP16_SHA512_ID, KEX_GSS_GRP16_SHA512, 0, SSH_DIGEST_SHA512 }, | ||
1385 | + { KEX_GSS_NISTP256_SHA256_ID, KEX_GSS_NISTP256_SHA256, | ||
1386 | + NID_X9_62_prime256v1, SSH_DIGEST_SHA256 }, | ||
1387 | + { KEX_GSS_C25519_SHA256_ID, KEX_GSS_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, | ||
1482 | +#endif | 1388 | +#endif |
1483 | + { NULL, -1, -1, -1 }, | 1389 | + { NULL, -1, -1, -1 }, |
1484 | +}; | 1390 | +}; |
1485 | 1391 | ||
1486 | char * | 1392 | -char * |
1487 | kex_alg_list(char sep) | 1393 | -kex_alg_list(char sep) |
1488 | @@ -137,6 +149,10 @@ kex_alg_by_name(const char *name) | 1394 | +static char * |
1395 | +kex_alg_list_internal(char sep, const struct kexalg *algs) | ||
1396 | { | ||
1397 | char *ret = NULL, *tmp; | ||
1398 | size_t nlen, rlen = 0; | ||
1399 | const struct kexalg *k; | ||
1400 | |||
1401 | - for (k = kexalgs; k->name != NULL; k++) { | ||
1402 | + for (k = algs; k->name != NULL; k++) { | ||
1403 | if (ret != NULL) | ||
1404 | ret[rlen++] = sep; | ||
1405 | nlen = strlen(k->name); | ||
1406 | @@ -136,6 +154,18 @@ kex_alg_list(char sep) | ||
1407 | return ret; | ||
1408 | } | ||
1409 | |||
1410 | +char * | ||
1411 | +kex_alg_list(char sep) | ||
1412 | +{ | ||
1413 | + return kex_alg_list_internal(sep, kexalgs); | ||
1414 | +} | ||
1415 | + | ||
1416 | +char * | ||
1417 | +kex_gss_alg_list(char sep) | ||
1418 | +{ | ||
1419 | + return kex_alg_list_internal(sep, gss_kexalgs); | ||
1420 | +} | ||
1421 | + | ||
1422 | static const struct kexalg * | ||
1423 | kex_alg_by_name(const char *name) | ||
1424 | { | ||
1425 | @@ -145,6 +175,10 @@ kex_alg_by_name(const char *name) | ||
1489 | if (strcmp(k->name, name) == 0) | 1426 | if (strcmp(k->name, name) == 0) |
1490 | return k; | 1427 | return k; |
1491 | } | 1428 | } |
1492 | + for (k = kexalg_prefixes; k->name != NULL; k++) { | 1429 | + for (k = gss_kexalgs; k->name != NULL; k++) { |
1493 | + if (strncmp(k->name, name, strlen(k->name)) == 0) | 1430 | + if (strncmp(k->name, name, strlen(k->name)) == 0) |
1494 | + return k; | 1431 | + return k; |
1495 | + } | 1432 | + } |
1496 | return NULL; | 1433 | return NULL; |
1497 | } | 1434 | } |
1498 | 1435 | ||
1499 | @@ -653,6 +669,9 @@ kex_free(struct kex *kex) | 1436 | @@ -301,6 +335,29 @@ kex_assemble_names(char **listp, const char *def, const char *all) |
1500 | sshbuf_free(kex->peer); | 1437 | return r; |
1501 | sshbuf_free(kex->my); | 1438 | } |
1439 | |||
1440 | +/* Validate GSS KEX method name list */ | ||
1441 | +int | ||
1442 | +kex_gss_names_valid(const char *names) | ||
1443 | +{ | ||
1444 | + char *s, *cp, *p; | ||
1445 | + | ||
1446 | + if (names == NULL || *names == '\0') | ||
1447 | + return 0; | ||
1448 | + s = cp = xstrdup(names); | ||
1449 | + for ((p = strsep(&cp, ",")); p && *p != '\0'; | ||
1450 | + (p = strsep(&cp, ","))) { | ||
1451 | + if (strncmp(p, "gss-", 4) != 0 | ||
1452 | + || kex_alg_by_name(p) == NULL) { | ||
1453 | + error("Unsupported KEX algorithm \"%.100s\"", p); | ||
1454 | + free(s); | ||
1455 | + return 0; | ||
1456 | + } | ||
1457 | + } | ||
1458 | + debug3("gss kex names ok: [%s]", names); | ||
1459 | + free(s); | ||
1460 | + return 1; | ||
1461 | +} | ||
1462 | + | ||
1463 | /* put algorithm proposal into buffer */ | ||
1464 | int | ||
1465 | kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX]) | ||
1466 | @@ -657,6 +714,9 @@ kex_free(struct kex *kex) | ||
1467 | sshbuf_free(kex->server_version); | ||
1468 | sshbuf_free(kex->client_pub); | ||
1502 | free(kex->session_id); | 1469 | free(kex->session_id); |
1503 | +#ifdef GSSAPI | 1470 | +#ifdef GSSAPI |
1504 | + free(kex->gss_host); | 1471 | + free(kex->gss_host); |
1505 | +#endif /* GSSAPI */ | 1472 | +#endif /* GSSAPI */ |
1506 | free(kex->client_version_string); | ||
1507 | free(kex->server_version_string); | ||
1508 | free(kex->failed_choice); | 1473 | free(kex->failed_choice); |
1474 | free(kex->hostkey_alg); | ||
1475 | free(kex->name); | ||
1509 | diff --git a/kex.h b/kex.h | 1476 | diff --git a/kex.h b/kex.h |
1510 | index 593de1208..4e5ead839 100644 | 1477 | index 6d446d1cc..2d5f1d4ed 100644 |
1511 | --- a/kex.h | 1478 | --- a/kex.h |
1512 | +++ b/kex.h | 1479 | +++ b/kex.h |
1513 | @@ -100,6 +100,9 @@ enum kex_exchange { | 1480 | @@ -103,6 +103,15 @@ enum kex_exchange { |
1514 | KEX_DH_GEX_SHA256, | ||
1515 | KEX_ECDH_SHA2, | 1481 | KEX_ECDH_SHA2, |
1516 | KEX_C25519_SHA256, | 1482 | KEX_C25519_SHA256, |
1483 | KEX_KEM_SNTRUP4591761X25519_SHA512, | ||
1484 | +#ifdef GSSAPI | ||
1517 | + KEX_GSS_GRP1_SHA1, | 1485 | + KEX_GSS_GRP1_SHA1, |
1518 | + KEX_GSS_GRP14_SHA1, | 1486 | + KEX_GSS_GRP14_SHA1, |
1487 | + KEX_GSS_GRP14_SHA256, | ||
1488 | + KEX_GSS_GRP16_SHA512, | ||
1519 | + KEX_GSS_GEX_SHA1, | 1489 | + KEX_GSS_GEX_SHA1, |
1490 | + KEX_GSS_NISTP256_SHA256, | ||
1491 | + KEX_GSS_C25519_SHA256, | ||
1492 | +#endif | ||
1520 | KEX_MAX | 1493 | KEX_MAX |
1521 | }; | 1494 | }; |
1522 | 1495 | ||
1523 | @@ -148,6 +151,12 @@ struct kex { | 1496 | @@ -154,6 +163,12 @@ struct kex { |
1524 | u_int flags; | 1497 | u_int flags; |
1525 | int hash_alg; | 1498 | int hash_alg; |
1526 | int ec_nid; | 1499 | int ec_nid; |
@@ -1530,27 +1503,93 @@ index 593de1208..4e5ead839 100644 | |||
1530 | + char *gss_host; | 1503 | + char *gss_host; |
1531 | + char *gss_client; | 1504 | + char *gss_client; |
1532 | +#endif | 1505 | +#endif |
1533 | char *client_version_string; | ||
1534 | char *server_version_string; | ||
1535 | char *failed_choice; | 1506 | char *failed_choice; |
1536 | @@ -198,6 +207,11 @@ int kexecdh_server(struct ssh *); | 1507 | int (*verify_host_key)(struct sshkey *, struct ssh *); |
1537 | int kexc25519_client(struct ssh *); | 1508 | struct sshkey *(*load_host_public_key)(int, int, struct ssh *); |
1538 | int kexc25519_server(struct ssh *); | 1509 | @@ -175,8 +190,10 @@ struct kex { |
1539 | 1510 | ||
1540 | +#ifdef GSSAPI | 1511 | int kex_names_valid(const char *); |
1512 | char *kex_alg_list(char); | ||
1513 | +char *kex_gss_alg_list(char); | ||
1514 | char *kex_names_cat(const char *, const char *); | ||
1515 | int kex_assemble_names(char **, const char *, const char *); | ||
1516 | +int kex_gss_names_valid(const char *); | ||
1517 | |||
1518 | int kex_exchange_identification(struct ssh *, int, const char *); | ||
1519 | |||
1520 | @@ -203,6 +220,12 @@ int kexgex_client(struct ssh *); | ||
1521 | int kexgex_server(struct ssh *); | ||
1522 | int kex_gen_client(struct ssh *); | ||
1523 | int kex_gen_server(struct ssh *); | ||
1524 | +#if defined(GSSAPI) && defined(WITH_OPENSSL) | ||
1525 | +int kexgssgex_client(struct ssh *); | ||
1526 | +int kexgssgex_server(struct ssh *); | ||
1541 | +int kexgss_client(struct ssh *); | 1527 | +int kexgss_client(struct ssh *); |
1542 | +int kexgss_server(struct ssh *); | 1528 | +int kexgss_server(struct ssh *); |
1543 | +#endif | 1529 | +#endif |
1544 | + | 1530 | |
1545 | int kex_dh_hash(int, const char *, const char *, | 1531 | int kex_dh_keypair(struct kex *); |
1546 | const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, | 1532 | int kex_dh_enc(struct kex *, const struct sshbuf *, struct sshbuf **, |
1547 | const BIGNUM *, const BIGNUM *, const BIGNUM *, u_char *, size_t *); | 1533 | @@ -235,6 +258,12 @@ int kexgex_hash(int, const struct sshbuf *, const struct sshbuf *, |
1534 | const BIGNUM *, const u_char *, size_t, | ||
1535 | u_char *, size_t *); | ||
1536 | |||
1537 | +int kex_gen_hash(int hash_alg, const struct sshbuf *client_version, | ||
1538 | + const struct sshbuf *server_version, const struct sshbuf *client_kexinit, | ||
1539 | + const struct sshbuf *server_kexinit, const struct sshbuf *server_host_key_blob, | ||
1540 | + const struct sshbuf *client_pub, const struct sshbuf *server_pub, | ||
1541 | + const struct sshbuf *shared_secret, u_char *hash, size_t *hashlen); | ||
1542 | + | ||
1543 | void kexc25519_keygen(u_char key[CURVE25519_SIZE], u_char pub[CURVE25519_SIZE]) | ||
1544 | __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) | ||
1545 | __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); | ||
1546 | diff --git a/kexdh.c b/kexdh.c | ||
1547 | index 67133e339..edaa46762 100644 | ||
1548 | --- a/kexdh.c | ||
1549 | +++ b/kexdh.c | ||
1550 | @@ -48,13 +48,23 @@ kex_dh_keygen(struct kex *kex) | ||
1551 | { | ||
1552 | switch (kex->kex_type) { | ||
1553 | case KEX_DH_GRP1_SHA1: | ||
1554 | +#ifdef GSSAPI | ||
1555 | + case KEX_GSS_GRP1_SHA1: | ||
1556 | +#endif | ||
1557 | kex->dh = dh_new_group1(); | ||
1558 | break; | ||
1559 | case KEX_DH_GRP14_SHA1: | ||
1560 | case KEX_DH_GRP14_SHA256: | ||
1561 | +#ifdef GSSAPI | ||
1562 | + case KEX_GSS_GRP14_SHA1: | ||
1563 | + case KEX_GSS_GRP14_SHA256: | ||
1564 | +#endif | ||
1565 | kex->dh = dh_new_group14(); | ||
1566 | break; | ||
1567 | case KEX_DH_GRP16_SHA512: | ||
1568 | +#ifdef GSSAPI | ||
1569 | + case KEX_GSS_GRP16_SHA512: | ||
1570 | +#endif | ||
1571 | kex->dh = dh_new_group16(); | ||
1572 | break; | ||
1573 | case KEX_DH_GRP18_SHA512: | ||
1574 | diff --git a/kexgen.c b/kexgen.c | ||
1575 | index 2abbb9ef6..569dc83f3 100644 | ||
1576 | --- a/kexgen.c | ||
1577 | +++ b/kexgen.c | ||
1578 | @@ -43,7 +43,7 @@ | ||
1579 | static int input_kex_gen_init(int, u_int32_t, struct ssh *); | ||
1580 | static int input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh); | ||
1581 | |||
1582 | -static int | ||
1583 | +int | ||
1584 | kex_gen_hash( | ||
1585 | int hash_alg, | ||
1586 | const struct sshbuf *client_version, | ||
1548 | diff --git a/kexgssc.c b/kexgssc.c | 1587 | diff --git a/kexgssc.c b/kexgssc.c |
1549 | new file mode 100644 | 1588 | new file mode 100644 |
1550 | index 000000000..3c8ae08dd | 1589 | index 000000000..f6e1405eb |
1551 | --- /dev/null | 1590 | --- /dev/null |
1552 | +++ b/kexgssc.c | 1591 | +++ b/kexgssc.c |
1553 | @@ -0,0 +1,341 @@ | 1592 | @@ -0,0 +1,606 @@ |
1554 | +/* | 1593 | +/* |
1555 | + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. | 1594 | + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. |
1556 | + * | 1595 | + * |
@@ -1577,7 +1616,7 @@ index 000000000..3c8ae08dd | |||
1577 | + | 1616 | + |
1578 | +#include "includes.h" | 1617 | +#include "includes.h" |
1579 | + | 1618 | + |
1580 | +#ifdef GSSAPI | 1619 | +#if defined(GSSAPI) && defined(WITH_OPENSSL) |
1581 | + | 1620 | + |
1582 | +#include "includes.h" | 1621 | +#include "includes.h" |
1583 | + | 1622 | + |
@@ -1596,113 +1635,88 @@ index 000000000..3c8ae08dd | |||
1596 | +#include "packet.h" | 1635 | +#include "packet.h" |
1597 | +#include "dh.h" | 1636 | +#include "dh.h" |
1598 | +#include "digest.h" | 1637 | +#include "digest.h" |
1638 | +#include "ssherr.h" | ||
1599 | + | 1639 | + |
1600 | +#include "ssh-gss.h" | 1640 | +#include "ssh-gss.h" |
1601 | + | 1641 | + |
1602 | +int | 1642 | +int |
1603 | +kexgss_client(struct ssh *ssh) { | 1643 | +kexgss_client(struct ssh *ssh) |
1604 | + gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; | 1644 | +{ |
1605 | + gss_buffer_desc recv_tok, gssbuf, msg_tok, *token_ptr; | 1645 | + struct kex *kex = ssh->kex; |
1646 | + gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER, | ||
1647 | + recv_tok = GSS_C_EMPTY_BUFFER, | ||
1648 | + gssbuf, msg_tok = GSS_C_EMPTY_BUFFER, *token_ptr; | ||
1606 | + Gssctxt *ctxt; | 1649 | + Gssctxt *ctxt; |
1607 | + OM_uint32 maj_status, min_status, ret_flags; | 1650 | + OM_uint32 maj_status, min_status, ret_flags; |
1608 | + u_int klen, kout, slen = 0, strlen; | 1651 | + struct sshbuf *server_blob = NULL; |
1609 | + DH *dh; | 1652 | + struct sshbuf *shared_secret = NULL; |
1610 | + BIGNUM *dh_server_pub = NULL; | 1653 | + struct sshbuf *server_host_key_blob = NULL; |
1611 | + BIGNUM *shared_secret = NULL; | 1654 | + struct sshbuf *empty = NULL; |
1612 | + const BIGNUM *pub_key, *dh_p, *dh_g; | 1655 | + u_char *msg; |
1613 | + BIGNUM *p = NULL; | ||
1614 | + BIGNUM *g = NULL; | ||
1615 | + u_char *kbuf; | ||
1616 | + u_char *serverhostkey = NULL; | ||
1617 | + u_char *empty = ""; | ||
1618 | + char *msg; | ||
1619 | + int type = 0; | 1656 | + int type = 0; |
1620 | + int first = 1; | 1657 | + int first = 1; |
1621 | + int nbits = 0, min = DH_GRP_MIN, max = DH_GRP_MAX; | ||
1622 | + u_char hash[SSH_DIGEST_MAX_LENGTH]; | 1658 | + u_char hash[SSH_DIGEST_MAX_LENGTH]; |
1623 | + size_t hashlen; | 1659 | + size_t hashlen; |
1660 | + u_char c; | ||
1661 | + int r; | ||
1624 | + | 1662 | + |
1625 | + /* Initialise our GSSAPI world */ | 1663 | + /* Initialise our GSSAPI world */ |
1626 | + ssh_gssapi_build_ctx(&ctxt); | 1664 | + ssh_gssapi_build_ctx(&ctxt); |
1627 | + if (ssh_gssapi_id_kex(ctxt, ssh->kex->name, ssh->kex->kex_type) | 1665 | + if (ssh_gssapi_id_kex(ctxt, kex->name, kex->kex_type) |
1628 | + == GSS_C_NO_OID) | 1666 | + == GSS_C_NO_OID) |
1629 | + fatal("Couldn't identify host exchange"); | 1667 | + fatal("Couldn't identify host exchange"); |
1630 | + | 1668 | + |
1631 | + if (ssh_gssapi_import_name(ctxt, ssh->kex->gss_host)) | 1669 | + if (ssh_gssapi_import_name(ctxt, kex->gss_host)) |
1632 | + fatal("Couldn't import hostname"); | 1670 | + fatal("Couldn't import hostname"); |
1633 | + | 1671 | + |
1634 | + if (ssh->kex->gss_client && | 1672 | + if (kex->gss_client && |
1635 | + ssh_gssapi_client_identity(ctxt, ssh->kex->gss_client)) | 1673 | + ssh_gssapi_client_identity(ctxt, kex->gss_client)) |
1636 | + fatal("Couldn't acquire client credentials"); | 1674 | + fatal("Couldn't acquire client credentials"); |
1637 | + | 1675 | + |
1638 | + switch (ssh->kex->kex_type) { | 1676 | + /* Step 1 */ |
1677 | + switch (kex->kex_type) { | ||
1639 | + case KEX_GSS_GRP1_SHA1: | 1678 | + case KEX_GSS_GRP1_SHA1: |
1640 | + dh = dh_new_group1(); | ||
1641 | + break; | ||
1642 | + case KEX_GSS_GRP14_SHA1: | 1679 | + case KEX_GSS_GRP14_SHA1: |
1643 | + dh = dh_new_group14(); | 1680 | + case KEX_GSS_GRP14_SHA256: |
1681 | + case KEX_GSS_GRP16_SHA512: | ||
1682 | + r = kex_dh_keypair(kex); | ||
1683 | + break; | ||
1684 | + case KEX_GSS_NISTP256_SHA256: | ||
1685 | + r = kex_ecdh_keypair(kex); | ||
1644 | + break; | 1686 | + break; |
1645 | + case KEX_GSS_GEX_SHA1: | 1687 | + case KEX_GSS_C25519_SHA256: |
1646 | + debug("Doing group exchange\n"); | 1688 | + r = kex_c25519_keypair(kex); |
1647 | + nbits = dh_estimate(ssh->kex->we_need * 8); | ||
1648 | + packet_start(SSH2_MSG_KEXGSS_GROUPREQ); | ||
1649 | + packet_put_int(min); | ||
1650 | + packet_put_int(nbits); | ||
1651 | + packet_put_int(max); | ||
1652 | + | ||
1653 | + packet_send(); | ||
1654 | + | ||
1655 | + packet_read_expect(SSH2_MSG_KEXGSS_GROUP); | ||
1656 | + | ||
1657 | + if ((p = BN_new()) == NULL) | ||
1658 | + fatal("BN_new() failed"); | ||
1659 | + packet_get_bignum2(p); | ||
1660 | + if ((g = BN_new()) == NULL) | ||
1661 | + fatal("BN_new() failed"); | ||
1662 | + packet_get_bignum2(g); | ||
1663 | + packet_check_eom(); | ||
1664 | + | ||
1665 | + if (BN_num_bits(p) < min || BN_num_bits(p) > max) | ||
1666 | + fatal("GSSGRP_GEX group out of range: %d !< %d !< %d", | ||
1667 | + min, BN_num_bits(p), max); | ||
1668 | + | ||
1669 | + dh = dh_new_group(g, p); | ||
1670 | + break; | 1689 | + break; |
1671 | + default: | 1690 | + default: |
1672 | + fatal("%s: Unexpected KEX type %d", __func__, ssh->kex->kex_type); | 1691 | + fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); |
1673 | + } | 1692 | + } |
1674 | + | 1693 | + if (r != 0) |
1675 | + /* Step 1 - e is dh->pub_key */ | 1694 | + return r; |
1676 | + dh_gen_key(dh, ssh->kex->we_need * 8); | ||
1677 | + DH_get0_key(dh, &pub_key, NULL); | ||
1678 | + DH_get0_pqg(dh, &dh_p, NULL, &dh_g); | ||
1679 | + | ||
1680 | + /* This is f, we initialise it now to make life easier */ | ||
1681 | + dh_server_pub = BN_new(); | ||
1682 | + if (dh_server_pub == NULL) | ||
1683 | + fatal("dh_server_pub == NULL"); | ||
1684 | + | 1695 | + |
1685 | + token_ptr = GSS_C_NO_BUFFER; | 1696 | + token_ptr = GSS_C_NO_BUFFER; |
1686 | + | 1697 | + |
1687 | + do { | 1698 | + do { |
1688 | + debug("Calling gss_init_sec_context"); | 1699 | + debug("Calling gss_init_sec_context"); |
1689 | + | 1700 | + |
1690 | + maj_status = ssh_gssapi_init_ctx(ctxt, | 1701 | + maj_status = ssh_gssapi_init_ctx(ctxt, |
1691 | + ssh->kex->gss_deleg_creds, token_ptr, &send_tok, | 1702 | + kex->gss_deleg_creds, token_ptr, &send_tok, |
1692 | + &ret_flags); | 1703 | + &ret_flags); |
1693 | + | 1704 | + |
1694 | + if (GSS_ERROR(maj_status)) { | 1705 | + if (GSS_ERROR(maj_status)) { |
1706 | + /* XXX Useles code: Missing send? */ | ||
1695 | + if (send_tok.length != 0) { | 1707 | + if (send_tok.length != 0) { |
1696 | + packet_start(SSH2_MSG_KEXGSS_CONTINUE); | 1708 | + if ((r = sshpkt_start(ssh, |
1697 | + packet_put_string(send_tok.value, | 1709 | + SSH2_MSG_KEXGSS_CONTINUE)) != 0 || |
1698 | + send_tok.length); | 1710 | + (r = sshpkt_put_string(ssh, send_tok.value, |
1711 | + send_tok.length)) != 0) | ||
1712 | + fatal("sshpkt failed: %s", ssh_err(r)); | ||
1699 | + } | 1713 | + } |
1700 | + fatal("gss_init_context failed"); | 1714 | + fatal("gss_init_context failed"); |
1701 | + } | 1715 | + } |
1702 | + | 1716 | + |
1703 | + /* If we've got an old receive buffer get rid of it */ | 1717 | + /* If we've got an old receive buffer get rid of it */ |
1704 | + if (token_ptr != GSS_C_NO_BUFFER) | 1718 | + if (token_ptr != GSS_C_NO_BUFFER) |
1705 | + free(recv_tok.value); | 1719 | + gss_release_buffer(&min_status, &recv_tok); |
1706 | + | 1720 | + |
1707 | + if (maj_status == GSS_S_COMPLETE) { | 1721 | + if (maj_status == GSS_S_COMPLETE) { |
1708 | + /* If mutual state flag is not true, kex fails */ | 1722 | + /* If mutual state flag is not true, kex fails */ |
@@ -1714,75 +1728,90 @@ index 000000000..3c8ae08dd | |||
1714 | + fatal("Integrity check failed"); | 1728 | + fatal("Integrity check failed"); |
1715 | + } | 1729 | + } |
1716 | + | 1730 | + |
1717 | + /* | 1731 | + /* |
1718 | + * If we have data to send, then the last message that we | 1732 | + * If we have data to send, then the last message that we |
1719 | + * received cannot have been a 'complete'. | 1733 | + * received cannot have been a 'complete'. |
1720 | + */ | 1734 | + */ |
1721 | + if (send_tok.length != 0) { | 1735 | + if (send_tok.length != 0) { |
1722 | + if (first) { | 1736 | + if (first) { |
1723 | + packet_start(SSH2_MSG_KEXGSS_INIT); | 1737 | + if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_INIT)) != 0 || |
1724 | + packet_put_string(send_tok.value, | 1738 | + (r = sshpkt_put_string(ssh, send_tok.value, |
1725 | + send_tok.length); | 1739 | + send_tok.length)) != 0 || |
1726 | + packet_put_bignum2(pub_key); | 1740 | + (r = sshpkt_put_stringb(ssh, kex->client_pub)) != 0) |
1741 | + fatal("failed to construct packet: %s", ssh_err(r)); | ||
1727 | + first = 0; | 1742 | + first = 0; |
1728 | + } else { | 1743 | + } else { |
1729 | + packet_start(SSH2_MSG_KEXGSS_CONTINUE); | 1744 | + if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || |
1730 | + packet_put_string(send_tok.value, | 1745 | + (r = sshpkt_put_string(ssh, send_tok.value, |
1731 | + send_tok.length); | 1746 | + send_tok.length)) != 0) |
1747 | + fatal("failed to construct packet: %s", ssh_err(r)); | ||
1732 | + } | 1748 | + } |
1733 | + packet_send(); | 1749 | + if ((r = sshpkt_send(ssh)) != 0) |
1750 | + fatal("failed to send packet: %s", ssh_err(r)); | ||
1734 | + gss_release_buffer(&min_status, &send_tok); | 1751 | + gss_release_buffer(&min_status, &send_tok); |
1735 | + | 1752 | + |
1736 | + /* If we've sent them data, they should reply */ | 1753 | + /* If we've sent them data, they should reply */ |
1737 | + do { | 1754 | + do { |
1738 | + type = packet_read(); | 1755 | + type = ssh_packet_read(ssh); |
1739 | + if (type == SSH2_MSG_KEXGSS_HOSTKEY) { | 1756 | + if (type == SSH2_MSG_KEXGSS_HOSTKEY) { |
1740 | + debug("Received KEXGSS_HOSTKEY"); | 1757 | + debug("Received KEXGSS_HOSTKEY"); |
1741 | + if (serverhostkey) | 1758 | + if (server_host_key_blob) |
1742 | + fatal("Server host key received more than once"); | 1759 | + fatal("Server host key received more than once"); |
1743 | + serverhostkey = | 1760 | + if ((r = sshpkt_getb_froms(ssh, &server_host_key_blob)) != 0) |
1744 | + packet_get_string(&slen); | 1761 | + fatal("Failed to read server host key: %s", ssh_err(r)); |
1745 | + } | 1762 | + } |
1746 | + } while (type == SSH2_MSG_KEXGSS_HOSTKEY); | 1763 | + } while (type == SSH2_MSG_KEXGSS_HOSTKEY); |
1747 | + | 1764 | + |
1748 | + switch (type) { | 1765 | + switch (type) { |
1749 | + case SSH2_MSG_KEXGSS_CONTINUE: | 1766 | + case SSH2_MSG_KEXGSS_CONTINUE: |
1750 | + debug("Received GSSAPI_CONTINUE"); | 1767 | + debug("Received GSSAPI_CONTINUE"); |
1751 | + if (maj_status == GSS_S_COMPLETE) | 1768 | + if (maj_status == GSS_S_COMPLETE) |
1752 | + fatal("GSSAPI Continue received from server when complete"); | 1769 | + fatal("GSSAPI Continue received from server when complete"); |
1753 | + recv_tok.value = packet_get_string(&strlen); | 1770 | + if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, |
1754 | + recv_tok.length = strlen; | 1771 | + &recv_tok)) != 0 || |
1772 | + (r = sshpkt_get_end(ssh)) != 0) | ||
1773 | + fatal("Failed to read token: %s", ssh_err(r)); | ||
1755 | + break; | 1774 | + break; |
1756 | + case SSH2_MSG_KEXGSS_COMPLETE: | 1775 | + case SSH2_MSG_KEXGSS_COMPLETE: |
1757 | + debug("Received GSSAPI_COMPLETE"); | 1776 | + debug("Received GSSAPI_COMPLETE"); |
1758 | + packet_get_bignum2(dh_server_pub); | 1777 | + if (msg_tok.value != NULL) |
1759 | + msg_tok.value = packet_get_string(&strlen); | 1778 | + fatal("Received GSSAPI_COMPLETE twice?"); |
1760 | + msg_tok.length = strlen; | 1779 | + if ((r = sshpkt_getb_froms(ssh, &server_blob)) != 0 || |
1780 | + (r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, | ||
1781 | + &msg_tok)) != 0) | ||
1782 | + fatal("Failed to read message: %s", ssh_err(r)); | ||
1761 | + | 1783 | + |
1762 | + /* Is there a token included? */ | 1784 | + /* Is there a token included? */ |
1763 | + if (packet_get_char()) { | 1785 | + if ((r = sshpkt_get_u8(ssh, &c)) != 0) |
1764 | + recv_tok.value= | 1786 | + fatal("sshpkt failed: %s", ssh_err(r)); |
1765 | + packet_get_string(&strlen); | 1787 | + if (c) { |
1766 | + recv_tok.length = strlen; | 1788 | + if ((r = ssh_gssapi_sshpkt_get_buffer_desc( |
1789 | + ssh, &recv_tok)) != 0) | ||
1790 | + fatal("Failed to read token: %s", ssh_err(r)); | ||
1767 | + /* If we're already complete - protocol error */ | 1791 | + /* If we're already complete - protocol error */ |
1768 | + if (maj_status == GSS_S_COMPLETE) | 1792 | + if (maj_status == GSS_S_COMPLETE) |
1769 | + packet_disconnect("Protocol error: received token when complete"); | 1793 | + sshpkt_disconnect(ssh, "Protocol error: received token when complete"); |
1770 | + } else { | 1794 | + } else { |
1771 | + /* No token included */ | 1795 | + /* No token included */ |
1772 | + if (maj_status != GSS_S_COMPLETE) | 1796 | + if (maj_status != GSS_S_COMPLETE) |
1773 | + packet_disconnect("Protocol error: did not receive final token"); | 1797 | + sshpkt_disconnect(ssh, "Protocol error: did not receive final token"); |
1798 | + } | ||
1799 | + if ((r = sshpkt_get_end(ssh)) != 0) { | ||
1800 | + fatal("Expecting end of packet."); | ||
1774 | + } | 1801 | + } |
1775 | + break; | 1802 | + break; |
1776 | + case SSH2_MSG_KEXGSS_ERROR: | 1803 | + case SSH2_MSG_KEXGSS_ERROR: |
1777 | + debug("Received Error"); | 1804 | + debug("Received Error"); |
1778 | + maj_status = packet_get_int(); | 1805 | + if ((r = sshpkt_get_u32(ssh, &maj_status)) != 0 || |
1779 | + min_status = packet_get_int(); | 1806 | + (r = sshpkt_get_u32(ssh, &min_status)) != 0 || |
1780 | + msg = packet_get_string(NULL); | 1807 | + (r = sshpkt_get_string(ssh, &msg, NULL)) != 0 || |
1781 | + (void) packet_get_string_ptr(NULL); | 1808 | + (r = sshpkt_get_string(ssh, NULL, NULL)) != 0 || /* lang tag */ |
1782 | + fatal("GSSAPI Error: \n%.400s",msg); | 1809 | + (r = sshpkt_get_end(ssh)) != 0) |
1810 | + fatal("sshpkt_get failed: %s", ssh_err(r)); | ||
1811 | + fatal("GSSAPI Error: \n%.400s", msg); | ||
1783 | + default: | 1812 | + default: |
1784 | + packet_disconnect("Protocol error: didn't expect packet type %d", | 1813 | + sshpkt_disconnect(ssh, "Protocol error: didn't expect packet type %d", |
1785 | + type); | 1814 | + type); |
1786 | + } | 1815 | + } |
1787 | + token_ptr = &recv_tok; | 1816 | + token_ptr = &recv_tok; |
1788 | + } else { | 1817 | + } else { |
@@ -1792,93 +1821,358 @@ index 000000000..3c8ae08dd | |||
1792 | + } | 1821 | + } |
1793 | + } while (maj_status & GSS_S_CONTINUE_NEEDED); | 1822 | + } while (maj_status & GSS_S_CONTINUE_NEEDED); |
1794 | + | 1823 | + |
1795 | + /* | 1824 | + /* |
1796 | + * We _must_ have received a COMPLETE message in reply from the | 1825 | + * We _must_ have received a COMPLETE message in reply from the |
1797 | + * server, which will have set dh_server_pub and msg_tok | 1826 | + * server, which will have set server_blob and msg_tok |
1798 | + */ | 1827 | + */ |
1799 | + | 1828 | + |
1800 | + if (type != SSH2_MSG_KEXGSS_COMPLETE) | 1829 | + if (type != SSH2_MSG_KEXGSS_COMPLETE) |
1801 | + fatal("Didn't receive a SSH2_MSG_KEXGSS_COMPLETE when I expected it"); | 1830 | + fatal("Didn't receive a SSH2_MSG_KEXGSS_COMPLETE when I expected it"); |
1802 | + | 1831 | + |
1803 | + /* Check f in range [1, p-1] */ | 1832 | + /* compute shared secret */ |
1804 | + if (!dh_pub_is_valid(dh, dh_server_pub)) | 1833 | + switch (kex->kex_type) { |
1805 | + packet_disconnect("bad server public DH value"); | ||
1806 | + | ||
1807 | + /* compute K=f^x mod p */ | ||
1808 | + klen = DH_size(dh); | ||
1809 | + kbuf = xmalloc(klen); | ||
1810 | + kout = DH_compute_key(kbuf, dh_server_pub, dh); | ||
1811 | + if (kout < 0) | ||
1812 | + fatal("DH_compute_key: failed"); | ||
1813 | + | ||
1814 | + shared_secret = BN_new(); | ||
1815 | + if (shared_secret == NULL) | ||
1816 | + fatal("kexgss_client: BN_new failed"); | ||
1817 | + | ||
1818 | + if (BN_bin2bn(kbuf, kout, shared_secret) == NULL) | ||
1819 | + fatal("kexdh_client: BN_bin2bn failed"); | ||
1820 | + | ||
1821 | + memset(kbuf, 0, klen); | ||
1822 | + free(kbuf); | ||
1823 | + | ||
1824 | + hashlen = sizeof(hash); | ||
1825 | + switch (ssh->kex->kex_type) { | ||
1826 | + case KEX_GSS_GRP1_SHA1: | 1834 | + case KEX_GSS_GRP1_SHA1: |
1827 | + case KEX_GSS_GRP14_SHA1: | 1835 | + case KEX_GSS_GRP14_SHA1: |
1828 | + kex_dh_hash( | 1836 | + case KEX_GSS_GRP14_SHA256: |
1829 | + ssh->kex->hash_alg, | 1837 | + case KEX_GSS_GRP16_SHA512: |
1830 | + ssh->kex->client_version_string, | 1838 | + r = kex_dh_dec(kex, server_blob, &shared_secret); |
1831 | + ssh->kex->server_version_string, | 1839 | + break; |
1832 | + sshbuf_ptr(ssh->kex->my), sshbuf_len(ssh->kex->my), | 1840 | + case KEX_GSS_C25519_SHA256: |
1833 | + sshbuf_ptr(ssh->kex->peer), sshbuf_len(ssh->kex->peer), | 1841 | + if (sshbuf_ptr(server_blob)[sshbuf_len(server_blob)] & 0x80) |
1834 | + (serverhostkey ? serverhostkey : empty), slen, | 1842 | + fatal("The received key has MSB of last octet set!"); |
1835 | + pub_key, /* e */ | 1843 | + r = kex_c25519_dec(kex, server_blob, &shared_secret); |
1836 | + dh_server_pub, /* f */ | ||
1837 | + shared_secret, /* K */ | ||
1838 | + hash, &hashlen | ||
1839 | + ); | ||
1840 | + break; | 1844 | + break; |
1841 | + case KEX_GSS_GEX_SHA1: | 1845 | + case KEX_GSS_NISTP256_SHA256: |
1842 | + kexgex_hash( | 1846 | + if (sshbuf_len(server_blob) != 65) |
1843 | + ssh->kex->hash_alg, | 1847 | + fatal("The received NIST-P256 key did not match" |
1844 | + ssh->kex->client_version_string, | 1848 | + "expected length (expected 65, got %zu)", sshbuf_len(server_blob)); |
1845 | + ssh->kex->server_version_string, | 1849 | + |
1846 | + sshbuf_ptr(ssh->kex->my), sshbuf_len(ssh->kex->my), | 1850 | + if (sshbuf_ptr(server_blob)[0] != POINT_CONVERSION_UNCOMPRESSED) |
1847 | + sshbuf_ptr(ssh->kex->peer), sshbuf_len(ssh->kex->peer), | 1851 | + fatal("The received NIST-P256 key does not have first octet 0x04"); |
1848 | + (serverhostkey ? serverhostkey : empty), slen, | 1852 | + |
1849 | + min, nbits, max, | 1853 | + r = kex_ecdh_dec(kex, server_blob, &shared_secret); |
1850 | + dh_p, dh_g, | ||
1851 | + pub_key, | ||
1852 | + dh_server_pub, | ||
1853 | + shared_secret, | ||
1854 | + hash, &hashlen | ||
1855 | + ); | ||
1856 | + break; | 1854 | + break; |
1857 | + default: | 1855 | + default: |
1858 | + fatal("%s: Unexpected KEX type %d", __func__, ssh->kex->kex_type); | 1856 | + r = SSH_ERR_INVALID_ARGUMENT; |
1857 | + break; | ||
1858 | + } | ||
1859 | + if (r != 0) | ||
1860 | + goto out; | ||
1861 | + | ||
1862 | + if ((empty = sshbuf_new()) == NULL) { | ||
1863 | + r = SSH_ERR_ALLOC_FAIL; | ||
1864 | + goto out; | ||
1859 | + } | 1865 | + } |
1860 | + | 1866 | + |
1867 | + hashlen = sizeof(hash); | ||
1868 | + if ((r = kex_gen_hash( | ||
1869 | + kex->hash_alg, | ||
1870 | + kex->client_version, | ||
1871 | + kex->server_version, | ||
1872 | + kex->my, | ||
1873 | + kex->peer, | ||
1874 | + (server_host_key_blob ? server_host_key_blob : empty), | ||
1875 | + kex->client_pub, | ||
1876 | + server_blob, | ||
1877 | + shared_secret, | ||
1878 | + hash, &hashlen)) != 0) | ||
1879 | + fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); | ||
1880 | + | ||
1861 | + gssbuf.value = hash; | 1881 | + gssbuf.value = hash; |
1862 | + gssbuf.length = hashlen; | 1882 | + gssbuf.length = hashlen; |
1863 | + | 1883 | + |
1864 | + /* Verify that the hash matches the MIC we just got. */ | 1884 | + /* Verify that the hash matches the MIC we just got. */ |
1865 | + if (GSS_ERROR(ssh_gssapi_checkmic(ctxt, &gssbuf, &msg_tok))) | 1885 | + if (GSS_ERROR(ssh_gssapi_checkmic(ctxt, &gssbuf, &msg_tok))) |
1866 | + packet_disconnect("Hash's MIC didn't verify"); | 1886 | + sshpkt_disconnect(ssh, "Hash's MIC didn't verify"); |
1867 | + | 1887 | + |
1868 | + free(msg_tok.value); | 1888 | + gss_release_buffer(&min_status, &msg_tok); |
1869 | + | 1889 | + |
1870 | + DH_free(dh); | 1890 | + if (kex->gss_deleg_creds) |
1871 | + free(serverhostkey); | 1891 | + ssh_gssapi_credentials_updated(ctxt); |
1872 | + BN_clear_free(dh_server_pub); | 1892 | + |
1893 | + if (gss_kex_context == NULL) | ||
1894 | + gss_kex_context = ctxt; | ||
1895 | + else | ||
1896 | + ssh_gssapi_delete_ctx(&ctxt); | ||
1897 | + | ||
1898 | + if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) | ||
1899 | + r = kex_send_newkeys(ssh); | ||
1900 | + | ||
1901 | +out: | ||
1902 | + explicit_bzero(hash, sizeof(hash)); | ||
1903 | + explicit_bzero(kex->c25519_client_key, sizeof(kex->c25519_client_key)); | ||
1904 | + sshbuf_free(empty); | ||
1905 | + sshbuf_free(server_host_key_blob); | ||
1906 | + sshbuf_free(server_blob); | ||
1907 | + sshbuf_free(shared_secret); | ||
1908 | + sshbuf_free(kex->client_pub); | ||
1909 | + kex->client_pub = NULL; | ||
1910 | + return r; | ||
1911 | +} | ||
1912 | + | ||
1913 | +int | ||
1914 | +kexgssgex_client(struct ssh *ssh) | ||
1915 | +{ | ||
1916 | + struct kex *kex = ssh->kex; | ||
1917 | + gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER, | ||
1918 | + recv_tok = GSS_C_EMPTY_BUFFER, gssbuf, | ||
1919 | + msg_tok = GSS_C_EMPTY_BUFFER, *token_ptr; | ||
1920 | + Gssctxt *ctxt; | ||
1921 | + OM_uint32 maj_status, min_status, ret_flags; | ||
1922 | + struct sshbuf *shared_secret = NULL; | ||
1923 | + BIGNUM *p = NULL; | ||
1924 | + BIGNUM *g = NULL; | ||
1925 | + struct sshbuf *buf = NULL; | ||
1926 | + struct sshbuf *server_host_key_blob = NULL; | ||
1927 | + struct sshbuf *server_blob = NULL; | ||
1928 | + BIGNUM *dh_server_pub = NULL; | ||
1929 | + u_char *msg; | ||
1930 | + int type = 0; | ||
1931 | + int first = 1; | ||
1932 | + u_char hash[SSH_DIGEST_MAX_LENGTH]; | ||
1933 | + size_t hashlen; | ||
1934 | + const BIGNUM *pub_key, *dh_p, *dh_g; | ||
1935 | + int nbits = 0, min = DH_GRP_MIN, max = DH_GRP_MAX; | ||
1936 | + struct sshbuf *empty = NULL; | ||
1937 | + u_char c; | ||
1938 | + int r; | ||
1939 | + | ||
1940 | + /* Initialise our GSSAPI world */ | ||
1941 | + ssh_gssapi_build_ctx(&ctxt); | ||
1942 | + if (ssh_gssapi_id_kex(ctxt, kex->name, kex->kex_type) | ||
1943 | + == GSS_C_NO_OID) | ||
1944 | + fatal("Couldn't identify host exchange"); | ||
1945 | + | ||
1946 | + if (ssh_gssapi_import_name(ctxt, kex->gss_host)) | ||
1947 | + fatal("Couldn't import hostname"); | ||
1948 | + | ||
1949 | + if (kex->gss_client && | ||
1950 | + ssh_gssapi_client_identity(ctxt, kex->gss_client)) | ||
1951 | + fatal("Couldn't acquire client credentials"); | ||
1952 | + | ||
1953 | + debug("Doing group exchange"); | ||
1954 | + nbits = dh_estimate(kex->dh_need * 8); | ||
1955 | + | ||
1956 | + kex->min = DH_GRP_MIN; | ||
1957 | + kex->max = DH_GRP_MAX; | ||
1958 | + kex->nbits = nbits; | ||
1959 | + if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_GROUPREQ)) != 0 || | ||
1960 | + (r = sshpkt_put_u32(ssh, min)) != 0 || | ||
1961 | + (r = sshpkt_put_u32(ssh, nbits)) != 0 || | ||
1962 | + (r = sshpkt_put_u32(ssh, max)) != 0 || | ||
1963 | + (r = sshpkt_send(ssh)) != 0) | ||
1964 | + fatal("Failed to construct a packet: %s", ssh_err(r)); | ||
1965 | + | ||
1966 | + if ((r = ssh_packet_read_expect(ssh, SSH2_MSG_KEXGSS_GROUP)) != 0) | ||
1967 | + fatal("Error: %s", ssh_err(r)); | ||
1968 | + | ||
1969 | + if ((r = sshpkt_get_bignum2(ssh, &p)) != 0 || | ||
1970 | + (r = sshpkt_get_bignum2(ssh, &g)) != 0 || | ||
1971 | + (r = sshpkt_get_end(ssh)) != 0) | ||
1972 | + fatal("shpkt_get_bignum2 failed: %s", ssh_err(r)); | ||
1973 | + | ||
1974 | + if (BN_num_bits(p) < min || BN_num_bits(p) > max) | ||
1975 | + fatal("GSSGRP_GEX group out of range: %d !< %d !< %d", | ||
1976 | + min, BN_num_bits(p), max); | ||
1977 | + | ||
1978 | + if ((kex->dh = dh_new_group(g, p)) == NULL) | ||
1979 | + fatal("dn_new_group() failed"); | ||
1980 | + p = g = NULL; /* belong to kex->dh now */ | ||
1981 | + | ||
1982 | + if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0) | ||
1983 | + goto out; | ||
1984 | + DH_get0_key(kex->dh, &pub_key, NULL); | ||
1985 | + | ||
1986 | + token_ptr = GSS_C_NO_BUFFER; | ||
1987 | + | ||
1988 | + do { | ||
1989 | + /* Step 2 - call GSS_Init_sec_context() */ | ||
1990 | + debug("Calling gss_init_sec_context"); | ||
1991 | + | ||
1992 | + maj_status = ssh_gssapi_init_ctx(ctxt, | ||
1993 | + kex->gss_deleg_creds, token_ptr, &send_tok, | ||
1994 | + &ret_flags); | ||
1995 | + | ||
1996 | + if (GSS_ERROR(maj_status)) { | ||
1997 | + /* XXX Useles code: Missing send? */ | ||
1998 | + if (send_tok.length != 0) { | ||
1999 | + if ((r = sshpkt_start(ssh, | ||
2000 | + SSH2_MSG_KEXGSS_CONTINUE)) != 0 || | ||
2001 | + (r = sshpkt_put_string(ssh, send_tok.value, | ||
2002 | + send_tok.length)) != 0) | ||
2003 | + fatal("sshpkt failed: %s", ssh_err(r)); | ||
2004 | + } | ||
2005 | + fatal("gss_init_context failed"); | ||
2006 | + } | ||
2007 | + | ||
2008 | + /* If we've got an old receive buffer get rid of it */ | ||
2009 | + if (token_ptr != GSS_C_NO_BUFFER) | ||
2010 | + gss_release_buffer(&min_status, &recv_tok); | ||
2011 | + | ||
2012 | + if (maj_status == GSS_S_COMPLETE) { | ||
2013 | + /* If mutual state flag is not true, kex fails */ | ||
2014 | + if (!(ret_flags & GSS_C_MUTUAL_FLAG)) | ||
2015 | + fatal("Mutual authentication failed"); | ||
2016 | + | ||
2017 | + /* If integ avail flag is not true kex fails */ | ||
2018 | + if (!(ret_flags & GSS_C_INTEG_FLAG)) | ||
2019 | + fatal("Integrity check failed"); | ||
2020 | + } | ||
2021 | + | ||
2022 | + /* | ||
2023 | + * If we have data to send, then the last message that we | ||
2024 | + * received cannot have been a 'complete'. | ||
2025 | + */ | ||
2026 | + if (send_tok.length != 0) { | ||
2027 | + if (first) { | ||
2028 | + if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_INIT)) != 0 || | ||
2029 | + (r = sshpkt_put_string(ssh, send_tok.value, | ||
2030 | + send_tok.length)) != 0 || | ||
2031 | + (r = sshpkt_put_bignum2(ssh, pub_key)) != 0) | ||
2032 | + fatal("sshpkt failed: %s", ssh_err(r)); | ||
2033 | + first = 0; | ||
2034 | + } else { | ||
2035 | + if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || | ||
2036 | + (r = sshpkt_put_string(ssh,send_tok.value, | ||
2037 | + send_tok.length)) != 0) | ||
2038 | + fatal("sshpkt failed: %s", ssh_err(r)); | ||
2039 | + } | ||
2040 | + if ((r = sshpkt_send(ssh)) != 0) | ||
2041 | + fatal("sshpkt_send failed: %s", ssh_err(r)); | ||
2042 | + gss_release_buffer(&min_status, &send_tok); | ||
2043 | + | ||
2044 | + /* If we've sent them data, they should reply */ | ||
2045 | + do { | ||
2046 | + type = ssh_packet_read(ssh); | ||
2047 | + if (type == SSH2_MSG_KEXGSS_HOSTKEY) { | ||
2048 | + debug("Received KEXGSS_HOSTKEY"); | ||
2049 | + if (server_host_key_blob) | ||
2050 | + fatal("Server host key received more than once"); | ||
2051 | + if ((r = sshpkt_getb_froms(ssh, &server_host_key_blob)) != 0) | ||
2052 | + fatal("sshpkt failed: %s", ssh_err(r)); | ||
2053 | + } | ||
2054 | + } while (type == SSH2_MSG_KEXGSS_HOSTKEY); | ||
2055 | + | ||
2056 | + switch (type) { | ||
2057 | + case SSH2_MSG_KEXGSS_CONTINUE: | ||
2058 | + debug("Received GSSAPI_CONTINUE"); | ||
2059 | + if (maj_status == GSS_S_COMPLETE) | ||
2060 | + fatal("GSSAPI Continue received from server when complete"); | ||
2061 | + if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, | ||
2062 | + &recv_tok)) != 0 || | ||
2063 | + (r = sshpkt_get_end(ssh)) != 0) | ||
2064 | + fatal("sshpkt failed: %s", ssh_err(r)); | ||
2065 | + break; | ||
2066 | + case SSH2_MSG_KEXGSS_COMPLETE: | ||
2067 | + debug("Received GSSAPI_COMPLETE"); | ||
2068 | + if (msg_tok.value != NULL) | ||
2069 | + fatal("Received GSSAPI_COMPLETE twice?"); | ||
2070 | + if ((r = sshpkt_getb_froms(ssh, &server_blob)) != 0 || | ||
2071 | + (r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, | ||
2072 | + &msg_tok)) != 0) | ||
2073 | + fatal("sshpkt failed: %s", ssh_err(r)); | ||
2074 | + | ||
2075 | + /* Is there a token included? */ | ||
2076 | + if ((r = sshpkt_get_u8(ssh, &c)) != 0) | ||
2077 | + fatal("sshpkt failed: %s", ssh_err(r)); | ||
2078 | + if (c) { | ||
2079 | + if ((r = ssh_gssapi_sshpkt_get_buffer_desc( | ||
2080 | + ssh, &recv_tok)) != 0 || | ||
2081 | + (r = sshpkt_get_end(ssh)) != 0) | ||
2082 | + fatal("sshpkt failed: %s", ssh_err(r)); | ||
2083 | + /* If we're already complete - protocol error */ | ||
2084 | + if (maj_status == GSS_S_COMPLETE) | ||
2085 | + sshpkt_disconnect(ssh, "Protocol error: received token when complete"); | ||
2086 | + } else { | ||
2087 | + /* No token included */ | ||
2088 | + if (maj_status != GSS_S_COMPLETE) | ||
2089 | + sshpkt_disconnect(ssh, "Protocol error: did not receive final token"); | ||
2090 | + } | ||
2091 | + break; | ||
2092 | + case SSH2_MSG_KEXGSS_ERROR: | ||
2093 | + debug("Received Error"); | ||
2094 | + if ((r = sshpkt_get_u32(ssh, &maj_status)) != 0 || | ||
2095 | + (r = sshpkt_get_u32(ssh, &min_status)) != 0 || | ||
2096 | + (r = sshpkt_get_string(ssh, &msg, NULL)) != 0 || | ||
2097 | + (r = sshpkt_get_string(ssh, NULL, NULL)) != 0 || /* lang tag */ | ||
2098 | + (r = sshpkt_get_end(ssh)) != 0) | ||
2099 | + fatal("sshpkt failed: %s", ssh_err(r)); | ||
2100 | + fatal("GSSAPI Error: \n%.400s", msg); | ||
2101 | + default: | ||
2102 | + sshpkt_disconnect(ssh, "Protocol error: didn't expect packet type %d", | ||
2103 | + type); | ||
2104 | + } | ||
2105 | + token_ptr = &recv_tok; | ||
2106 | + } else { | ||
2107 | + /* No data, and not complete */ | ||
2108 | + if (maj_status != GSS_S_COMPLETE) | ||
2109 | + fatal("Not complete, and no token output"); | ||
2110 | + } | ||
2111 | + } while (maj_status & GSS_S_CONTINUE_NEEDED); | ||
2112 | + | ||
2113 | + /* | ||
2114 | + * We _must_ have received a COMPLETE message in reply from the | ||
2115 | + * server, which will have set dh_server_pub and msg_tok | ||
2116 | + */ | ||
2117 | + | ||
2118 | + if (type != SSH2_MSG_KEXGSS_COMPLETE) | ||
2119 | + fatal("Didn't receive a SSH2_MSG_KEXGSS_COMPLETE when I expected it"); | ||
2120 | + | ||
2121 | + /* 7. C verifies that the key Q_S is valid */ | ||
2122 | + /* 8. C computes shared secret */ | ||
2123 | + if ((buf = sshbuf_new()) == NULL || | ||
2124 | + (r = sshbuf_put_stringb(buf, server_blob)) != 0 || | ||
2125 | + (r = sshbuf_get_bignum2(buf, &dh_server_pub)) != 0) | ||
2126 | + goto out; | ||
2127 | + sshbuf_free(buf); | ||
2128 | + buf = NULL; | ||
2129 | + | ||
2130 | + if ((shared_secret = sshbuf_new()) == NULL) { | ||
2131 | + r = SSH_ERR_ALLOC_FAIL; | ||
2132 | + goto out; | ||
2133 | + } | ||
2134 | + | ||
2135 | + if ((r = kex_dh_compute_key(kex, dh_server_pub, shared_secret)) != 0) | ||
2136 | + goto out; | ||
2137 | + if ((empty = sshbuf_new()) == NULL) { | ||
2138 | + r = SSH_ERR_ALLOC_FAIL; | ||
2139 | + goto out; | ||
2140 | + } | ||
2141 | + | ||
2142 | + DH_get0_pqg(kex->dh, &dh_p, NULL, &dh_g); | ||
2143 | + hashlen = sizeof(hash); | ||
2144 | + if ((r = kexgex_hash( | ||
2145 | + kex->hash_alg, | ||
2146 | + kex->client_version, | ||
2147 | + kex->server_version, | ||
2148 | + kex->my, | ||
2149 | + kex->peer, | ||
2150 | + (server_host_key_blob ? server_host_key_blob : empty), | ||
2151 | + kex->min, kex->nbits, kex->max, | ||
2152 | + dh_p, dh_g, | ||
2153 | + pub_key, | ||
2154 | + dh_server_pub, | ||
2155 | + sshbuf_ptr(shared_secret), sshbuf_len(shared_secret), | ||
2156 | + hash, &hashlen)) != 0) | ||
2157 | + fatal("Failed to calculate hash: %s", ssh_err(r)); | ||
2158 | + | ||
2159 | + gssbuf.value = hash; | ||
2160 | + gssbuf.length = hashlen; | ||
2161 | + | ||
2162 | + /* Verify that the hash matches the MIC we just got. */ | ||
2163 | + if (GSS_ERROR(ssh_gssapi_checkmic(ctxt, &gssbuf, &msg_tok))) | ||
2164 | + sshpkt_disconnect(ssh, "Hash's MIC didn't verify"); | ||
2165 | + | ||
2166 | + gss_release_buffer(&min_status, &msg_tok); | ||
1873 | + | 2167 | + |
1874 | + /* save session id */ | 2168 | + /* save session id */ |
1875 | + if (ssh->kex->session_id == NULL) { | 2169 | + if (kex->session_id == NULL) { |
1876 | + ssh->kex->session_id_len = hashlen; | 2170 | + kex->session_id_len = hashlen; |
1877 | + ssh->kex->session_id = xmalloc(ssh->kex->session_id_len); | 2171 | + kex->session_id = xmalloc(kex->session_id_len); |
1878 | + memcpy(ssh->kex->session_id, hash, ssh->kex->session_id_len); | 2172 | + memcpy(kex->session_id, hash, kex->session_id_len); |
1879 | + } | 2173 | + } |
1880 | + | 2174 | + |
1881 | + if (ssh->kex->gss_deleg_creds) | 2175 | + if (kex->gss_deleg_creds) |
1882 | + ssh_gssapi_credentials_updated(ctxt); | 2176 | + ssh_gssapi_credentials_updated(ctxt); |
1883 | + | 2177 | + |
1884 | + if (gss_kex_context == NULL) | 2178 | + if (gss_kex_context == NULL) |
@@ -1886,18 +2180,28 @@ index 000000000..3c8ae08dd | |||
1886 | + else | 2180 | + else |
1887 | + ssh_gssapi_delete_ctx(&ctxt); | 2181 | + ssh_gssapi_delete_ctx(&ctxt); |
1888 | + | 2182 | + |
1889 | + kex_derive_keys_bn(ssh, hash, hashlen, shared_secret); | 2183 | + /* Finally derive the keys and send them */ |
1890 | + BN_clear_free(shared_secret); | 2184 | + if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) |
1891 | + return kex_send_newkeys(ssh); | 2185 | + r = kex_send_newkeys(ssh); |
2186 | +out: | ||
2187 | + sshbuf_free(buf); | ||
2188 | + sshbuf_free(server_blob); | ||
2189 | + sshbuf_free(empty); | ||
2190 | + explicit_bzero(hash, sizeof(hash)); | ||
2191 | + DH_free(kex->dh); | ||
2192 | + kex->dh = NULL; | ||
2193 | + BN_clear_free(dh_server_pub); | ||
2194 | + sshbuf_free(shared_secret); | ||
2195 | + sshbuf_free(server_host_key_blob); | ||
2196 | + return r; | ||
1892 | +} | 2197 | +} |
1893 | + | 2198 | +#endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ |
1894 | +#endif /* GSSAPI */ | ||
1895 | diff --git a/kexgsss.c b/kexgsss.c | 2199 | diff --git a/kexgsss.c b/kexgsss.c |
1896 | new file mode 100644 | 2200 | new file mode 100644 |
1897 | index 000000000..18070f1d7 | 2201 | index 000000000..60bc02deb |
1898 | --- /dev/null | 2202 | --- /dev/null |
1899 | +++ b/kexgsss.c | 2203 | +++ b/kexgsss.c |
1900 | @@ -0,0 +1,300 @@ | 2204 | @@ -0,0 +1,474 @@ |
1901 | +/* | 2205 | +/* |
1902 | + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. | 2206 | + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. |
1903 | + * | 2207 | + * |
@@ -1924,7 +2228,7 @@ index 000000000..18070f1d7 | |||
1924 | + | 2228 | + |
1925 | +#include "includes.h" | 2229 | +#include "includes.h" |
1926 | + | 2230 | + |
1927 | +#ifdef GSSAPI | 2231 | +#if defined(GSSAPI) && defined(WITH_OPENSSL) |
1928 | + | 2232 | + |
1929 | +#include <string.h> | 2233 | +#include <string.h> |
1930 | + | 2234 | + |
@@ -1942,40 +2246,41 @@ index 000000000..18070f1d7 | |||
1942 | +#include "dh.h" | 2246 | +#include "dh.h" |
1943 | +#include "ssh-gss.h" | 2247 | +#include "ssh-gss.h" |
1944 | +#include "monitor_wrap.h" | 2248 | +#include "monitor_wrap.h" |
1945 | +#include "misc.h" | 2249 | +#include "misc.h" /* servconf.h needs misc.h for struct ForwardOptions */ |
1946 | +#include "servconf.h" | 2250 | +#include "servconf.h" |
2251 | +#include "ssh-gss.h" | ||
1947 | +#include "digest.h" | 2252 | +#include "digest.h" |
2253 | +#include "ssherr.h" | ||
1948 | + | 2254 | + |
1949 | +extern ServerOptions options; | 2255 | +extern ServerOptions options; |
1950 | + | 2256 | + |
1951 | +int | 2257 | +int |
1952 | +kexgss_server(struct ssh *ssh) | 2258 | +kexgss_server(struct ssh *ssh) |
1953 | +{ | 2259 | +{ |
2260 | + struct kex *kex = ssh->kex; | ||
1954 | + OM_uint32 maj_status, min_status; | 2261 | + OM_uint32 maj_status, min_status; |
1955 | + | 2262 | + |
1956 | + /* | 2263 | + /* |
1957 | + * Some GSSAPI implementations use the input value of ret_flags (an | 2264 | + * Some GSSAPI implementations use the input value of ret_flags (an |
1958 | + * output variable) as a means of triggering mechanism specific | 2265 | + * output variable) as a means of triggering mechanism specific |
1959 | + * features. Initializing it to zero avoids inadvertently | 2266 | + * features. Initializing it to zero avoids inadvertently |
1960 | + * activating this non-standard behaviour. | 2267 | + * activating this non-standard behaviour. |
1961 | + */ | 2268 | + */ |
1962 | + | 2269 | + |
1963 | + OM_uint32 ret_flags = 0; | 2270 | + OM_uint32 ret_flags = 0; |
1964 | + gss_buffer_desc gssbuf, recv_tok, msg_tok; | 2271 | + gss_buffer_desc gssbuf, recv_tok, msg_tok; |
1965 | + gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; | 2272 | + gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; |
1966 | + Gssctxt *ctxt = NULL; | 2273 | + Gssctxt *ctxt = NULL; |
1967 | + u_int slen, klen, kout; | 2274 | + struct sshbuf *shared_secret = NULL; |
1968 | + u_char *kbuf; | 2275 | + struct sshbuf *client_pubkey = NULL; |
1969 | + DH *dh; | 2276 | + struct sshbuf *server_pubkey = NULL; |
1970 | + int min = -1, max = -1, nbits = -1; | 2277 | + struct sshbuf *empty = sshbuf_new(); |
1971 | + const BIGNUM *pub_key, *dh_p, *dh_g; | ||
1972 | + BIGNUM *shared_secret = NULL; | ||
1973 | + BIGNUM *dh_client_pub = NULL; | ||
1974 | + int type = 0; | 2278 | + int type = 0; |
1975 | + gss_OID oid; | 2279 | + gss_OID oid; |
1976 | + char *mechs; | 2280 | + char *mechs; |
1977 | + u_char hash[SSH_DIGEST_MAX_LENGTH]; | 2281 | + u_char hash[SSH_DIGEST_MAX_LENGTH]; |
1978 | + size_t hashlen; | 2282 | + size_t hashlen; |
2283 | + int r; | ||
1979 | + | 2284 | + |
1980 | + /* Initialise GSSAPI */ | 2285 | + /* Initialise GSSAPI */ |
1981 | + | 2286 | + |
@@ -1988,8 +2293,8 @@ index 000000000..18070f1d7 | |||
1988 | + free(mechs); | 2293 | + free(mechs); |
1989 | + } | 2294 | + } |
1990 | + | 2295 | + |
1991 | + debug2("%s: Identifying %s", __func__, ssh->kex->name); | 2296 | + debug2("%s: Identifying %s", __func__, kex->name); |
1992 | + oid = ssh_gssapi_id_kex(NULL, ssh->kex->name, ssh->kex->kex_type); | 2297 | + oid = ssh_gssapi_id_kex(NULL, kex->name, kex->kex_type); |
1993 | + if (oid == GSS_C_NO_OID) | 2298 | + if (oid == GSS_C_NO_OID) |
1994 | + fatal("Unknown gssapi mechanism"); | 2299 | + fatal("Unknown gssapi mechanism"); |
1995 | + | 2300 | + |
@@ -1998,94 +2303,82 @@ index 000000000..18070f1d7 | |||
1998 | + if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid)))) | 2303 | + if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid)))) |
1999 | + fatal("Unable to acquire credentials for the server"); | 2304 | + fatal("Unable to acquire credentials for the server"); |
2000 | + | 2305 | + |
2001 | + switch (ssh->kex->kex_type) { | ||
2002 | + case KEX_GSS_GRP1_SHA1: | ||
2003 | + dh = dh_new_group1(); | ||
2004 | + break; | ||
2005 | + case KEX_GSS_GRP14_SHA1: | ||
2006 | + dh = dh_new_group14(); | ||
2007 | + break; | ||
2008 | + case KEX_GSS_GEX_SHA1: | ||
2009 | + debug("Doing group exchange"); | ||
2010 | + packet_read_expect(SSH2_MSG_KEXGSS_GROUPREQ); | ||
2011 | + min = packet_get_int(); | ||
2012 | + nbits = packet_get_int(); | ||
2013 | + max = packet_get_int(); | ||
2014 | + packet_check_eom(); | ||
2015 | + if (max < min || nbits < min || max < nbits) | ||
2016 | + fatal("GSS_GEX, bad parameters: %d !< %d !< %d", | ||
2017 | + min, nbits, max); | ||
2018 | + dh = PRIVSEP(choose_dh(MAX(DH_GRP_MIN, min), | ||
2019 | + nbits, MIN(DH_GRP_MAX, max))); | ||
2020 | + if (dh == NULL) | ||
2021 | + packet_disconnect("Protocol error: no matching group found"); | ||
2022 | + DH_get0_pqg(dh, &dh_p, NULL, &dh_g); | ||
2023 | + | ||
2024 | + packet_start(SSH2_MSG_KEXGSS_GROUP); | ||
2025 | + packet_put_bignum2(dh_p); | ||
2026 | + packet_put_bignum2(dh_g); | ||
2027 | + packet_send(); | ||
2028 | + | ||
2029 | + packet_write_wait(); | ||
2030 | + break; | ||
2031 | + default: | ||
2032 | + fatal("%s: Unexpected KEX type %d", __func__, ssh->kex->kex_type); | ||
2033 | + } | ||
2034 | + | ||
2035 | + dh_gen_key(dh, ssh->kex->we_need * 8); | ||
2036 | + | ||
2037 | + do { | 2306 | + do { |
2038 | + debug("Wait SSH2_MSG_GSSAPI_INIT"); | 2307 | + debug("Wait SSH2_MSG_KEXGSS_INIT"); |
2039 | + type = packet_read(); | 2308 | + type = ssh_packet_read(ssh); |
2040 | + switch(type) { | 2309 | + switch(type) { |
2041 | + case SSH2_MSG_KEXGSS_INIT: | 2310 | + case SSH2_MSG_KEXGSS_INIT: |
2042 | + if (dh_client_pub != NULL) | 2311 | + if (client_pubkey != NULL) |
2043 | + fatal("Received KEXGSS_INIT after initialising"); | 2312 | + fatal("Received KEXGSS_INIT after initialising"); |
2044 | + recv_tok.value = packet_get_string(&slen); | 2313 | + if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, |
2045 | + recv_tok.length = slen; | 2314 | + &recv_tok)) != 0 || |
2046 | + | 2315 | + (r = sshpkt_getb_froms(ssh, &client_pubkey)) != 0 || |
2047 | + if ((dh_client_pub = BN_new()) == NULL) | 2316 | + (r = sshpkt_get_end(ssh)) != 0) |
2048 | + fatal("dh_client_pub == NULL"); | 2317 | + fatal("sshpkt failed: %s", ssh_err(r)); |
2049 | + | 2318 | + |
2050 | + packet_get_bignum2(dh_client_pub); | 2319 | + switch (kex->kex_type) { |
2320 | + case KEX_GSS_GRP1_SHA1: | ||
2321 | + case KEX_GSS_GRP14_SHA1: | ||
2322 | + case KEX_GSS_GRP14_SHA256: | ||
2323 | + case KEX_GSS_GRP16_SHA512: | ||
2324 | + r = kex_dh_enc(kex, client_pubkey, &server_pubkey, | ||
2325 | + &shared_secret); | ||
2326 | + break; | ||
2327 | + case KEX_GSS_NISTP256_SHA256: | ||
2328 | + r = kex_ecdh_enc(kex, client_pubkey, &server_pubkey, | ||
2329 | + &shared_secret); | ||
2330 | + break; | ||
2331 | + case KEX_GSS_C25519_SHA256: | ||
2332 | + r = kex_c25519_enc(kex, client_pubkey, &server_pubkey, | ||
2333 | + &shared_secret); | ||
2334 | + break; | ||
2335 | + default: | ||
2336 | + fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); | ||
2337 | + } | ||
2338 | + if (r != 0) | ||
2339 | + goto out; | ||
2051 | + | 2340 | + |
2052 | + /* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */ | 2341 | + /* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */ |
2053 | + break; | 2342 | + break; |
2054 | + case SSH2_MSG_KEXGSS_CONTINUE: | 2343 | + case SSH2_MSG_KEXGSS_CONTINUE: |
2055 | + recv_tok.value = packet_get_string(&slen); | 2344 | + if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, |
2056 | + recv_tok.length = slen; | 2345 | + &recv_tok)) != 0 || |
2346 | + (r = sshpkt_get_end(ssh)) != 0) | ||
2347 | + fatal("sshpkt failed: %s", ssh_err(r)); | ||
2057 | + break; | 2348 | + break; |
2058 | + default: | 2349 | + default: |
2059 | + packet_disconnect( | 2350 | + sshpkt_disconnect(ssh, |
2060 | + "Protocol error: didn't expect packet type %d", | 2351 | + "Protocol error: didn't expect packet type %d", |
2061 | + type); | 2352 | + type); |
2062 | + } | 2353 | + } |
2063 | + | 2354 | + |
2064 | + maj_status = PRIVSEP(ssh_gssapi_accept_ctx(ctxt, &recv_tok, | 2355 | + maj_status = PRIVSEP(ssh_gssapi_accept_ctx(ctxt, &recv_tok, |
2065 | + &send_tok, &ret_flags)); | 2356 | + &send_tok, &ret_flags)); |
2066 | + | 2357 | + |
2067 | + free(recv_tok.value); | 2358 | + gss_release_buffer(&min_status, &recv_tok); |
2068 | + | 2359 | + |
2069 | + if (maj_status != GSS_S_COMPLETE && send_tok.length == 0) | 2360 | + if (maj_status != GSS_S_COMPLETE && send_tok.length == 0) |
2070 | + fatal("Zero length token output when incomplete"); | 2361 | + fatal("Zero length token output when incomplete"); |
2071 | + | 2362 | + |
2072 | + if (dh_client_pub == NULL) | 2363 | + if (client_pubkey == NULL) |
2073 | + fatal("No client public key"); | 2364 | + fatal("No client public key"); |
2074 | + | 2365 | + |
2075 | + if (maj_status & GSS_S_CONTINUE_NEEDED) { | 2366 | + if (maj_status & GSS_S_CONTINUE_NEEDED) { |
2076 | + debug("Sending GSSAPI_CONTINUE"); | 2367 | + debug("Sending GSSAPI_CONTINUE"); |
2077 | + packet_start(SSH2_MSG_KEXGSS_CONTINUE); | 2368 | + if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || |
2078 | + packet_put_string(send_tok.value, send_tok.length); | 2369 | + (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0 || |
2079 | + packet_send(); | 2370 | + (r = sshpkt_send(ssh)) != 0) |
2371 | + fatal("sshpkt failed: %s", ssh_err(r)); | ||
2080 | + gss_release_buffer(&min_status, &send_tok); | 2372 | + gss_release_buffer(&min_status, &send_tok); |
2081 | + } | 2373 | + } |
2082 | + } while (maj_status & GSS_S_CONTINUE_NEEDED); | 2374 | + } while (maj_status & GSS_S_CONTINUE_NEEDED); |
2083 | + | 2375 | + |
2084 | + if (GSS_ERROR(maj_status)) { | 2376 | + if (GSS_ERROR(maj_status)) { |
2085 | + if (send_tok.length > 0) { | 2377 | + if (send_tok.length > 0) { |
2086 | + packet_start(SSH2_MSG_KEXGSS_CONTINUE); | 2378 | + if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || |
2087 | + packet_put_string(send_tok.value, send_tok.length); | 2379 | + (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0 || |
2088 | + packet_send(); | 2380 | + (r = sshpkt_send(ssh)) != 0) |
2381 | + fatal("sshpkt failed: %s", ssh_err(r)); | ||
2089 | + } | 2382 | + } |
2090 | + fatal("accept_ctx died"); | 2383 | + fatal("accept_ctx died"); |
2091 | + } | 2384 | + } |
@@ -2095,123 +2388,320 @@ index 000000000..18070f1d7 | |||
2095 | + | 2388 | + |
2096 | + if (!(ret_flags & GSS_C_INTEG_FLAG)) | 2389 | + if (!(ret_flags & GSS_C_INTEG_FLAG)) |
2097 | + fatal("Integrity flag wasn't set"); | 2390 | + fatal("Integrity flag wasn't set"); |
2098 | + | ||
2099 | + if (!dh_pub_is_valid(dh, dh_client_pub)) | ||
2100 | + packet_disconnect("bad client public DH value"); | ||
2101 | + | 2391 | + |
2102 | + klen = DH_size(dh); | 2392 | + hashlen = sizeof(hash); |
2103 | + kbuf = xmalloc(klen); | 2393 | + if ((r = kex_gen_hash( |
2104 | + kout = DH_compute_key(kbuf, dh_client_pub, dh); | 2394 | + kex->hash_alg, |
2105 | + if (kout < 0) | 2395 | + kex->client_version, |
2106 | + fatal("DH_compute_key: failed"); | 2396 | + kex->server_version, |
2397 | + kex->peer, | ||
2398 | + kex->my, | ||
2399 | + empty, | ||
2400 | + client_pubkey, | ||
2401 | + server_pubkey, | ||
2402 | + shared_secret, | ||
2403 | + hash, &hashlen)) != 0) | ||
2404 | + goto out; | ||
2107 | + | 2405 | + |
2108 | + shared_secret = BN_new(); | 2406 | + gssbuf.value = hash; |
2109 | + if (shared_secret == NULL) | 2407 | + gssbuf.length = hashlen; |
2110 | + fatal("kexgss_server: BN_new failed"); | ||
2111 | + | 2408 | + |
2112 | + if (BN_bin2bn(kbuf, kout, shared_secret) == NULL) | 2409 | + if (GSS_ERROR(PRIVSEP(ssh_gssapi_sign(ctxt, &gssbuf, &msg_tok)))) |
2113 | + fatal("kexgss_server: BN_bin2bn failed"); | 2410 | + fatal("Couldn't get MIC"); |
2114 | + | 2411 | + |
2115 | + memset(kbuf, 0, klen); | 2412 | + if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_COMPLETE)) != 0 || |
2116 | + free(kbuf); | 2413 | + (r = sshpkt_put_stringb(ssh, server_pubkey)) != 0 || |
2414 | + (r = sshpkt_put_string(ssh, msg_tok.value, msg_tok.length)) != 0) | ||
2415 | + fatal("sshpkt failed: %s", ssh_err(r)); | ||
2117 | + | 2416 | + |
2118 | + DH_get0_key(dh, &pub_key, NULL); | 2417 | + if (send_tok.length != 0) { |
2119 | + DH_get0_pqg(dh, &dh_p, NULL, &dh_g); | 2418 | + if ((r = sshpkt_put_u8(ssh, 1)) != 0 || /* true */ |
2419 | + (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0) | ||
2420 | + fatal("sshpkt failed: %s", ssh_err(r)); | ||
2421 | + } else { | ||
2422 | + if ((r = sshpkt_put_u8(ssh, 0)) != 0) /* false */ | ||
2423 | + fatal("sshpkt failed: %s", ssh_err(r)); | ||
2424 | + } | ||
2425 | + if ((r = sshpkt_send(ssh)) != 0) | ||
2426 | + fatal("sshpkt_send failed: %s", ssh_err(r)); | ||
2120 | + | 2427 | + |
2121 | + hashlen = sizeof(hash); | 2428 | + gss_release_buffer(&min_status, &send_tok); |
2122 | + switch (ssh->kex->kex_type) { | 2429 | + gss_release_buffer(&min_status, &msg_tok); |
2123 | + case KEX_GSS_GRP1_SHA1: | 2430 | + |
2124 | + case KEX_GSS_GRP14_SHA1: | 2431 | + if (gss_kex_context == NULL) |
2125 | + kex_dh_hash( | 2432 | + gss_kex_context = ctxt; |
2126 | + ssh->kex->hash_alg, | 2433 | + else |
2127 | + ssh->kex->client_version_string, ssh->kex->server_version_string, | 2434 | + ssh_gssapi_delete_ctx(&ctxt); |
2128 | + sshbuf_ptr(ssh->kex->peer), sshbuf_len(ssh->kex->peer), | 2435 | + |
2129 | + sshbuf_ptr(ssh->kex->my), sshbuf_len(ssh->kex->my), | 2436 | + if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) |
2130 | + NULL, 0, /* Change this if we start sending host keys */ | 2437 | + r = kex_send_newkeys(ssh); |
2131 | + dh_client_pub, pub_key, shared_secret, | 2438 | + |
2132 | + hash, &hashlen | 2439 | + /* If this was a rekey, then save out any delegated credentials we |
2133 | + ); | 2440 | + * just exchanged. */ |
2134 | + break; | 2441 | + if (options.gss_store_rekey) |
2135 | + case KEX_GSS_GEX_SHA1: | 2442 | + ssh_gssapi_rekey_creds(); |
2136 | + kexgex_hash( | 2443 | +out: |
2137 | + ssh->kex->hash_alg, | 2444 | + sshbuf_free(empty); |
2138 | + ssh->kex->client_version_string, ssh->kex->server_version_string, | 2445 | + explicit_bzero(hash, sizeof(hash)); |
2139 | + sshbuf_ptr(ssh->kex->peer), sshbuf_len(ssh->kex->peer), | 2446 | + sshbuf_free(shared_secret); |
2140 | + sshbuf_ptr(ssh->kex->my), sshbuf_len(ssh->kex->my), | 2447 | + sshbuf_free(client_pubkey); |
2141 | + NULL, 0, | 2448 | + sshbuf_free(server_pubkey); |
2142 | + min, nbits, max, | 2449 | + return r; |
2143 | + dh_p, dh_g, | 2450 | +} |
2144 | + dh_client_pub, | 2451 | + |
2145 | + pub_key, | 2452 | +int |
2146 | + shared_secret, | 2453 | +kexgssgex_server(struct ssh *ssh) |
2147 | + hash, &hashlen | 2454 | +{ |
2148 | + ); | 2455 | + struct kex *kex = ssh->kex; |
2149 | + break; | 2456 | + OM_uint32 maj_status, min_status; |
2150 | + default: | 2457 | + |
2151 | + fatal("%s: Unexpected KEX type %d", __func__, ssh->kex->kex_type); | 2458 | + /* |
2459 | + * Some GSSAPI implementations use the input value of ret_flags (an | ||
2460 | + * output variable) as a means of triggering mechanism specific | ||
2461 | + * features. Initializing it to zero avoids inadvertently | ||
2462 | + * activating this non-standard behaviour. | ||
2463 | + */ | ||
2464 | + | ||
2465 | + OM_uint32 ret_flags = 0; | ||
2466 | + gss_buffer_desc gssbuf, recv_tok, msg_tok; | ||
2467 | + gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; | ||
2468 | + Gssctxt *ctxt = NULL; | ||
2469 | + struct sshbuf *shared_secret = NULL; | ||
2470 | + int type = 0; | ||
2471 | + gss_OID oid; | ||
2472 | + char *mechs; | ||
2473 | + u_char hash[SSH_DIGEST_MAX_LENGTH]; | ||
2474 | + size_t hashlen; | ||
2475 | + BIGNUM *dh_client_pub = NULL; | ||
2476 | + const BIGNUM *pub_key, *dh_p, *dh_g; | ||
2477 | + int min = -1, max = -1, nbits = -1; | ||
2478 | + int cmin = -1, cmax = -1; /* client proposal */ | ||
2479 | + struct sshbuf *empty = sshbuf_new(); | ||
2480 | + int r; | ||
2481 | + | ||
2482 | + /* Initialise GSSAPI */ | ||
2483 | + | ||
2484 | + /* If we're rekeying, privsep means that some of the private structures | ||
2485 | + * in the GSSAPI code are no longer available. This kludges them back | ||
2486 | + * into life | ||
2487 | + */ | ||
2488 | + if (!ssh_gssapi_oid_table_ok()) | ||
2489 | + if ((mechs = ssh_gssapi_server_mechanisms())) | ||
2490 | + free(mechs); | ||
2491 | + | ||
2492 | + debug2("%s: Identifying %s", __func__, kex->name); | ||
2493 | + oid = ssh_gssapi_id_kex(NULL, kex->name, kex->kex_type); | ||
2494 | + if (oid == GSS_C_NO_OID) | ||
2495 | + fatal("Unknown gssapi mechanism"); | ||
2496 | + | ||
2497 | + debug2("%s: Acquiring credentials", __func__); | ||
2498 | + | ||
2499 | + if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid)))) | ||
2500 | + fatal("Unable to acquire credentials for the server"); | ||
2501 | + | ||
2502 | + /* 5. S generates an ephemeral key pair (do the allocations early) */ | ||
2503 | + debug("Doing group exchange"); | ||
2504 | + ssh_packet_read_expect(ssh, SSH2_MSG_KEXGSS_GROUPREQ); | ||
2505 | + /* store client proposal to provide valid signature */ | ||
2506 | + if ((r = sshpkt_get_u32(ssh, &cmin)) != 0 || | ||
2507 | + (r = sshpkt_get_u32(ssh, &nbits)) != 0 || | ||
2508 | + (r = sshpkt_get_u32(ssh, &cmax)) != 0 || | ||
2509 | + (r = sshpkt_get_end(ssh)) != 0) | ||
2510 | + fatal("sshpkt failed: %s", ssh_err(r)); | ||
2511 | + kex->nbits = nbits; | ||
2512 | + kex->min = cmin; | ||
2513 | + kex->max = cmax; | ||
2514 | + min = MAX(DH_GRP_MIN, cmin); | ||
2515 | + max = MIN(DH_GRP_MAX, cmax); | ||
2516 | + nbits = MAXIMUM(DH_GRP_MIN, nbits); | ||
2517 | + nbits = MINIMUM(DH_GRP_MAX, nbits); | ||
2518 | + if (max < min || nbits < min || max < nbits) | ||
2519 | + fatal("GSS_GEX, bad parameters: %d !< %d !< %d", | ||
2520 | + min, nbits, max); | ||
2521 | + kex->dh = PRIVSEP(choose_dh(min, nbits, max)); | ||
2522 | + if (kex->dh == NULL) { | ||
2523 | + sshpkt_disconnect(ssh, "Protocol error: no matching group found"); | ||
2524 | + fatal("Protocol error: no matching group found"); | ||
2152 | + } | 2525 | + } |
2153 | + | 2526 | + |
2154 | + BN_clear_free(dh_client_pub); | 2527 | + DH_get0_pqg(kex->dh, &dh_p, NULL, &dh_g); |
2528 | + if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_GROUP)) != 0 || | ||
2529 | + (r = sshpkt_put_bignum2(ssh, dh_p)) != 0 || | ||
2530 | + (r = sshpkt_put_bignum2(ssh, dh_g)) != 0 || | ||
2531 | + (r = sshpkt_send(ssh)) != 0) | ||
2532 | + fatal("sshpkt failed: %s", ssh_err(r)); | ||
2533 | + | ||
2534 | + if ((r = ssh_packet_write_wait(ssh)) != 0) | ||
2535 | + fatal("ssh_packet_write_wait: %s", ssh_err(r)); | ||
2536 | + | ||
2537 | + /* Compute our exchange value in parallel with the client */ | ||
2538 | + if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0) | ||
2539 | + goto out; | ||
2540 | + | ||
2541 | + do { | ||
2542 | + debug("Wait SSH2_MSG_GSSAPI_INIT"); | ||
2543 | + type = ssh_packet_read(ssh); | ||
2544 | + switch(type) { | ||
2545 | + case SSH2_MSG_KEXGSS_INIT: | ||
2546 | + if (dh_client_pub != NULL) | ||
2547 | + fatal("Received KEXGSS_INIT after initialising"); | ||
2548 | + if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, | ||
2549 | + &recv_tok)) != 0 || | ||
2550 | + (r = sshpkt_get_bignum2(ssh, &dh_client_pub)) != 0 || | ||
2551 | + (r = sshpkt_get_end(ssh)) != 0) | ||
2552 | + fatal("sshpkt failed: %s", ssh_err(r)); | ||
2553 | + | ||
2554 | + /* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */ | ||
2555 | + break; | ||
2556 | + case SSH2_MSG_KEXGSS_CONTINUE: | ||
2557 | + if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh, | ||
2558 | + &recv_tok)) != 0 || | ||
2559 | + (r = sshpkt_get_end(ssh)) != 0) | ||
2560 | + fatal("sshpkt failed: %s", ssh_err(r)); | ||
2561 | + break; | ||
2562 | + default: | ||
2563 | + sshpkt_disconnect(ssh, | ||
2564 | + "Protocol error: didn't expect packet type %d", | ||
2565 | + type); | ||
2566 | + } | ||
2567 | + | ||
2568 | + maj_status = PRIVSEP(ssh_gssapi_accept_ctx(ctxt, &recv_tok, | ||
2569 | + &send_tok, &ret_flags)); | ||
2570 | + | ||
2571 | + gss_release_buffer(&min_status, &recv_tok); | ||
2572 | + | ||
2573 | + if (maj_status != GSS_S_COMPLETE && send_tok.length == 0) | ||
2574 | + fatal("Zero length token output when incomplete"); | ||
2575 | + | ||
2576 | + if (dh_client_pub == NULL) | ||
2577 | + fatal("No client public key"); | ||
2578 | + | ||
2579 | + if (maj_status & GSS_S_CONTINUE_NEEDED) { | ||
2580 | + debug("Sending GSSAPI_CONTINUE"); | ||
2581 | + if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || | ||
2582 | + (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0 || | ||
2583 | + (r = sshpkt_send(ssh)) != 0) | ||
2584 | + fatal("sshpkt failed: %s", ssh_err(r)); | ||
2585 | + gss_release_buffer(&min_status, &send_tok); | ||
2586 | + } | ||
2587 | + } while (maj_status & GSS_S_CONTINUE_NEEDED); | ||
2588 | + | ||
2589 | + if (GSS_ERROR(maj_status)) { | ||
2590 | + if (send_tok.length > 0) { | ||
2591 | + if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_CONTINUE)) != 0 || | ||
2592 | + (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0 || | ||
2593 | + (r = sshpkt_send(ssh)) != 0) | ||
2594 | + fatal("sshpkt failed: %s", ssh_err(r)); | ||
2595 | + } | ||
2596 | + fatal("accept_ctx died"); | ||
2597 | + } | ||
2155 | + | 2598 | + |
2156 | + if (ssh->kex->session_id == NULL) { | 2599 | + if (!(ret_flags & GSS_C_MUTUAL_FLAG)) |
2157 | + ssh->kex->session_id_len = hashlen; | 2600 | + fatal("Mutual Authentication flag wasn't set"); |
2158 | + ssh->kex->session_id = xmalloc(ssh->kex->session_id_len); | 2601 | + |
2159 | + memcpy(ssh->kex->session_id, hash, ssh->kex->session_id_len); | 2602 | + if (!(ret_flags & GSS_C_INTEG_FLAG)) |
2603 | + fatal("Integrity flag wasn't set"); | ||
2604 | + | ||
2605 | + /* calculate shared secret */ | ||
2606 | + if ((shared_secret = sshbuf_new()) == NULL) { | ||
2607 | + r = SSH_ERR_ALLOC_FAIL; | ||
2608 | + goto out; | ||
2160 | + } | 2609 | + } |
2610 | + if ((r = kex_dh_compute_key(kex, dh_client_pub, shared_secret)) != 0) | ||
2611 | + goto out; | ||
2612 | + | ||
2613 | + DH_get0_key(kex->dh, &pub_key, NULL); | ||
2614 | + DH_get0_pqg(kex->dh, &dh_p, NULL, &dh_g); | ||
2615 | + hashlen = sizeof(hash); | ||
2616 | + if ((r = kexgex_hash( | ||
2617 | + kex->hash_alg, | ||
2618 | + kex->client_version, | ||
2619 | + kex->server_version, | ||
2620 | + kex->peer, | ||
2621 | + kex->my, | ||
2622 | + empty, | ||
2623 | + cmin, nbits, cmax, | ||
2624 | + dh_p, dh_g, | ||
2625 | + dh_client_pub, | ||
2626 | + pub_key, | ||
2627 | + sshbuf_ptr(shared_secret), sshbuf_len(shared_secret), | ||
2628 | + hash, &hashlen)) != 0) | ||
2629 | + fatal("kexgex_hash failed: %s", ssh_err(r)); | ||
2161 | + | 2630 | + |
2162 | + gssbuf.value = hash; | 2631 | + gssbuf.value = hash; |
2163 | + gssbuf.length = hashlen; | 2632 | + gssbuf.length = hashlen; |
2164 | + | 2633 | + |
2165 | + if (GSS_ERROR(PRIVSEP(ssh_gssapi_sign(ctxt,&gssbuf,&msg_tok)))) | 2634 | + if (GSS_ERROR(PRIVSEP(ssh_gssapi_sign(ctxt, &gssbuf, &msg_tok)))) |
2166 | + fatal("Couldn't get MIC"); | 2635 | + fatal("Couldn't get MIC"); |
2167 | + | 2636 | + |
2168 | + packet_start(SSH2_MSG_KEXGSS_COMPLETE); | 2637 | + if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_COMPLETE)) != 0 || |
2169 | + packet_put_bignum2(pub_key); | 2638 | + (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 || |
2170 | + packet_put_string(msg_tok.value,msg_tok.length); | 2639 | + (r = sshpkt_put_string(ssh, msg_tok.value, msg_tok.length)) != 0) |
2640 | + fatal("sshpkt failed: %s", ssh_err(r)); | ||
2171 | + | 2641 | + |
2172 | + if (send_tok.length != 0) { | 2642 | + if (send_tok.length != 0) { |
2173 | + packet_put_char(1); /* true */ | 2643 | + if ((r = sshpkt_put_u8(ssh, 1)) != 0 || /* true */ |
2174 | + packet_put_string(send_tok.value, send_tok.length); | 2644 | + (r = sshpkt_put_string(ssh, send_tok.value, send_tok.length)) != 0) |
2645 | + fatal("sshpkt failed: %s", ssh_err(r)); | ||
2175 | + } else { | 2646 | + } else { |
2176 | + packet_put_char(0); /* false */ | 2647 | + if ((r = sshpkt_put_u8(ssh, 0)) != 0) /* false */ |
2648 | + fatal("sshpkt failed: %s", ssh_err(r)); | ||
2177 | + } | 2649 | + } |
2178 | + packet_send(); | 2650 | + if ((r = sshpkt_send(ssh)) != 0) |
2651 | + fatal("sshpkt failed: %s", ssh_err(r)); | ||
2179 | + | 2652 | + |
2180 | + gss_release_buffer(&min_status, &send_tok); | 2653 | + gss_release_buffer(&min_status, &send_tok); |
2181 | + gss_release_buffer(&min_status, &msg_tok); | 2654 | + gss_release_buffer(&min_status, &msg_tok); |
2182 | + | 2655 | + |
2183 | + if (gss_kex_context == NULL) | 2656 | + if (gss_kex_context == NULL) |
2184 | + gss_kex_context = ctxt; | 2657 | + gss_kex_context = ctxt; |
2185 | + else | 2658 | + else |
2186 | + ssh_gssapi_delete_ctx(&ctxt); | 2659 | + ssh_gssapi_delete_ctx(&ctxt); |
2187 | + | 2660 | + |
2188 | + DH_free(dh); | 2661 | + /* Finally derive the keys and send them */ |
2189 | + | 2662 | + if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) |
2190 | + kex_derive_keys_bn(ssh, hash, hashlen, shared_secret); | 2663 | + r = kex_send_newkeys(ssh); |
2191 | + BN_clear_free(shared_secret); | ||
2192 | + kex_send_newkeys(ssh); | ||
2193 | + | 2664 | + |
2194 | + /* If this was a rekey, then save out any delegated credentials we | 2665 | + /* If this was a rekey, then save out any delegated credentials we |
2195 | + * just exchanged. */ | 2666 | + * just exchanged. */ |
2196 | + if (options.gss_store_rekey) | 2667 | + if (options.gss_store_rekey) |
2197 | + ssh_gssapi_rekey_creds(); | 2668 | + ssh_gssapi_rekey_creds(); |
2198 | + return 0; | 2669 | +out: |
2670 | + sshbuf_free(empty); | ||
2671 | + explicit_bzero(hash, sizeof(hash)); | ||
2672 | + DH_free(kex->dh); | ||
2673 | + kex->dh = NULL; | ||
2674 | + BN_clear_free(dh_client_pub); | ||
2675 | + sshbuf_free(shared_secret); | ||
2676 | + return r; | ||
2199 | +} | 2677 | +} |
2200 | +#endif /* GSSAPI */ | 2678 | +#endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ |
2679 | diff --git a/mac.c b/mac.c | ||
2680 | index 51dc11d76..3d11eba62 100644 | ||
2681 | --- a/mac.c | ||
2682 | +++ b/mac.c | ||
2683 | @@ -29,6 +29,7 @@ | ||
2684 | |||
2685 | #include <string.h> | ||
2686 | #include <stdio.h> | ||
2687 | +#include <stdlib.h> | ||
2688 | |||
2689 | #include "digest.h" | ||
2690 | #include "hmac.h" | ||
2201 | diff --git a/monitor.c b/monitor.c | 2691 | diff --git a/monitor.c b/monitor.c |
2202 | index 531b2993a..eabc1e89b 100644 | 2692 | index 60e529444..0766d6ef5 100644 |
2203 | --- a/monitor.c | 2693 | --- a/monitor.c |
2204 | +++ b/monitor.c | 2694 | +++ b/monitor.c |
2205 | @@ -145,6 +145,8 @@ int mm_answer_gss_setup_ctx(int, struct sshbuf *); | 2695 | @@ -147,6 +147,8 @@ int mm_answer_gss_setup_ctx(struct ssh *, int, struct sshbuf *); |
2206 | int mm_answer_gss_accept_ctx(int, struct sshbuf *); | 2696 | int mm_answer_gss_accept_ctx(struct ssh *, int, struct sshbuf *); |
2207 | int mm_answer_gss_userok(int, struct sshbuf *); | 2697 | int mm_answer_gss_userok(struct ssh *, int, struct sshbuf *); |
2208 | int mm_answer_gss_checkmic(int, struct sshbuf *); | 2698 | int mm_answer_gss_checkmic(struct ssh *, int, struct sshbuf *); |
2209 | +int mm_answer_gss_sign(int, struct sshbuf *); | 2699 | +int mm_answer_gss_sign(struct ssh *, int, struct sshbuf *); |
2210 | +int mm_answer_gss_updatecreds(int, struct sshbuf *); | 2700 | +int mm_answer_gss_updatecreds(struct ssh *, int, struct sshbuf *); |
2211 | #endif | 2701 | #endif |
2212 | 2702 | ||
2213 | #ifdef SSH_AUDIT_EVENTS | 2703 | #ifdef SSH_AUDIT_EVENTS |
2214 | @@ -215,11 +217,18 @@ struct mon_table mon_dispatch_proto20[] = { | 2704 | @@ -219,11 +221,18 @@ struct mon_table mon_dispatch_proto20[] = { |
2215 | {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, | 2705 | {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, |
2216 | {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok}, | 2706 | {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok}, |
2217 | {MONITOR_REQ_GSSCHECKMIC, MON_ONCE, mm_answer_gss_checkmic}, | 2707 | {MONITOR_REQ_GSSCHECKMIC, MON_ONCE, mm_answer_gss_checkmic}, |
@@ -2230,7 +2720,7 @@ index 531b2993a..eabc1e89b 100644 | |||
2230 | #ifdef WITH_OPENSSL | 2720 | #ifdef WITH_OPENSSL |
2231 | {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, | 2721 | {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, |
2232 | #endif | 2722 | #endif |
2233 | @@ -289,6 +298,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) | 2723 | @@ -292,6 +301,10 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor) |
2234 | /* Permit requests for moduli and signatures */ | 2724 | /* Permit requests for moduli and signatures */ |
2235 | monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); | 2725 | monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); |
2236 | monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); | 2726 | monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); |
@@ -2241,32 +2731,36 @@ index 531b2993a..eabc1e89b 100644 | |||
2241 | 2731 | ||
2242 | /* The first few requests do not require asynchronous access */ | 2732 | /* The first few requests do not require asynchronous access */ |
2243 | while (!authenticated) { | 2733 | while (!authenticated) { |
2244 | @@ -401,6 +414,10 @@ monitor_child_postauth(struct monitor *pmonitor) | 2734 | @@ -405,6 +418,10 @@ monitor_child_postauth(struct ssh *ssh, struct monitor *pmonitor) |
2245 | monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); | 2735 | monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); |
2246 | monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); | 2736 | monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); |
2247 | monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); | 2737 | monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); |
2248 | +#ifdef GSSAPI | 2738 | +#ifdef GSSAPI |
2249 | + /* and for the GSSAPI key exchange */ | 2739 | + /* and for the GSSAPI key exchange */ |
2250 | + monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); | 2740 | + monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); |
2251 | +#endif | 2741 | +#endif |
2252 | 2742 | ||
2253 | if (auth_opts->permit_pty_flag) { | 2743 | if (auth_opts->permit_pty_flag) { |
2254 | monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); | 2744 | monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); |
2255 | @@ -1666,6 +1683,13 @@ monitor_apply_keystate(struct monitor *pmonitor) | 2745 | @@ -1687,6 +1704,17 @@ monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor) |
2746 | # ifdef OPENSSL_HAS_ECC | ||
2747 | kex->kex[KEX_ECDH_SHA2] = kex_gen_server; | ||
2256 | # endif | 2748 | # endif |
2257 | #endif /* WITH_OPENSSL */ | 2749 | +# ifdef GSSAPI |
2258 | kex->kex[KEX_C25519_SHA256] = kexc25519_server; | ||
2259 | +#ifdef GSSAPI | ||
2260 | + if (options.gss_keyex) { | 2750 | + if (options.gss_keyex) { |
2261 | + kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; | 2751 | + kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; |
2262 | + kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server; | 2752 | + kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server; |
2263 | + kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server; | 2753 | + kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_server; |
2754 | + kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_server; | ||
2755 | + kex->kex[KEX_GSS_GEX_SHA1] = kexgssgex_server; | ||
2756 | + kex->kex[KEX_GSS_NISTP256_SHA256] = kexgss_server; | ||
2757 | + kex->kex[KEX_GSS_C25519_SHA256] = kexgss_server; | ||
2264 | + } | 2758 | + } |
2265 | +#endif | 2759 | +# endif |
2266 | kex->load_host_public_key=&get_hostkey_public_by_type; | 2760 | #endif /* WITH_OPENSSL */ |
2267 | kex->load_host_private_key=&get_hostkey_private_by_type; | 2761 | kex->kex[KEX_C25519_SHA256] = kex_gen_server; |
2268 | kex->host_key_index=&get_hostkey_index; | 2762 | kex->kex[KEX_KEM_SNTRUP4591761X25519_SHA512] = kex_gen_server; |
2269 | @@ -1756,8 +1780,8 @@ mm_answer_gss_setup_ctx(int sock, struct sshbuf *m) | 2763 | @@ -1780,8 +1808,8 @@ mm_answer_gss_setup_ctx(struct ssh *ssh, int sock, struct sshbuf *m) |
2270 | u_char *p; | 2764 | u_char *p; |
2271 | int r; | 2765 | int r; |
2272 | 2766 | ||
@@ -2277,7 +2771,7 @@ index 531b2993a..eabc1e89b 100644 | |||
2277 | 2771 | ||
2278 | if ((r = sshbuf_get_string(m, &p, &len)) != 0) | 2772 | if ((r = sshbuf_get_string(m, &p, &len)) != 0) |
2279 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 2773 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
2280 | @@ -1789,8 +1813,8 @@ mm_answer_gss_accept_ctx(int sock, struct sshbuf *m) | 2774 | @@ -1813,8 +1841,8 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) |
2281 | OM_uint32 flags = 0; /* GSI needs this */ | 2775 | OM_uint32 flags = 0; /* GSI needs this */ |
2282 | int r; | 2776 | int r; |
2283 | 2777 | ||
@@ -2288,7 +2782,7 @@ index 531b2993a..eabc1e89b 100644 | |||
2288 | 2782 | ||
2289 | if ((r = ssh_gssapi_get_buffer_desc(m, &in)) != 0) | 2783 | if ((r = ssh_gssapi_get_buffer_desc(m, &in)) != 0) |
2290 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 2784 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
2291 | @@ -1810,6 +1834,7 @@ mm_answer_gss_accept_ctx(int sock, struct sshbuf *m) | 2785 | @@ -1834,6 +1862,7 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) |
2292 | monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); | 2786 | monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); |
2293 | monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); | 2787 | monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); |
2294 | monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); | 2788 | monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); |
@@ -2296,7 +2790,7 @@ index 531b2993a..eabc1e89b 100644 | |||
2296 | } | 2790 | } |
2297 | return (0); | 2791 | return (0); |
2298 | } | 2792 | } |
2299 | @@ -1821,8 +1846,8 @@ mm_answer_gss_checkmic(int sock, struct sshbuf *m) | 2793 | @@ -1845,8 +1874,8 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) |
2300 | OM_uint32 ret; | 2794 | OM_uint32 ret; |
2301 | int r; | 2795 | int r; |
2302 | 2796 | ||
@@ -2307,8 +2801,12 @@ index 531b2993a..eabc1e89b 100644 | |||
2307 | 2801 | ||
2308 | if ((r = ssh_gssapi_get_buffer_desc(m, &gssbuf)) != 0 || | 2802 | if ((r = ssh_gssapi_get_buffer_desc(m, &gssbuf)) != 0 || |
2309 | (r = ssh_gssapi_get_buffer_desc(m, &mic)) != 0) | 2803 | (r = ssh_gssapi_get_buffer_desc(m, &mic)) != 0) |
2310 | @@ -1851,10 +1876,11 @@ mm_answer_gss_userok(int sock, struct sshbuf *m) | 2804 | @@ -1872,13 +1901,17 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) |
2311 | int r, authenticated; | 2805 | int |
2806 | mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) | ||
2807 | { | ||
2808 | - int r, authenticated; | ||
2809 | + int r, authenticated, kex; | ||
2312 | const char *displayname; | 2810 | const char *displayname; |
2313 | 2811 | ||
2314 | - if (!options.gss_authentication) | 2812 | - if (!options.gss_authentication) |
@@ -2317,24 +2815,40 @@ index 531b2993a..eabc1e89b 100644 | |||
2317 | + fatal("%s: GSSAPI not enabled", __func__); | 2815 | + fatal("%s: GSSAPI not enabled", __func__); |
2318 | 2816 | ||
2319 | - authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); | 2817 | - authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); |
2320 | + authenticated = authctxt->valid && | 2818 | + if ((r = sshbuf_get_u32(m, &kex)) != 0) |
2321 | + ssh_gssapi_userok(authctxt->user, authctxt->pw); | 2819 | + fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
2820 | + | ||
2821 | + authenticated = authctxt->valid && | ||
2822 | + ssh_gssapi_userok(authctxt->user, authctxt->pw, kex); | ||
2322 | 2823 | ||
2323 | sshbuf_reset(m); | 2824 | sshbuf_reset(m); |
2324 | if ((r = sshbuf_put_u32(m, authenticated)) != 0) | 2825 | if ((r = sshbuf_put_u32(m, authenticated)) != 0) |
2325 | @@ -1871,5 +1897,83 @@ mm_answer_gss_userok(int sock, struct sshbuf *m) | 2826 | @@ -1887,7 +1920,11 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) |
2827 | debug3("%s: sending result %d", __func__, authenticated); | ||
2828 | mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); | ||
2829 | |||
2830 | - auth_method = "gssapi-with-mic"; | ||
2831 | + if (kex) { | ||
2832 | + auth_method = "gssapi-keyex"; | ||
2833 | + } else { | ||
2834 | + auth_method = "gssapi-with-mic"; | ||
2835 | + } | ||
2836 | |||
2837 | if ((displayname = ssh_gssapi_displayname()) != NULL) | ||
2838 | auth2_record_info(authctxt, "%s", displayname); | ||
2839 | @@ -1895,5 +1932,85 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) | ||
2326 | /* Monitor loop will terminate if authenticated */ | 2840 | /* Monitor loop will terminate if authenticated */ |
2327 | return (authenticated); | 2841 | return (authenticated); |
2328 | } | 2842 | } |
2329 | + | 2843 | + |
2330 | +int | 2844 | +int |
2331 | +mm_answer_gss_sign(int socket, struct sshbuf *m) | 2845 | +mm_answer_gss_sign(struct ssh *ssh, int socket, struct sshbuf *m) |
2332 | +{ | 2846 | +{ |
2333 | + gss_buffer_desc data; | 2847 | + gss_buffer_desc data; |
2334 | + gss_buffer_desc hash = GSS_C_EMPTY_BUFFER; | 2848 | + gss_buffer_desc hash = GSS_C_EMPTY_BUFFER; |
2335 | + OM_uint32 major, minor; | 2849 | + OM_uint32 major, minor; |
2336 | + size_t len; | 2850 | + size_t len; |
2337 | + u_char *p; | 2851 | + u_char *p = NULL; |
2338 | + int r; | 2852 | + int r; |
2339 | + | 2853 | + |
2340 | + if (!options.gss_authentication && !options.gss_keyex) | 2854 | + if (!options.gss_authentication && !options.gss_keyex) |
@@ -2344,8 +2858,9 @@ index 531b2993a..eabc1e89b 100644 | |||
2344 | + fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 2858 | + fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
2345 | + data.value = p; | 2859 | + data.value = p; |
2346 | + data.length = len; | 2860 | + data.length = len; |
2347 | + if (data.length != 20) | 2861 | + /* Lengths of SHA-1, SHA-256 and SHA-512 hashes that are used */ |
2348 | + fatal("%s: data length incorrect: %d", __func__, | 2862 | + if (data.length != 20 && data.length != 32 && data.length != 64) |
2863 | + fatal("%s: data length incorrect: %d", __func__, | ||
2349 | + (int) data.length); | 2864 | + (int) data.length); |
2350 | + | 2865 | + |
2351 | + /* Save the session ID on the first time around */ | 2866 | + /* Save the session ID on the first time around */ |
@@ -2359,6 +2874,7 @@ index 531b2993a..eabc1e89b 100644 | |||
2359 | + free(data.value); | 2874 | + free(data.value); |
2360 | + | 2875 | + |
2361 | + sshbuf_reset(m); | 2876 | + sshbuf_reset(m); |
2877 | + | ||
2362 | + if ((r = sshbuf_put_u32(m, major)) != 0 || | 2878 | + if ((r = sshbuf_put_u32(m, major)) != 0 || |
2363 | + (r = sshbuf_put_string(m, hash.value, hash.length)) != 0) | 2879 | + (r = sshbuf_put_string(m, hash.value, hash.length)) != 0) |
2364 | + fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 2880 | + fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
@@ -2369,7 +2885,7 @@ index 531b2993a..eabc1e89b 100644 | |||
2369 | + | 2885 | + |
2370 | + /* Turn on getpwnam permissions */ | 2886 | + /* Turn on getpwnam permissions */ |
2371 | + monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1); | 2887 | + monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1); |
2372 | + | 2888 | + |
2373 | + /* And credential updating, for when rekeying */ | 2889 | + /* And credential updating, for when rekeying */ |
2374 | + monitor_permit(mon_dispatch, MONITOR_REQ_GSSUPCREDS, 1); | 2890 | + monitor_permit(mon_dispatch, MONITOR_REQ_GSSUPCREDS, 1); |
2375 | + | 2891 | + |
@@ -2377,16 +2893,16 @@ index 531b2993a..eabc1e89b 100644 | |||
2377 | +} | 2893 | +} |
2378 | + | 2894 | + |
2379 | +int | 2895 | +int |
2380 | +mm_answer_gss_updatecreds(int socket, struct sshbuf *m) { | 2896 | +mm_answer_gss_updatecreds(struct ssh *ssh, int socket, struct sshbuf *m) { |
2381 | + ssh_gssapi_ccache store; | 2897 | + ssh_gssapi_ccache store; |
2382 | + int r, ok; | 2898 | + int r, ok; |
2383 | + | 2899 | + |
2384 | + if (!options.gss_authentication && !options.gss_keyex) | 2900 | + if (!options.gss_authentication && !options.gss_keyex) |
2385 | + fatal("%s: GSSAPI not enabled", __func__); | 2901 | + fatal("%s: GSSAPI not enabled", __func__); |
2386 | + | 2902 | + |
2387 | + if ((r = sshbuf_get_cstring(m, &store.filename, NULL)) != 0 || | 2903 | + if ((r = sshbuf_get_string(m, (u_char **)&store.filename, NULL)) != 0 || |
2388 | + (r = sshbuf_get_cstring(m, &store.envvar, NULL)) != 0 || | 2904 | + (r = sshbuf_get_string(m, (u_char **)&store.envvar, NULL)) != 0 || |
2389 | + (r = sshbuf_get_cstring(m, &store.envval, NULL)) != 0) | 2905 | + (r = sshbuf_get_string(m, (u_char **)&store.envval, NULL)) != 0) |
2390 | + fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 2906 | + fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
2391 | + | 2907 | + |
2392 | + ok = ssh_gssapi_update_creds(&store); | 2908 | + ok = ssh_gssapi_update_creds(&store); |
@@ -2407,33 +2923,40 @@ index 531b2993a..eabc1e89b 100644 | |||
2407 | #endif /* GSSAPI */ | 2923 | #endif /* GSSAPI */ |
2408 | 2924 | ||
2409 | diff --git a/monitor.h b/monitor.h | 2925 | diff --git a/monitor.h b/monitor.h |
2410 | index 16047299f..44fbed589 100644 | 2926 | index 683e5e071..2b1a2d590 100644 |
2411 | --- a/monitor.h | 2927 | --- a/monitor.h |
2412 | +++ b/monitor.h | 2928 | +++ b/monitor.h |
2413 | @@ -63,6 +63,9 @@ enum monitor_reqtype { | 2929 | @@ -63,6 +63,8 @@ enum monitor_reqtype { |
2414 | MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111, | 2930 | MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111, |
2415 | MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113, | 2931 | MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113, |
2416 | 2932 | ||
2417 | + MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151, | 2933 | + MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151, |
2418 | + MONITOR_REQ_GSSUPCREDS = 152, MONITOR_ANS_GSSUPCREDS = 153, | 2934 | + MONITOR_REQ_GSSUPCREDS = 152, MONITOR_ANS_GSSUPCREDS = 153, |
2419 | + | ||
2420 | }; | 2935 | }; |
2421 | 2936 | ||
2422 | struct monitor { | 2937 | struct ssh; |
2423 | diff --git a/monitor_wrap.c b/monitor_wrap.c | 2938 | diff --git a/monitor_wrap.c b/monitor_wrap.c |
2424 | index 732fb3476..1865a122a 100644 | 2939 | index 186e8f022..8e4c1c1f8 100644 |
2425 | --- a/monitor_wrap.c | 2940 | --- a/monitor_wrap.c |
2426 | +++ b/monitor_wrap.c | 2941 | +++ b/monitor_wrap.c |
2427 | @@ -984,7 +984,7 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) | 2942 | @@ -978,13 +978,15 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) |
2428 | } | 2943 | } |
2429 | 2944 | ||
2430 | int | 2945 | int |
2431 | -mm_ssh_gssapi_userok(char *user) | 2946 | -mm_ssh_gssapi_userok(char *user) |
2432 | +mm_ssh_gssapi_userok(char *user, struct passwd *pw) | 2947 | +mm_ssh_gssapi_userok(char *user, struct passwd *pw, int kex) |
2433 | { | 2948 | { |
2434 | struct sshbuf *m; | 2949 | struct sshbuf *m; |
2435 | int r, authenticated = 0; | 2950 | int r, authenticated = 0; |
2436 | @@ -1003,4 +1003,55 @@ mm_ssh_gssapi_userok(char *user) | 2951 | |
2952 | if ((m = sshbuf_new()) == NULL) | ||
2953 | fatal("%s: sshbuf_new failed", __func__); | ||
2954 | + if ((r = sshbuf_put_u32(m, kex)) != 0) | ||
2955 | + fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
2956 | |||
2957 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, m); | ||
2958 | mm_request_receive_expect(pmonitor->m_recvfd, | ||
2959 | @@ -997,4 +999,57 @@ mm_ssh_gssapi_userok(char *user) | ||
2437 | debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not "); | 2960 | debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not "); |
2438 | return (authenticated); | 2961 | return (authenticated); |
2439 | } | 2962 | } |
@@ -2459,7 +2982,7 @@ index 732fb3476..1865a122a 100644 | |||
2459 | + | 2982 | + |
2460 | + sshbuf_free(m); | 2983 | + sshbuf_free(m); |
2461 | + | 2984 | + |
2462 | + return(major); | 2985 | + return (major); |
2463 | +} | 2986 | +} |
2464 | + | 2987 | + |
2465 | +int | 2988 | +int |
@@ -2470,6 +2993,7 @@ index 732fb3476..1865a122a 100644 | |||
2470 | + | 2993 | + |
2471 | + if ((m = sshbuf_new()) == NULL) | 2994 | + if ((m = sshbuf_new()) == NULL) |
2472 | + fatal("%s: sshbuf_new failed", __func__); | 2995 | + fatal("%s: sshbuf_new failed", __func__); |
2996 | + | ||
2473 | + if ((r = sshbuf_put_cstring(m, | 2997 | + if ((r = sshbuf_put_cstring(m, |
2474 | + store->filename ? store->filename : "")) != 0 || | 2998 | + store->filename ? store->filename : "")) != 0 || |
2475 | + (r = sshbuf_put_cstring(m, | 2999 | + (r = sshbuf_put_cstring(m, |
@@ -2483,6 +3007,7 @@ index 732fb3476..1865a122a 100644 | |||
2483 | + | 3007 | + |
2484 | + if ((r = sshbuf_get_u32(m, &ok)) != 0) | 3008 | + if ((r = sshbuf_get_u32(m, &ok)) != 0) |
2485 | + fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 3009 | + fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
3010 | + | ||
2486 | + sshbuf_free(m); | 3011 | + sshbuf_free(m); |
2487 | + | 3012 | + |
2488 | + return (ok); | 3013 | + return (ok); |
@@ -2490,61 +3015,43 @@ index 732fb3476..1865a122a 100644 | |||
2490 | + | 3015 | + |
2491 | #endif /* GSSAPI */ | 3016 | #endif /* GSSAPI */ |
2492 | diff --git a/monitor_wrap.h b/monitor_wrap.h | 3017 | diff --git a/monitor_wrap.h b/monitor_wrap.h |
2493 | index 644da081d..7f93144ff 100644 | 3018 | index fdebb3aa4..69164a8c0 100644 |
2494 | --- a/monitor_wrap.h | 3019 | --- a/monitor_wrap.h |
2495 | +++ b/monitor_wrap.h | 3020 | +++ b/monitor_wrap.h |
2496 | @@ -60,8 +60,10 @@ int mm_sshkey_verify(const struct sshkey *, const u_char *, size_t, | 3021 | @@ -61,8 +61,10 @@ int mm_sshkey_verify(const struct sshkey *, const u_char *, size_t, |
2497 | OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); | 3022 | OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); |
2498 | OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, | 3023 | OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, |
2499 | gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *); | 3024 | gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *); |
2500 | -int mm_ssh_gssapi_userok(char *user); | 3025 | -int mm_ssh_gssapi_userok(char *user); |
2501 | +int mm_ssh_gssapi_userok(char *user, struct passwd *); | 3026 | +int mm_ssh_gssapi_userok(char *user, struct passwd *, int kex); |
2502 | OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); | 3027 | OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); |
2503 | +OM_uint32 mm_ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); | 3028 | +OM_uint32 mm_ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); |
2504 | +int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *); | 3029 | +int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *); |
2505 | #endif | 3030 | #endif |
2506 | 3031 | ||
2507 | #ifdef USE_PAM | 3032 | #ifdef USE_PAM |
2508 | diff --git a/opacket.c b/opacket.c | ||
2509 | index e637d7a71..7672c0b59 100644 | ||
2510 | --- a/opacket.c | ||
2511 | +++ b/opacket.c | ||
2512 | @@ -80,7 +80,7 @@ ssh_packet_put_raw(struct ssh *ssh, const void *buf, u_int len) | ||
2513 | |||
2514 | #ifdef WITH_OPENSSL | ||
2515 | void | ||
2516 | -ssh_packet_put_bignum2(struct ssh *ssh, BIGNUM * value) | ||
2517 | +ssh_packet_put_bignum2(struct ssh *ssh, const BIGNUM * value) | ||
2518 | { | ||
2519 | int r; | ||
2520 | |||
2521 | diff --git a/opacket.h b/opacket.h | ||
2522 | index f92fe586e..1cf66a2d3 100644 | ||
2523 | --- a/opacket.h | ||
2524 | +++ b/opacket.h | ||
2525 | @@ -7,7 +7,7 @@ void ssh_packet_start(struct ssh *, u_char); | ||
2526 | void ssh_packet_put_char(struct ssh *, int ch); | ||
2527 | void ssh_packet_put_int(struct ssh *, u_int value); | ||
2528 | void ssh_packet_put_int64(struct ssh *, u_int64_t value); | ||
2529 | -void ssh_packet_put_bignum2(struct ssh *, BIGNUM * value); | ||
2530 | +void ssh_packet_put_bignum2(struct ssh *, const BIGNUM * value); | ||
2531 | void ssh_packet_put_ecpoint(struct ssh *, const EC_GROUP *, const EC_POINT *); | ||
2532 | void ssh_packet_put_string(struct ssh *, const void *buf, u_int len); | ||
2533 | void ssh_packet_put_cstring(struct ssh *, const char *str); | ||
2534 | diff --git a/readconf.c b/readconf.c | 3033 | diff --git a/readconf.c b/readconf.c |
2535 | index 433811521..36bc5e59a 100644 | 3034 | index ec497e79f..4d699e5f1 100644 |
2536 | --- a/readconf.c | 3035 | --- a/readconf.c |
2537 | +++ b/readconf.c | 3036 | +++ b/readconf.c |
2538 | @@ -161,6 +161,8 @@ typedef enum { | 3037 | @@ -67,6 +67,7 @@ |
3038 | #include "uidswap.h" | ||
3039 | #include "myproposal.h" | ||
3040 | #include "digest.h" | ||
3041 | +#include "ssh-gss.h" | ||
3042 | |||
3043 | /* Format of the configuration file: | ||
3044 | |||
3045 | @@ -162,6 +163,8 @@ typedef enum { | ||
2539 | oClearAllForwardings, oNoHostAuthenticationForLocalhost, | 3046 | oClearAllForwardings, oNoHostAuthenticationForLocalhost, |
2540 | oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, | 3047 | oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, |
2541 | oAddressFamily, oGssAuthentication, oGssDelegateCreds, | 3048 | oAddressFamily, oGssAuthentication, oGssDelegateCreds, |
2542 | + oGssTrustDns, oGssKeyEx, oGssClientIdentity, oGssRenewalRekey, | 3049 | + oGssTrustDns, oGssKeyEx, oGssClientIdentity, oGssRenewalRekey, |
2543 | + oGssServerIdentity, | 3050 | + oGssServerIdentity, oGssKexAlgorithms, |
2544 | oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, | 3051 | oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, |
2545 | oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist, | 3052 | oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist, |
2546 | oHashKnownHosts, | 3053 | oHashKnownHosts, |
2547 | @@ -201,10 +203,20 @@ static struct { | 3054 | @@ -202,10 +205,22 @@ static struct { |
2548 | /* Sometimes-unsupported options */ | 3055 | /* Sometimes-unsupported options */ |
2549 | #if defined(GSSAPI) | 3056 | #if defined(GSSAPI) |
2550 | { "gssapiauthentication", oGssAuthentication }, | 3057 | { "gssapiauthentication", oGssAuthentication }, |
@@ -2554,6 +3061,7 @@ index 433811521..36bc5e59a 100644 | |||
2554 | + { "gssapiclientidentity", oGssClientIdentity }, | 3061 | + { "gssapiclientidentity", oGssClientIdentity }, |
2555 | + { "gssapiserveridentity", oGssServerIdentity }, | 3062 | + { "gssapiserveridentity", oGssServerIdentity }, |
2556 | + { "gssapirenewalforcesrekey", oGssRenewalRekey }, | 3063 | + { "gssapirenewalforcesrekey", oGssRenewalRekey }, |
3064 | + { "gssapikexalgorithms", oGssKexAlgorithms }, | ||
2557 | # else | 3065 | # else |
2558 | { "gssapiauthentication", oUnsupported }, | 3066 | { "gssapiauthentication", oUnsupported }, |
2559 | + { "gssapikeyexchange", oUnsupported }, | 3067 | + { "gssapikeyexchange", oUnsupported }, |
@@ -2562,10 +3070,11 @@ index 433811521..36bc5e59a 100644 | |||
2562 | + { "gssapiclientidentity", oUnsupported }, | 3070 | + { "gssapiclientidentity", oUnsupported }, |
2563 | + { "gssapiserveridentity", oUnsupported }, | 3071 | + { "gssapiserveridentity", oUnsupported }, |
2564 | + { "gssapirenewalforcesrekey", oUnsupported }, | 3072 | + { "gssapirenewalforcesrekey", oUnsupported }, |
3073 | + { "gssapikexalgorithms", oUnsupported }, | ||
2565 | #endif | 3074 | #endif |
2566 | #ifdef ENABLE_PKCS11 | 3075 | #ifdef ENABLE_PKCS11 |
2567 | { "smartcarddevice", oPKCS11Provider }, | 3076 | { "pkcs11provider", oPKCS11Provider }, |
2568 | @@ -974,10 +986,30 @@ parse_time: | 3077 | @@ -983,10 +998,42 @@ parse_time: |
2569 | intptr = &options->gss_authentication; | 3078 | intptr = &options->gss_authentication; |
2570 | goto parse_flag; | 3079 | goto parse_flag; |
2571 | 3080 | ||
@@ -2593,10 +3102,22 @@ index 433811521..36bc5e59a 100644 | |||
2593 | + intptr = &options->gss_renewal_rekey; | 3102 | + intptr = &options->gss_renewal_rekey; |
2594 | + goto parse_flag; | 3103 | + goto parse_flag; |
2595 | + | 3104 | + |
3105 | + case oGssKexAlgorithms: | ||
3106 | + arg = strdelim(&s); | ||
3107 | + if (!arg || *arg == '\0') | ||
3108 | + fatal("%.200s line %d: Missing argument.", | ||
3109 | + filename, linenum); | ||
3110 | + if (!kex_gss_names_valid(arg)) | ||
3111 | + fatal("%.200s line %d: Bad GSSAPI KexAlgorithms '%s'.", | ||
3112 | + filename, linenum, arg ? arg : "<NONE>"); | ||
3113 | + if (*activep && options->gss_kex_algorithms == NULL) | ||
3114 | + options->gss_kex_algorithms = xstrdup(arg); | ||
3115 | + break; | ||
3116 | + | ||
2596 | case oBatchMode: | 3117 | case oBatchMode: |
2597 | intptr = &options->batch_mode; | 3118 | intptr = &options->batch_mode; |
2598 | goto parse_flag; | 3119 | goto parse_flag; |
2599 | @@ -1842,7 +1874,12 @@ initialize_options(Options * options) | 3120 | @@ -1854,7 +1901,13 @@ initialize_options(Options * options) |
2600 | options->pubkey_authentication = -1; | 3121 | options->pubkey_authentication = -1; |
2601 | options->challenge_response_authentication = -1; | 3122 | options->challenge_response_authentication = -1; |
2602 | options->gss_authentication = -1; | 3123 | options->gss_authentication = -1; |
@@ -2606,10 +3127,11 @@ index 433811521..36bc5e59a 100644 | |||
2606 | + options->gss_renewal_rekey = -1; | 3127 | + options->gss_renewal_rekey = -1; |
2607 | + options->gss_client_identity = NULL; | 3128 | + options->gss_client_identity = NULL; |
2608 | + options->gss_server_identity = NULL; | 3129 | + options->gss_server_identity = NULL; |
3130 | + options->gss_kex_algorithms = NULL; | ||
2609 | options->password_authentication = -1; | 3131 | options->password_authentication = -1; |
2610 | options->kbd_interactive_authentication = -1; | 3132 | options->kbd_interactive_authentication = -1; |
2611 | options->kbd_interactive_devices = NULL; | 3133 | options->kbd_interactive_devices = NULL; |
2612 | @@ -1988,8 +2025,14 @@ fill_default_options(Options * options) | 3134 | @@ -2000,8 +2053,18 @@ fill_default_options(Options * options) |
2613 | options->challenge_response_authentication = 1; | 3135 | options->challenge_response_authentication = 1; |
2614 | if (options->gss_authentication == -1) | 3136 | if (options->gss_authentication == -1) |
2615 | options->gss_authentication = 0; | 3137 | options->gss_authentication = 0; |
@@ -2621,14 +3143,33 @@ index 433811521..36bc5e59a 100644 | |||
2621 | + options->gss_trust_dns = 0; | 3143 | + options->gss_trust_dns = 0; |
2622 | + if (options->gss_renewal_rekey == -1) | 3144 | + if (options->gss_renewal_rekey == -1) |
2623 | + options->gss_renewal_rekey = 0; | 3145 | + options->gss_renewal_rekey = 0; |
3146 | +#ifdef GSSAPI | ||
3147 | + if (options->gss_kex_algorithms == NULL) | ||
3148 | + options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX); | ||
3149 | +#endif | ||
2624 | if (options->password_authentication == -1) | 3150 | if (options->password_authentication == -1) |
2625 | options->password_authentication = 1; | 3151 | options->password_authentication = 1; |
2626 | if (options->kbd_interactive_authentication == -1) | 3152 | if (options->kbd_interactive_authentication == -1) |
3153 | @@ -2616,7 +2679,14 @@ dump_client_config(Options *o, const char *host) | ||
3154 | dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports); | ||
3155 | #ifdef GSSAPI | ||
3156 | dump_cfg_fmtint(oGssAuthentication, o->gss_authentication); | ||
3157 | + dump_cfg_fmtint(oGssKeyEx, o->gss_keyex); | ||
3158 | dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds); | ||
3159 | + dump_cfg_fmtint(oGssTrustDns, o->gss_trust_dns); | ||
3160 | + dump_cfg_fmtint(oGssRenewalRekey, o->gss_renewal_rekey); | ||
3161 | + dump_cfg_string(oGssClientIdentity, o->gss_client_identity); | ||
3162 | + dump_cfg_string(oGssServerIdentity, o->gss_server_identity); | ||
3163 | + dump_cfg_string(oGssKexAlgorithms, o->gss_kex_algorithms ? | ||
3164 | + o->gss_kex_algorithms : GSS_KEX_DEFAULT_KEX); | ||
3165 | #endif /* GSSAPI */ | ||
3166 | dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts); | ||
3167 | dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication); | ||
2627 | diff --git a/readconf.h b/readconf.h | 3168 | diff --git a/readconf.h b/readconf.h |
2628 | index fc7e38251..8e4900d01 100644 | 3169 | index 8e36bf32a..0bff6d80a 100644 |
2629 | --- a/readconf.h | 3170 | --- a/readconf.h |
2630 | +++ b/readconf.h | 3171 | +++ b/readconf.h |
2631 | @@ -40,7 +40,12 @@ typedef struct { | 3172 | @@ -40,7 +40,13 @@ typedef struct { |
2632 | int challenge_response_authentication; | 3173 | int challenge_response_authentication; |
2633 | /* Try S/Key or TIS, authentication. */ | 3174 | /* Try S/Key or TIS, authentication. */ |
2634 | int gss_authentication; /* Try GSS authentication */ | 3175 | int gss_authentication; /* Try GSS authentication */ |
@@ -2638,14 +3179,23 @@ index fc7e38251..8e4900d01 100644 | |||
2638 | + int gss_renewal_rekey; /* Credential renewal forces rekey */ | 3179 | + int gss_renewal_rekey; /* Credential renewal forces rekey */ |
2639 | + char *gss_client_identity; /* Principal to initiate GSSAPI with */ | 3180 | + char *gss_client_identity; /* Principal to initiate GSSAPI with */ |
2640 | + char *gss_server_identity; /* GSSAPI target principal */ | 3181 | + char *gss_server_identity; /* GSSAPI target principal */ |
3182 | + char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */ | ||
2641 | int password_authentication; /* Try password | 3183 | int password_authentication; /* Try password |
2642 | * authentication. */ | 3184 | * authentication. */ |
2643 | int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ | 3185 | int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ |
2644 | diff --git a/servconf.c b/servconf.c | 3186 | diff --git a/servconf.c b/servconf.c |
2645 | index 932d363bb..4668b8a45 100644 | 3187 | index ffac5d2c7..ffdad31e7 100644 |
2646 | --- a/servconf.c | 3188 | --- a/servconf.c |
2647 | +++ b/servconf.c | 3189 | +++ b/servconf.c |
2648 | @@ -124,8 +124,10 @@ initialize_server_options(ServerOptions *options) | 3190 | @@ -64,6 +64,7 @@ |
3191 | #include "auth.h" | ||
3192 | #include "myproposal.h" | ||
3193 | #include "digest.h" | ||
3194 | +#include "ssh-gss.h" | ||
3195 | |||
3196 | static void add_listen_addr(ServerOptions *, const char *, | ||
3197 | const char *, int); | ||
3198 | @@ -124,8 +125,11 @@ initialize_server_options(ServerOptions *options) | ||
2649 | options->kerberos_ticket_cleanup = -1; | 3199 | options->kerberos_ticket_cleanup = -1; |
2650 | options->kerberos_get_afs_token = -1; | 3200 | options->kerberos_get_afs_token = -1; |
2651 | options->gss_authentication=-1; | 3201 | options->gss_authentication=-1; |
@@ -2653,10 +3203,11 @@ index 932d363bb..4668b8a45 100644 | |||
2653 | options->gss_cleanup_creds = -1; | 3203 | options->gss_cleanup_creds = -1; |
2654 | options->gss_strict_acceptor = -1; | 3204 | options->gss_strict_acceptor = -1; |
2655 | + options->gss_store_rekey = -1; | 3205 | + options->gss_store_rekey = -1; |
3206 | + options->gss_kex_algorithms = NULL; | ||
2656 | options->password_authentication = -1; | 3207 | options->password_authentication = -1; |
2657 | options->kbd_interactive_authentication = -1; | 3208 | options->kbd_interactive_authentication = -1; |
2658 | options->challenge_response_authentication = -1; | 3209 | options->challenge_response_authentication = -1; |
2659 | @@ -337,10 +339,14 @@ fill_default_server_options(ServerOptions *options) | 3210 | @@ -351,10 +355,18 @@ fill_default_server_options(ServerOptions *options) |
2660 | options->kerberos_get_afs_token = 0; | 3211 | options->kerberos_get_afs_token = 0; |
2661 | if (options->gss_authentication == -1) | 3212 | if (options->gss_authentication == -1) |
2662 | options->gss_authentication = 0; | 3213 | options->gss_authentication = 0; |
@@ -2668,18 +3219,22 @@ index 932d363bb..4668b8a45 100644 | |||
2668 | options->gss_strict_acceptor = 1; | 3219 | options->gss_strict_acceptor = 1; |
2669 | + if (options->gss_store_rekey == -1) | 3220 | + if (options->gss_store_rekey == -1) |
2670 | + options->gss_store_rekey = 0; | 3221 | + options->gss_store_rekey = 0; |
3222 | +#ifdef GSSAPI | ||
3223 | + if (options->gss_kex_algorithms == NULL) | ||
3224 | + options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX); | ||
3225 | +#endif | ||
2671 | if (options->password_authentication == -1) | 3226 | if (options->password_authentication == -1) |
2672 | options->password_authentication = 1; | 3227 | options->password_authentication = 1; |
2673 | if (options->kbd_interactive_authentication == -1) | 3228 | if (options->kbd_interactive_authentication == -1) |
2674 | @@ -485,6 +491,7 @@ typedef enum { | 3229 | @@ -498,6 +510,7 @@ typedef enum { |
2675 | sHostKeyAlgorithms, | 3230 | sHostKeyAlgorithms, |
2676 | sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, | 3231 | sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, |
2677 | sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, | 3232 | sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, |
2678 | + sGssKeyEx, sGssStoreRekey, | 3233 | + sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey, |
2679 | sAcceptEnv, sSetEnv, sPermitTunnel, | 3234 | sAcceptEnv, sSetEnv, sPermitTunnel, |
2680 | sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, | 3235 | sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, |
2681 | sUsePrivilegeSeparation, sAllowAgentForwarding, | 3236 | sUsePrivilegeSeparation, sAllowAgentForwarding, |
2682 | @@ -559,12 +566,20 @@ static struct { | 3237 | @@ -572,12 +585,22 @@ static struct { |
2683 | #ifdef GSSAPI | 3238 | #ifdef GSSAPI |
2684 | { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, | 3239 | { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, |
2685 | { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, | 3240 | { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, |
@@ -2687,6 +3242,7 @@ index 932d363bb..4668b8a45 100644 | |||
2687 | { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, | 3242 | { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, |
2688 | + { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, | 3243 | + { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, |
2689 | + { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, | 3244 | + { "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, |
3245 | + { "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL }, | ||
2690 | #else | 3246 | #else |
2691 | { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, | 3247 | { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, |
2692 | { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, | 3248 | { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, |
@@ -2694,13 +3250,14 @@ index 932d363bb..4668b8a45 100644 | |||
2694 | { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, | 3250 | { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, |
2695 | + { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, | 3251 | + { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, |
2696 | + { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, | 3252 | + { "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, |
3253 | + { "gssapikexalgorithms", sUnsupported, SSHCFG_GLOBAL }, | ||
2697 | #endif | 3254 | #endif |
2698 | + { "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL }, | 3255 | + { "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL }, |
2699 | + { "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL }, | 3256 | + { "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL }, |
2700 | { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, | 3257 | { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, |
2701 | { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, | 3258 | { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, |
2702 | { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, | 3259 | { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, |
2703 | @@ -1468,6 +1483,10 @@ process_server_config_line(ServerOptions *options, char *line, | 3260 | @@ -1485,6 +1508,10 @@ process_server_config_line(ServerOptions *options, char *line, |
2704 | intptr = &options->gss_authentication; | 3261 | intptr = &options->gss_authentication; |
2705 | goto parse_flag; | 3262 | goto parse_flag; |
2706 | 3263 | ||
@@ -2711,7 +3268,7 @@ index 932d363bb..4668b8a45 100644 | |||
2711 | case sGssCleanupCreds: | 3268 | case sGssCleanupCreds: |
2712 | intptr = &options->gss_cleanup_creds; | 3269 | intptr = &options->gss_cleanup_creds; |
2713 | goto parse_flag; | 3270 | goto parse_flag; |
2714 | @@ -1476,6 +1495,10 @@ process_server_config_line(ServerOptions *options, char *line, | 3271 | @@ -1493,6 +1520,22 @@ process_server_config_line(ServerOptions *options, char *line, |
2715 | intptr = &options->gss_strict_acceptor; | 3272 | intptr = &options->gss_strict_acceptor; |
2716 | goto parse_flag; | 3273 | goto parse_flag; |
2717 | 3274 | ||
@@ -2719,25 +3276,37 @@ index 932d363bb..4668b8a45 100644 | |||
2719 | + intptr = &options->gss_store_rekey; | 3276 | + intptr = &options->gss_store_rekey; |
2720 | + goto parse_flag; | 3277 | + goto parse_flag; |
2721 | + | 3278 | + |
3279 | + case sGssKexAlgorithms: | ||
3280 | + arg = strdelim(&cp); | ||
3281 | + if (!arg || *arg == '\0') | ||
3282 | + fatal("%.200s line %d: Missing argument.", | ||
3283 | + filename, linenum); | ||
3284 | + if (!kex_gss_names_valid(arg)) | ||
3285 | + fatal("%.200s line %d: Bad GSSAPI KexAlgorithms '%s'.", | ||
3286 | + filename, linenum, arg ? arg : "<NONE>"); | ||
3287 | + if (*activep && options->gss_kex_algorithms == NULL) | ||
3288 | + options->gss_kex_algorithms = xstrdup(arg); | ||
3289 | + break; | ||
3290 | + | ||
2722 | case sPasswordAuthentication: | 3291 | case sPasswordAuthentication: |
2723 | intptr = &options->password_authentication; | 3292 | intptr = &options->password_authentication; |
2724 | goto parse_flag; | 3293 | goto parse_flag; |
2725 | @@ -2560,7 +2583,10 @@ dump_config(ServerOptions *o) | 3294 | @@ -2579,6 +2622,10 @@ dump_config(ServerOptions *o) |
2726 | #endif | ||
2727 | #ifdef GSSAPI | 3295 | #ifdef GSSAPI |
2728 | dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); | 3296 | dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); |
2729 | + dump_cfg_fmtint(sGssKeyEx, o->gss_keyex); | ||
2730 | dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); | 3297 | dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); |
3298 | + dump_cfg_fmtint(sGssKeyEx, o->gss_keyex); | ||
2731 | + dump_cfg_fmtint(sGssStrictAcceptor, o->gss_strict_acceptor); | 3299 | + dump_cfg_fmtint(sGssStrictAcceptor, o->gss_strict_acceptor); |
2732 | + dump_cfg_fmtint(sGssStoreRekey, o->gss_store_rekey); | 3300 | + dump_cfg_fmtint(sGssStoreRekey, o->gss_store_rekey); |
3301 | + dump_cfg_string(sGssKexAlgorithms, o->gss_kex_algorithms); | ||
2733 | #endif | 3302 | #endif |
2734 | dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); | 3303 | dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); |
2735 | dump_cfg_fmtint(sKbdInteractiveAuthentication, | 3304 | dump_cfg_fmtint(sKbdInteractiveAuthentication, |
2736 | diff --git a/servconf.h b/servconf.h | 3305 | diff --git a/servconf.h b/servconf.h |
2737 | index 0175e00e8..3b76da816 100644 | 3306 | index 54e0a8d8d..a476d5220 100644 |
2738 | --- a/servconf.h | 3307 | --- a/servconf.h |
2739 | +++ b/servconf.h | 3308 | +++ b/servconf.h |
2740 | @@ -125,8 +125,10 @@ typedef struct { | 3309 | @@ -126,8 +126,11 @@ typedef struct { |
2741 | int kerberos_get_afs_token; /* If true, try to get AFS token if | 3310 | int kerberos_get_afs_token; /* If true, try to get AFS token if |
2742 | * authenticated with Kerberos. */ | 3311 | * authenticated with Kerberos. */ |
2743 | int gss_authentication; /* If true, permit GSSAPI authentication */ | 3312 | int gss_authentication; /* If true, permit GSSAPI authentication */ |
@@ -2745,11 +3314,38 @@ index 0175e00e8..3b76da816 100644 | |||
2745 | int gss_cleanup_creds; /* If true, destroy cred cache on logout */ | 3314 | int gss_cleanup_creds; /* If true, destroy cred cache on logout */ |
2746 | int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ | 3315 | int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ |
2747 | + int gss_store_rekey; | 3316 | + int gss_store_rekey; |
3317 | + char *gss_kex_algorithms; /* GSSAPI kex methods to be offered by client. */ | ||
2748 | int password_authentication; /* If true, permit password | 3318 | int password_authentication; /* If true, permit password |
2749 | * authentication. */ | 3319 | * authentication. */ |
2750 | int kbd_interactive_authentication; /* If true, permit */ | 3320 | int kbd_interactive_authentication; /* If true, permit */ |
3321 | diff --git a/session.c b/session.c | ||
3322 | index ac06b08e9..ac3d9d19d 100644 | ||
3323 | --- a/session.c | ||
3324 | +++ b/session.c | ||
3325 | @@ -2674,13 +2674,19 @@ do_cleanup(struct ssh *ssh, Authctxt *authctxt) | ||
3326 | |||
3327 | #ifdef KRB5 | ||
3328 | if (options.kerberos_ticket_cleanup && | ||
3329 | - authctxt->krb5_ctx) | ||
3330 | + authctxt->krb5_ctx) { | ||
3331 | + temporarily_use_uid(authctxt->pw); | ||
3332 | krb5_cleanup_proc(authctxt); | ||
3333 | + restore_uid(); | ||
3334 | + } | ||
3335 | #endif | ||
3336 | |||
3337 | #ifdef GSSAPI | ||
3338 | - if (options.gss_cleanup_creds) | ||
3339 | + if (options.gss_cleanup_creds) { | ||
3340 | + temporarily_use_uid(authctxt->pw); | ||
3341 | ssh_gssapi_cleanup_creds(); | ||
3342 | + restore_uid(); | ||
3343 | + } | ||
3344 | #endif | ||
3345 | |||
3346 | /* remove agent socket */ | ||
2751 | diff --git a/ssh-gss.h b/ssh-gss.h | 3347 | diff --git a/ssh-gss.h b/ssh-gss.h |
2752 | index 36180d07a..350ce7882 100644 | 3348 | index 36180d07a..70dd36658 100644 |
2753 | --- a/ssh-gss.h | 3349 | --- a/ssh-gss.h |
2754 | +++ b/ssh-gss.h | 3350 | +++ b/ssh-gss.h |
2755 | @@ -1,6 +1,6 @@ | 3351 | @@ -1,6 +1,6 @@ |
@@ -2760,7 +3356,7 @@ index 36180d07a..350ce7882 100644 | |||
2760 | * | 3356 | * |
2761 | * Redistribution and use in source and binary forms, with or without | 3357 | * Redistribution and use in source and binary forms, with or without |
2762 | * modification, are permitted provided that the following conditions | 3358 | * modification, are permitted provided that the following conditions |
2763 | @@ -61,10 +61,22 @@ | 3359 | @@ -61,10 +61,30 @@ |
2764 | 3360 | ||
2765 | #define SSH_GSS_OIDTYPE 0x06 | 3361 | #define SSH_GSS_OIDTYPE 0x06 |
2766 | 3362 | ||
@@ -2773,7 +3369,15 @@ index 36180d07a..350ce7882 100644 | |||
2773 | +#define SSH2_MSG_KEXGSS_GROUP 41 | 3369 | +#define SSH2_MSG_KEXGSS_GROUP 41 |
2774 | +#define KEX_GSS_GRP1_SHA1_ID "gss-group1-sha1-" | 3370 | +#define KEX_GSS_GRP1_SHA1_ID "gss-group1-sha1-" |
2775 | +#define KEX_GSS_GRP14_SHA1_ID "gss-group14-sha1-" | 3371 | +#define KEX_GSS_GRP14_SHA1_ID "gss-group14-sha1-" |
3372 | +#define KEX_GSS_GRP14_SHA256_ID "gss-group14-sha256-" | ||
3373 | +#define KEX_GSS_GRP16_SHA512_ID "gss-group16-sha512-" | ||
2776 | +#define KEX_GSS_GEX_SHA1_ID "gss-gex-sha1-" | 3374 | +#define KEX_GSS_GEX_SHA1_ID "gss-gex-sha1-" |
3375 | +#define KEX_GSS_NISTP256_SHA256_ID "gss-nistp256-sha256-" | ||
3376 | +#define KEX_GSS_C25519_SHA256_ID "gss-curve25519-sha256-" | ||
3377 | + | ||
3378 | +#define GSS_KEX_DEFAULT_KEX \ | ||
3379 | + KEX_GSS_GEX_SHA1_ID "," \ | ||
3380 | + KEX_GSS_GRP14_SHA1_ID | ||
2777 | + | 3381 | + |
2778 | typedef struct { | 3382 | typedef struct { |
2779 | char *filename; | 3383 | char *filename; |
@@ -2783,7 +3387,7 @@ index 36180d07a..350ce7882 100644 | |||
2783 | void *data; | 3387 | void *data; |
2784 | } ssh_gssapi_ccache; | 3388 | } ssh_gssapi_ccache; |
2785 | 3389 | ||
2786 | @@ -72,8 +84,11 @@ typedef struct { | 3390 | @@ -72,8 +92,11 @@ typedef struct { |
2787 | gss_buffer_desc displayname; | 3391 | gss_buffer_desc displayname; |
2788 | gss_buffer_desc exportedname; | 3392 | gss_buffer_desc exportedname; |
2789 | gss_cred_id_t creds; | 3393 | gss_cred_id_t creds; |
@@ -2795,7 +3399,7 @@ index 36180d07a..350ce7882 100644 | |||
2795 | } ssh_gssapi_client; | 3399 | } ssh_gssapi_client; |
2796 | 3400 | ||
2797 | typedef struct ssh_gssapi_mech_struct { | 3401 | typedef struct ssh_gssapi_mech_struct { |
2798 | @@ -84,6 +99,7 @@ typedef struct ssh_gssapi_mech_struct { | 3402 | @@ -84,6 +107,7 @@ typedef struct ssh_gssapi_mech_struct { |
2799 | int (*userok) (ssh_gssapi_client *, char *); | 3403 | int (*userok) (ssh_gssapi_client *, char *); |
2800 | int (*localname) (ssh_gssapi_client *, char **); | 3404 | int (*localname) (ssh_gssapi_client *, char **); |
2801 | void (*storecreds) (ssh_gssapi_client *); | 3405 | void (*storecreds) (ssh_gssapi_client *); |
@@ -2803,7 +3407,7 @@ index 36180d07a..350ce7882 100644 | |||
2803 | } ssh_gssapi_mech; | 3407 | } ssh_gssapi_mech; |
2804 | 3408 | ||
2805 | typedef struct { | 3409 | typedef struct { |
2806 | @@ -94,10 +110,11 @@ typedef struct { | 3410 | @@ -94,10 +118,11 @@ typedef struct { |
2807 | gss_OID oid; /* client */ | 3411 | gss_OID oid; /* client */ |
2808 | gss_cred_id_t creds; /* server */ | 3412 | gss_cred_id_t creds; /* server */ |
2809 | gss_name_t client; /* server */ | 3413 | gss_name_t client; /* server */ |
@@ -2816,7 +3420,15 @@ index 36180d07a..350ce7882 100644 | |||
2816 | 3420 | ||
2817 | int ssh_gssapi_check_oid(Gssctxt *, void *, size_t); | 3421 | int ssh_gssapi_check_oid(Gssctxt *, void *, size_t); |
2818 | void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t); | 3422 | void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t); |
2819 | @@ -123,17 +140,33 @@ void ssh_gssapi_delete_ctx(Gssctxt **); | 3423 | @@ -109,6 +134,7 @@ OM_uint32 ssh_gssapi_test_oid_supported(OM_uint32 *, gss_OID, int *); |
3424 | |||
3425 | struct sshbuf; | ||
3426 | int ssh_gssapi_get_buffer_desc(struct sshbuf *, gss_buffer_desc *); | ||
3427 | +int ssh_gssapi_sshpkt_get_buffer_desc(struct ssh *, gss_buffer_desc *); | ||
3428 | |||
3429 | OM_uint32 ssh_gssapi_import_name(Gssctxt *, const char *); | ||
3430 | OM_uint32 ssh_gssapi_init_ctx(Gssctxt *, int, | ||
3431 | @@ -123,17 +149,33 @@ void ssh_gssapi_delete_ctx(Gssctxt **); | ||
2820 | OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); | 3432 | OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); |
2821 | void ssh_gssapi_buildmic(struct sshbuf *, const char *, | 3433 | void ssh_gssapi_buildmic(struct sshbuf *, const char *, |
2822 | const char *, const char *); | 3434 | const char *, const char *); |
@@ -2826,17 +3438,17 @@ index 36180d07a..350ce7882 100644 | |||
2826 | +int ssh_gssapi_credentials_updated(Gssctxt *); | 3438 | +int ssh_gssapi_credentials_updated(Gssctxt *); |
2827 | 3439 | ||
2828 | /* In the server */ | 3440 | /* In the server */ |
2829 | +typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, | 3441 | +typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, |
2830 | + const char *); | 3442 | + const char *); |
2831 | +char *ssh_gssapi_client_mechanisms(const char *, const char *); | 3443 | +char *ssh_gssapi_client_mechanisms(const char *, const char *, const char *); |
2832 | +char *ssh_gssapi_kex_mechs(gss_OID_set, ssh_gssapi_check_fn *, const char *, | 3444 | +char *ssh_gssapi_kex_mechs(gss_OID_set, ssh_gssapi_check_fn *, const char *, |
2833 | + const char *); | 3445 | + const char *, const char *); |
2834 | +gss_OID ssh_gssapi_id_kex(Gssctxt *, char *, int); | 3446 | +gss_OID ssh_gssapi_id_kex(Gssctxt *, char *, int); |
2835 | +int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *, | 3447 | +int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *, |
2836 | + const char *); | 3448 | + const char *); |
2837 | OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID); | 3449 | OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID); |
2838 | -int ssh_gssapi_userok(char *name); | 3450 | -int ssh_gssapi_userok(char *name); |
2839 | +int ssh_gssapi_userok(char *name, struct passwd *); | 3451 | +int ssh_gssapi_userok(char *name, struct passwd *, int kex); |
2840 | OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); | 3452 | OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); |
2841 | void ssh_gssapi_do_child(char ***, u_int *); | 3453 | void ssh_gssapi_do_child(char ***, u_int *); |
2842 | void ssh_gssapi_cleanup_creds(void); | 3454 | void ssh_gssapi_cleanup_creds(void); |
@@ -2852,8 +3464,57 @@ index 36180d07a..350ce7882 100644 | |||
2852 | #endif /* GSSAPI */ | 3464 | #endif /* GSSAPI */ |
2853 | 3465 | ||
2854 | #endif /* _SSH_GSS_H */ | 3466 | #endif /* _SSH_GSS_H */ |
3467 | diff --git a/ssh.1 b/ssh.1 | ||
3468 | index 9480eba8d..a1c7d2305 100644 | ||
3469 | --- a/ssh.1 | ||
3470 | +++ b/ssh.1 | ||
3471 | @@ -497,7 +497,13 @@ For full details of the options listed below, and their possible values, see | ||
3472 | .It GatewayPorts | ||
3473 | .It GlobalKnownHostsFile | ||
3474 | .It GSSAPIAuthentication | ||
3475 | +.It GSSAPIKeyExchange | ||
3476 | +.It GSSAPIClientIdentity | ||
3477 | .It GSSAPIDelegateCredentials | ||
3478 | +.It GSSAPIKexAlgorithms | ||
3479 | +.It GSSAPIRenewalForcesRekey | ||
3480 | +.It GSSAPIServerIdentity | ||
3481 | +.It GSSAPITrustDns | ||
3482 | .It HashKnownHosts | ||
3483 | .It Host | ||
3484 | .It HostbasedAuthentication | ||
3485 | @@ -573,6 +579,8 @@ flag), | ||
3486 | (supported message integrity codes), | ||
3487 | .Ar kex | ||
3488 | (key exchange algorithms), | ||
3489 | +.Ar kex-gss | ||
3490 | +(GSSAPI key exchange algorithms), | ||
3491 | .Ar key | ||
3492 | (key types), | ||
3493 | .Ar key-cert | ||
3494 | diff --git a/ssh.c b/ssh.c | ||
3495 | index 91e7c3511..42be7d88f 100644 | ||
3496 | --- a/ssh.c | ||
3497 | +++ b/ssh.c | ||
3498 | @@ -736,6 +736,8 @@ main(int ac, char **av) | ||
3499 | cp = mac_alg_list('\n'); | ||
3500 | else if (strcmp(optarg, "kex") == 0) | ||
3501 | cp = kex_alg_list('\n'); | ||
3502 | + else if (strcmp(optarg, "kex-gss") == 0) | ||
3503 | + cp = kex_gss_alg_list('\n'); | ||
3504 | else if (strcmp(optarg, "key") == 0) | ||
3505 | cp = sshkey_alg_list(0, 0, 0, '\n'); | ||
3506 | else if (strcmp(optarg, "key-cert") == 0) | ||
3507 | @@ -748,7 +750,7 @@ main(int ac, char **av) | ||
3508 | cp = xstrdup("2"); | ||
3509 | else if (strcmp(optarg, "help") == 0) { | ||
3510 | cp = xstrdup( | ||
3511 | - "cipher\ncipher-auth\nkex\nkey\n" | ||
3512 | + "cipher\ncipher-auth\nkex\nkex-gss\nkey\n" | ||
3513 | "key-cert\nkey-plain\nmac\n" | ||
3514 | "protocol-version\nsig"); | ||
3515 | } | ||
2855 | diff --git a/ssh_config b/ssh_config | 3516 | diff --git a/ssh_config b/ssh_config |
2856 | index c12f5ef52..bcb9f153d 100644 | 3517 | index 5e8ef548b..1ff999b68 100644 |
2857 | --- a/ssh_config | 3518 | --- a/ssh_config |
2858 | +++ b/ssh_config | 3519 | +++ b/ssh_config |
2859 | @@ -24,6 +24,8 @@ | 3520 | @@ -24,6 +24,8 @@ |
@@ -2866,61 +3527,95 @@ index c12f5ef52..bcb9f153d 100644 | |||
2866 | # CheckHostIP yes | 3527 | # CheckHostIP yes |
2867 | # AddressFamily any | 3528 | # AddressFamily any |
2868 | diff --git a/ssh_config.5 b/ssh_config.5 | 3529 | diff --git a/ssh_config.5 b/ssh_config.5 |
2869 | index 4d5b01d3e..16c79368a 100644 | 3530 | index 412629637..c3c8b274a 100644 |
2870 | --- a/ssh_config.5 | 3531 | --- a/ssh_config.5 |
2871 | +++ b/ssh_config.5 | 3532 | +++ b/ssh_config.5 |
2872 | @@ -736,10 +736,42 @@ The default is | 3533 | @@ -754,10 +754,67 @@ The default is |
2873 | Specifies whether user authentication based on GSSAPI is allowed. | 3534 | Specifies whether user authentication based on GSSAPI is allowed. |
2874 | The default is | 3535 | The default is |
2875 | .Cm no . | 3536 | .Cm no . |
2876 | +.It Cm GSSAPIKeyExchange | ||
2877 | +Specifies whether key exchange based on GSSAPI may be used. When using | ||
2878 | +GSSAPI key exchange the server need not have a host key. | ||
2879 | +The default is | ||
2880 | +.Cm no . | ||
2881 | +.It Cm GSSAPIClientIdentity | 3537 | +.It Cm GSSAPIClientIdentity |
2882 | +If set, specifies the GSSAPI client identity that ssh should use when | 3538 | +If set, specifies the GSSAPI client identity that ssh should use when |
2883 | +connecting to the server. The default is unset, which means that the default | 3539 | +connecting to the server. The default is unset, which means that the default |
2884 | +identity will be used. | 3540 | +identity will be used. |
2885 | +.It Cm GSSAPIServerIdentity | ||
2886 | +If set, specifies the GSSAPI server identity that ssh should expect when | ||
2887 | +connecting to the server. The default is unset, which means that the | ||
2888 | +expected GSSAPI server identity will be determined from the target | ||
2889 | +hostname. | ||
2890 | .It Cm GSSAPIDelegateCredentials | 3541 | .It Cm GSSAPIDelegateCredentials |
2891 | Forward (delegate) credentials to the server. | 3542 | Forward (delegate) credentials to the server. |
2892 | The default is | 3543 | The default is |
2893 | .Cm no . | 3544 | .Cm no . |
3545 | +.It Cm GSSAPIKeyExchange | ||
3546 | +Specifies whether key exchange based on GSSAPI may be used. When using | ||
3547 | +GSSAPI key exchange the server need not have a host key. | ||
3548 | +The default is | ||
3549 | +.Dq no . | ||
2894 | +.It Cm GSSAPIRenewalForcesRekey | 3550 | +.It Cm GSSAPIRenewalForcesRekey |
2895 | +If set to | 3551 | +If set to |
2896 | +.Cm yes | 3552 | +.Dq yes |
2897 | +then renewal of the client's GSSAPI credentials will force the rekeying of the | 3553 | +then renewal of the client's GSSAPI credentials will force the rekeying of the |
2898 | +ssh connection. With a compatible server, this can delegate the renewed | 3554 | +ssh connection. With a compatible server, this will delegate the renewed |
2899 | +credentials to a session on the server. | 3555 | +credentials to a session on the server. |
3556 | +.Pp | ||
3557 | +Checks are made to ensure that credentials are only propagated when the new | ||
3558 | +credentials match the old ones on the originating client and where the | ||
3559 | +receiving server still has the old set in its cache. | ||
3560 | +.Pp | ||
2900 | +The default is | 3561 | +The default is |
2901 | +.Cm no . | 3562 | +.Dq no . |
3563 | +.Pp | ||
3564 | +For this to work | ||
3565 | +.Cm GSSAPIKeyExchange | ||
3566 | +needs to be enabled in the server and also used by the client. | ||
3567 | +.It Cm GSSAPIServerIdentity | ||
3568 | +If set, specifies the GSSAPI server identity that ssh should expect when | ||
3569 | +connecting to the server. The default is unset, which means that the | ||
3570 | +expected GSSAPI server identity will be determined from the target | ||
3571 | +hostname. | ||
2902 | +.It Cm GSSAPITrustDns | 3572 | +.It Cm GSSAPITrustDns |
2903 | +Set to | 3573 | +Set to |
2904 | +.Cm yes | 3574 | +.Dq yes |
2905 | +to indicate that the DNS is trusted to securely canonicalize | 3575 | +to indicate that the DNS is trusted to securely canonicalize |
2906 | +the name of the host being connected to. If | 3576 | +the name of the host being connected to. If |
2907 | +.Cm no , | 3577 | +.Dq no , |
2908 | +the hostname entered on the | 3578 | +the hostname entered on the |
2909 | +command line will be passed untouched to the GSSAPI library. | 3579 | +command line will be passed untouched to the GSSAPI library. |
2910 | +The default is | 3580 | +The default is |
2911 | +.Cm no . | 3581 | +.Dq no . |
3582 | +.It Cm GSSAPIKexAlgorithms | ||
3583 | +The list of key exchange algorithms that are offered for GSSAPI | ||
3584 | +key exchange. Possible values are | ||
3585 | +.Bd -literal -offset 3n | ||
3586 | +gss-gex-sha1-, | ||
3587 | +gss-group1-sha1-, | ||
3588 | +gss-group14-sha1-, | ||
3589 | +gss-group14-sha256-, | ||
3590 | +gss-group16-sha512-, | ||
3591 | +gss-nistp256-sha256-, | ||
3592 | +gss-curve25519-sha256- | ||
3593 | +.Ed | ||
3594 | +.Pp | ||
3595 | +The default is | ||
3596 | +.Dq gss-gex-sha1-,gss-group14-sha1- . | ||
3597 | +This option only applies to protocol version 2 connections using GSSAPI. | ||
2912 | .It Cm HashKnownHosts | 3598 | .It Cm HashKnownHosts |
2913 | Indicates that | 3599 | Indicates that |
2914 | .Xr ssh 1 | 3600 | .Xr ssh 1 |
2915 | diff --git a/sshconnect2.c b/sshconnect2.c | 3601 | diff --git a/sshconnect2.c b/sshconnect2.c |
2916 | index 1675f3935..8c872a4fb 100644 | 3602 | index dffee90b1..4020371ae 100644 |
2917 | --- a/sshconnect2.c | 3603 | --- a/sshconnect2.c |
2918 | +++ b/sshconnect2.c | 3604 | +++ b/sshconnect2.c |
2919 | @@ -162,6 +162,11 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) | 3605 | @@ -78,8 +78,6 @@ |
2920 | struct kex *kex; | 3606 | #endif |
3607 | |||
3608 | /* import */ | ||
3609 | -extern char *client_version_string; | ||
3610 | -extern char *server_version_string; | ||
3611 | extern Options options; | ||
3612 | |||
3613 | /* | ||
3614 | @@ -161,6 +159,11 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port) | ||
3615 | char *s, *all_key; | ||
2921 | int r; | 3616 | int r; |
2922 | 3617 | ||
2923 | +#ifdef GSSAPI | 3618 | +#if defined(GSSAPI) && defined(WITH_OPENSSL) |
2924 | + char *orig = NULL, *gss = NULL; | 3619 | + char *orig = NULL, *gss = NULL; |
2925 | + char *gss_host = NULL; | 3620 | + char *gss_host = NULL; |
2926 | +#endif | 3621 | +#endif |
@@ -2928,11 +3623,11 @@ index 1675f3935..8c872a4fb 100644 | |||
2928 | xxx_host = host; | 3623 | xxx_host = host; |
2929 | xxx_hostaddr = hostaddr; | 3624 | xxx_hostaddr = hostaddr; |
2930 | 3625 | ||
2931 | @@ -194,6 +199,35 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) | 3626 | @@ -193,6 +196,35 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port) |
2932 | order_hostkeyalgs(host, hostaddr, port)); | 3627 | order_hostkeyalgs(host, hostaddr, port)); |
2933 | } | 3628 | } |
2934 | 3629 | ||
2935 | +#ifdef GSSAPI | 3630 | +#if defined(GSSAPI) && defined(WITH_OPENSSL) |
2936 | + if (options.gss_keyex) { | 3631 | + if (options.gss_keyex) { |
2937 | + /* Add the GSSAPI mechanisms currently supported on this | 3632 | + /* Add the GSSAPI mechanisms currently supported on this |
2938 | + * client to the key exchange algorithm proposal */ | 3633 | + * client to the key exchange algorithm proposal */ |
@@ -2941,19 +3636,19 @@ index 1675f3935..8c872a4fb 100644 | |||
2941 | + if (options.gss_server_identity) | 3636 | + if (options.gss_server_identity) |
2942 | + gss_host = xstrdup(options.gss_server_identity); | 3637 | + gss_host = xstrdup(options.gss_server_identity); |
2943 | + else if (options.gss_trust_dns) | 3638 | + else if (options.gss_trust_dns) |
2944 | + gss_host = remote_hostname(active_state); | 3639 | + gss_host = remote_hostname(ssh); |
2945 | + else | 3640 | + else |
2946 | + gss_host = xstrdup(host); | 3641 | + gss_host = xstrdup(host); |
2947 | + | 3642 | + |
2948 | + gss = ssh_gssapi_client_mechanisms(gss_host, | 3643 | + gss = ssh_gssapi_client_mechanisms(gss_host, |
2949 | + options.gss_client_identity); | 3644 | + options.gss_client_identity, options.gss_kex_algorithms); |
2950 | + if (gss) { | 3645 | + if (gss) { |
2951 | + debug("Offering GSSAPI proposal: %s", gss); | 3646 | + debug("Offering GSSAPI proposal: %s", gss); |
2952 | + xasprintf(&myproposal[PROPOSAL_KEX_ALGS], | 3647 | + xasprintf(&myproposal[PROPOSAL_KEX_ALGS], |
2953 | + "%s,%s", gss, orig); | 3648 | + "%s,%s", gss, orig); |
2954 | + | 3649 | + |
2955 | + /* If we've got GSSAPI algorithms, then we also | 3650 | + /* If we've got GSSAPI algorithms, then we also support the |
2956 | + * support the 'null' hostkey, as a last resort */ | 3651 | + * 'null' hostkey, as a last resort */ |
2957 | + orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]; | 3652 | + orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]; |
2958 | + xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], | 3653 | + xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], |
2959 | + "%s,null", orig); | 3654 | + "%s,null", orig); |
@@ -2962,38 +3657,43 @@ index 1675f3935..8c872a4fb 100644 | |||
2962 | +#endif | 3657 | +#endif |
2963 | + | 3658 | + |
2964 | if (options.rekey_limit || options.rekey_interval) | 3659 | if (options.rekey_limit || options.rekey_interval) |
2965 | packet_set_rekey_limits(options.rekey_limit, | 3660 | ssh_packet_set_rekey_limits(ssh, options.rekey_limit, |
2966 | options.rekey_interval); | 3661 | options.rekey_interval); |
2967 | @@ -215,15 +249,41 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) | 3662 | @@ -211,16 +243,46 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port) |
3663 | # ifdef OPENSSL_HAS_ECC | ||
3664 | ssh->kex->kex[KEX_ECDH_SHA2] = kex_gen_client; | ||
2968 | # endif | 3665 | # endif |
2969 | #endif | 3666 | +# ifdef GSSAPI |
2970 | kex->kex[KEX_C25519_SHA256] = kexc25519_client; | ||
2971 | +#ifdef GSSAPI | ||
2972 | + if (options.gss_keyex) { | 3667 | + if (options.gss_keyex) { |
2973 | + kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client; | 3668 | + ssh->kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client; |
2974 | + kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_client; | 3669 | + ssh->kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_client; |
2975 | + kex->kex[KEX_GSS_GEX_SHA1] = kexgss_client; | 3670 | + ssh->kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_client; |
3671 | + ssh->kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_client; | ||
3672 | + ssh->kex->kex[KEX_GSS_GEX_SHA1] = kexgssgex_client; | ||
3673 | + ssh->kex->kex[KEX_GSS_NISTP256_SHA256] = kexgss_client; | ||
3674 | + ssh->kex->kex[KEX_GSS_C25519_SHA256] = kexgss_client; | ||
2976 | + } | 3675 | + } |
2977 | +#endif | 3676 | +# endif |
2978 | kex->client_version_string=client_version_string; | 3677 | #endif |
2979 | kex->server_version_string=server_version_string; | 3678 | ssh->kex->kex[KEX_C25519_SHA256] = kex_gen_client; |
2980 | kex->verify_host_key=&verify_host_key_callback; | 3679 | ssh->kex->kex[KEX_KEM_SNTRUP4591761X25519_SHA512] = kex_gen_client; |
3680 | ssh->kex->verify_host_key=&verify_host_key_callback; | ||
2981 | 3681 | ||
2982 | +#ifdef GSSAPI | 3682 | +#if defined(GSSAPI) && defined(WITH_OPENSSL) |
2983 | + if (options.gss_keyex) { | 3683 | + if (options.gss_keyex) { |
2984 | + kex->gss_deleg_creds = options.gss_deleg_creds; | 3684 | + ssh->kex->gss_deleg_creds = options.gss_deleg_creds; |
2985 | + kex->gss_trust_dns = options.gss_trust_dns; | 3685 | + ssh->kex->gss_trust_dns = options.gss_trust_dns; |
2986 | + kex->gss_client = options.gss_client_identity; | 3686 | + ssh->kex->gss_client = options.gss_client_identity; |
2987 | + kex->gss_host = gss_host; | 3687 | + ssh->kex->gss_host = gss_host; |
2988 | + } | 3688 | + } |
2989 | +#endif | 3689 | +#endif |
2990 | + | 3690 | + |
2991 | ssh_dispatch_run_fatal(active_state, DISPATCH_BLOCK, &kex->done); | 3691 | ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &ssh->kex->done); |
2992 | 3692 | ||
2993 | /* remove ext-info from the KEX proposals for rekeying */ | 3693 | /* remove ext-info from the KEX proposals for rekeying */ |
2994 | myproposal[PROPOSAL_KEX_ALGS] = | 3694 | myproposal[PROPOSAL_KEX_ALGS] = |
2995 | compat_kex_proposal(options.kex_algorithms); | 3695 | compat_kex_proposal(options.kex_algorithms); |
2996 | +#ifdef GSSAPI | 3696 | +#if defined(GSSAPI) && defined(WITH_OPENSSL) |
2997 | + /* repair myproposal after it was crumpled by the */ | 3697 | + /* repair myproposal after it was crumpled by the */ |
2998 | + /* ext-info removal above */ | 3698 | + /* ext-info removal above */ |
2999 | + if (gss) { | 3699 | + if (gss) { |
@@ -3003,82 +3703,83 @@ index 1675f3935..8c872a4fb 100644 | |||
3003 | + free(gss); | 3703 | + free(gss); |
3004 | + } | 3704 | + } |
3005 | +#endif | 3705 | +#endif |
3006 | if ((r = kex_prop2buf(kex->my, myproposal)) != 0) | 3706 | if ((r = kex_prop2buf(ssh->kex->my, myproposal)) != 0) |
3007 | fatal("kex_prop2buf: %s", ssh_err(r)); | 3707 | fatal("kex_prop2buf: %s", ssh_err(r)); |
3008 | 3708 | ||
3009 | @@ -314,6 +374,7 @@ int input_gssapi_token(int type, u_int32_t, struct ssh *); | 3709 | @@ -317,6 +379,7 @@ static int input_gssapi_response(int type, u_int32_t, struct ssh *); |
3010 | int input_gssapi_hash(int type, u_int32_t, struct ssh *); | 3710 | static int input_gssapi_token(int type, u_int32_t, struct ssh *); |
3011 | int input_gssapi_error(int, u_int32_t, struct ssh *); | 3711 | static int input_gssapi_error(int, u_int32_t, struct ssh *); |
3012 | int input_gssapi_errtok(int, u_int32_t, struct ssh *); | 3712 | static int input_gssapi_errtok(int, u_int32_t, struct ssh *); |
3013 | +int userauth_gsskeyex(Authctxt *authctxt); | 3713 | +static int userauth_gsskeyex(struct ssh *); |
3014 | #endif | 3714 | #endif |
3015 | 3715 | ||
3016 | void userauth(Authctxt *, char *); | 3716 | void userauth(struct ssh *, char *); |
3017 | @@ -330,6 +391,11 @@ static char *authmethods_get(void); | 3717 | @@ -333,6 +396,11 @@ static char *authmethods_get(void); |
3018 | 3718 | ||
3019 | Authmethod authmethods[] = { | 3719 | Authmethod authmethods[] = { |
3020 | #ifdef GSSAPI | 3720 | #ifdef GSSAPI |
3021 | + {"gssapi-keyex", | 3721 | + {"gssapi-keyex", |
3022 | + userauth_gsskeyex, | 3722 | + userauth_gsskeyex, |
3023 | + NULL, | 3723 | + NULL, |
3024 | + &options.gss_authentication, | 3724 | + &options.gss_keyex, |
3025 | + NULL}, | 3725 | + NULL}, |
3026 | {"gssapi-with-mic", | 3726 | {"gssapi-with-mic", |
3027 | userauth_gssapi, | 3727 | userauth_gssapi, |
3028 | NULL, | 3728 | userauth_gssapi_cleanup, |
3029 | @@ -686,25 +752,40 @@ userauth_gssapi(Authctxt *authctxt) | 3729 | @@ -698,12 +766,25 @@ userauth_gssapi(struct ssh *ssh) |
3030 | static u_int mech = 0; | ||
3031 | OM_uint32 min; | 3730 | OM_uint32 min; |
3032 | int r, ok = 0; | 3731 | int r, ok = 0; |
3732 | gss_OID mech = NULL; | ||
3033 | + char *gss_host; | 3733 | + char *gss_host; |
3034 | + | 3734 | + |
3035 | + if (options.gss_server_identity) | 3735 | + if (options.gss_server_identity) |
3036 | + gss_host = xstrdup(options.gss_server_identity); | 3736 | + gss_host = xstrdup(options.gss_server_identity); |
3037 | + else if (options.gss_trust_dns) | 3737 | + else if (options.gss_trust_dns) |
3038 | + gss_host = remote_hostname(active_state); | 3738 | + gss_host = remote_hostname(ssh); |
3039 | + else | 3739 | + else |
3040 | + gss_host = xstrdup(authctxt->host); | 3740 | + gss_host = xstrdup(authctxt->host); |
3041 | 3741 | ||
3042 | /* Try one GSSAPI method at a time, rather than sending them all at | 3742 | /* Try one GSSAPI method at a time, rather than sending them all at |
3043 | * once. */ | 3743 | * once. */ |
3044 | 3744 | ||
3045 | if (gss_supported == NULL) | 3745 | if (authctxt->gss_supported_mechs == NULL) |
3046 | - gss_indicate_mechs(&min, &gss_supported); | 3746 | - gss_indicate_mechs(&min, &authctxt->gss_supported_mechs); |
3047 | + if (GSS_ERROR(gss_indicate_mechs(&min, &gss_supported))) { | 3747 | + if (GSS_ERROR(gss_indicate_mechs(&min, |
3048 | + gss_supported = NULL; | 3748 | + &authctxt->gss_supported_mechs))) { |
3749 | + authctxt->gss_supported_mechs = NULL; | ||
3049 | + free(gss_host); | 3750 | + free(gss_host); |
3050 | + return 0; | 3751 | + return 0; |
3051 | + } | 3752 | + } |
3052 | 3753 | ||
3053 | /* Check to see if the mechanism is usable before we offer it */ | 3754 | /* Check to see whether the mechanism is usable before we offer it */ |
3054 | while (mech < gss_supported->count && !ok) { | 3755 | while (authctxt->mech_tried < authctxt->gss_supported_mechs->count && |
3756 | @@ -712,13 +793,15 @@ userauth_gssapi(struct ssh *ssh) | ||
3757 | elements[authctxt->mech_tried]; | ||
3055 | /* My DER encoding requires length<128 */ | 3758 | /* My DER encoding requires length<128 */ |
3056 | if (gss_supported->elements[mech].length < 128 && | 3759 | if (mech->length < 128 && ssh_gssapi_check_mechanism(&gssctxt, |
3057 | ssh_gssapi_check_mechanism(&gssctxt, | 3760 | - mech, authctxt->host)) { |
3058 | - &gss_supported->elements[mech], authctxt->host)) { | 3761 | + mech, gss_host, options.gss_client_identity)) { |
3059 | + &gss_supported->elements[mech], gss_host, | ||
3060 | + options.gss_client_identity)) { | ||
3061 | ok = 1; /* Mechanism works */ | 3762 | ok = 1; /* Mechanism works */ |
3062 | } else { | 3763 | } else { |
3063 | mech++; | 3764 | authctxt->mech_tried++; |
3064 | } | 3765 | } |
3065 | } | 3766 | } |
3066 | 3767 | ||
3067 | + free(gss_host); | 3768 | + free(gss_host); |
3068 | + | 3769 | + |
3069 | if (!ok) | 3770 | if (!ok || mech == NULL) |
3070 | return 0; | 3771 | return 0; |
3071 | 3772 | ||
3072 | @@ -935,6 +1016,54 @@ input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh) | 3773 | @@ -958,6 +1041,55 @@ input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh) |
3073 | free(lang); | 3774 | free(lang); |
3074 | return r; | 3775 | return r; |
3075 | } | 3776 | } |
3076 | + | 3777 | + |
3077 | +int | 3778 | +int |
3078 | +userauth_gsskeyex(Authctxt *authctxt) | 3779 | +userauth_gsskeyex(struct ssh *ssh) |
3079 | +{ | 3780 | +{ |
3080 | + struct ssh *ssh = active_state; /* XXX */ | 3781 | + struct sshbuf *b = NULL; |
3081 | + struct sshbuf *b; | 3782 | + Authctxt *authctxt = ssh->authctxt; |
3082 | + gss_buffer_desc gssbuf; | 3783 | + gss_buffer_desc gssbuf; |
3083 | + gss_buffer_desc mic = GSS_C_EMPTY_BUFFER; | 3784 | + gss_buffer_desc mic = GSS_C_EMPTY_BUFFER; |
3084 | + OM_uint32 ms; | 3785 | + OM_uint32 ms; |
@@ -3089,12 +3790,13 @@ index 1675f3935..8c872a4fb 100644 | |||
3089 | + return (0); | 3790 | + return (0); |
3090 | + | 3791 | + |
3091 | + if (gss_kex_context == NULL) { | 3792 | + if (gss_kex_context == NULL) { |
3092 | + debug("No valid Key exchange context"); | 3793 | + debug("No valid Key exchange context"); |
3093 | + return (0); | 3794 | + return (0); |
3094 | + } | 3795 | + } |
3095 | + | 3796 | + |
3096 | + if ((b = sshbuf_new()) == NULL) | 3797 | + if ((b = sshbuf_new()) == NULL) |
3097 | + fatal("%s: sshbuf_new failed", __func__); | 3798 | + fatal("%s: sshbuf_new failed", __func__); |
3799 | + | ||
3098 | + ssh_gssapi_buildmic(b, authctxt->server_user, authctxt->service, | 3800 | + ssh_gssapi_buildmic(b, authctxt->server_user, authctxt->service, |
3099 | + "gssapi-keyex"); | 3801 | + "gssapi-keyex"); |
3100 | + | 3802 | + |
@@ -3123,9 +3825,9 @@ index 1675f3935..8c872a4fb 100644 | |||
3123 | + | 3825 | + |
3124 | #endif /* GSSAPI */ | 3826 | #endif /* GSSAPI */ |
3125 | 3827 | ||
3126 | int | 3828 | static int |
3127 | diff --git a/sshd.c b/sshd.c | 3829 | diff --git a/sshd.c b/sshd.c |
3128 | index ba26287ba..539a000fd 100644 | 3830 | index cbd3bce91..98680721b 100644 |
3129 | --- a/sshd.c | 3831 | --- a/sshd.c |
3130 | +++ b/sshd.c | 3832 | +++ b/sshd.c |
3131 | @@ -123,6 +123,10 @@ | 3833 | @@ -123,6 +123,10 @@ |
@@ -3139,21 +3841,28 @@ index ba26287ba..539a000fd 100644 | |||
3139 | /* Re-exec fds */ | 3841 | /* Re-exec fds */ |
3140 | #define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1) | 3842 | #define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1) |
3141 | #define REEXEC_STARTUP_PIPE_FD (STDERR_FILENO + 2) | 3843 | #define REEXEC_STARTUP_PIPE_FD (STDERR_FILENO + 2) |
3142 | @@ -1810,10 +1814,13 @@ main(int ac, char **av) | 3844 | @@ -796,8 +800,8 @@ notify_hostkeys(struct ssh *ssh) |
3845 | } | ||
3846 | debug3("%s: sent %u hostkeys", __func__, nkeys); | ||
3847 | if (nkeys == 0) | ||
3848 | - fatal("%s: no hostkeys", __func__); | ||
3849 | - if ((r = sshpkt_send(ssh)) != 0) | ||
3850 | + debug3("%s: no hostkeys", __func__); | ||
3851 | + else if ((r = sshpkt_send(ssh)) != 0) | ||
3852 | sshpkt_fatal(ssh, r, "%s: send", __func__); | ||
3853 | sshbuf_free(buf); | ||
3854 | } | ||
3855 | @@ -1769,7 +1773,8 @@ main(int ac, char **av) | ||
3143 | free(fp); | 3856 | free(fp); |
3144 | } | 3857 | } |
3145 | accumulate_host_timing_secret(cfg, NULL); | 3858 | accumulate_host_timing_secret(cfg, NULL); |
3146 | +#ifndef GSSAPI | 3859 | - if (!sensitive_data.have_ssh2_key) { |
3147 | + /* The GSSAPI key exchange can run without a host key */ | 3860 | + /* The GSSAPI key exchange can run without a host key */ |
3148 | if (!sensitive_data.have_ssh2_key) { | 3861 | + if (!sensitive_data.have_ssh2_key && !options.gss_keyex) { |
3149 | logit("sshd: no hostkeys available -- exiting."); | 3862 | logit("sshd: no hostkeys available -- exiting."); |
3150 | exit(1); | 3863 | exit(1); |
3151 | } | 3864 | } |
3152 | +#endif | 3865 | @@ -2064,6 +2069,60 @@ main(int ac, char **av) |
3153 | |||
3154 | /* | ||
3155 | * Load certificates. They are stored in an array at identical | ||
3156 | @@ -2104,6 +2111,60 @@ main(int ac, char **av) | ||
3157 | rdomain == NULL ? "" : "\""); | 3866 | rdomain == NULL ? "" : "\""); |
3158 | free(laddr); | 3867 | free(laddr); |
3159 | 3868 | ||
@@ -3214,18 +3923,18 @@ index ba26287ba..539a000fd 100644 | |||
3214 | /* | 3923 | /* |
3215 | * We don't want to listen forever unless the other side | 3924 | * We don't want to listen forever unless the other side |
3216 | * successfully authenticates itself. So we set up an alarm which is | 3925 | * successfully authenticates itself. So we set up an alarm which is |
3217 | @@ -2287,6 +2348,48 @@ do_ssh2_kex(void) | 3926 | @@ -2260,6 +2319,48 @@ do_ssh2_kex(struct ssh *ssh) |
3218 | myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( | 3927 | myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( |
3219 | list_hostkey_types()); | 3928 | list_hostkey_types()); |
3220 | 3929 | ||
3221 | +#ifdef GSSAPI | 3930 | +#if defined(GSSAPI) && defined(WITH_OPENSSL) |
3222 | + { | 3931 | + { |
3223 | + char *orig; | 3932 | + char *orig; |
3224 | + char *gss = NULL; | 3933 | + char *gss = NULL; |
3225 | + char *newstr = NULL; | 3934 | + char *newstr = NULL; |
3226 | + orig = myproposal[PROPOSAL_KEX_ALGS]; | 3935 | + orig = myproposal[PROPOSAL_KEX_ALGS]; |
3227 | + | 3936 | + |
3228 | + /* | 3937 | + /* |
3229 | + * If we don't have a host key, then there's no point advertising | 3938 | + * If we don't have a host key, then there's no point advertising |
3230 | + * the other key exchange algorithms | 3939 | + * the other key exchange algorithms |
3231 | + */ | 3940 | + */ |
@@ -3245,10 +3954,10 @@ index ba26287ba..539a000fd 100644 | |||
3245 | + else if (orig) | 3954 | + else if (orig) |
3246 | + newstr = orig; | 3955 | + newstr = orig; |
3247 | + | 3956 | + |
3248 | + /* | 3957 | + /* |
3249 | + * If we've got GSSAPI mechanisms, then we've got the 'null' host | 3958 | + * If we've got GSSAPI mechanisms, then we've got the 'null' host |
3250 | + * key alg, but we can't tell people about it unless its the only | 3959 | + * key alg, but we can't tell people about it unless its the only |
3251 | + * host key algorithm we support | 3960 | + * host key algorithm we support |
3252 | + */ | 3961 | + */ |
3253 | + if (gss && (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])) == 0) | 3962 | + if (gss && (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])) == 0) |
3254 | + myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = "null"; | 3963 | + myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = "null"; |
@@ -3261,22 +3970,28 @@ index ba26287ba..539a000fd 100644 | |||
3261 | +#endif | 3970 | +#endif |
3262 | + | 3971 | + |
3263 | /* start key exchange */ | 3972 | /* start key exchange */ |
3264 | if ((r = kex_setup(active_state, myproposal)) != 0) | 3973 | if ((r = kex_setup(ssh, myproposal)) != 0) |
3265 | fatal("kex_setup: %s", ssh_err(r)); | 3974 | fatal("kex_setup: %s", ssh_err(r)); |
3266 | @@ -2304,6 +2407,13 @@ do_ssh2_kex(void) | 3975 | @@ -2275,7 +2376,18 @@ do_ssh2_kex(struct ssh *ssh) |
3976 | # ifdef OPENSSL_HAS_ECC | ||
3977 | kex->kex[KEX_ECDH_SHA2] = kex_gen_server; | ||
3267 | # endif | 3978 | # endif |
3268 | #endif | 3979 | -#endif |
3269 | kex->kex[KEX_C25519_SHA256] = kexc25519_server; | 3980 | +# ifdef GSSAPI |
3270 | +#ifdef GSSAPI | ||
3271 | + if (options.gss_keyex) { | 3981 | + if (options.gss_keyex) { |
3272 | + kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; | 3982 | + kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; |
3273 | + kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server; | 3983 | + kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server; |
3274 | + kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server; | 3984 | + kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_server; |
3985 | + kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_server; | ||
3986 | + kex->kex[KEX_GSS_GEX_SHA1] = kexgssgex_server; | ||
3987 | + kex->kex[KEX_GSS_NISTP256_SHA256] = kexgss_server; | ||
3988 | + kex->kex[KEX_GSS_C25519_SHA256] = kexgss_server; | ||
3275 | + } | 3989 | + } |
3276 | +#endif | 3990 | +# endif |
3277 | kex->server = 1; | 3991 | +#endif /* WITH_OPENSSL */ |
3278 | kex->client_version_string=client_version_string; | 3992 | kex->kex[KEX_C25519_SHA256] = kex_gen_server; |
3279 | kex->server_version_string=server_version_string; | 3993 | kex->kex[KEX_KEM_SNTRUP4591761X25519_SHA512] = kex_gen_server; |
3994 | kex->load_host_public_key=&get_hostkey_public_by_type; | ||
3280 | diff --git a/sshd_config b/sshd_config | 3995 | diff --git a/sshd_config b/sshd_config |
3281 | index 19b7c91a1..2c48105f8 100644 | 3996 | index 19b7c91a1..2c48105f8 100644 |
3282 | --- a/sshd_config | 3997 | --- a/sshd_config |
@@ -3291,35 +4006,55 @@ index 19b7c91a1..2c48105f8 100644 | |||
3291 | # Set this to 'yes' to enable PAM authentication, account processing, | 4006 | # Set this to 'yes' to enable PAM authentication, account processing, |
3292 | # and session processing. If this is enabled, PAM authentication will | 4007 | # and session processing. If this is enabled, PAM authentication will |
3293 | diff --git a/sshd_config.5 b/sshd_config.5 | 4008 | diff --git a/sshd_config.5 b/sshd_config.5 |
3294 | index c6484370b..985eef5a2 100644 | 4009 | index b224f2929..2baa6622b 100644 |
3295 | --- a/sshd_config.5 | 4010 | --- a/sshd_config.5 |
3296 | +++ b/sshd_config.5 | 4011 | +++ b/sshd_config.5 |
3297 | @@ -648,6 +648,11 @@ The default is | 4012 | @@ -653,6 +653,11 @@ Specifies whether to automatically destroy the user's credentials cache |
3298 | Specifies whether user authentication based on GSSAPI is allowed. | 4013 | on logout. |
3299 | The default is | 4014 | The default is |
3300 | .Cm no . | 4015 | .Cm yes . |
3301 | +.It Cm GSSAPIKeyExchange | 4016 | +.It Cm GSSAPIKeyExchange |
3302 | +Specifies whether key exchange based on GSSAPI is allowed. GSSAPI key exchange | 4017 | +Specifies whether key exchange based on GSSAPI is allowed. GSSAPI key exchange |
3303 | +doesn't rely on ssh keys to verify host identity. | 4018 | +doesn't rely on ssh keys to verify host identity. |
3304 | +The default is | 4019 | +The default is |
3305 | +.Cm no . | 4020 | +.Cm no . |
3306 | .It Cm GSSAPICleanupCredentials | 4021 | .It Cm GSSAPIStrictAcceptorCheck |
3307 | Specifies whether to automatically destroy the user's credentials cache | 4022 | Determines whether to be strict about the identity of the GSSAPI acceptor |
3308 | on logout. | 4023 | a client authenticates against. |
3309 | @@ -667,6 +672,11 @@ machine's default store. | 4024 | @@ -667,6 +672,31 @@ machine's default store. |
3310 | This facility is provided to assist with operation on multi homed machines. | 4025 | This facility is provided to assist with operation on multi homed machines. |
3311 | The default is | 4026 | The default is |
3312 | .Cm yes . | 4027 | .Cm yes . |
3313 | +.It Cm GSSAPIStoreCredentialsOnRekey | 4028 | +.It Cm GSSAPIStoreCredentialsOnRekey |
3314 | +Controls whether the user's GSSAPI credentials should be updated following a | 4029 | +Controls whether the user's GSSAPI credentials should be updated following a |
3315 | +successful connection rekeying. This option can be used to accepted renewed | 4030 | +successful connection rekeying. This option can be used to accepted renewed |
3316 | +or updated credentials from a compatible client. The default is | 4031 | +or updated credentials from a compatible client. The default is |
3317 | +.Cm no . | 4032 | +.Dq no . |
4033 | +.Pp | ||
4034 | +For this to work | ||
4035 | +.Cm GSSAPIKeyExchange | ||
4036 | +needs to be enabled in the server and also used by the client. | ||
4037 | +.It Cm GSSAPIKexAlgorithms | ||
4038 | +The list of key exchange algorithms that are accepted by GSSAPI | ||
4039 | +key exchange. Possible values are | ||
4040 | +.Bd -literal -offset 3n | ||
4041 | +gss-gex-sha1-, | ||
4042 | +gss-group1-sha1-, | ||
4043 | +gss-group14-sha1-, | ||
4044 | +gss-group14-sha256-, | ||
4045 | +gss-group16-sha512-, | ||
4046 | +gss-nistp256-sha256-, | ||
4047 | +gss-curve25519-sha256- | ||
4048 | +.Ed | ||
4049 | +.Pp | ||
4050 | +The default is | ||
4051 | +.Dq gss-gex-sha1-,gss-group14-sha1- . | ||
4052 | +This option only applies to protocol version 2 connections using GSSAPI. | ||
3318 | .It Cm HostbasedAcceptedKeyTypes | 4053 | .It Cm HostbasedAcceptedKeyTypes |
3319 | Specifies the key types that will be accepted for hostbased authentication | 4054 | Specifies the key types that will be accepted for hostbased authentication |
3320 | as a list of comma-separated patterns. | 4055 | as a list of comma-separated patterns. |
3321 | diff --git a/sshkey.c b/sshkey.c | 4056 | diff --git a/sshkey.c b/sshkey.c |
3322 | index 6555c5ef8..a85c185fc 100644 | 4057 | index ad1957762..789cd61ef 100644 |
3323 | --- a/sshkey.c | 4058 | --- a/sshkey.c |
3324 | +++ b/sshkey.c | 4059 | +++ b/sshkey.c |
3325 | @@ -135,6 +135,7 @@ static const struct keytype keytypes[] = { | 4060 | @@ -135,6 +135,7 @@ static const struct keytype keytypes[] = { |
@@ -3340,10 +4075,10 @@ index 6555c5ef8..a85c185fc 100644 | |||
3340 | if (!include_sigonly && kt->sigonly) | 4075 | if (!include_sigonly && kt->sigonly) |
3341 | continue; | 4076 | continue; |
3342 | diff --git a/sshkey.h b/sshkey.h | 4077 | diff --git a/sshkey.h b/sshkey.h |
3343 | index f6a007fdf..f54deb0c0 100644 | 4078 | index a91e60436..c11106c93 100644 |
3344 | --- a/sshkey.h | 4079 | --- a/sshkey.h |
3345 | +++ b/sshkey.h | 4080 | +++ b/sshkey.h |
3346 | @@ -64,6 +64,7 @@ enum sshkey_types { | 4081 | @@ -65,6 +65,7 @@ enum sshkey_types { |
3347 | KEY_ED25519_CERT, | 4082 | KEY_ED25519_CERT, |
3348 | KEY_XMSS, | 4083 | KEY_XMSS, |
3349 | KEY_XMSS_CERT, | 4084 | KEY_XMSS_CERT, |
diff --git a/debian/patches/have-progressmeter-force-update-at-beginning-and-end-transfer.patch b/debian/patches/have-progressmeter-force-update-at-beginning-and-end-transfer.patch deleted file mode 100644 index 767dbf2b5..000000000 --- a/debian/patches/have-progressmeter-force-update-at-beginning-and-end-transfer.patch +++ /dev/null | |||
@@ -1,120 +0,0 @@ | |||
1 | From 2a8f710447442e9a03e71c022859112ec2d77d17 Mon Sep 17 00:00:00 2001 | ||
2 | From: "dtucker@openbsd.org" <dtucker@openbsd.org> | ||
3 | Date: Thu, 24 Jan 2019 16:52:17 +0000 | ||
4 | Subject: upstream: Have progressmeter force an update at the beginning and | ||
5 | |||
6 | end of each transfer. Fixes the problem recently introduces where very quick | ||
7 | transfers do not display the progressmeter at all. Spotted by naddy@ | ||
8 | |||
9 | OpenBSD-Commit-ID: 68dc46c259e8fdd4f5db3ec2a130f8e4590a7a9a | ||
10 | |||
11 | Origin: upstream, https://anongit.mindrot.org/openssh.git/commit/?id=bdc6c63c80b55bcbaa66b5fde31c1cb1d09a41eb | ||
12 | Last-Update: 2019-02-08 | ||
13 | |||
14 | Patch-Name: have-progressmeter-force-update-at-beginning-and-end-transfer.patch | ||
15 | --- | ||
16 | progressmeter.c | 13 +++++-------- | ||
17 | progressmeter.h | 4 ++-- | ||
18 | scp.c | 2 +- | ||
19 | sftp-client.c | 2 +- | ||
20 | 4 files changed, 9 insertions(+), 12 deletions(-) | ||
21 | |||
22 | diff --git a/progressmeter.c b/progressmeter.c | ||
23 | index add462dde..e385c1254 100644 | ||
24 | --- a/progressmeter.c | ||
25 | +++ b/progressmeter.c | ||
26 | @@ -1,4 +1,4 @@ | ||
27 | -/* $OpenBSD: progressmeter.c,v 1.46 2019/01/23 08:01:46 dtucker Exp $ */ | ||
28 | +/* $OpenBSD: progressmeter.c,v 1.47 2019/01/24 16:52:17 dtucker Exp $ */ | ||
29 | /* | ||
30 | * Copyright (c) 2003 Nils Nordman. All rights reserved. | ||
31 | * | ||
32 | @@ -59,9 +59,6 @@ static void format_rate(char *, int, off_t); | ||
33 | static void sig_winch(int); | ||
34 | static void setscreensize(void); | ||
35 | |||
36 | -/* updates the progressmeter to reflect the current state of the transfer */ | ||
37 | -void refresh_progress_meter(void); | ||
38 | - | ||
39 | /* signal handler for updating the progress meter */ | ||
40 | static void sig_alarm(int); | ||
41 | |||
42 | @@ -120,7 +117,7 @@ format_size(char *buf, int size, off_t bytes) | ||
43 | } | ||
44 | |||
45 | void | ||
46 | -refresh_progress_meter(void) | ||
47 | +refresh_progress_meter(int force_update) | ||
48 | { | ||
49 | char buf[MAX_WINSIZE + 1]; | ||
50 | off_t transferred; | ||
51 | @@ -131,7 +128,7 @@ refresh_progress_meter(void) | ||
52 | int hours, minutes, seconds; | ||
53 | int file_len; | ||
54 | |||
55 | - if ((!alarm_fired && !win_resized) || !can_output()) | ||
56 | + if ((!force_update && !alarm_fired && !win_resized) || !can_output()) | ||
57 | return; | ||
58 | alarm_fired = 0; | ||
59 | |||
60 | @@ -254,7 +251,7 @@ start_progress_meter(const char *f, off_t filesize, off_t *ctr) | ||
61 | bytes_per_second = 0; | ||
62 | |||
63 | setscreensize(); | ||
64 | - refresh_progress_meter(); | ||
65 | + refresh_progress_meter(1); | ||
66 | |||
67 | signal(SIGALRM, sig_alarm); | ||
68 | signal(SIGWINCH, sig_winch); | ||
69 | @@ -271,7 +268,7 @@ stop_progress_meter(void) | ||
70 | |||
71 | /* Ensure we complete the progress */ | ||
72 | if (cur_pos != end_pos) | ||
73 | - refresh_progress_meter(); | ||
74 | + refresh_progress_meter(1); | ||
75 | |||
76 | atomicio(vwrite, STDOUT_FILENO, "\n", 1); | ||
77 | } | ||
78 | diff --git a/progressmeter.h b/progressmeter.h | ||
79 | index 8f6678060..1703ea75b 100644 | ||
80 | --- a/progressmeter.h | ||
81 | +++ b/progressmeter.h | ||
82 | @@ -1,4 +1,4 @@ | ||
83 | -/* $OpenBSD: progressmeter.h,v 1.4 2019/01/23 08:01:46 dtucker Exp $ */ | ||
84 | +/* $OpenBSD: progressmeter.h,v 1.5 2019/01/24 16:52:17 dtucker Exp $ */ | ||
85 | /* | ||
86 | * Copyright (c) 2002 Nils Nordman. All rights reserved. | ||
87 | * | ||
88 | @@ -24,5 +24,5 @@ | ||
89 | */ | ||
90 | |||
91 | void start_progress_meter(const char *, off_t, off_t *); | ||
92 | -void refresh_progress_meter(void); | ||
93 | +void refresh_progress_meter(int); | ||
94 | void stop_progress_meter(void); | ||
95 | diff --git a/scp.c b/scp.c | ||
96 | index 80308573c..1971c80cd 100644 | ||
97 | --- a/scp.c | ||
98 | +++ b/scp.c | ||
99 | @@ -593,7 +593,7 @@ scpio(void *_cnt, size_t s) | ||
100 | off_t *cnt = (off_t *)_cnt; | ||
101 | |||
102 | *cnt += s; | ||
103 | - refresh_progress_meter(); | ||
104 | + refresh_progress_meter(0); | ||
105 | if (limit_kbps > 0) | ||
106 | bandwidth_limit(&bwlimit, s); | ||
107 | return 0; | ||
108 | diff --git a/sftp-client.c b/sftp-client.c | ||
109 | index 2bc698f86..cf2887a40 100644 | ||
110 | --- a/sftp-client.c | ||
111 | +++ b/sftp-client.c | ||
112 | @@ -101,7 +101,7 @@ sftpio(void *_bwlimit, size_t amount) | ||
113 | { | ||
114 | struct bwlimit *bwlimit = (struct bwlimit *)_bwlimit; | ||
115 | |||
116 | - refresh_progress_meter(); | ||
117 | + refresh_progress_meter(0); | ||
118 | if (bwlimit != NULL) | ||
119 | bandwidth_limit(bwlimit, amount); | ||
120 | return 0; | ||
diff --git a/debian/patches/keepalive-extensions.patch b/debian/patches/keepalive-extensions.patch index 4207302c3..fbfe6a1fb 100644 --- a/debian/patches/keepalive-extensions.patch +++ b/debian/patches/keepalive-extensions.patch | |||
@@ -1,4 +1,4 @@ | |||
1 | From 7ba31c6ff505278fb9f33b695605ca3a093caba2 Mon Sep 17 00:00:00 2001 | 1 | From 4d8dd12bab7bbc954815d7953a0c86ce1687bd34 Mon Sep 17 00:00:00 2001 |
2 | From: Richard Kettlewell <rjk@greenend.org.uk> | 2 | From: Richard Kettlewell <rjk@greenend.org.uk> |
3 | Date: Sun, 9 Feb 2014 16:09:52 +0000 | 3 | Date: Sun, 9 Feb 2014 16:09:52 +0000 |
4 | Subject: Various keepalive extensions | 4 | Subject: Various keepalive extensions |
@@ -26,10 +26,10 @@ Patch-Name: keepalive-extensions.patch | |||
26 | 3 files changed, 34 insertions(+), 4 deletions(-) | 26 | 3 files changed, 34 insertions(+), 4 deletions(-) |
27 | 27 | ||
28 | diff --git a/readconf.c b/readconf.c | 28 | diff --git a/readconf.c b/readconf.c |
29 | index 5e655e924..052d4b1ac 100644 | 29 | index 29f3bd98d..3d0b6ff90 100644 |
30 | --- a/readconf.c | 30 | --- a/readconf.c |
31 | +++ b/readconf.c | 31 | +++ b/readconf.c |
32 | @@ -175,6 +175,7 @@ typedef enum { | 32 | @@ -177,6 +177,7 @@ typedef enum { |
33 | oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys, | 33 | oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys, |
34 | oFingerprintHash, oUpdateHostkeys, oHostbasedKeyTypes, | 34 | oFingerprintHash, oUpdateHostkeys, oHostbasedKeyTypes, |
35 | oPubkeyAcceptedKeyTypes, oCASignatureAlgorithms, oProxyJump, | 35 | oPubkeyAcceptedKeyTypes, oCASignatureAlgorithms, oProxyJump, |
@@ -37,7 +37,7 @@ index 5e655e924..052d4b1ac 100644 | |||
37 | oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported | 37 | oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported |
38 | } OpCodes; | 38 | } OpCodes; |
39 | 39 | ||
40 | @@ -322,6 +323,8 @@ static struct { | 40 | @@ -326,6 +327,8 @@ static struct { |
41 | { "pubkeyacceptedkeytypes", oPubkeyAcceptedKeyTypes }, | 41 | { "pubkeyacceptedkeytypes", oPubkeyAcceptedKeyTypes }, |
42 | { "ignoreunknown", oIgnoreUnknown }, | 42 | { "ignoreunknown", oIgnoreUnknown }, |
43 | { "proxyjump", oProxyJump }, | 43 | { "proxyjump", oProxyJump }, |
@@ -46,7 +46,7 @@ index 5e655e924..052d4b1ac 100644 | |||
46 | 46 | ||
47 | { NULL, oBadOption } | 47 | { NULL, oBadOption } |
48 | }; | 48 | }; |
49 | @@ -1415,6 +1418,8 @@ parse_keytypes: | 49 | @@ -1440,6 +1443,8 @@ parse_keytypes: |
50 | goto parse_flag; | 50 | goto parse_flag; |
51 | 51 | ||
52 | case oServerAliveInterval: | 52 | case oServerAliveInterval: |
@@ -55,7 +55,7 @@ index 5e655e924..052d4b1ac 100644 | |||
55 | intptr = &options->server_alive_interval; | 55 | intptr = &options->server_alive_interval; |
56 | goto parse_time; | 56 | goto parse_time; |
57 | 57 | ||
58 | @@ -2101,8 +2106,13 @@ fill_default_options(Options * options) | 58 | @@ -2133,8 +2138,13 @@ fill_default_options(Options * options) |
59 | options->rekey_interval = 0; | 59 | options->rekey_interval = 0; |
60 | if (options->verify_host_key_dns == -1) | 60 | if (options->verify_host_key_dns == -1) |
61 | options->verify_host_key_dns = 0; | 61 | options->verify_host_key_dns = 0; |
@@ -72,10 +72,10 @@ index 5e655e924..052d4b1ac 100644 | |||
72 | options->server_alive_count_max = 3; | 72 | options->server_alive_count_max = 3; |
73 | if (options->control_master == -1) | 73 | if (options->control_master == -1) |
74 | diff --git a/ssh_config.5 b/ssh_config.5 | 74 | diff --git a/ssh_config.5 b/ssh_config.5 |
75 | index 16c79368a..54e143c93 100644 | 75 | index c3c8b274a..250c92d04 100644 |
76 | --- a/ssh_config.5 | 76 | --- a/ssh_config.5 |
77 | +++ b/ssh_config.5 | 77 | +++ b/ssh_config.5 |
78 | @@ -247,8 +247,12 @@ Valid arguments are | 78 | @@ -265,8 +265,12 @@ Valid arguments are |
79 | If set to | 79 | If set to |
80 | .Cm yes , | 80 | .Cm yes , |
81 | passphrase/password querying will be disabled. | 81 | passphrase/password querying will be disabled. |
@@ -89,7 +89,7 @@ index 16c79368a..54e143c93 100644 | |||
89 | The argument must be | 89 | The argument must be |
90 | .Cm yes | 90 | .Cm yes |
91 | or | 91 | or |
92 | @@ -1485,7 +1489,14 @@ from the server, | 92 | @@ -1535,7 +1539,14 @@ from the server, |
93 | will send a message through the encrypted | 93 | will send a message through the encrypted |
94 | channel to request a response from the server. | 94 | channel to request a response from the server. |
95 | The default | 95 | The default |
@@ -105,7 +105,7 @@ index 16c79368a..54e143c93 100644 | |||
105 | .It Cm SetEnv | 105 | .It Cm SetEnv |
106 | Directly specify one or more environment variables and their contents to | 106 | Directly specify one or more environment variables and their contents to |
107 | be sent to the server. | 107 | be sent to the server. |
108 | @@ -1565,6 +1576,12 @@ Specifies whether the system should send TCP keepalive messages to the | 108 | @@ -1615,6 +1626,12 @@ Specifies whether the system should send TCP keepalive messages to the |
109 | other side. | 109 | other side. |
110 | If they are sent, death of the connection or crash of one | 110 | If they are sent, death of the connection or crash of one |
111 | of the machines will be properly noticed. | 111 | of the machines will be properly noticed. |
@@ -119,10 +119,10 @@ index 16c79368a..54e143c93 100644 | |||
119 | connections will die if the route is down temporarily, and some people | 119 | connections will die if the route is down temporarily, and some people |
120 | find it annoying. | 120 | find it annoying. |
121 | diff --git a/sshd_config.5 b/sshd_config.5 | 121 | diff --git a/sshd_config.5 b/sshd_config.5 |
122 | index 985eef5a2..e7e55dd71 100644 | 122 | index 2baa6622b..2ef671d1b 100644 |
123 | --- a/sshd_config.5 | 123 | --- a/sshd_config.5 |
124 | +++ b/sshd_config.5 | 124 | +++ b/sshd_config.5 |
125 | @@ -1577,6 +1577,9 @@ This avoids infinitely hanging sessions. | 125 | @@ -1597,6 +1597,9 @@ This avoids infinitely hanging sessions. |
126 | .Pp | 126 | .Pp |
127 | To disable TCP keepalive messages, the value should be set to | 127 | To disable TCP keepalive messages, the value should be set to |
128 | .Cm no . | 128 | .Cm no . |
diff --git a/debian/patches/mention-ssh-keygen-on-keychange.patch b/debian/patches/mention-ssh-keygen-on-keychange.patch index 75ed46db7..21e8d7947 100644 --- a/debian/patches/mention-ssh-keygen-on-keychange.patch +++ b/debian/patches/mention-ssh-keygen-on-keychange.patch | |||
@@ -1,4 +1,4 @@ | |||
1 | From bb8bb2621914ad600202e38d5b9b4f4544b191e5 Mon Sep 17 00:00:00 2001 | 1 | From 15b7cc25dea4efdef7fdd129d0e3d1a091afd67b Mon Sep 17 00:00:00 2001 |
2 | From: Scott Moser <smoser@ubuntu.com> | 2 | From: Scott Moser <smoser@ubuntu.com> |
3 | Date: Sun, 9 Feb 2014 16:10:03 +0000 | 3 | Date: Sun, 9 Feb 2014 16:10:03 +0000 |
4 | Subject: Mention ssh-keygen in ssh fingerprint changed warning | 4 | Subject: Mention ssh-keygen in ssh fingerprint changed warning |
@@ -14,10 +14,10 @@ Patch-Name: mention-ssh-keygen-on-keychange.patch | |||
14 | 1 file changed, 8 insertions(+), 1 deletion(-) | 14 | 1 file changed, 8 insertions(+), 1 deletion(-) |
15 | 15 | ||
16 | diff --git a/sshconnect.c b/sshconnect.c | 16 | diff --git a/sshconnect.c b/sshconnect.c |
17 | index 700ea6c3c..158e8146f 100644 | 17 | index 103d84e38..0b6f6af4b 100644 |
18 | --- a/sshconnect.c | 18 | --- a/sshconnect.c |
19 | +++ b/sshconnect.c | 19 | +++ b/sshconnect.c |
20 | @@ -1121,9 +1121,13 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, | 20 | @@ -986,9 +986,13 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, |
21 | error("%s. This could either mean that", key_msg); | 21 | error("%s. This could either mean that", key_msg); |
22 | error("DNS SPOOFING is happening or the IP address for the host"); | 22 | error("DNS SPOOFING is happening or the IP address for the host"); |
23 | error("and its host key have changed at the same time."); | 23 | error("and its host key have changed at the same time."); |
@@ -32,7 +32,7 @@ index 700ea6c3c..158e8146f 100644 | |||
32 | } | 32 | } |
33 | /* The host key has changed. */ | 33 | /* The host key has changed. */ |
34 | warn_changed_key(host_key); | 34 | warn_changed_key(host_key); |
35 | @@ -1132,6 +1136,9 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, | 35 | @@ -997,6 +1001,9 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, |
36 | error("Offending %s key in %s:%lu", | 36 | error("Offending %s key in %s:%lu", |
37 | sshkey_type(host_found->key), | 37 | sshkey_type(host_found->key), |
38 | host_found->file, host_found->line); | 38 | host_found->file, host_found->line); |
diff --git a/debian/patches/no-openssl-version-status.patch b/debian/patches/no-openssl-version-status.patch index 3b2e05e58..dcc672726 100644 --- a/debian/patches/no-openssl-version-status.patch +++ b/debian/patches/no-openssl-version-status.patch | |||
@@ -1,4 +1,4 @@ | |||
1 | From 690051b3aa4ff72af57e4a82d640858357eef820 Mon Sep 17 00:00:00 2001 | 1 | From 1f61e987ccec2a2af15044196c1a6730959ead98 Mon Sep 17 00:00:00 2001 |
2 | From: Kurt Roeckx <kurt@roeckx.be> | 2 | From: Kurt Roeckx <kurt@roeckx.be> |
3 | Date: Sun, 9 Feb 2014 16:10:14 +0000 | 3 | Date: Sun, 9 Feb 2014 16:10:14 +0000 |
4 | Subject: Don't check the status field of the OpenSSL version | 4 | Subject: Don't check the status field of the OpenSSL version |
@@ -23,7 +23,7 @@ Patch-Name: no-openssl-version-status.patch | |||
23 | 2 files changed, 4 insertions(+), 3 deletions(-) | 23 | 2 files changed, 4 insertions(+), 3 deletions(-) |
24 | 24 | ||
25 | diff --git a/openbsd-compat/openssl-compat.c b/openbsd-compat/openssl-compat.c | 25 | diff --git a/openbsd-compat/openssl-compat.c b/openbsd-compat/openssl-compat.c |
26 | index 8b4a36274..ea0b0c9fb 100644 | 26 | index a37ca61bf..c1749210d 100644 |
27 | --- a/openbsd-compat/openssl-compat.c | 27 | --- a/openbsd-compat/openssl-compat.c |
28 | +++ b/openbsd-compat/openssl-compat.c | 28 | +++ b/openbsd-compat/openssl-compat.c |
29 | @@ -34,7 +34,7 @@ | 29 | @@ -34,7 +34,7 @@ |
diff --git a/debian/patches/openbsd-docs.patch b/debian/patches/openbsd-docs.patch index cdb905b2e..e46967c72 100644 --- a/debian/patches/openbsd-docs.patch +++ b/debian/patches/openbsd-docs.patch | |||
@@ -1,4 +1,4 @@ | |||
1 | From 96c85e746d4f94c7d2748a200e5817ad8a987918 Mon Sep 17 00:00:00 2001 | 1 | From 47beec5c944ea9add7d267110fc9dcf15e7b8932 Mon Sep 17 00:00:00 2001 |
2 | From: Colin Watson <cjwatson@debian.org> | 2 | From: Colin Watson <cjwatson@debian.org> |
3 | Date: Sun, 9 Feb 2014 16:10:09 +0000 | 3 | Date: Sun, 9 Feb 2014 16:10:09 +0000 |
4 | Subject: Adjust various OpenBSD-specific references in manual pages | 4 | Subject: Adjust various OpenBSD-specific references in manual pages |
@@ -44,10 +44,10 @@ index ef0de0850..149846c8c 100644 | |||
44 | .Sh SEE ALSO | 44 | .Sh SEE ALSO |
45 | .Xr ssh-keygen 1 , | 45 | .Xr ssh-keygen 1 , |
46 | diff --git a/ssh-keygen.1 b/ssh-keygen.1 | 46 | diff --git a/ssh-keygen.1 b/ssh-keygen.1 |
47 | index bfa2eb5f3..da6b5ed76 100644 | 47 | index 124456577..9b877b860 100644 |
48 | --- a/ssh-keygen.1 | 48 | --- a/ssh-keygen.1 |
49 | +++ b/ssh-keygen.1 | 49 | +++ b/ssh-keygen.1 |
50 | @@ -176,9 +176,7 @@ key in | 50 | @@ -178,9 +178,7 @@ key in |
51 | .Pa ~/.ssh/id_ed25519 | 51 | .Pa ~/.ssh/id_ed25519 |
52 | or | 52 | or |
53 | .Pa ~/.ssh/id_rsa . | 53 | .Pa ~/.ssh/id_rsa . |
@@ -58,7 +58,7 @@ index bfa2eb5f3..da6b5ed76 100644 | |||
58 | .Pp | 58 | .Pp |
59 | Normally this program generates the key and asks for a file in which | 59 | Normally this program generates the key and asks for a file in which |
60 | to store the private key. | 60 | to store the private key. |
61 | @@ -229,9 +227,7 @@ If | 61 | @@ -243,9 +241,7 @@ If |
62 | .Fl f | 62 | .Fl f |
63 | has also been specified, its argument is used as a prefix to the | 63 | has also been specified, its argument is used as a prefix to the |
64 | default path for the resulting host key files. | 64 | default path for the resulting host key files. |
@@ -69,7 +69,7 @@ index bfa2eb5f3..da6b5ed76 100644 | |||
69 | .It Fl a Ar rounds | 69 | .It Fl a Ar rounds |
70 | When saving a private key this option specifies the number of KDF | 70 | When saving a private key this option specifies the number of KDF |
71 | (key derivation function) rounds used. | 71 | (key derivation function) rounds used. |
72 | @@ -677,7 +673,7 @@ option. | 72 | @@ -703,7 +699,7 @@ option. |
73 | Valid generator values are 2, 3, and 5. | 73 | Valid generator values are 2, 3, and 5. |
74 | .Pp | 74 | .Pp |
75 | Screened DH groups may be installed in | 75 | Screened DH groups may be installed in |
@@ -78,7 +78,7 @@ index bfa2eb5f3..da6b5ed76 100644 | |||
78 | It is important that this file contains moduli of a range of bit lengths and | 78 | It is important that this file contains moduli of a range of bit lengths and |
79 | that both ends of a connection share common moduli. | 79 | that both ends of a connection share common moduli. |
80 | .Sh CERTIFICATES | 80 | .Sh CERTIFICATES |
81 | @@ -877,7 +873,7 @@ on all machines | 81 | @@ -903,7 +899,7 @@ on all machines |
82 | where the user wishes to log in using public key authentication. | 82 | where the user wishes to log in using public key authentication. |
83 | There is no need to keep the contents of this file secret. | 83 | There is no need to keep the contents of this file secret. |
84 | .Pp | 84 | .Pp |
@@ -88,10 +88,10 @@ index bfa2eb5f3..da6b5ed76 100644 | |||
88 | The file format is described in | 88 | The file format is described in |
89 | .Xr moduli 5 . | 89 | .Xr moduli 5 . |
90 | diff --git a/ssh.1 b/ssh.1 | 90 | diff --git a/ssh.1 b/ssh.1 |
91 | index 81f29af43..5dfad6daa 100644 | 91 | index 64ead5f57..e4aeae7b4 100644 |
92 | --- a/ssh.1 | 92 | --- a/ssh.1 |
93 | +++ b/ssh.1 | 93 | +++ b/ssh.1 |
94 | @@ -860,6 +860,10 @@ implements public key authentication protocol automatically, | 94 | @@ -873,6 +873,10 @@ implements public key authentication protocol automatically, |
95 | using one of the DSA, ECDSA, Ed25519 or RSA algorithms. | 95 | using one of the DSA, ECDSA, Ed25519 or RSA algorithms. |
96 | The HISTORY section of | 96 | The HISTORY section of |
97 | .Xr ssl 8 | 97 | .Xr ssl 8 |
@@ -133,7 +133,7 @@ index 57a7fd66b..4abc01d66 100644 | |||
133 | .Xr sshd_config 5 , | 133 | .Xr sshd_config 5 , |
134 | .Xr inetd 8 , | 134 | .Xr inetd 8 , |
135 | diff --git a/sshd_config.5 b/sshd_config.5 | 135 | diff --git a/sshd_config.5 b/sshd_config.5 |
136 | index 37e6be38f..23f71fd1d 100644 | 136 | index addea54a0..f995e4ab0 100644 |
137 | --- a/sshd_config.5 | 137 | --- a/sshd_config.5 |
138 | +++ b/sshd_config.5 | 138 | +++ b/sshd_config.5 |
139 | @@ -395,8 +395,7 @@ Certificates signed using other algorithms will not be accepted for | 139 | @@ -395,8 +395,7 @@ Certificates signed using other algorithms will not be accepted for |
diff --git a/debian/patches/package-versioning.patch b/debian/patches/package-versioning.patch index 809c78846..0d2be82dc 100644 --- a/debian/patches/package-versioning.patch +++ b/debian/patches/package-versioning.patch | |||
@@ -1,4 +1,4 @@ | |||
1 | From b258a00bedcf29200b394c671c6deb1e53157f32 Mon Sep 17 00:00:00 2001 | 1 | From 85e700a732e9a308eeee67f5a284e19fd6befbb8 Mon Sep 17 00:00:00 2001 |
2 | From: Matthew Vernon <matthew@debian.org> | 2 | From: Matthew Vernon <matthew@debian.org> |
3 | Date: Sun, 9 Feb 2014 16:10:05 +0000 | 3 | Date: Sun, 9 Feb 2014 16:10:05 +0000 |
4 | Subject: Include the Debian version in our identification | 4 | Subject: Include the Debian version in our identification |
@@ -9,47 +9,33 @@ generally just try attacks rather than bothering to scan for | |||
9 | vulnerable-looking version strings. (However, see debian-banner.patch.) | 9 | vulnerable-looking version strings. (However, see debian-banner.patch.) |
10 | 10 | ||
11 | Forwarded: not-needed | 11 | Forwarded: not-needed |
12 | Last-Update: 2017-10-04 | 12 | Last-Update: 2019-06-05 |
13 | 13 | ||
14 | Patch-Name: package-versioning.patch | 14 | Patch-Name: package-versioning.patch |
15 | --- | 15 | --- |
16 | sshconnect.c | 2 +- | 16 | kex.c | 2 +- |
17 | sshd.c | 2 +- | 17 | version.h | 7 ++++++- |
18 | version.h | 7 ++++++- | 18 | 2 files changed, 7 insertions(+), 2 deletions(-) |
19 | 3 files changed, 8 insertions(+), 3 deletions(-) | ||
20 | 19 | ||
21 | diff --git a/sshconnect.c b/sshconnect.c | 20 | diff --git a/kex.c b/kex.c |
22 | index 158e8146f..b9418e277 100644 | 21 | index a2a4794e8..be354206d 100644 |
23 | --- a/sshconnect.c | 22 | --- a/kex.c |
24 | +++ b/sshconnect.c | 23 | +++ b/kex.c |
25 | @@ -609,7 +609,7 @@ send_client_banner(int connection_out, int minor1) | 24 | @@ -1186,7 +1186,7 @@ kex_exchange_identification(struct ssh *ssh, int timeout_ms, |
26 | { | 25 | if (version_addendum != NULL && *version_addendum == '\0') |
27 | /* Send our own protocol version identification. */ | 26 | version_addendum = NULL; |
28 | xasprintf(&client_version_string, "SSH-%d.%d-%.100s\r\n", | 27 | if ((r = sshbuf_putf(our_version, "SSH-%d.%d-%.100s%s%s\r\n", |
29 | - PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION); | 28 | - PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION, |
30 | + PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_RELEASE); | 29 | + PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_RELEASE, |
31 | if (atomicio(vwrite, connection_out, client_version_string, | 30 | version_addendum == NULL ? "" : " ", |
32 | strlen(client_version_string)) != strlen(client_version_string)) | 31 | version_addendum == NULL ? "" : version_addendum)) != 0) { |
33 | fatal("write: %.100s", strerror(errno)); | 32 | error("%s: sshbuf_putf: %s", __func__, ssh_err(r)); |
34 | diff --git a/sshd.c b/sshd.c | ||
35 | index 2bc6679e5..9481272fc 100644 | ||
36 | --- a/sshd.c | ||
37 | +++ b/sshd.c | ||
38 | @@ -384,7 +384,7 @@ sshd_exchange_identification(struct ssh *ssh, int sock_in, int sock_out) | ||
39 | char remote_version[256]; /* Must be at least as big as buf. */ | ||
40 | |||
41 | xasprintf(&server_version_string, "SSH-%d.%d-%.100s%s%s\r\n", | ||
42 | - PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION, | ||
43 | + PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_RELEASE, | ||
44 | *options.version_addendum == '\0' ? "" : " ", | ||
45 | options.version_addendum); | ||
46 | |||
47 | diff --git a/version.h b/version.h | 33 | diff --git a/version.h b/version.h |
48 | index 422dfbc3a..5e1ce0426 100644 | 34 | index 806ead9a6..599c859e6 100644 |
49 | --- a/version.h | 35 | --- a/version.h |
50 | +++ b/version.h | 36 | +++ b/version.h |
51 | @@ -3,4 +3,9 @@ | 37 | @@ -3,4 +3,9 @@ |
52 | #define SSH_VERSION "OpenSSH_7.9" | 38 | #define SSH_VERSION "OpenSSH_8.0" |
53 | 39 | ||
54 | #define SSH_PORTABLE "p1" | 40 | #define SSH_PORTABLE "p1" |
55 | -#define SSH_RELEASE SSH_VERSION SSH_PORTABLE | 41 | -#define SSH_RELEASE SSH_VERSION SSH_PORTABLE |
diff --git a/debian/patches/request-rsa-sha2-cert-signatures.patch b/debian/patches/request-rsa-sha2-cert-signatures.patch deleted file mode 100644 index 2c876be31..000000000 --- a/debian/patches/request-rsa-sha2-cert-signatures.patch +++ /dev/null | |||
@@ -1,39 +0,0 @@ | |||
1 | From d94226d4fcefbc398c5583e12b5d07ca33884ba4 Mon Sep 17 00:00:00 2001 | ||
2 | From: "djm@openbsd.org" <djm@openbsd.org> | ||
3 | Date: Thu, 27 Dec 2018 23:02:11 +0000 | ||
4 | Subject: upstream: Request RSA-SHA2 signatures for | ||
5 | |||
6 | rsa-sha2-{256|512}-cert-v01@openssh.com cert algorithms; ok markus@ | ||
7 | |||
8 | OpenBSD-Commit-ID: afc6f7ca216ccd821656d1c911d2a3deed685033 | ||
9 | |||
10 | Origin: upstream, https://anongit.mindrot.org/openssh.git/commit/?id=f429c1b2ef631f2855e51a790cf71761d752bbca | ||
11 | Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=2944 | ||
12 | Bug-Debian: https://bugs.debian.org/923419 | ||
13 | Last-Update: 2019-02-28 | ||
14 | |||
15 | Patch-Name: request-rsa-sha2-cert-signatures.patch | ||
16 | --- | ||
17 | authfd.c | 8 +++++--- | ||
18 | 1 file changed, 5 insertions(+), 3 deletions(-) | ||
19 | |||
20 | diff --git a/authfd.c b/authfd.c | ||
21 | index ecdd869ab..62cbf8c19 100644 | ||
22 | --- a/authfd.c | ||
23 | +++ b/authfd.c | ||
24 | @@ -327,10 +327,12 @@ ssh_free_identitylist(struct ssh_identitylist *idl) | ||
25 | static u_int | ||
26 | agent_encode_alg(const struct sshkey *key, const char *alg) | ||
27 | { | ||
28 | - if (alg != NULL && key->type == KEY_RSA) { | ||
29 | - if (strcmp(alg, "rsa-sha2-256") == 0) | ||
30 | + if (alg != NULL && sshkey_type_plain(key->type) == KEY_RSA) { | ||
31 | + if (strcmp(alg, "rsa-sha2-256") == 0 || | ||
32 | + strcmp(alg, "rsa-sha2-256-cert-v01@openssh.com") == 0) | ||
33 | return SSH_AGENT_RSA_SHA2_256; | ||
34 | - else if (strcmp(alg, "rsa-sha2-512") == 0) | ||
35 | + if (strcmp(alg, "rsa-sha2-512") == 0 || | ||
36 | + strcmp(alg, "rsa-sha2-512-cert-v01@openssh.com") == 0) | ||
37 | return SSH_AGENT_RSA_SHA2_512; | ||
38 | } | ||
39 | return 0; | ||
diff --git a/debian/patches/restore-authorized_keys2.patch b/debian/patches/restore-authorized_keys2.patch index fcb1ac7e3..574923e1c 100644 --- a/debian/patches/restore-authorized_keys2.patch +++ b/debian/patches/restore-authorized_keys2.patch | |||
@@ -1,4 +1,4 @@ | |||
1 | From cebe4b82b280810172877a7f3d489c506c9a0691 Mon Sep 17 00:00:00 2001 | 1 | From 1af6147744892b18e2239c085abe87f5408cbaae Mon Sep 17 00:00:00 2001 |
2 | From: Colin Watson <cjwatson@debian.org> | 2 | From: Colin Watson <cjwatson@debian.org> |
3 | Date: Sun, 5 Mar 2017 02:02:11 +0000 | 3 | Date: Sun, 5 Mar 2017 02:02:11 +0000 |
4 | Subject: Restore reading authorized_keys2 by default | 4 | Subject: Restore reading authorized_keys2 by default |
diff --git a/debian/patches/restore-tcp-wrappers.patch b/debian/patches/restore-tcp-wrappers.patch index fdc6cf18a..0472ea7d0 100644 --- a/debian/patches/restore-tcp-wrappers.patch +++ b/debian/patches/restore-tcp-wrappers.patch | |||
@@ -1,4 +1,4 @@ | |||
1 | From 389e16d0109d8c49a761cd7c267438b05c9ab984 Mon Sep 17 00:00:00 2001 | 1 | From 0f9f44654708e4fde2f52c52f717d061b5e458fa Mon Sep 17 00:00:00 2001 |
2 | From: Colin Watson <cjwatson@debian.org> | 2 | From: Colin Watson <cjwatson@debian.org> |
3 | Date: Tue, 7 Oct 2014 13:22:41 +0100 | 3 | Date: Tue, 7 Oct 2014 13:22:41 +0100 |
4 | Subject: Restore TCP wrappers support | 4 | Subject: Restore TCP wrappers support |
@@ -18,7 +18,7 @@ but it at least probably doesn't involve dropping this feature shortly | |||
18 | before a freeze. | 18 | before a freeze. |
19 | 19 | ||
20 | Forwarded: not-needed | 20 | Forwarded: not-needed |
21 | Last-Update: 2018-08-24 | 21 | Last-Update: 2019-06-05 |
22 | 22 | ||
23 | Patch-Name: restore-tcp-wrappers.patch | 23 | Patch-Name: restore-tcp-wrappers.patch |
24 | --- | 24 | --- |
@@ -28,10 +28,10 @@ Patch-Name: restore-tcp-wrappers.patch | |||
28 | 3 files changed, 89 insertions(+) | 28 | 3 files changed, 89 insertions(+) |
29 | 29 | ||
30 | diff --git a/configure.ac b/configure.ac | 30 | diff --git a/configure.ac b/configure.ac |
31 | index 023e7cc55..917300b43 100644 | 31 | index 2869f7042..ce16e7758 100644 |
32 | --- a/configure.ac | 32 | --- a/configure.ac |
33 | +++ b/configure.ac | 33 | +++ b/configure.ac |
34 | @@ -1517,6 +1517,62 @@ else | 34 | @@ -1518,6 +1518,62 @@ else |
35 | AC_MSG_RESULT([no]) | 35 | AC_MSG_RESULT([no]) |
36 | fi | 36 | fi |
37 | 37 | ||
@@ -94,7 +94,7 @@ index 023e7cc55..917300b43 100644 | |||
94 | # Check whether user wants to use ldns | 94 | # Check whether user wants to use ldns |
95 | LDNS_MSG="no" | 95 | LDNS_MSG="no" |
96 | AC_ARG_WITH(ldns, | 96 | AC_ARG_WITH(ldns, |
97 | @@ -5329,6 +5385,7 @@ echo " PAM support: $PAM_MSG" | 97 | @@ -5269,6 +5325,7 @@ echo " PAM support: $PAM_MSG" |
98 | echo " OSF SIA support: $SIA_MSG" | 98 | echo " OSF SIA support: $SIA_MSG" |
99 | echo " KerberosV support: $KRB5_MSG" | 99 | echo " KerberosV support: $KRB5_MSG" |
100 | echo " SELinux support: $SELINUX_MSG" | 100 | echo " SELinux support: $SELINUX_MSG" |
@@ -128,7 +128,7 @@ index fb133c14b..57a7fd66b 100644 | |||
128 | .Xr moduli 5 , | 128 | .Xr moduli 5 , |
129 | .Xr sshd_config 5 , | 129 | .Xr sshd_config 5 , |
130 | diff --git a/sshd.c b/sshd.c | 130 | diff --git a/sshd.c b/sshd.c |
131 | index 539a000fd..673db87f6 100644 | 131 | index 98680721b..46870d3b5 100644 |
132 | --- a/sshd.c | 132 | --- a/sshd.c |
133 | +++ b/sshd.c | 133 | +++ b/sshd.c |
134 | @@ -127,6 +127,13 @@ | 134 | @@ -127,6 +127,13 @@ |
@@ -145,7 +145,7 @@ index 539a000fd..673db87f6 100644 | |||
145 | /* Re-exec fds */ | 145 | /* Re-exec fds */ |
146 | #define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1) | 146 | #define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1) |
147 | #define REEXEC_STARTUP_PIPE_FD (STDERR_FILENO + 2) | 147 | #define REEXEC_STARTUP_PIPE_FD (STDERR_FILENO + 2) |
148 | @@ -2099,6 +2106,24 @@ main(int ac, char **av) | 148 | @@ -2057,6 +2064,24 @@ main(int ac, char **av) |
149 | #ifdef SSH_AUDIT_EVENTS | 149 | #ifdef SSH_AUDIT_EVENTS |
150 | audit_connection_from(remote_ip, remote_port); | 150 | audit_connection_from(remote_ip, remote_port); |
151 | #endif | 151 | #endif |
@@ -153,7 +153,7 @@ index 539a000fd..673db87f6 100644 | |||
153 | + allow_severity = options.log_facility|LOG_INFO; | 153 | + allow_severity = options.log_facility|LOG_INFO; |
154 | + deny_severity = options.log_facility|LOG_WARNING; | 154 | + deny_severity = options.log_facility|LOG_WARNING; |
155 | + /* Check whether logins are denied from this host. */ | 155 | + /* Check whether logins are denied from this host. */ |
156 | + if (packet_connection_is_on_socket()) { | 156 | + if (ssh_packet_connection_is_on_socket(ssh)) { |
157 | + struct request_info req; | 157 | + struct request_info req; |
158 | + | 158 | + |
159 | + request_init(&req, RQ_DAEMON, __progname, RQ_FILE, sock_in, 0); | 159 | + request_init(&req, RQ_DAEMON, __progname, RQ_FILE, sock_in, 0); |
diff --git a/debian/patches/revert-ipqos-defaults.patch b/debian/patches/revert-ipqos-defaults.patch index a329b9be1..d0b02d792 100644 --- a/debian/patches/revert-ipqos-defaults.patch +++ b/debian/patches/revert-ipqos-defaults.patch | |||
@@ -1,4 +1,4 @@ | |||
1 | From 6b56cd57db9061296231f14d537f1ebaf25e8877 Mon Sep 17 00:00:00 2001 | 1 | From 7d50f9e5be88179325983a1f58c9d51bb58f025a Mon Sep 17 00:00:00 2001 |
2 | From: Colin Watson <cjwatson@debian.org> | 2 | From: Colin Watson <cjwatson@debian.org> |
3 | Date: Mon, 8 Apr 2019 10:46:29 +0100 | 3 | Date: Mon, 8 Apr 2019 10:46:29 +0100 |
4 | Subject: Revert "upstream: Update default IPQoS in ssh(1), sshd(8) to DSCP | 4 | Subject: Revert "upstream: Update default IPQoS in ssh(1), sshd(8) to DSCP |
@@ -24,10 +24,10 @@ Patch-Name: revert-ipqos-defaults.patch | |||
24 | 4 files changed, 8 insertions(+), 12 deletions(-) | 24 | 4 files changed, 8 insertions(+), 12 deletions(-) |
25 | 25 | ||
26 | diff --git a/readconf.c b/readconf.c | 26 | diff --git a/readconf.c b/readconf.c |
27 | index 661b8bf40..6d046f063 100644 | 27 | index f35bde6e6..2ba312441 100644 |
28 | --- a/readconf.c | 28 | --- a/readconf.c |
29 | +++ b/readconf.c | 29 | +++ b/readconf.c |
30 | @@ -2133,9 +2133,9 @@ fill_default_options(Options * options) | 30 | @@ -2165,9 +2165,9 @@ fill_default_options(Options * options) |
31 | if (options->visual_host_key == -1) | 31 | if (options->visual_host_key == -1) |
32 | options->visual_host_key = 0; | 32 | options->visual_host_key = 0; |
33 | if (options->ip_qos_interactive == -1) | 33 | if (options->ip_qos_interactive == -1) |
@@ -40,10 +40,10 @@ index 661b8bf40..6d046f063 100644 | |||
40 | options->request_tty = REQUEST_TTY_AUTO; | 40 | options->request_tty = REQUEST_TTY_AUTO; |
41 | if (options->proxy_use_fdpass == -1) | 41 | if (options->proxy_use_fdpass == -1) |
42 | diff --git a/servconf.c b/servconf.c | 42 | diff --git a/servconf.c b/servconf.c |
43 | index c5dd617ef..bf2669147 100644 | 43 | index 8d2bced52..365e6ff1e 100644 |
44 | --- a/servconf.c | 44 | --- a/servconf.c |
45 | +++ b/servconf.c | 45 | +++ b/servconf.c |
46 | @@ -403,9 +403,9 @@ fill_default_server_options(ServerOptions *options) | 46 | @@ -423,9 +423,9 @@ fill_default_server_options(ServerOptions *options) |
47 | if (options->permit_tun == -1) | 47 | if (options->permit_tun == -1) |
48 | options->permit_tun = SSH_TUNMODE_NO; | 48 | options->permit_tun = SSH_TUNMODE_NO; |
49 | if (options->ip_qos_interactive == -1) | 49 | if (options->ip_qos_interactive == -1) |
@@ -56,10 +56,10 @@ index c5dd617ef..bf2669147 100644 | |||
56 | options->version_addendum = xstrdup(""); | 56 | options->version_addendum = xstrdup(""); |
57 | if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1) | 57 | if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1) |
58 | diff --git a/ssh_config.5 b/ssh_config.5 | 58 | diff --git a/ssh_config.5 b/ssh_config.5 |
59 | index 1a8e24bd1..f6c1b3b33 100644 | 59 | index a27631ae9..a9f6d906f 100644 |
60 | --- a/ssh_config.5 | 60 | --- a/ssh_config.5 |
61 | +++ b/ssh_config.5 | 61 | +++ b/ssh_config.5 |
62 | @@ -1055,11 +1055,9 @@ If one argument is specified, it is used as the packet class unconditionally. | 62 | @@ -1098,11 +1098,9 @@ If one argument is specified, it is used as the packet class unconditionally. |
63 | If two values are specified, the first is automatically selected for | 63 | If two values are specified, the first is automatically selected for |
64 | interactive sessions and the second for non-interactive sessions. | 64 | interactive sessions and the second for non-interactive sessions. |
65 | The default is | 65 | The default is |
@@ -74,10 +74,10 @@ index 1a8e24bd1..f6c1b3b33 100644 | |||
74 | .It Cm KbdInteractiveAuthentication | 74 | .It Cm KbdInteractiveAuthentication |
75 | Specifies whether to use keyboard-interactive authentication. | 75 | Specifies whether to use keyboard-interactive authentication. |
76 | diff --git a/sshd_config.5 b/sshd_config.5 | 76 | diff --git a/sshd_config.5 b/sshd_config.5 |
77 | index ba50a30f1..03f813e72 100644 | 77 | index c0c4ebd66..e5380f5dc 100644 |
78 | --- a/sshd_config.5 | 78 | --- a/sshd_config.5 |
79 | +++ b/sshd_config.5 | 79 | +++ b/sshd_config.5 |
80 | @@ -866,11 +866,9 @@ If one argument is specified, it is used as the packet class unconditionally. | 80 | @@ -886,11 +886,9 @@ If one argument is specified, it is used as the packet class unconditionally. |
81 | If two values are specified, the first is automatically selected for | 81 | If two values are specified, the first is automatically selected for |
82 | interactive sessions and the second for non-interactive sessions. | 82 | interactive sessions and the second for non-interactive sessions. |
83 | The default is | 83 | The default is |
diff --git a/debian/patches/sanitize-scp-filenames-via-snmprintf.patch b/debian/patches/sanitize-scp-filenames-via-snmprintf.patch deleted file mode 100644 index e58b8b1bd..000000000 --- a/debian/patches/sanitize-scp-filenames-via-snmprintf.patch +++ /dev/null | |||
@@ -1,276 +0,0 @@ | |||
1 | From 11b88754cadcad0ba79b4ffcc127223248dccb54 Mon Sep 17 00:00:00 2001 | ||
2 | From: "dtucker@openbsd.org" <dtucker@openbsd.org> | ||
3 | Date: Wed, 23 Jan 2019 08:01:46 +0000 | ||
4 | Subject: upstream: Sanitize scp filenames via snmprintf. To do this we move | ||
5 | |||
6 | the progressmeter formatting outside of signal handler context and have the | ||
7 | atomicio callback called for EINTR too. bz#2434 with contributions from djm | ||
8 | and jjelen at redhat.com, ok djm@ | ||
9 | |||
10 | OpenBSD-Commit-ID: 1af61c1f70e4f3bd8ab140b9f1fa699481db57d8 | ||
11 | |||
12 | CVE-2019-6109 | ||
13 | |||
14 | Origin: backport, https://anongit.mindrot.org/openssh.git/commit/?id=8976f1c4b2721c26e878151f52bdf346dfe2d54c | ||
15 | Bug-Debian: https://bugs.debian.org/793412 | ||
16 | Last-Update: 2019-02-08 | ||
17 | |||
18 | Patch-Name: sanitize-scp-filenames-via-snmprintf.patch | ||
19 | --- | ||
20 | atomicio.c | 20 ++++++++++++++----- | ||
21 | progressmeter.c | 53 ++++++++++++++++++++++--------------------------- | ||
22 | progressmeter.h | 3 ++- | ||
23 | scp.c | 1 + | ||
24 | sftp-client.c | 16 ++++++++------- | ||
25 | 5 files changed, 51 insertions(+), 42 deletions(-) | ||
26 | |||
27 | diff --git a/atomicio.c b/atomicio.c | ||
28 | index f854a06f5..d91bd7621 100644 | ||
29 | --- a/atomicio.c | ||
30 | +++ b/atomicio.c | ||
31 | @@ -1,4 +1,4 @@ | ||
32 | -/* $OpenBSD: atomicio.c,v 1.28 2016/07/27 23:18:12 djm Exp $ */ | ||
33 | +/* $OpenBSD: atomicio.c,v 1.29 2019/01/23 08:01:46 dtucker Exp $ */ | ||
34 | /* | ||
35 | * Copyright (c) 2006 Damien Miller. All rights reserved. | ||
36 | * Copyright (c) 2005 Anil Madhavapeddy. All rights reserved. | ||
37 | @@ -65,9 +65,14 @@ atomicio6(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n, | ||
38 | res = (f) (fd, s + pos, n - pos); | ||
39 | switch (res) { | ||
40 | case -1: | ||
41 | - if (errno == EINTR) | ||
42 | + if (errno == EINTR) { | ||
43 | + /* possible SIGALARM, update callback */ | ||
44 | + if (cb != NULL && cb(cb_arg, 0) == -1) { | ||
45 | + errno = EINTR; | ||
46 | + return pos; | ||
47 | + } | ||
48 | continue; | ||
49 | - if (errno == EAGAIN || errno == EWOULDBLOCK) { | ||
50 | + } else if (errno == EAGAIN || errno == EWOULDBLOCK) { | ||
51 | #ifndef BROKEN_READ_COMPARISON | ||
52 | (void)poll(&pfd, 1, -1); | ||
53 | #endif | ||
54 | @@ -122,9 +127,14 @@ atomiciov6(ssize_t (*f) (int, const struct iovec *, int), int fd, | ||
55 | res = (f) (fd, iov, iovcnt); | ||
56 | switch (res) { | ||
57 | case -1: | ||
58 | - if (errno == EINTR) | ||
59 | + if (errno == EINTR) { | ||
60 | + /* possible SIGALARM, update callback */ | ||
61 | + if (cb != NULL && cb(cb_arg, 0) == -1) { | ||
62 | + errno = EINTR; | ||
63 | + return pos; | ||
64 | + } | ||
65 | continue; | ||
66 | - if (errno == EAGAIN || errno == EWOULDBLOCK) { | ||
67 | + } else if (errno == EAGAIN || errno == EWOULDBLOCK) { | ||
68 | #ifndef BROKEN_READV_COMPARISON | ||
69 | (void)poll(&pfd, 1, -1); | ||
70 | #endif | ||
71 | diff --git a/progressmeter.c b/progressmeter.c | ||
72 | index fe9bf52e4..add462dde 100644 | ||
73 | --- a/progressmeter.c | ||
74 | +++ b/progressmeter.c | ||
75 | @@ -1,4 +1,4 @@ | ||
76 | -/* $OpenBSD: progressmeter.c,v 1.45 2016/06/30 05:17:05 dtucker Exp $ */ | ||
77 | +/* $OpenBSD: progressmeter.c,v 1.46 2019/01/23 08:01:46 dtucker Exp $ */ | ||
78 | /* | ||
79 | * Copyright (c) 2003 Nils Nordman. All rights reserved. | ||
80 | * | ||
81 | @@ -31,6 +31,7 @@ | ||
82 | |||
83 | #include <errno.h> | ||
84 | #include <signal.h> | ||
85 | +#include <stdarg.h> | ||
86 | #include <stdio.h> | ||
87 | #include <string.h> | ||
88 | #include <time.h> | ||
89 | @@ -39,6 +40,7 @@ | ||
90 | #include "progressmeter.h" | ||
91 | #include "atomicio.h" | ||
92 | #include "misc.h" | ||
93 | +#include "utf8.h" | ||
94 | |||
95 | #define DEFAULT_WINSIZE 80 | ||
96 | #define MAX_WINSIZE 512 | ||
97 | @@ -61,7 +63,7 @@ static void setscreensize(void); | ||
98 | void refresh_progress_meter(void); | ||
99 | |||
100 | /* signal handler for updating the progress meter */ | ||
101 | -static void update_progress_meter(int); | ||
102 | +static void sig_alarm(int); | ||
103 | |||
104 | static double start; /* start progress */ | ||
105 | static double last_update; /* last progress update */ | ||
106 | @@ -74,6 +76,7 @@ static long stalled; /* how long we have been stalled */ | ||
107 | static int bytes_per_second; /* current speed in bytes per second */ | ||
108 | static int win_size; /* terminal window size */ | ||
109 | static volatile sig_atomic_t win_resized; /* for window resizing */ | ||
110 | +static volatile sig_atomic_t alarm_fired; | ||
111 | |||
112 | /* units for format_size */ | ||
113 | static const char unit[] = " KMGT"; | ||
114 | @@ -126,9 +129,17 @@ refresh_progress_meter(void) | ||
115 | off_t bytes_left; | ||
116 | int cur_speed; | ||
117 | int hours, minutes, seconds; | ||
118 | - int i, len; | ||
119 | int file_len; | ||
120 | |||
121 | + if ((!alarm_fired && !win_resized) || !can_output()) | ||
122 | + return; | ||
123 | + alarm_fired = 0; | ||
124 | + | ||
125 | + if (win_resized) { | ||
126 | + setscreensize(); | ||
127 | + win_resized = 0; | ||
128 | + } | ||
129 | + | ||
130 | transferred = *counter - (cur_pos ? cur_pos : start_pos); | ||
131 | cur_pos = *counter; | ||
132 | now = monotime_double(); | ||
133 | @@ -158,16 +169,11 @@ refresh_progress_meter(void) | ||
134 | |||
135 | /* filename */ | ||
136 | buf[0] = '\0'; | ||
137 | - file_len = win_size - 35; | ||
138 | + file_len = win_size - 36; | ||
139 | if (file_len > 0) { | ||
140 | - len = snprintf(buf, file_len + 1, "\r%s", file); | ||
141 | - if (len < 0) | ||
142 | - len = 0; | ||
143 | - if (len >= file_len + 1) | ||
144 | - len = file_len; | ||
145 | - for (i = len; i < file_len; i++) | ||
146 | - buf[i] = ' '; | ||
147 | - buf[file_len] = '\0'; | ||
148 | + buf[0] = '\r'; | ||
149 | + snmprintf(buf+1, sizeof(buf)-1 , &file_len, "%*s", | ||
150 | + file_len * -1, file); | ||
151 | } | ||
152 | |||
153 | /* percent of transfer done */ | ||
154 | @@ -228,22 +234,11 @@ refresh_progress_meter(void) | ||
155 | |||
156 | /*ARGSUSED*/ | ||
157 | static void | ||
158 | -update_progress_meter(int ignore) | ||
159 | +sig_alarm(int ignore) | ||
160 | { | ||
161 | - int save_errno; | ||
162 | - | ||
163 | - save_errno = errno; | ||
164 | - | ||
165 | - if (win_resized) { | ||
166 | - setscreensize(); | ||
167 | - win_resized = 0; | ||
168 | - } | ||
169 | - if (can_output()) | ||
170 | - refresh_progress_meter(); | ||
171 | - | ||
172 | - signal(SIGALRM, update_progress_meter); | ||
173 | + signal(SIGALRM, sig_alarm); | ||
174 | + alarm_fired = 1; | ||
175 | alarm(UPDATE_INTERVAL); | ||
176 | - errno = save_errno; | ||
177 | } | ||
178 | |||
179 | void | ||
180 | @@ -259,10 +254,9 @@ start_progress_meter(const char *f, off_t filesize, off_t *ctr) | ||
181 | bytes_per_second = 0; | ||
182 | |||
183 | setscreensize(); | ||
184 | - if (can_output()) | ||
185 | - refresh_progress_meter(); | ||
186 | + refresh_progress_meter(); | ||
187 | |||
188 | - signal(SIGALRM, update_progress_meter); | ||
189 | + signal(SIGALRM, sig_alarm); | ||
190 | signal(SIGWINCH, sig_winch); | ||
191 | alarm(UPDATE_INTERVAL); | ||
192 | } | ||
193 | @@ -286,6 +280,7 @@ stop_progress_meter(void) | ||
194 | static void | ||
195 | sig_winch(int sig) | ||
196 | { | ||
197 | + signal(SIGWINCH, sig_winch); | ||
198 | win_resized = 1; | ||
199 | } | ||
200 | |||
201 | diff --git a/progressmeter.h b/progressmeter.h | ||
202 | index bf179dca6..8f6678060 100644 | ||
203 | --- a/progressmeter.h | ||
204 | +++ b/progressmeter.h | ||
205 | @@ -1,4 +1,4 @@ | ||
206 | -/* $OpenBSD: progressmeter.h,v 1.3 2015/01/14 13:54:13 djm Exp $ */ | ||
207 | +/* $OpenBSD: progressmeter.h,v 1.4 2019/01/23 08:01:46 dtucker Exp $ */ | ||
208 | /* | ||
209 | * Copyright (c) 2002 Nils Nordman. All rights reserved. | ||
210 | * | ||
211 | @@ -24,4 +24,5 @@ | ||
212 | */ | ||
213 | |||
214 | void start_progress_meter(const char *, off_t, off_t *); | ||
215 | +void refresh_progress_meter(void); | ||
216 | void stop_progress_meter(void); | ||
217 | diff --git a/scp.c b/scp.c | ||
218 | index 7163d33dc..80308573c 100644 | ||
219 | --- a/scp.c | ||
220 | +++ b/scp.c | ||
221 | @@ -593,6 +593,7 @@ scpio(void *_cnt, size_t s) | ||
222 | off_t *cnt = (off_t *)_cnt; | ||
223 | |||
224 | *cnt += s; | ||
225 | + refresh_progress_meter(); | ||
226 | if (limit_kbps > 0) | ||
227 | bandwidth_limit(&bwlimit, s); | ||
228 | return 0; | ||
229 | diff --git a/sftp-client.c b/sftp-client.c | ||
230 | index 4986d6d8d..2bc698f86 100644 | ||
231 | --- a/sftp-client.c | ||
232 | +++ b/sftp-client.c | ||
233 | @@ -101,7 +101,9 @@ sftpio(void *_bwlimit, size_t amount) | ||
234 | { | ||
235 | struct bwlimit *bwlimit = (struct bwlimit *)_bwlimit; | ||
236 | |||
237 | - bandwidth_limit(bwlimit, amount); | ||
238 | + refresh_progress_meter(); | ||
239 | + if (bwlimit != NULL) | ||
240 | + bandwidth_limit(bwlimit, amount); | ||
241 | return 0; | ||
242 | } | ||
243 | |||
244 | @@ -121,8 +123,8 @@ send_msg(struct sftp_conn *conn, struct sshbuf *m) | ||
245 | iov[1].iov_base = (u_char *)sshbuf_ptr(m); | ||
246 | iov[1].iov_len = sshbuf_len(m); | ||
247 | |||
248 | - if (atomiciov6(writev, conn->fd_out, iov, 2, | ||
249 | - conn->limit_kbps > 0 ? sftpio : NULL, &conn->bwlimit_out) != | ||
250 | + if (atomiciov6(writev, conn->fd_out, iov, 2, sftpio, | ||
251 | + conn->limit_kbps > 0 ? &conn->bwlimit_out : NULL) != | ||
252 | sshbuf_len(m) + sizeof(mlen)) | ||
253 | fatal("Couldn't send packet: %s", strerror(errno)); | ||
254 | |||
255 | @@ -138,8 +140,8 @@ get_msg_extended(struct sftp_conn *conn, struct sshbuf *m, int initial) | ||
256 | |||
257 | if ((r = sshbuf_reserve(m, 4, &p)) != 0) | ||
258 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
259 | - if (atomicio6(read, conn->fd_in, p, 4, | ||
260 | - conn->limit_kbps > 0 ? sftpio : NULL, &conn->bwlimit_in) != 4) { | ||
261 | + if (atomicio6(read, conn->fd_in, p, 4, sftpio, | ||
262 | + conn->limit_kbps > 0 ? &conn->bwlimit_in : NULL) != 4) { | ||
263 | if (errno == EPIPE || errno == ECONNRESET) | ||
264 | fatal("Connection closed"); | ||
265 | else | ||
266 | @@ -157,8 +159,8 @@ get_msg_extended(struct sftp_conn *conn, struct sshbuf *m, int initial) | ||
267 | |||
268 | if ((r = sshbuf_reserve(m, msg_len, &p)) != 0) | ||
269 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
270 | - if (atomicio6(read, conn->fd_in, p, msg_len, | ||
271 | - conn->limit_kbps > 0 ? sftpio : NULL, &conn->bwlimit_in) | ||
272 | + if (atomicio6(read, conn->fd_in, p, msg_len, sftpio, | ||
273 | + conn->limit_kbps > 0 ? &conn->bwlimit_in : NULL) | ||
274 | != msg_len) { | ||
275 | if (errno == EPIPE) | ||
276 | fatal("Connection closed"); | ||
diff --git a/debian/patches/scp-disallow-dot-or-empty-filename.patch b/debian/patches/scp-disallow-dot-or-empty-filename.patch deleted file mode 100644 index 716f2ffa8..000000000 --- a/debian/patches/scp-disallow-dot-or-empty-filename.patch +++ /dev/null | |||
@@ -1,32 +0,0 @@ | |||
1 | From dee21e97428e69d30e2d15c71f3e7cc08bf8e4f8 Mon Sep 17 00:00:00 2001 | ||
2 | From: "djm@openbsd.org" <djm@openbsd.org> | ||
3 | Date: Fri, 16 Nov 2018 03:03:10 +0000 | ||
4 | Subject: upstream: disallow empty incoming filename or ones that refer to the | ||
5 | |||
6 | current directory; based on report/patch from Harry Sintonen | ||
7 | |||
8 | OpenBSD-Commit-ID: f27651b30eaee2df49540ab68d030865c04f6de9 | ||
9 | |||
10 | Origin: upstream, https://anongit.mindrot.org/openssh.git/commit/?id=6010c0303a422a9c5fa8860c061bf7105eb7f8b2 | ||
11 | Bug-Debian: https://bugs.debian.org/919101 | ||
12 | Last-Update: 2019-01-12 | ||
13 | |||
14 | Patch-Name: scp-disallow-dot-or-empty-filename.patch | ||
15 | --- | ||
16 | scp.c | 3 ++- | ||
17 | 1 file changed, 2 insertions(+), 1 deletion(-) | ||
18 | |||
19 | diff --git a/scp.c b/scp.c | ||
20 | index ed2864250..7163d33dc 100644 | ||
21 | --- a/scp.c | ||
22 | +++ b/scp.c | ||
23 | @@ -1114,7 +1114,8 @@ sink(int argc, char **argv) | ||
24 | SCREWUP("size out of range"); | ||
25 | size = (off_t)ull; | ||
26 | |||
27 | - if ((strchr(cp, '/') != NULL) || (strcmp(cp, "..") == 0)) { | ||
28 | + if (*cp == '\0' || strchr(cp, '/') != NULL || | ||
29 | + strcmp(cp, ".") == 0 || strcmp(cp, "..") == 0) { | ||
30 | run_err("error: unexpected filename: %s", cp); | ||
31 | exit(1); | ||
32 | } | ||
diff --git a/debian/patches/scp-handle-braces.patch b/debian/patches/scp-handle-braces.patch deleted file mode 100644 index 0cbdcfdc0..000000000 --- a/debian/patches/scp-handle-braces.patch +++ /dev/null | |||
@@ -1,353 +0,0 @@ | |||
1 | From 7a3fa37583d4abf128f7f4c6eb1e7ffc90115eab Mon Sep 17 00:00:00 2001 | ||
2 | From: "djm@openbsd.org" <djm@openbsd.org> | ||
3 | Date: Sun, 10 Feb 2019 11:15:52 +0000 | ||
4 | Subject: upstream: when checking that filenames sent by the server side | ||
5 | |||
6 | match what the client requested, be prepared to handle shell-style brace | ||
7 | alternations, e.g. "{foo,bar}". | ||
8 | |||
9 | "looks good to me" millert@ + in snaps for the last week courtesy | ||
10 | deraadt@ | ||
11 | |||
12 | OpenBSD-Commit-ID: 3b1ce7639b0b25b2248e3a30f561a548f6815f3e | ||
13 | |||
14 | Origin: upstream, https://anongit.mindrot.org/openssh.git/commit/?id=3d896c157c722bc47adca51a58dca859225b5874 | ||
15 | Bug-Debian: https://bugs.debian.org/923486 | ||
16 | Last-Update: 2019-03-01 | ||
17 | |||
18 | Patch-Name: scp-handle-braces.patch | ||
19 | --- | ||
20 | scp.c | 280 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--- | ||
21 | 1 file changed, 269 insertions(+), 11 deletions(-) | ||
22 | |||
23 | diff --git a/scp.c b/scp.c | ||
24 | index 035037bcc..3888baab0 100644 | ||
25 | --- a/scp.c | ||
26 | +++ b/scp.c | ||
27 | @@ -635,6 +635,253 @@ parse_scp_uri(const char *uri, char **userp, char **hostp, int *portp, | ||
28 | return r; | ||
29 | } | ||
30 | |||
31 | +/* Appends a string to an array; returns 0 on success, -1 on alloc failure */ | ||
32 | +static int | ||
33 | +append(char *cp, char ***ap, size_t *np) | ||
34 | +{ | ||
35 | + char **tmp; | ||
36 | + | ||
37 | + if ((tmp = reallocarray(*ap, *np + 1, sizeof(*tmp))) == NULL) | ||
38 | + return -1; | ||
39 | + tmp[(*np)] = cp; | ||
40 | + (*np)++; | ||
41 | + *ap = tmp; | ||
42 | + return 0; | ||
43 | +} | ||
44 | + | ||
45 | +/* | ||
46 | + * Finds the start and end of the first brace pair in the pattern. | ||
47 | + * returns 0 on success or -1 for invalid patterns. | ||
48 | + */ | ||
49 | +static int | ||
50 | +find_brace(const char *pattern, int *startp, int *endp) | ||
51 | +{ | ||
52 | + int i; | ||
53 | + int in_bracket, brace_level; | ||
54 | + | ||
55 | + *startp = *endp = -1; | ||
56 | + in_bracket = brace_level = 0; | ||
57 | + for (i = 0; i < INT_MAX && *endp < 0 && pattern[i] != '\0'; i++) { | ||
58 | + switch (pattern[i]) { | ||
59 | + case '\\': | ||
60 | + /* skip next character */ | ||
61 | + if (pattern[i + 1] != '\0') | ||
62 | + i++; | ||
63 | + break; | ||
64 | + case '[': | ||
65 | + in_bracket = 1; | ||
66 | + break; | ||
67 | + case ']': | ||
68 | + in_bracket = 0; | ||
69 | + break; | ||
70 | + case '{': | ||
71 | + if (in_bracket) | ||
72 | + break; | ||
73 | + if (pattern[i + 1] == '}') { | ||
74 | + /* Protect a single {}, for find(1), like csh */ | ||
75 | + i++; /* skip */ | ||
76 | + break; | ||
77 | + } | ||
78 | + if (*startp == -1) | ||
79 | + *startp = i; | ||
80 | + brace_level++; | ||
81 | + break; | ||
82 | + case '}': | ||
83 | + if (in_bracket) | ||
84 | + break; | ||
85 | + if (*startp < 0) { | ||
86 | + /* Unbalanced brace */ | ||
87 | + return -1; | ||
88 | + } | ||
89 | + if (--brace_level <= 0) | ||
90 | + *endp = i; | ||
91 | + break; | ||
92 | + } | ||
93 | + } | ||
94 | + /* unbalanced brackets/braces */ | ||
95 | + if (*endp < 0 && (*startp >= 0 || in_bracket)) | ||
96 | + return -1; | ||
97 | + return 0; | ||
98 | +} | ||
99 | + | ||
100 | +/* | ||
101 | + * Assembles and records a successfully-expanded pattern, returns -1 on | ||
102 | + * alloc failure. | ||
103 | + */ | ||
104 | +static int | ||
105 | +emit_expansion(const char *pattern, int brace_start, int brace_end, | ||
106 | + int sel_start, int sel_end, char ***patternsp, size_t *npatternsp) | ||
107 | +{ | ||
108 | + char *cp; | ||
109 | + int o = 0, tail_len = strlen(pattern + brace_end + 1); | ||
110 | + | ||
111 | + if ((cp = malloc(brace_start + (sel_end - sel_start) + | ||
112 | + tail_len + 1)) == NULL) | ||
113 | + return -1; | ||
114 | + | ||
115 | + /* Pattern before initial brace */ | ||
116 | + if (brace_start > 0) { | ||
117 | + memcpy(cp, pattern, brace_start); | ||
118 | + o = brace_start; | ||
119 | + } | ||
120 | + /* Current braced selection */ | ||
121 | + if (sel_end - sel_start > 0) { | ||
122 | + memcpy(cp + o, pattern + sel_start, | ||
123 | + sel_end - sel_start); | ||
124 | + o += sel_end - sel_start; | ||
125 | + } | ||
126 | + /* Remainder of pattern after closing brace */ | ||
127 | + if (tail_len > 0) { | ||
128 | + memcpy(cp + o, pattern + brace_end + 1, tail_len); | ||
129 | + o += tail_len; | ||
130 | + } | ||
131 | + cp[o] = '\0'; | ||
132 | + if (append(cp, patternsp, npatternsp) != 0) { | ||
133 | + free(cp); | ||
134 | + return -1; | ||
135 | + } | ||
136 | + return 0; | ||
137 | +} | ||
138 | + | ||
139 | +/* | ||
140 | + * Expand the first encountered brace in pattern, appending the expanded | ||
141 | + * patterns it yielded to the *patternsp array. | ||
142 | + * | ||
143 | + * Returns 0 on success or -1 on allocation failure. | ||
144 | + * | ||
145 | + * Signals whether expansion was performed via *expanded and whether | ||
146 | + * pattern was invalid via *invalid. | ||
147 | + */ | ||
148 | +static int | ||
149 | +brace_expand_one(const char *pattern, char ***patternsp, size_t *npatternsp, | ||
150 | + int *expanded, int *invalid) | ||
151 | +{ | ||
152 | + int i; | ||
153 | + int in_bracket, brace_start, brace_end, brace_level; | ||
154 | + int sel_start, sel_end; | ||
155 | + | ||
156 | + *invalid = *expanded = 0; | ||
157 | + | ||
158 | + if (find_brace(pattern, &brace_start, &brace_end) != 0) { | ||
159 | + *invalid = 1; | ||
160 | + return 0; | ||
161 | + } else if (brace_start == -1) | ||
162 | + return 0; | ||
163 | + | ||
164 | + in_bracket = brace_level = 0; | ||
165 | + for (i = sel_start = brace_start + 1; i < brace_end; i++) { | ||
166 | + switch (pattern[i]) { | ||
167 | + case '{': | ||
168 | + if (in_bracket) | ||
169 | + break; | ||
170 | + brace_level++; | ||
171 | + break; | ||
172 | + case '}': | ||
173 | + if (in_bracket) | ||
174 | + break; | ||
175 | + brace_level--; | ||
176 | + break; | ||
177 | + case '[': | ||
178 | + in_bracket = 1; | ||
179 | + break; | ||
180 | + case ']': | ||
181 | + in_bracket = 0; | ||
182 | + break; | ||
183 | + case '\\': | ||
184 | + if (i < brace_end - 1) | ||
185 | + i++; /* skip */ | ||
186 | + break; | ||
187 | + } | ||
188 | + if (pattern[i] == ',' || i == brace_end - 1) { | ||
189 | + if (in_bracket || brace_level > 0) | ||
190 | + continue; | ||
191 | + /* End of a selection, emit an expanded pattern */ | ||
192 | + | ||
193 | + /* Adjust end index for last selection */ | ||
194 | + sel_end = (i == brace_end - 1) ? brace_end : i; | ||
195 | + if (emit_expansion(pattern, brace_start, brace_end, | ||
196 | + sel_start, sel_end, patternsp, npatternsp) != 0) | ||
197 | + return -1; | ||
198 | + /* move on to the next selection */ | ||
199 | + sel_start = i + 1; | ||
200 | + continue; | ||
201 | + } | ||
202 | + } | ||
203 | + if (in_bracket || brace_level > 0) { | ||
204 | + *invalid = 1; | ||
205 | + return 0; | ||
206 | + } | ||
207 | + /* success */ | ||
208 | + *expanded = 1; | ||
209 | + return 0; | ||
210 | +} | ||
211 | + | ||
212 | +/* Expand braces from pattern. Returns 0 on success, -1 on failure */ | ||
213 | +static int | ||
214 | +brace_expand(const char *pattern, char ***patternsp, size_t *npatternsp) | ||
215 | +{ | ||
216 | + char *cp, *cp2, **active = NULL, **done = NULL; | ||
217 | + size_t i, nactive = 0, ndone = 0; | ||
218 | + int ret = -1, invalid = 0, expanded = 0; | ||
219 | + | ||
220 | + *patternsp = NULL; | ||
221 | + *npatternsp = 0; | ||
222 | + | ||
223 | + /* Start the worklist with the original pattern */ | ||
224 | + if ((cp = strdup(pattern)) == NULL) | ||
225 | + return -1; | ||
226 | + if (append(cp, &active, &nactive) != 0) { | ||
227 | + free(cp); | ||
228 | + return -1; | ||
229 | + } | ||
230 | + while (nactive > 0) { | ||
231 | + cp = active[nactive - 1]; | ||
232 | + nactive--; | ||
233 | + if (brace_expand_one(cp, &active, &nactive, | ||
234 | + &expanded, &invalid) == -1) { | ||
235 | + free(cp); | ||
236 | + goto fail; | ||
237 | + } | ||
238 | + if (invalid) | ||
239 | + fatal("%s: invalid brace pattern \"%s\"", __func__, cp); | ||
240 | + if (expanded) { | ||
241 | + /* | ||
242 | + * Current entry expanded to new entries on the | ||
243 | + * active list; discard the progenitor pattern. | ||
244 | + */ | ||
245 | + free(cp); | ||
246 | + continue; | ||
247 | + } | ||
248 | + /* | ||
249 | + * Pattern did not expand; append the finename component to | ||
250 | + * the completed list | ||
251 | + */ | ||
252 | + if ((cp2 = strrchr(cp, '/')) != NULL) | ||
253 | + *cp2++ = '\0'; | ||
254 | + else | ||
255 | + cp2 = cp; | ||
256 | + if (append(xstrdup(cp2), &done, &ndone) != 0) { | ||
257 | + free(cp); | ||
258 | + goto fail; | ||
259 | + } | ||
260 | + free(cp); | ||
261 | + } | ||
262 | + /* success */ | ||
263 | + *patternsp = done; | ||
264 | + *npatternsp = ndone; | ||
265 | + done = NULL; | ||
266 | + ndone = 0; | ||
267 | + ret = 0; | ||
268 | + fail: | ||
269 | + for (i = 0; i < nactive; i++) | ||
270 | + free(active[i]); | ||
271 | + free(active); | ||
272 | + for (i = 0; i < ndone; i++) | ||
273 | + free(done[i]); | ||
274 | + free(done); | ||
275 | + return ret; | ||
276 | +} | ||
277 | + | ||
278 | void | ||
279 | toremote(int argc, char **argv) | ||
280 | { | ||
281 | @@ -998,7 +1245,8 @@ sink(int argc, char **argv, const char *src) | ||
282 | unsigned long long ull; | ||
283 | int setimes, targisdir, wrerrno = 0; | ||
284 | char ch, *cp, *np, *targ, *why, *vect[1], buf[2048], visbuf[2048]; | ||
285 | - char *src_copy = NULL, *restrict_pattern = NULL; | ||
286 | + char **patterns = NULL; | ||
287 | + size_t n, npatterns = 0; | ||
288 | struct timeval tv[2]; | ||
289 | |||
290 | #define atime tv[0] | ||
291 | @@ -1028,16 +1276,13 @@ sink(int argc, char **argv, const char *src) | ||
292 | * Prepare to try to restrict incoming filenames to match | ||
293 | * the requested destination file glob. | ||
294 | */ | ||
295 | - if ((src_copy = strdup(src)) == NULL) | ||
296 | - fatal("strdup failed"); | ||
297 | - if ((restrict_pattern = strrchr(src_copy, '/')) != NULL) { | ||
298 | - *restrict_pattern++ = '\0'; | ||
299 | - } | ||
300 | + if (brace_expand(src, &patterns, &npatterns) != 0) | ||
301 | + fatal("%s: could not expand pattern", __func__); | ||
302 | } | ||
303 | for (first = 1;; first = 0) { | ||
304 | cp = buf; | ||
305 | if (atomicio(read, remin, cp, 1) != 1) | ||
306 | - return; | ||
307 | + goto done; | ||
308 | if (*cp++ == '\n') | ||
309 | SCREWUP("unexpected <newline>"); | ||
310 | do { | ||
311 | @@ -1063,7 +1308,7 @@ sink(int argc, char **argv, const char *src) | ||
312 | } | ||
313 | if (buf[0] == 'E') { | ||
314 | (void) atomicio(vwrite, remout, "", 1); | ||
315 | - return; | ||
316 | + goto done; | ||
317 | } | ||
318 | if (ch == '\n') | ||
319 | *--cp = 0; | ||
320 | @@ -1138,9 +1383,14 @@ sink(int argc, char **argv, const char *src) | ||
321 | run_err("error: unexpected filename: %s", cp); | ||
322 | exit(1); | ||
323 | } | ||
324 | - if (restrict_pattern != NULL && | ||
325 | - fnmatch(restrict_pattern, cp, 0) != 0) | ||
326 | - SCREWUP("filename does not match request"); | ||
327 | + if (npatterns > 0) { | ||
328 | + for (n = 0; n < npatterns; n++) { | ||
329 | + if (fnmatch(patterns[n], cp, 0) == 0) | ||
330 | + break; | ||
331 | + } | ||
332 | + if (n >= npatterns) | ||
333 | + SCREWUP("filename does not match request"); | ||
334 | + } | ||
335 | if (targisdir) { | ||
336 | static char *namebuf; | ||
337 | static size_t cursize; | ||
338 | @@ -1299,7 +1549,15 @@ bad: run_err("%s: %s", np, strerror(errno)); | ||
339 | break; | ||
340 | } | ||
341 | } | ||
342 | +done: | ||
343 | + for (n = 0; n < npatterns; n++) | ||
344 | + free(patterns[n]); | ||
345 | + free(patterns); | ||
346 | + return; | ||
347 | screwup: | ||
348 | + for (n = 0; n < npatterns; n++) | ||
349 | + free(patterns[n]); | ||
350 | + free(patterns); | ||
351 | run_err("protocol error: %s", why); | ||
352 | exit(1); | ||
353 | } | ||
diff --git a/debian/patches/scp-quoting.patch b/debian/patches/scp-quoting.patch index d054b2a82..29cf5603f 100644 --- a/debian/patches/scp-quoting.patch +++ b/debian/patches/scp-quoting.patch | |||
@@ -1,4 +1,4 @@ | |||
1 | From eefdc7046766b52e39f1b6eafcde22c1e013ce9f Mon Sep 17 00:00:00 2001 | 1 | From 76a51e544a6a6a674ff1dddf4bb6da05d9cce774 Mon Sep 17 00:00:00 2001 |
2 | From: =?UTF-8?q?Nicolas=20Valc=C3=A1rcel?= <nvalcarcel@ubuntu.com> | 2 | From: =?UTF-8?q?Nicolas=20Valc=C3=A1rcel?= <nvalcarcel@ubuntu.com> |
3 | Date: Sun, 9 Feb 2014 16:09:59 +0000 | 3 | Date: Sun, 9 Feb 2014 16:09:59 +0000 |
4 | Subject: Adjust scp quoting in verbose mode | 4 | Subject: Adjust scp quoting in verbose mode |
@@ -17,10 +17,10 @@ Patch-Name: scp-quoting.patch | |||
17 | 1 file changed, 10 insertions(+), 2 deletions(-) | 17 | 1 file changed, 10 insertions(+), 2 deletions(-) |
18 | 18 | ||
19 | diff --git a/scp.c b/scp.c | 19 | diff --git a/scp.c b/scp.c |
20 | index 60682c687..ed2864250 100644 | 20 | index 80bc0e8b1..a2dc410bd 100644 |
21 | --- a/scp.c | 21 | --- a/scp.c |
22 | +++ b/scp.c | 22 | +++ b/scp.c |
23 | @@ -198,8 +198,16 @@ do_local_cmd(arglist *a) | 23 | @@ -199,8 +199,16 @@ do_local_cmd(arglist *a) |
24 | 24 | ||
25 | if (verbose_mode) { | 25 | if (verbose_mode) { |
26 | fprintf(stderr, "Executing:"); | 26 | fprintf(stderr, "Executing:"); |
diff --git a/debian/patches/seccomp-s390-flock-ipc.patch b/debian/patches/seccomp-s390-flock-ipc.patch index e864427bd..ad00d1220 100644 --- a/debian/patches/seccomp-s390-flock-ipc.patch +++ b/debian/patches/seccomp-s390-flock-ipc.patch | |||
@@ -1,4 +1,4 @@ | |||
1 | From 690939ba320d93e6f3ab5266bea94d8fb06c8bae Mon Sep 17 00:00:00 2001 | 1 | From 9fa2ceb14b6e7e5e902cff416bc9ad3963be9883 Mon Sep 17 00:00:00 2001 |
2 | From: Eduardo Barretto <ebarretto@linux.vnet.ibm.com> | 2 | From: Eduardo Barretto <ebarretto@linux.vnet.ibm.com> |
3 | Date: Tue, 9 May 2017 10:53:04 -0300 | 3 | Date: Tue, 9 May 2017 10:53:04 -0300 |
4 | Subject: Allow flock and ipc syscall for s390 architecture | 4 | Subject: Allow flock and ipc syscall for s390 architecture |
diff --git a/debian/patches/seccomp-s390-ioctl-ep11-crypto.patch b/debian/patches/seccomp-s390-ioctl-ep11-crypto.patch index ecbe1d142..fcd7285bd 100644 --- a/debian/patches/seccomp-s390-ioctl-ep11-crypto.patch +++ b/debian/patches/seccomp-s390-ioctl-ep11-crypto.patch | |||
@@ -1,4 +1,4 @@ | |||
1 | From 9ce189b9f22890421b7f8d3f49a39186d3ce3e14 Mon Sep 17 00:00:00 2001 | 1 | From 9d4508c5c1d6466c662befcb26aff09f41966102 Mon Sep 17 00:00:00 2001 |
2 | From: Eduardo Barretto <ebarretto@linux.vnet.ibm.com> | 2 | From: Eduardo Barretto <ebarretto@linux.vnet.ibm.com> |
3 | Date: Tue, 9 May 2017 13:33:30 -0300 | 3 | Date: Tue, 9 May 2017 13:33:30 -0300 |
4 | Subject: Enable specific ioctl call for EP11 crypto card (s390) | 4 | Subject: Enable specific ioctl call for EP11 crypto card (s390) |
diff --git a/debian/patches/selinux-role.patch b/debian/patches/selinux-role.patch index 269a87c76..5ab339ac9 100644 --- a/debian/patches/selinux-role.patch +++ b/debian/patches/selinux-role.patch | |||
@@ -1,4 +1,4 @@ | |||
1 | From cf3f6ac19812e4d32874304b3854b055831c2124 Mon Sep 17 00:00:00 2001 | 1 | From 21e3ff3ab4791d3c94bd775da66cde29797fcb36 Mon Sep 17 00:00:00 2001 |
2 | From: Manoj Srivastava <srivasta@debian.org> | 2 | From: Manoj Srivastava <srivasta@debian.org> |
3 | Date: Sun, 9 Feb 2014 16:09:49 +0000 | 3 | Date: Sun, 9 Feb 2014 16:09:49 +0000 |
4 | Subject: Handle SELinux authorisation roles | 4 | Subject: Handle SELinux authorisation roles |
@@ -9,7 +9,7 @@ SELinux maintainer, so we'll keep it until we have something better. | |||
9 | 9 | ||
10 | Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1641 | 10 | Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1641 |
11 | Bug-Debian: http://bugs.debian.org/394795 | 11 | Bug-Debian: http://bugs.debian.org/394795 |
12 | Last-Update: 2018-08-24 | 12 | Last-Update: 2019-06-05 |
13 | 13 | ||
14 | Patch-Name: selinux-role.patch | 14 | Patch-Name: selinux-role.patch |
15 | --- | 15 | --- |
@@ -31,7 +31,7 @@ Patch-Name: selinux-role.patch | |||
31 | 15 files changed, 99 insertions(+), 32 deletions(-) | 31 | 15 files changed, 99 insertions(+), 32 deletions(-) |
32 | 32 | ||
33 | diff --git a/auth.h b/auth.h | 33 | diff --git a/auth.h b/auth.h |
34 | index 977562f0a..90802a5eb 100644 | 34 | index bf393e755..8f13bdf48 100644 |
35 | --- a/auth.h | 35 | --- a/auth.h |
36 | +++ b/auth.h | 36 | +++ b/auth.h |
37 | @@ -65,6 +65,7 @@ struct Authctxt { | 37 | @@ -65,6 +65,7 @@ struct Authctxt { |
@@ -43,19 +43,19 @@ index 977562f0a..90802a5eb 100644 | |||
43 | /* Method lists for multiple authentication */ | 43 | /* Method lists for multiple authentication */ |
44 | char **auth_methods; /* modified from server config */ | 44 | char **auth_methods; /* modified from server config */ |
45 | diff --git a/auth2.c b/auth2.c | 45 | diff --git a/auth2.c b/auth2.c |
46 | index a77742819..3035926ba 100644 | 46 | index 7417eafa4..d60e7f1f2 100644 |
47 | --- a/auth2.c | 47 | --- a/auth2.c |
48 | +++ b/auth2.c | 48 | +++ b/auth2.c |
49 | @@ -257,7 +257,7 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) | 49 | @@ -267,7 +267,7 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) |
50 | { | 50 | { |
51 | Authctxt *authctxt = ssh->authctxt; | 51 | Authctxt *authctxt = ssh->authctxt; |
52 | Authmethod *m = NULL; | 52 | Authmethod *m = NULL; |
53 | - char *user, *service, *method, *style = NULL; | 53 | - char *user = NULL, *service = NULL, *method = NULL, *style = NULL; |
54 | + char *user, *service, *method, *style = NULL, *role = NULL; | 54 | + char *user = NULL, *service = NULL, *method = NULL, *style = NULL, *role = NULL; |
55 | int authenticated = 0; | 55 | int r, authenticated = 0; |
56 | double tstart = monotime_double(); | 56 | double tstart = monotime_double(); |
57 | 57 | ||
58 | @@ -270,8 +270,13 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) | 58 | @@ -281,8 +281,13 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) |
59 | debug("userauth-request for user %s service %s method %s", user, service, method); | 59 | debug("userauth-request for user %s service %s method %s", user, service, method); |
60 | debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); | 60 | debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); |
61 | 61 | ||
@@ -69,7 +69,7 @@ index a77742819..3035926ba 100644 | |||
69 | 69 | ||
70 | if (authctxt->attempt++ == 0) { | 70 | if (authctxt->attempt++ == 0) { |
71 | /* setup auth context */ | 71 | /* setup auth context */ |
72 | @@ -298,8 +303,9 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) | 72 | @@ -309,8 +314,9 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) |
73 | use_privsep ? " [net]" : ""); | 73 | use_privsep ? " [net]" : ""); |
74 | authctxt->service = xstrdup(service); | 74 | authctxt->service = xstrdup(service); |
75 | authctxt->style = style ? xstrdup(style) : NULL; | 75 | authctxt->style = style ? xstrdup(style) : NULL; |
@@ -77,22 +77,22 @@ index a77742819..3035926ba 100644 | |||
77 | if (use_privsep) | 77 | if (use_privsep) |
78 | - mm_inform_authserv(service, style); | 78 | - mm_inform_authserv(service, style); |
79 | + mm_inform_authserv(service, style, role); | 79 | + mm_inform_authserv(service, style, role); |
80 | userauth_banner(); | 80 | userauth_banner(ssh); |
81 | if (auth2_setup_methods_lists(authctxt) != 0) | 81 | if (auth2_setup_methods_lists(authctxt) != 0) |
82 | packet_disconnect("no authentication methods enabled"); | 82 | ssh_packet_disconnect(ssh, |
83 | diff --git a/monitor.c b/monitor.c | 83 | diff --git a/monitor.c b/monitor.c |
84 | index eabc1e89b..08fddabd7 100644 | 84 | index 0766d6ef5..5f84e880d 100644 |
85 | --- a/monitor.c | 85 | --- a/monitor.c |
86 | +++ b/monitor.c | 86 | +++ b/monitor.c |
87 | @@ -117,6 +117,7 @@ int mm_answer_sign(int, struct sshbuf *); | 87 | @@ -117,6 +117,7 @@ int mm_answer_sign(struct ssh *, int, struct sshbuf *); |
88 | int mm_answer_pwnamallow(int, struct sshbuf *); | 88 | int mm_answer_pwnamallow(struct ssh *, int, struct sshbuf *); |
89 | int mm_answer_auth2_read_banner(int, struct sshbuf *); | 89 | int mm_answer_auth2_read_banner(struct ssh *, int, struct sshbuf *); |
90 | int mm_answer_authserv(int, struct sshbuf *); | 90 | int mm_answer_authserv(struct ssh *, int, struct sshbuf *); |
91 | +int mm_answer_authrole(int, struct sshbuf *); | 91 | +int mm_answer_authrole(struct ssh *, int, struct sshbuf *); |
92 | int mm_answer_authpassword(int, struct sshbuf *); | 92 | int mm_answer_authpassword(struct ssh *, int, struct sshbuf *); |
93 | int mm_answer_bsdauthquery(int, struct sshbuf *); | 93 | int mm_answer_bsdauthquery(struct ssh *, int, struct sshbuf *); |
94 | int mm_answer_bsdauthrespond(int, struct sshbuf *); | 94 | int mm_answer_bsdauthrespond(struct ssh *, int, struct sshbuf *); |
95 | @@ -193,6 +194,7 @@ struct mon_table mon_dispatch_proto20[] = { | 95 | @@ -197,6 +198,7 @@ struct mon_table mon_dispatch_proto20[] = { |
96 | {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, | 96 | {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, |
97 | {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, | 97 | {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, |
98 | {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, | 98 | {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, |
@@ -100,7 +100,7 @@ index eabc1e89b..08fddabd7 100644 | |||
100 | {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, | 100 | {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, |
101 | {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, | 101 | {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, |
102 | #ifdef USE_PAM | 102 | #ifdef USE_PAM |
103 | @@ -817,6 +819,7 @@ mm_answer_pwnamallow(int sock, struct sshbuf *m) | 103 | @@ -819,6 +821,7 @@ mm_answer_pwnamallow(struct ssh *ssh, int sock, struct sshbuf *m) |
104 | 104 | ||
105 | /* Allow service/style information on the auth context */ | 105 | /* Allow service/style information on the auth context */ |
106 | monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); | 106 | monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); |
@@ -108,7 +108,7 @@ index eabc1e89b..08fddabd7 100644 | |||
108 | monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); | 108 | monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); |
109 | 109 | ||
110 | #ifdef USE_PAM | 110 | #ifdef USE_PAM |
111 | @@ -850,16 +853,42 @@ mm_answer_authserv(int sock, struct sshbuf *m) | 111 | @@ -852,16 +855,42 @@ mm_answer_authserv(struct ssh *ssh, int sock, struct sshbuf *m) |
112 | monitor_permit_authentications(1); | 112 | monitor_permit_authentications(1); |
113 | 113 | ||
114 | if ((r = sshbuf_get_cstring(m, &authctxt->service, NULL)) != 0 || | 114 | if ((r = sshbuf_get_cstring(m, &authctxt->service, NULL)) != 0 || |
@@ -135,7 +135,7 @@ index eabc1e89b..08fddabd7 100644 | |||
135 | +} | 135 | +} |
136 | + | 136 | + |
137 | +int | 137 | +int |
138 | +mm_answer_authrole(int sock, struct sshbuf *m) | 138 | +mm_answer_authrole(struct ssh *ssh, int sock, struct sshbuf *m) |
139 | +{ | 139 | +{ |
140 | + int r; | 140 | + int r; |
141 | + | 141 | + |
@@ -154,7 +154,7 @@ index eabc1e89b..08fddabd7 100644 | |||
154 | return (0); | 154 | return (0); |
155 | } | 155 | } |
156 | 156 | ||
157 | @@ -1501,7 +1530,7 @@ mm_answer_pty(int sock, struct sshbuf *m) | 157 | @@ -1528,7 +1557,7 @@ mm_answer_pty(struct ssh *ssh, int sock, struct sshbuf *m) |
158 | res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)); | 158 | res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)); |
159 | if (res == 0) | 159 | if (res == 0) |
160 | goto error; | 160 | goto error; |
@@ -164,23 +164,23 @@ index eabc1e89b..08fddabd7 100644 | |||
164 | if ((r = sshbuf_put_u32(m, 1)) != 0 || | 164 | if ((r = sshbuf_put_u32(m, 1)) != 0 || |
165 | (r = sshbuf_put_cstring(m, s->tty)) != 0) | 165 | (r = sshbuf_put_cstring(m, s->tty)) != 0) |
166 | diff --git a/monitor.h b/monitor.h | 166 | diff --git a/monitor.h b/monitor.h |
167 | index 44fbed589..8f65e684d 100644 | 167 | index 2b1a2d590..4d87284aa 100644 |
168 | --- a/monitor.h | 168 | --- a/monitor.h |
169 | +++ b/monitor.h | 169 | +++ b/monitor.h |
170 | @@ -66,6 +66,8 @@ enum monitor_reqtype { | 170 | @@ -65,6 +65,8 @@ enum monitor_reqtype { |
171 | |||
171 | MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151, | 172 | MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151, |
172 | MONITOR_REQ_GSSUPCREDS = 152, MONITOR_ANS_GSSUPCREDS = 153, | 173 | MONITOR_REQ_GSSUPCREDS = 152, MONITOR_ANS_GSSUPCREDS = 153, |
173 | |||
174 | + MONITOR_REQ_AUTHROLE = 154, | ||
175 | + | 174 | + |
175 | + MONITOR_REQ_AUTHROLE = 154, | ||
176 | }; | 176 | }; |
177 | 177 | ||
178 | struct monitor { | 178 | struct ssh; |
179 | diff --git a/monitor_wrap.c b/monitor_wrap.c | 179 | diff --git a/monitor_wrap.c b/monitor_wrap.c |
180 | index 1865a122a..fd4d7eb3b 100644 | 180 | index 8e4c1c1f8..6b3a6251c 100644 |
181 | --- a/monitor_wrap.c | 181 | --- a/monitor_wrap.c |
182 | +++ b/monitor_wrap.c | 182 | +++ b/monitor_wrap.c |
183 | @@ -369,10 +369,10 @@ mm_auth2_read_banner(void) | 183 | @@ -364,10 +364,10 @@ mm_auth2_read_banner(void) |
184 | return (banner); | 184 | return (banner); |
185 | } | 185 | } |
186 | 186 | ||
@@ -193,7 +193,7 @@ index 1865a122a..fd4d7eb3b 100644 | |||
193 | { | 193 | { |
194 | struct sshbuf *m; | 194 | struct sshbuf *m; |
195 | int r; | 195 | int r; |
196 | @@ -382,7 +382,8 @@ mm_inform_authserv(char *service, char *style) | 196 | @@ -377,7 +377,8 @@ mm_inform_authserv(char *service, char *style) |
197 | if ((m = sshbuf_new()) == NULL) | 197 | if ((m = sshbuf_new()) == NULL) |
198 | fatal("%s: sshbuf_new failed", __func__); | 198 | fatal("%s: sshbuf_new failed", __func__); |
199 | if ((r = sshbuf_put_cstring(m, service)) != 0 || | 199 | if ((r = sshbuf_put_cstring(m, service)) != 0 || |
@@ -203,7 +203,7 @@ index 1865a122a..fd4d7eb3b 100644 | |||
203 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 203 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
204 | 204 | ||
205 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, m); | 205 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, m); |
206 | @@ -390,6 +391,26 @@ mm_inform_authserv(char *service, char *style) | 206 | @@ -385,6 +386,26 @@ mm_inform_authserv(char *service, char *style) |
207 | sshbuf_free(m); | 207 | sshbuf_free(m); |
208 | } | 208 | } |
209 | 209 | ||
@@ -231,17 +231,17 @@ index 1865a122a..fd4d7eb3b 100644 | |||
231 | int | 231 | int |
232 | mm_auth_password(struct ssh *ssh, char *password) | 232 | mm_auth_password(struct ssh *ssh, char *password) |
233 | diff --git a/monitor_wrap.h b/monitor_wrap.h | 233 | diff --git a/monitor_wrap.h b/monitor_wrap.h |
234 | index 7f93144ff..79e78cc90 100644 | 234 | index 69164a8c0..3d0e32d48 100644 |
235 | --- a/monitor_wrap.h | 235 | --- a/monitor_wrap.h |
236 | +++ b/monitor_wrap.h | 236 | +++ b/monitor_wrap.h |
237 | @@ -43,7 +43,8 @@ int mm_is_monitor(void); | 237 | @@ -44,7 +44,8 @@ int mm_is_monitor(void); |
238 | DH *mm_choose_dh(int, int, int); | 238 | DH *mm_choose_dh(int, int, int); |
239 | int mm_sshkey_sign(struct sshkey *, u_char **, size_t *, const u_char *, size_t, | 239 | int mm_sshkey_sign(struct ssh *, struct sshkey *, u_char **, size_t *, |
240 | const char *, u_int compat); | 240 | const u_char *, size_t, const char *, u_int compat); |
241 | -void mm_inform_authserv(char *, char *); | 241 | -void mm_inform_authserv(char *, char *); |
242 | +void mm_inform_authserv(char *, char *, char *); | 242 | +void mm_inform_authserv(char *, char *, char *); |
243 | +void mm_inform_authrole(char *); | 243 | +void mm_inform_authrole(char *); |
244 | struct passwd *mm_getpwnamallow(const char *); | 244 | struct passwd *mm_getpwnamallow(struct ssh *, const char *); |
245 | char *mm_auth2_read_banner(void); | 245 | char *mm_auth2_read_banner(void); |
246 | int mm_auth_password(struct ssh *, char *); | 246 | int mm_auth_password(struct ssh *, char *); |
247 | diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c | 247 | diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c |
@@ -363,10 +363,10 @@ index ea4f9c584..60d72ffe7 100644 | |||
363 | char *platform_krb5_get_principal_name(const char *); | 363 | char *platform_krb5_get_principal_name(const char *); |
364 | int platform_sys_dir_uid(uid_t); | 364 | int platform_sys_dir_uid(uid_t); |
365 | diff --git a/session.c b/session.c | 365 | diff --git a/session.c b/session.c |
366 | index 2d0958d11..19f38637e 100644 | 366 | index ac3d9d19d..d87ea4d44 100644 |
367 | --- a/session.c | 367 | --- a/session.c |
368 | +++ b/session.c | 368 | +++ b/session.c |
369 | @@ -1380,7 +1380,7 @@ safely_chroot(const char *path, uid_t uid) | 369 | @@ -1356,7 +1356,7 @@ safely_chroot(const char *path, uid_t uid) |
370 | 370 | ||
371 | /* Set login name, uid, gid, and groups. */ | 371 | /* Set login name, uid, gid, and groups. */ |
372 | void | 372 | void |
@@ -375,7 +375,7 @@ index 2d0958d11..19f38637e 100644 | |||
375 | { | 375 | { |
376 | char uidstr[32], *chroot_path, *tmp; | 376 | char uidstr[32], *chroot_path, *tmp; |
377 | 377 | ||
378 | @@ -1408,7 +1408,7 @@ do_setusercontext(struct passwd *pw) | 378 | @@ -1384,7 +1384,7 @@ do_setusercontext(struct passwd *pw) |
379 | endgrent(); | 379 | endgrent(); |
380 | #endif | 380 | #endif |
381 | 381 | ||
@@ -384,7 +384,7 @@ index 2d0958d11..19f38637e 100644 | |||
384 | 384 | ||
385 | if (!in_chroot && options.chroot_directory != NULL && | 385 | if (!in_chroot && options.chroot_directory != NULL && |
386 | strcasecmp(options.chroot_directory, "none") != 0) { | 386 | strcasecmp(options.chroot_directory, "none") != 0) { |
387 | @@ -1547,7 +1547,7 @@ do_child(struct ssh *ssh, Session *s, const char *command) | 387 | @@ -1525,7 +1525,7 @@ do_child(struct ssh *ssh, Session *s, const char *command) |
388 | 388 | ||
389 | /* Force a password change */ | 389 | /* Force a password change */ |
390 | if (s->authctxt->force_pwchange) { | 390 | if (s->authctxt->force_pwchange) { |
@@ -393,7 +393,7 @@ index 2d0958d11..19f38637e 100644 | |||
393 | child_close_fds(ssh); | 393 | child_close_fds(ssh); |
394 | do_pwchange(s); | 394 | do_pwchange(s); |
395 | exit(1); | 395 | exit(1); |
396 | @@ -1565,7 +1565,7 @@ do_child(struct ssh *ssh, Session *s, const char *command) | 396 | @@ -1543,7 +1543,7 @@ do_child(struct ssh *ssh, Session *s, const char *command) |
397 | /* When PAM is enabled we rely on it to do the nologin check */ | 397 | /* When PAM is enabled we rely on it to do the nologin check */ |
398 | if (!options.use_pam) | 398 | if (!options.use_pam) |
399 | do_nologin(pw); | 399 | do_nologin(pw); |
@@ -402,8 +402,8 @@ index 2d0958d11..19f38637e 100644 | |||
402 | /* | 402 | /* |
403 | * PAM session modules in do_setusercontext may have | 403 | * PAM session modules in do_setusercontext may have |
404 | * generated messages, so if this in an interactive | 404 | * generated messages, so if this in an interactive |
405 | @@ -1955,7 +1955,7 @@ session_pty_req(struct ssh *ssh, Session *s) | 405 | @@ -1942,7 +1942,7 @@ session_pty_req(struct ssh *ssh, Session *s) |
406 | ssh_tty_parse_modes(ssh, s->ttyfd); | 406 | sshpkt_fatal(ssh, r, "%s: parse packet", __func__); |
407 | 407 | ||
408 | if (!use_privsep) | 408 | if (!use_privsep) |
409 | - pty_setowner(s->pw, s->tty); | 409 | - pty_setowner(s->pw, s->tty); |
@@ -425,10 +425,10 @@ index ce59dabd9..675c91146 100644 | |||
425 | const char *session_get_remote_name_or_ip(struct ssh *, u_int, int); | 425 | const char *session_get_remote_name_or_ip(struct ssh *, u_int, int); |
426 | 426 | ||
427 | diff --git a/sshd.c b/sshd.c | 427 | diff --git a/sshd.c b/sshd.c |
428 | index 673db87f6..2bc6679e5 100644 | 428 | index 46870d3b5..e3e96426e 100644 |
429 | --- a/sshd.c | 429 | --- a/sshd.c |
430 | +++ b/sshd.c | 430 | +++ b/sshd.c |
431 | @@ -683,7 +683,7 @@ privsep_postauth(Authctxt *authctxt) | 431 | @@ -594,7 +594,7 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt) |
432 | reseed_prngs(); | 432 | reseed_prngs(); |
433 | 433 | ||
434 | /* Drop privileges */ | 434 | /* Drop privileges */ |
diff --git a/debian/patches/series b/debian/patches/series index b0da97283..6304f537a 100644 --- a/debian/patches/series +++ b/debian/patches/series | |||
@@ -24,11 +24,4 @@ restore-authorized_keys2.patch | |||
24 | seccomp-s390-flock-ipc.patch | 24 | seccomp-s390-flock-ipc.patch |
25 | seccomp-s390-ioctl-ep11-crypto.patch | 25 | seccomp-s390-ioctl-ep11-crypto.patch |
26 | conch-old-privkey-format.patch | 26 | conch-old-privkey-format.patch |
27 | scp-disallow-dot-or-empty-filename.patch | ||
28 | sanitize-scp-filenames-via-snmprintf.patch | ||
29 | have-progressmeter-force-update-at-beginning-and-end-transfer.patch | ||
30 | check-filenames-in-scp-client.patch | ||
31 | fix-key-type-check.patch | ||
32 | request-rsa-sha2-cert-signatures.patch | ||
33 | scp-handle-braces.patch | ||
34 | revert-ipqos-defaults.patch | 27 | revert-ipqos-defaults.patch |
diff --git a/debian/patches/shell-path.patch b/debian/patches/shell-path.patch index ad574e829..2224eeead 100644 --- a/debian/patches/shell-path.patch +++ b/debian/patches/shell-path.patch | |||
@@ -1,4 +1,4 @@ | |||
1 | From cabad6b7182cd6eaa8b760718200a316e7f578ed Mon Sep 17 00:00:00 2001 | 1 | From b019e32a0ee7a79c0a08cb1199229d03b16934a7 Mon Sep 17 00:00:00 2001 |
2 | From: Colin Watson <cjwatson@debian.org> | 2 | From: Colin Watson <cjwatson@debian.org> |
3 | Date: Sun, 9 Feb 2014 16:10:00 +0000 | 3 | Date: Sun, 9 Feb 2014 16:10:00 +0000 |
4 | Subject: Look for $SHELL on the path for ProxyCommand/LocalCommand | 4 | Subject: Look for $SHELL on the path for ProxyCommand/LocalCommand |
@@ -16,10 +16,10 @@ Patch-Name: shell-path.patch | |||
16 | 1 file changed, 2 insertions(+), 2 deletions(-) | 16 | 1 file changed, 2 insertions(+), 2 deletions(-) |
17 | 17 | ||
18 | diff --git a/sshconnect.c b/sshconnect.c | 18 | diff --git a/sshconnect.c b/sshconnect.c |
19 | index 6d819279e..700ea6c3c 100644 | 19 | index fdcdcd855..103d84e38 100644 |
20 | --- a/sshconnect.c | 20 | --- a/sshconnect.c |
21 | +++ b/sshconnect.c | 21 | +++ b/sshconnect.c |
22 | @@ -229,7 +229,7 @@ ssh_proxy_connect(struct ssh *ssh, const char *host, u_short port, | 22 | @@ -257,7 +257,7 @@ ssh_proxy_connect(struct ssh *ssh, const char *host, u_short port, |
23 | /* Execute the proxy command. Note that we gave up any | 23 | /* Execute the proxy command. Note that we gave up any |
24 | extra privileges above. */ | 24 | extra privileges above. */ |
25 | signal(SIGPIPE, SIG_DFL); | 25 | signal(SIGPIPE, SIG_DFL); |
@@ -28,7 +28,7 @@ index 6d819279e..700ea6c3c 100644 | |||
28 | perror(argv[0]); | 28 | perror(argv[0]); |
29 | exit(1); | 29 | exit(1); |
30 | } | 30 | } |
31 | @@ -1534,7 +1534,7 @@ ssh_local_cmd(const char *args) | 31 | @@ -1382,7 +1382,7 @@ ssh_local_cmd(const char *args) |
32 | if (pid == 0) { | 32 | if (pid == 0) { |
33 | signal(SIGPIPE, SIG_DFL); | 33 | signal(SIGPIPE, SIG_DFL); |
34 | debug3("Executing %s -c \"%s\"", shell, args); | 34 | debug3("Executing %s -c \"%s\"", shell, args); |
diff --git a/debian/patches/ssh-agent-setgid.patch b/debian/patches/ssh-agent-setgid.patch index ed6ef3d46..e94e48a03 100644 --- a/debian/patches/ssh-agent-setgid.patch +++ b/debian/patches/ssh-agent-setgid.patch | |||
@@ -1,4 +1,4 @@ | |||
1 | From 6d4521d39a852dc5627187c045c933f4e1cb4601 Mon Sep 17 00:00:00 2001 | 1 | From 9e040aefaefa40bcbe5dcdc0f9f03555cf8fe2d0 Mon Sep 17 00:00:00 2001 |
2 | From: Colin Watson <cjwatson@debian.org> | 2 | From: Colin Watson <cjwatson@debian.org> |
3 | Date: Sun, 9 Feb 2014 16:10:13 +0000 | 3 | Date: Sun, 9 Feb 2014 16:10:13 +0000 |
4 | Subject: Document consequences of ssh-agent being setgid in ssh-agent(1) | 4 | Subject: Document consequences of ssh-agent being setgid in ssh-agent(1) |
diff --git a/debian/patches/ssh-argv0.patch b/debian/patches/ssh-argv0.patch index bb1e10973..a5aa9259a 100644 --- a/debian/patches/ssh-argv0.patch +++ b/debian/patches/ssh-argv0.patch | |||
@@ -1,4 +1,4 @@ | |||
1 | From d1064c2689df8d0894a68ac9671d14ab125bc91b Mon Sep 17 00:00:00 2001 | 1 | From 23b4cc85184891ad61bb98045629400e48d946dd Mon Sep 17 00:00:00 2001 |
2 | From: Colin Watson <cjwatson@debian.org> | 2 | From: Colin Watson <cjwatson@debian.org> |
3 | Date: Sun, 9 Feb 2014 16:10:10 +0000 | 3 | Date: Sun, 9 Feb 2014 16:10:10 +0000 |
4 | Subject: ssh(1): Refer to ssh-argv0(1) | 4 | Subject: ssh(1): Refer to ssh-argv0(1) |
@@ -18,10 +18,10 @@ Patch-Name: ssh-argv0.patch | |||
18 | 1 file changed, 1 insertion(+) | 18 | 1 file changed, 1 insertion(+) |
19 | 19 | ||
20 | diff --git a/ssh.1 b/ssh.1 | 20 | diff --git a/ssh.1 b/ssh.1 |
21 | index 5dfad6daa..ad1ed0f86 100644 | 21 | index e4aeae7b4..8d2b08a29 100644 |
22 | --- a/ssh.1 | 22 | --- a/ssh.1 |
23 | +++ b/ssh.1 | 23 | +++ b/ssh.1 |
24 | @@ -1585,6 +1585,7 @@ if an error occurred. | 24 | @@ -1584,6 +1584,7 @@ if an error occurred. |
25 | .Xr sftp 1 , | 25 | .Xr sftp 1 , |
26 | .Xr ssh-add 1 , | 26 | .Xr ssh-add 1 , |
27 | .Xr ssh-agent 1 , | 27 | .Xr ssh-agent 1 , |
diff --git a/debian/patches/ssh-vulnkey-compat.patch b/debian/patches/ssh-vulnkey-compat.patch index ca3e090bd..8adc301fc 100644 --- a/debian/patches/ssh-vulnkey-compat.patch +++ b/debian/patches/ssh-vulnkey-compat.patch | |||
@@ -1,4 +1,4 @@ | |||
1 | From eccbd3637a2b8544fdcfdd5d1a00a9dfdac62aeb Mon Sep 17 00:00:00 2001 | 1 | From 0138f331a73d692f4543477ce7f64f9ede7d6b08 Mon Sep 17 00:00:00 2001 |
2 | From: Colin Watson <cjwatson@ubuntu.com> | 2 | From: Colin Watson <cjwatson@ubuntu.com> |
3 | Date: Sun, 9 Feb 2014 16:09:50 +0000 | 3 | Date: Sun, 9 Feb 2014 16:09:50 +0000 |
4 | Subject: Accept obsolete ssh-vulnkey configuration options | 4 | Subject: Accept obsolete ssh-vulnkey configuration options |
@@ -17,10 +17,10 @@ Patch-Name: ssh-vulnkey-compat.patch | |||
17 | 2 files changed, 2 insertions(+) | 17 | 2 files changed, 2 insertions(+) |
18 | 18 | ||
19 | diff --git a/readconf.c b/readconf.c | 19 | diff --git a/readconf.c b/readconf.c |
20 | index 36bc5e59a..5e655e924 100644 | 20 | index 4d699e5f1..29f3bd98d 100644 |
21 | --- a/readconf.c | 21 | --- a/readconf.c |
22 | +++ b/readconf.c | 22 | +++ b/readconf.c |
23 | @@ -190,6 +190,7 @@ static struct { | 23 | @@ -192,6 +192,7 @@ static struct { |
24 | { "fallbacktorsh", oDeprecated }, | 24 | { "fallbacktorsh", oDeprecated }, |
25 | { "globalknownhostsfile2", oDeprecated }, | 25 | { "globalknownhostsfile2", oDeprecated }, |
26 | { "rhostsauthentication", oDeprecated }, | 26 | { "rhostsauthentication", oDeprecated }, |
@@ -29,10 +29,10 @@ index 36bc5e59a..5e655e924 100644 | |||
29 | { "useroaming", oDeprecated }, | 29 | { "useroaming", oDeprecated }, |
30 | { "usersh", oDeprecated }, | 30 | { "usersh", oDeprecated }, |
31 | diff --git a/servconf.c b/servconf.c | 31 | diff --git a/servconf.c b/servconf.c |
32 | index 4668b8a45..6caf1db38 100644 | 32 | index ffdad31e7..c01e0690e 100644 |
33 | --- a/servconf.c | 33 | --- a/servconf.c |
34 | +++ b/servconf.c | 34 | +++ b/servconf.c |
35 | @@ -600,6 +600,7 @@ static struct { | 35 | @@ -621,6 +621,7 @@ static struct { |
36 | { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL }, | 36 | { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL }, |
37 | { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL }, | 37 | { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL }, |
38 | { "strictmodes", sStrictModes, SSHCFG_GLOBAL }, | 38 | { "strictmodes", sStrictModes, SSHCFG_GLOBAL }, |
diff --git a/debian/patches/syslog-level-silent.patch b/debian/patches/syslog-level-silent.patch index 3093a41fb..aa7968090 100644 --- a/debian/patches/syslog-level-silent.patch +++ b/debian/patches/syslog-level-silent.patch | |||
@@ -1,4 +1,4 @@ | |||
1 | From e755ec70d62bfb9b02159123f4e870b00010be77 Mon Sep 17 00:00:00 2001 | 1 | From 0646a0cd5ea893cf822113d4f10c501540c18e40 Mon Sep 17 00:00:00 2001 |
2 | From: Jonathan David Amery <jdamery@ysolde.ucam.org> | 2 | From: Jonathan David Amery <jdamery@ysolde.ucam.org> |
3 | Date: Sun, 9 Feb 2014 16:09:54 +0000 | 3 | Date: Sun, 9 Feb 2014 16:09:54 +0000 |
4 | Subject: "LogLevel SILENT" compatibility | 4 | Subject: "LogLevel SILENT" compatibility |
@@ -33,10 +33,10 @@ index d9c2d136c..1749af6d1 100644 | |||
33 | { "FATAL", SYSLOG_LEVEL_FATAL }, | 33 | { "FATAL", SYSLOG_LEVEL_FATAL }, |
34 | { "ERROR", SYSLOG_LEVEL_ERROR }, | 34 | { "ERROR", SYSLOG_LEVEL_ERROR }, |
35 | diff --git a/ssh.c b/ssh.c | 35 | diff --git a/ssh.c b/ssh.c |
36 | index 0777c31e4..3140fed4c 100644 | 36 | index 42be7d88f..86f143341 100644 |
37 | --- a/ssh.c | 37 | --- a/ssh.c |
38 | +++ b/ssh.c | 38 | +++ b/ssh.c |
39 | @@ -1258,7 +1258,7 @@ main(int ac, char **av) | 39 | @@ -1265,7 +1265,7 @@ main(int ac, char **av) |
40 | /* Do not allocate a tty if stdin is not a tty. */ | 40 | /* Do not allocate a tty if stdin is not a tty. */ |
41 | if ((!isatty(fileno(stdin)) || stdin_null_flag) && | 41 | if ((!isatty(fileno(stdin)) || stdin_null_flag) && |
42 | options.request_tty != REQUEST_TTY_FORCE) { | 42 | options.request_tty != REQUEST_TTY_FORCE) { |
diff --git a/debian/patches/systemd-readiness.patch b/debian/patches/systemd-readiness.patch index c5dee41ad..51c7e32de 100644 --- a/debian/patches/systemd-readiness.patch +++ b/debian/patches/systemd-readiness.patch | |||
@@ -1,4 +1,4 @@ | |||
1 | From da34947128351bee9d2530574432190548f5be58 Mon Sep 17 00:00:00 2001 | 1 | From a88f67584ef5889d95c04b0294e92c11ed4904cd Mon Sep 17 00:00:00 2001 |
2 | From: Michael Biebl <biebl@debian.org> | 2 | From: Michael Biebl <biebl@debian.org> |
3 | Date: Mon, 21 Dec 2015 16:08:47 +0000 | 3 | Date: Mon, 21 Dec 2015 16:08:47 +0000 |
4 | Subject: Add systemd readiness notification support | 4 | Subject: Add systemd readiness notification support |
@@ -14,10 +14,10 @@ Patch-Name: systemd-readiness.patch | |||
14 | 2 files changed, 33 insertions(+) | 14 | 2 files changed, 33 insertions(+) |
15 | 15 | ||
16 | diff --git a/configure.ac b/configure.ac | 16 | diff --git a/configure.ac b/configure.ac |
17 | index 917300b43..8a5db4cb5 100644 | 17 | index ce16e7758..de140f578 100644 |
18 | --- a/configure.ac | 18 | --- a/configure.ac |
19 | +++ b/configure.ac | 19 | +++ b/configure.ac |
20 | @@ -4586,6 +4586,29 @@ AC_ARG_WITH([kerberos5], | 20 | @@ -4526,6 +4526,29 @@ AC_ARG_WITH([kerberos5], |
21 | AC_SUBST([GSSLIBS]) | 21 | AC_SUBST([GSSLIBS]) |
22 | AC_SUBST([K5LIBS]) | 22 | AC_SUBST([K5LIBS]) |
23 | 23 | ||
@@ -47,7 +47,7 @@ index 917300b43..8a5db4cb5 100644 | |||
47 | # Looking for programs, paths and files | 47 | # Looking for programs, paths and files |
48 | 48 | ||
49 | PRIVSEP_PATH=/var/empty | 49 | PRIVSEP_PATH=/var/empty |
50 | @@ -5392,6 +5415,7 @@ echo " libldns support: $LDNS_MSG" | 50 | @@ -5332,6 +5355,7 @@ echo " libldns support: $LDNS_MSG" |
51 | echo " Solaris process contract support: $SPC_MSG" | 51 | echo " Solaris process contract support: $SPC_MSG" |
52 | echo " Solaris project support: $SP_MSG" | 52 | echo " Solaris project support: $SP_MSG" |
53 | echo " Solaris privilege support: $SPP_MSG" | 53 | echo " Solaris privilege support: $SPP_MSG" |
@@ -56,7 +56,7 @@ index 917300b43..8a5db4cb5 100644 | |||
56 | echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG" | 56 | echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG" |
57 | echo " BSD Auth support: $BSD_AUTH_MSG" | 57 | echo " BSD Auth support: $BSD_AUTH_MSG" |
58 | diff --git a/sshd.c b/sshd.c | 58 | diff --git a/sshd.c b/sshd.c |
59 | index d7e77d343..a1c3970b3 100644 | 59 | index 1e7ece588..48162b629 100644 |
60 | --- a/sshd.c | 60 | --- a/sshd.c |
61 | +++ b/sshd.c | 61 | +++ b/sshd.c |
62 | @@ -85,6 +85,10 @@ | 62 | @@ -85,6 +85,10 @@ |
@@ -70,7 +70,7 @@ index d7e77d343..a1c3970b3 100644 | |||
70 | #include "xmalloc.h" | 70 | #include "xmalloc.h" |
71 | #include "ssh.h" | 71 | #include "ssh.h" |
72 | #include "ssh2.h" | 72 | #include "ssh2.h" |
73 | @@ -1990,6 +1994,11 @@ main(int ac, char **av) | 73 | @@ -1946,6 +1950,11 @@ main(int ac, char **av) |
74 | } | 74 | } |
75 | } | 75 | } |
76 | 76 | ||
diff --git a/debian/patches/user-group-modes.patch b/debian/patches/user-group-modes.patch index bc2390e06..899c60123 100644 --- a/debian/patches/user-group-modes.patch +++ b/debian/patches/user-group-modes.patch | |||
@@ -1,4 +1,4 @@ | |||
1 | From 7b931d36ad36a93d2b1811858ca29408ec44ecae Mon Sep 17 00:00:00 2001 | 1 | From e04a43bd5798ba43d910493d179438845e96f631 Mon Sep 17 00:00:00 2001 |
2 | From: Colin Watson <cjwatson@debian.org> | 2 | From: Colin Watson <cjwatson@debian.org> |
3 | Date: Sun, 9 Feb 2014 16:09:58 +0000 | 3 | Date: Sun, 9 Feb 2014 16:09:58 +0000 |
4 | Subject: Allow harmless group-writability | 4 | Subject: Allow harmless group-writability |
@@ -13,7 +13,7 @@ default. | |||
13 | 13 | ||
14 | Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1060 | 14 | Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1060 |
15 | Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=314347 | 15 | Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=314347 |
16 | Last-Update: 2017-10-04 | 16 | Last-Update: 2019-06-05 |
17 | 17 | ||
18 | Patch-Name: user-group-modes.patch | 18 | Patch-Name: user-group-modes.patch |
19 | --- | 19 | --- |
@@ -51,7 +51,7 @@ index 57296e1f6..546aa0495 100644 | |||
51 | pw->pw_name, buf); | 51 | pw->pw_name, buf); |
52 | auth_debug_add("Bad file modes for %.200s", buf); | 52 | auth_debug_add("Bad file modes for %.200s", buf); |
53 | diff --git a/auth.c b/auth.c | 53 | diff --git a/auth.c b/auth.c |
54 | index d8e6b4a3d..9d1d453f1 100644 | 54 | index f7a23afba..8ffd77662 100644 |
55 | --- a/auth.c | 55 | --- a/auth.c |
56 | +++ b/auth.c | 56 | +++ b/auth.c |
57 | @@ -473,8 +473,7 @@ check_key_in_hostfiles(struct passwd *pw, struct sshkey *key, const char *host, | 57 | @@ -473,8 +473,7 @@ check_key_in_hostfiles(struct passwd *pw, struct sshkey *key, const char *host, |
@@ -65,10 +65,10 @@ index d8e6b4a3d..9d1d453f1 100644 | |||
65 | "bad owner or modes for %.200s", | 65 | "bad owner or modes for %.200s", |
66 | pw->pw_name, user_hostfile); | 66 | pw->pw_name, user_hostfile); |
67 | diff --git a/misc.c b/misc.c | 67 | diff --git a/misc.c b/misc.c |
68 | index bdc06fdb3..5159e6692 100644 | 68 | index 009e02bc5..634b5060a 100644 |
69 | --- a/misc.c | 69 | --- a/misc.c |
70 | +++ b/misc.c | 70 | +++ b/misc.c |
71 | @@ -58,8 +58,9 @@ | 71 | @@ -59,8 +59,9 @@ |
72 | #include <netdb.h> | 72 | #include <netdb.h> |
73 | #ifdef HAVE_PATHS_H | 73 | #ifdef HAVE_PATHS_H |
74 | # include <paths.h> | 74 | # include <paths.h> |
@@ -79,7 +79,7 @@ index bdc06fdb3..5159e6692 100644 | |||
79 | #ifdef SSH_TUN_OPENBSD | 79 | #ifdef SSH_TUN_OPENBSD |
80 | #include <net/if.h> | 80 | #include <net/if.h> |
81 | #endif | 81 | #endif |
82 | @@ -1028,6 +1029,55 @@ percent_expand(const char *string, ...) | 82 | @@ -1103,6 +1104,55 @@ percent_expand(const char *string, ...) |
83 | #undef EXPAND_MAX_KEYS | 83 | #undef EXPAND_MAX_KEYS |
84 | } | 84 | } |
85 | 85 | ||
@@ -135,7 +135,7 @@ index bdc06fdb3..5159e6692 100644 | |||
135 | int | 135 | int |
136 | tun_open(int tun, int mode, char **ifname) | 136 | tun_open(int tun, int mode, char **ifname) |
137 | { | 137 | { |
138 | @@ -1786,8 +1836,7 @@ safe_path(const char *name, struct stat *stp, const char *pw_dir, | 138 | @@ -1860,8 +1910,7 @@ safe_path(const char *name, struct stat *stp, const char *pw_dir, |
139 | snprintf(err, errlen, "%s is not a regular file", buf); | 139 | snprintf(err, errlen, "%s is not a regular file", buf); |
140 | return -1; | 140 | return -1; |
141 | } | 141 | } |
@@ -145,7 +145,7 @@ index bdc06fdb3..5159e6692 100644 | |||
145 | snprintf(err, errlen, "bad ownership or modes for file %s", | 145 | snprintf(err, errlen, "bad ownership or modes for file %s", |
146 | buf); | 146 | buf); |
147 | return -1; | 147 | return -1; |
148 | @@ -1802,8 +1851,7 @@ safe_path(const char *name, struct stat *stp, const char *pw_dir, | 148 | @@ -1876,8 +1925,7 @@ safe_path(const char *name, struct stat *stp, const char *pw_dir, |
149 | strlcpy(buf, cp, sizeof(buf)); | 149 | strlcpy(buf, cp, sizeof(buf)); |
150 | 150 | ||
151 | if (stat(buf, &st) < 0 || | 151 | if (stat(buf, &st) < 0 || |
@@ -156,10 +156,10 @@ index bdc06fdb3..5159e6692 100644 | |||
156 | "bad ownership or modes for directory %s", buf); | 156 | "bad ownership or modes for directory %s", buf); |
157 | return -1; | 157 | return -1; |
158 | diff --git a/misc.h b/misc.h | 158 | diff --git a/misc.h b/misc.h |
159 | index 31b207a8d..aaf966e65 100644 | 159 | index 5b4325aba..a4bdee187 100644 |
160 | --- a/misc.h | 160 | --- a/misc.h |
161 | +++ b/misc.h | 161 | +++ b/misc.h |
162 | @@ -168,6 +168,8 @@ int safe_path_fd(int, const char *, struct passwd *, | 162 | @@ -175,6 +175,8 @@ int safe_path_fd(int, const char *, struct passwd *, |
163 | char *read_passphrase(const char *, int); | 163 | char *read_passphrase(const char *, int); |
164 | int ask_permission(const char *, ...) __attribute__((format(printf, 1, 2))); | 164 | int ask_permission(const char *, ...) __attribute__((format(printf, 1, 2))); |
165 | 165 | ||
@@ -169,10 +169,10 @@ index 31b207a8d..aaf966e65 100644 | |||
169 | #define MAXIMUM(a, b) (((a) > (b)) ? (a) : (b)) | 169 | #define MAXIMUM(a, b) (((a) > (b)) ? (a) : (b)) |
170 | #define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y)) | 170 | #define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y)) |
171 | diff --git a/readconf.c b/readconf.c | 171 | diff --git a/readconf.c b/readconf.c |
172 | index 052d4b1ac..6b01f20d2 100644 | 172 | index 3d0b6ff90..cd60007f8 100644 |
173 | --- a/readconf.c | 173 | --- a/readconf.c |
174 | +++ b/readconf.c | 174 | +++ b/readconf.c |
175 | @@ -1820,8 +1820,7 @@ read_config_file_depth(const char *filename, struct passwd *pw, | 175 | @@ -1846,8 +1846,7 @@ read_config_file_depth(const char *filename, struct passwd *pw, |
176 | 176 | ||
177 | if (fstat(fileno(f), &sb) == -1) | 177 | if (fstat(fileno(f), &sb) == -1) |
178 | fatal("fstat %s: %s", filename, strerror(errno)); | 178 | fatal("fstat %s: %s", filename, strerror(errno)); |
@@ -183,10 +183,10 @@ index 052d4b1ac..6b01f20d2 100644 | |||
183 | } | 183 | } |
184 | 184 | ||
185 | diff --git a/ssh.1 b/ssh.1 | 185 | diff --git a/ssh.1 b/ssh.1 |
186 | index 7760c3075..81f29af43 100644 | 186 | index a1c7d2305..64ead5f57 100644 |
187 | --- a/ssh.1 | 187 | --- a/ssh.1 |
188 | +++ b/ssh.1 | 188 | +++ b/ssh.1 |
189 | @@ -1485,6 +1485,8 @@ The file format and configuration options are described in | 189 | @@ -1484,6 +1484,8 @@ The file format and configuration options are described in |
190 | .Xr ssh_config 5 . | 190 | .Xr ssh_config 5 . |
191 | Because of the potential for abuse, this file must have strict permissions: | 191 | Because of the potential for abuse, this file must have strict permissions: |
192 | read/write for the user, and not writable by others. | 192 | read/write for the user, and not writable by others. |
@@ -196,13 +196,13 @@ index 7760c3075..81f29af43 100644 | |||
196 | .It Pa ~/.ssh/environment | 196 | .It Pa ~/.ssh/environment |
197 | Contains additional definitions for environment variables; see | 197 | Contains additional definitions for environment variables; see |
198 | diff --git a/ssh_config.5 b/ssh_config.5 | 198 | diff --git a/ssh_config.5 b/ssh_config.5 |
199 | index 54e143c93..7d55fa820 100644 | 199 | index 250c92d04..bd1e9311d 100644 |
200 | --- a/ssh_config.5 | 200 | --- a/ssh_config.5 |
201 | +++ b/ssh_config.5 | 201 | +++ b/ssh_config.5 |
202 | @@ -1835,6 +1835,8 @@ The format of this file is described above. | 202 | @@ -1885,6 +1885,8 @@ The format of this file is described above. |
203 | This file is used by the SSH client. | 203 | This file is used by the SSH client. |
204 | Because of the potential for abuse, this file must have strict permissions: | 204 | Because of the potential for abuse, this file must have strict permissions: |
205 | read/write for the user, and not accessible by others. | 205 | read/write for the user, and not writable by others. |
206 | +It may be group-writable provided that the group in question contains only | 206 | +It may be group-writable provided that the group in question contains only |
207 | +the user. | 207 | +the user. |
208 | .It Pa /etc/ssh/ssh_config | 208 | .It Pa /etc/ssh/ssh_config |