Merge ~sergiodj/ubuntu/+source/openssh:lp1966591-ssh-keygen-permission-bionic into ubuntu/+source/openssh:ubuntu/devel

Proposed by Sergio Durigan Junior
Status: Superseded
Proposed branch: ~sergiodj/ubuntu/+source/openssh:lp1966591-ssh-keygen-permission-bionic
Merge into: ubuntu/+source/openssh:ubuntu/devel
Diff against target: 1411 lines (+1309/-0) (has conflicts)
13 files modified
debian/changelog (+75/-0)
debian/control (+8/-0)
debian/patches/0001-upstream-preserve-group-world-read-permission-on-kno.patch (+46/-0)
debian/patches/CVE-2018-15473.patch (+138/-0)
debian/patches/CVE-2018-20685.patch (+29/-0)
debian/patches/CVE-2019-6109-1.patch (+253/-0)
debian/patches/CVE-2019-6109-2.patch (+106/-0)
debian/patches/CVE-2019-6111-2.patch (+348/-0)
debian/patches/CVE-2019-6111.patch (+182/-0)
debian/patches/lp-1863930-Fix-logic-bug-in-sshd_exchange_identification.patch (+31/-0)
debian/patches/lp-1863930-unbreak-clients-that-advertise-protocol.patch (+31/-0)
debian/patches/regress-2020.patch (+44/-0)
debian/patches/series (+18/-0)
Conflict in debian/changelog
Conflict in debian/control
Conflict in debian/patches/series
Reviewer Review Type Date Requested Status
Canonical Server packageset reviewers Pending
Canonical Server Pending
Review via email: mp+418099@code.launchpad.net

Description of the change

This MP fixes bug #1966591 on Bionic.

From the SRU template:

When using "ssh-keygen -R" to remove a host from "known_hosts" the command changes permissions on the file. This can cause problems particularly when used on the global "known_hosts" file (/etc/ssh/ssh_known_hosts), because then only root can read it. Programs running non-interactively as non-root users suddenly fail to SSH and it's not immediately obvious why.

This bug has been fixed upstream (https://github.com/openssh/openssh-portable/commit/f2d84f1b3fa68d77c99238d4c645d0266fae2a74) and only impacts openssh on Bionic and Focal. The patch is simple and well contained.

The idea is to do a single SRU upload with this MP plus Athos' changes to fix bug #1903516.

There is a PPA with the proposed change here:

https://launchpad.net/~sergiodj/+archive/ubuntu/openssh-bugfix/+packages

autopkgtest is still running, but I don't expect any problems. I'll post the results when they're done.

To post a comment you must log in.

Unmerged commits

80f1bdb... by Sergio Durigan Junior

changelog for 1:7.6p1-4ubuntu0.7

828e903... by Sergio Durigan Junior

  * d/p/0001-upstream-preserve-group-world-read-permission-on-kno.patch:
    Preserve group/world read permissions on known_hosts. (LP: #1966591)

5488a2a... by Christian Ehrhardt 

1:7.6p1-4ubuntu0.6 (patches unapplied)

Imported using git-ubuntu import.

f271687... by Marc Deslauriers

1:7.6p1-4ubuntu0.5 (patches unapplied)

Imported using git-ubuntu import.

18afe7e... by Dimitri John Ledkov

1:7.6p1-4ubuntu0.4 (patches unapplied)

Imported using git-ubuntu import.

4ac6e76... by Marc Deslauriers

1:7.6p1-4ubuntu0.3 (patches unapplied)

Imported using git-ubuntu import.

844c653... by Marc Deslauriers

1:7.6p1-4ubuntu0.2 (patches unapplied)

Imported using git-ubuntu import.

95749f1... by Leonidas S. Barbosa

1:7.6p1-4ubuntu0.1 (patches unapplied)

Imported using git-ubuntu import.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/debian/changelog b/debian/changelog
2index 9d6fadc..22a71c9 100644
3--- a/debian/changelog
4+++ b/debian/changelog
5@@ -1,3 +1,4 @@
6+<<<<<<< debian/changelog
7 openssh (1:8.9p1-3) unstable; urgency=medium
8
9 * Allow ppoll_time64 in seccomp filter (closes: #1006445).
10@@ -1532,6 +1533,80 @@ openssh (1:7.6p1-5) unstable; urgency=medium
11 #894558).
12
13 -- Colin Watson <cjwatson@debian.org> Sun, 01 Apr 2018 21:37:19 +0100
14+=======
15+openssh (1:7.6p1-4ubuntu0.7) bionic; urgency=medium
16+
17+ * d/p/0001-upstream-preserve-group-world-read-permission-on-kno.patch:
18+ Preserve group/world read permissions on known_hosts. (LP: #1966591)
19+
20+ -- Sergio Durigan Junior <sergio.durigan@canonical.com> Wed, 30 Mar 2022 19:04:23 -0400
21+
22+openssh (1:7.6p1-4ubuntu0.6) bionic; urgency=medium
23+
24+ * fix clients advertising version 1.99 (LP: #1863930)
25+ - d/p/lp-1863930-Fix-logic-bug-in-sshd_exchange_identification.patch
26+ - d/p/lp-1863930-unbreak-clients-that-advertise-protocol.patch
27+
28+ -- Christian Ehrhardt <christian.ehrhardt@canonical.com> Tue, 03 Mar 2020 07:47:02 +0100
29+
30+openssh (1:7.6p1-4ubuntu0.5) bionic-security; urgency=medium
31+
32+ * SECURITY REGRESSION: User enumeration issue (LP: #1934501)
33+ - debian/patches/CVE-2018-15473.patch: updated to fix bad patch
34+ backport.
35+
36+ -- Marc Deslauriers <marc.deslauriers@ubuntu.com> Wed, 11 Aug 2021 14:02:09 -0400
37+
38+openssh (1:7.6p1-4ubuntu0.4) bionic; urgency=medium
39+
40+ * Apply upstream patch to stop using 2020 as a future date in regress
41+ tests. LP: #1859013
42+
43+ -- Dimitri John Ledkov <xnox@ubuntu.com> Fri, 10 Jan 2020 00:00:50 +0000
44+
45+openssh (1:7.6p1-4ubuntu0.3) bionic-security; urgency=medium
46+
47+ * SECURITY UPDATE: Incomplete fix for CVE-2019-6111
48+ - debian/patches/CVE-2019-6111-2.patch: add another fix to the filename
49+ check in scp.c.
50+ - CVE-2019-6111
51+ * Fixed inverted CVE numbers in patch filenames and in previous
52+ changelog.
53+
54+ -- Marc Deslauriers <marc.deslauriers@ubuntu.com> Mon, 04 Mar 2019 07:17:51 -0500
55+
56+openssh (1:7.6p1-4ubuntu0.2) bionic-security; urgency=medium
57+
58+ * SECURITY UPDATE: access restrictions bypass in scp
59+ - debian/patches/CVE-2018-20685.patch: disallow empty filenames
60+ or ones that refer to the current directory in scp.c.
61+ - CVE-2018-20685
62+ * SECURITY UPDATE: scp client spoofing via object name
63+ - debian/patches/CVE-2019-6111.patch: make sure the filenames match
64+ the wildcard specified by the user, and add new flag to relax the new
65+ restrictions in scp.c, scp.1.
66+ - CVE-2019-6111
67+ * SECURITY UPDATE: scp client missing received object name validation
68+ - debian/patches/CVE-2019-6109-1.patch: sanitize scp filenames via
69+ snmprintf in atomicio.c, progressmeter.c, progressmeter.h,
70+ scp.c, sftp-client.c.
71+ - debian/patches/CVE-2019-6109-2.patch: force progressmeter updates in
72+ progressmeter.c, progressmeter.h, scp.c, sftp-client.c.
73+ - CVE-2019-6109
74+
75+ -- Marc Deslauriers <marc.deslauriers@ubuntu.com> Thu, 31 Jan 2019 08:58:34 -0500
76+
77+openssh (1:7.6p1-4ubuntu0.1) bionic-security; urgency=medium
78+
79+ [ Ryan Finnie ]
80+ * SECURITY UPDATE: OpenSSH User Enumeration Vulnerability (LP: #1794629)
81+ - debian/patches/CVE-2018-15473.patch: delay bailout for invalid
82+ authenticating user until after the packet containing the request
83+ has been fully parsed.
84+ - CVE-2018-15473
85+
86+ -- Leonidas S. Barbosa <leo.barbosa@canonical.com> Mon, 05 Nov 2018 08:51:29 -0300
87+>>>>>>> debian/changelog
88
89 openssh (1:7.6p1-4) unstable; urgency=medium
90
91diff --git a/debian/control b/debian/control
92index f9dc5f7..98035fb 100644
93--- a/debian/control
94+++ b/debian/control
95@@ -1,9 +1,17 @@
96 Source: openssh
97 Section: net
98 Priority: standard
99+<<<<<<< debian/control
100 Maintainer: Debian OpenSSH Maintainers <debian-ssh@lists.debian.org>
101 Build-Depends: debhelper (>= 13.1~),
102 debhelper-compat (= 13),
103+=======
104+Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
105+XSBC-Original-Maintainer: Debian OpenSSH Maintainers <debian-ssh@lists.debian.org>
106+Build-Depends: autotools-dev,
107+ debhelper (>= 9.20160709~),
108+ dh-autoreconf,
109+>>>>>>> debian/control
110 dh-exec,
111 dh-runit (>= 2.8.8),
112 dpkg-dev (>= 1.16.1~),
113diff --git a/debian/patches/0001-upstream-preserve-group-world-read-permission-on-kno.patch b/debian/patches/0001-upstream-preserve-group-world-read-permission-on-kno.patch
114new file mode 100644
115index 0000000..433ebfb
116--- /dev/null
117+++ b/debian/patches/0001-upstream-preserve-group-world-read-permission-on-kno.patch
118@@ -0,0 +1,46 @@
119+From: "djm@openbsd.org" <djm@openbsd.org>
120+Date: Wed, 13 May 2020 09:55:57 +0000
121+Subject: upstream: preserve group/world read permission on known_hosts
122+
123+file across runs of "ssh-keygen -Rf /path". The old behaviour was to remove
124+all rights for group/other. bz#3146 ok dtucker@
125+
126+OpenBSD-Commit-ID: dc369d0e0b5dd826430c63fd5f4b269953448a8a
127+
128+Origin: backport, https://github.com/openssh/openssh-portable/commit/f2d84f1b3fa68d77c99238d4c645d0266fae2a74
129+Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=3146
130+Bug-Ubuntu: https://bugs.launchpad.net/openssh/+bug/1966591
131+Applied-Upstream: 8.4
132+---
133+ ssh-keygen.c | 4 ++++
134+ 1 file changed, 4 insertions(+)
135+
136+diff --git a/ssh-keygen.c b/ssh-keygen.c
137+index 835f7d0..bfc5233 100644
138+--- a/ssh-keygen.c
139++++ b/ssh-keygen.c
140+@@ -1235,6 +1235,7 @@ do_known_hosts(struct passwd *pw, const char *name)
141+ int r, fd, oerrno, inplace = 0;
142+ struct known_hosts_ctx ctx;
143+ u_int foreach_options;
144++ struct stat sb;
145+
146+ if (!have_identity) {
147+ cp = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE, pw->pw_uid);
148+@@ -1244,6 +1245,8 @@ do_known_hosts(struct passwd *pw, const char *name)
149+ free(cp);
150+ have_identity = 1;
151+ }
152++ if (stat(identity_file, &sb) != 0)
153++ fatal("Cannot stat %s: %s", identity_file, strerror(errno));
154+
155+ memset(&ctx, 0, sizeof(ctx));
156+ ctx.out = stdout;
157+@@ -1267,6 +1270,7 @@ do_known_hosts(struct passwd *pw, const char *name)
158+ unlink(tmp);
159+ fatal("fdopen: %s", strerror(oerrno));
160+ }
161++ fchmod(fd, sb.st_mode & 0644);
162+ inplace = 1;
163+ }
164+
165diff --git a/debian/patches/CVE-2018-15473.patch b/debian/patches/CVE-2018-15473.patch
166new file mode 100644
167index 0000000..f439e37
168--- /dev/null
169+++ b/debian/patches/CVE-2018-15473.patch
170@@ -0,0 +1,138 @@
171+Updated: 2021-08-11
172+Backport of:
173+
174+From 779974d35b4859c07bc3cb8a12c74b43b0a7d1e0 Mon Sep 17 00:00:00 2001
175+From: djm <djm@openbsd.org>
176+Date: Tue, 31 Jul 2018 03:10:27 +0000
177+Subject: [PATCH] =?UTF-8?q?delay=20bailout=20for=20invalid=20authenticatin?=
178+ =?UTF-8?q?g=20user=20until=20after=20the=20packet=20containing=20the=20re?=
179+ =?UTF-8?q?quest=20has=20been=20fully=20parsed.=20Reported=20by=20Dariusz?=
180+ =?UTF-8?q?=20Tytko=20and=20Micha=C5=82=20Sajdak;=20ok=20deraadt?=
181+MIME-Version: 1.0
182+Content-Type: text/plain; charset=UTF-8
183+Content-Transfer-Encoding: 8bit
184+
185+delay bailout for invalid authenticating user until after the packet
186+containing the request has been fully parsed.
187+
188+---
189+ auth2-gss.c | 9 ++++++---
190+ auth2-hostbased.c | 9 +++++----
191+ auth2-pubkey.c | 21 ++++++++++++++-------
192+ 3 files changed, 25 insertions(+), 14 deletions(-)
193+
194+--- a/auth2-gss.c
195++++ b/auth2-gss.c
196+@@ -104,9 +104,6 @@ userauth_gssapi(struct ssh *ssh)
197+ u_int len;
198+ u_char *doid = NULL;
199+
200+- if (!authctxt->valid || authctxt->user == NULL)
201+- return (0);
202+-
203+ mechs = packet_get_int();
204+ if (mechs == 0) {
205+ debug("Mechanism negotiation is not supported");
206+@@ -137,6 +134,12 @@ userauth_gssapi(struct ssh *ssh)
207+ return (0);
208+ }
209+
210++ if (!authctxt->valid || authctxt->user == NULL) {
211++ debug2("%s: disabled because of invalid user", __func__);
212++ free(doid);
213++ return (0);
214++ }
215++
216+ if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, &goid)))) {
217+ if (ctxt != NULL)
218+ ssh_gssapi_delete_ctx(&ctxt);
219+--- a/auth2-hostbased.c
220++++ b/auth2-hostbased.c
221+@@ -67,10 +67,6 @@ userauth_hostbased(struct ssh *ssh)
222+ size_t alen, blen, slen;
223+ int r, pktype, authenticated = 0;
224+
225+- if (!authctxt->valid) {
226+- debug2("%s: disabled because of invalid user", __func__);
227+- return 0;
228+- }
229+ /* XXX use sshkey_froms() */
230+ if ((r = sshpkt_get_cstring(ssh, &pkalg, &alen)) != 0 ||
231+ (r = sshpkt_get_string(ssh, &pkblob, &blen)) != 0 ||
232+@@ -118,6 +114,11 @@ userauth_hostbased(struct ssh *ssh)
233+ goto done;
234+ }
235+
236++ if (!authctxt->valid || authctxt->user == NULL) {
237++ debug2("%s: disabled because of invalid user", __func__);
238++ goto done;
239++ }
240++
241+ service = ssh->compat & SSH_BUG_HBSERVICE ? "ssh-userauth" :
242+ authctxt->service;
243+ if ((b = sshbuf_new()) == NULL)
244+--- a/auth2-pubkey.c
245++++ b/auth2-pubkey.c
246+@@ -77,18 +77,14 @@ static int
247+ userauth_pubkey(struct ssh *ssh)
248+ {
249+ Authctxt *authctxt = ssh->authctxt;
250+- struct sshbuf *b;
251++ struct sshbuf *b = NULL;
252+ struct sshkey *key = NULL;
253+- char *pkalg, *userstyle = NULL, *fp = NULL;
254+- u_char *pkblob, *sig, have_sig;
255++ char *pkalg = NULL, *userstyle = NULL, *fp = NULL;
256++ u_char *pkblob = NULL, *sig = NULL, have_sig;
257+ size_t blen, slen;
258+ int r, pktype;
259+ int authenticated = 0;
260+
261+- if (!authctxt->valid) {
262+- debug2("%s: disabled because of invalid user", __func__);
263+- return 0;
264+- }
265+ if ((r = sshpkt_get_u8(ssh, &have_sig)) != 0)
266+ fatal("%s: sshpkt_get_u8 failed: %s", __func__, ssh_err(r));
267+ if (ssh->compat & SSH_BUG_PKAUTH) {
268+@@ -166,6 +162,12 @@ userauth_pubkey(struct ssh *ssh)
269+ fatal("%s: sshbuf_put_string session id: %s",
270+ __func__, ssh_err(r));
271+ }
272++ if (!authctxt->valid || authctxt->user == NULL) {
273++ debug2("%s: disabled because of invalid user",
274++ __func__);
275++ sshbuf_free(b);
276++ goto done;
277++ }
278+ /* reconstruct packet */
279+ xasprintf(&userstyle, "%s%s%s", authctxt->user,
280+ authctxt->style ? ":" : "",
281+@@ -202,7 +204,6 @@ userauth_pubkey(struct ssh *ssh)
282+ authenticated = 1;
283+ }
284+ sshbuf_free(b);
285+- free(sig);
286+ auth2_record_key(authctxt, authenticated, key);
287+ } else {
288+ debug("%s: test whether pkalg/pkblob are acceptable for %s %s",
289+@@ -210,6 +211,11 @@ userauth_pubkey(struct ssh *ssh)
290+ if ((r = sshpkt_get_end(ssh)) != 0)
291+ fatal("%s: %s", __func__, ssh_err(r));
292+
293++ if (!authctxt->valid || authctxt->user == NULL) {
294++ debug2("%s: disabled because of invalid user",
295++ __func__);
296++ goto done;
297++ }
298+ /* XXX fake reply and always send PK_OK ? */
299+ /*
300+ * XXX this allows testing whether a user is allowed
301+@@ -238,6 +244,7 @@ done:
302+ free(pkalg);
303+ free(pkblob);
304+ free(fp);
305++ free(sig);
306+ return authenticated;
307+ }
308+
309diff --git a/debian/patches/CVE-2018-20685.patch b/debian/patches/CVE-2018-20685.patch
310new file mode 100644
311index 0000000..0c2b94a
312--- /dev/null
313+++ b/debian/patches/CVE-2018-20685.patch
314@@ -0,0 +1,29 @@
315+Backport of:
316+
317+From 6010c0303a422a9c5fa8860c061bf7105eb7f8b2 Mon Sep 17 00:00:00 2001
318+From: "djm@openbsd.org" <djm@openbsd.org>
319+Date: Fri, 16 Nov 2018 03:03:10 +0000
320+Subject: [PATCH] upstream: disallow empty incoming filename or ones that refer
321+ to the
322+
323+current directory; based on report/patch from Harry Sintonen
324+
325+OpenBSD-Commit-ID: f27651b30eaee2df49540ab68d030865c04f6de9
326+---
327+ scp.c | 5 +++--
328+ 1 file changed, 3 insertions(+), 2 deletions(-)
329+
330+Index: openssh-7.6p1/scp.c
331+===================================================================
332+--- openssh-7.6p1.orig/scp.c 2019-01-31 08:56:55.553635620 -0500
333++++ openssh-7.6p1/scp.c 2019-01-31 08:56:55.553635620 -0500
334+@@ -1073,7 +1073,8 @@ sink(int argc, char **argv)
335+ SCREWUP("size out of range");
336+ size = (off_t)ull;
337+
338+- if ((strchr(cp, '/') != NULL) || (strcmp(cp, "..") == 0)) {
339++ if (*cp == '\0' || strchr(cp, '/') != NULL ||
340++ strcmp(cp, ".") == 0 || strcmp(cp, "..") == 0) {
341+ run_err("error: unexpected filename: %s", cp);
342+ exit(1);
343+ }
344diff --git a/debian/patches/CVE-2019-6109-1.patch b/debian/patches/CVE-2019-6109-1.patch
345new file mode 100644
346index 0000000..7da9698
347--- /dev/null
348+++ b/debian/patches/CVE-2019-6109-1.patch
349@@ -0,0 +1,253 @@
350+Backport of:
351+
352+From 8976f1c4b2721c26e878151f52bdf346dfe2d54c Mon Sep 17 00:00:00 2001
353+From: "dtucker@openbsd.org" <dtucker@openbsd.org>
354+Date: Wed, 23 Jan 2019 08:01:46 +0000
355+Subject: [PATCH] upstream: Sanitize scp filenames via snmprintf. To do this we
356+ move
357+
358+the progressmeter formatting outside of signal handler context and have the
359+atomicio callback called for EINTR too. bz#2434 with contributions from djm
360+and jjelen at redhat.com, ok djm@
361+
362+OpenBSD-Commit-ID: 1af61c1f70e4f3bd8ab140b9f1fa699481db57d8
363+---
364+ atomicio.c | 20 ++++++++++++++-----
365+ progressmeter.c | 53 ++++++++++++++++++++++---------------------------
366+ progressmeter.h | 3 ++-
367+ scp.c | 3 ++-
368+ sftp-client.c | 18 +++++++++--------
369+ 5 files changed, 53 insertions(+), 44 deletions(-)
370+
371+Index: openssh-7.6p1/atomicio.c
372+===================================================================
373+--- openssh-7.6p1.orig/atomicio.c 2019-01-31 08:58:23.885841566 -0500
374++++ openssh-7.6p1/atomicio.c 2019-01-31 08:58:23.881841557 -0500
375+@@ -65,9 +65,14 @@ atomicio6(ssize_t (*f) (int, void *, siz
376+ res = (f) (fd, s + pos, n - pos);
377+ switch (res) {
378+ case -1:
379+- if (errno == EINTR)
380++ if (errno == EINTR) {
381++ /* possible SIGALARM, update callback */
382++ if (cb != NULL && cb(cb_arg, 0) == -1) {
383++ errno = EINTR;
384++ return pos;
385++ }
386+ continue;
387+- if (errno == EAGAIN || errno == EWOULDBLOCK) {
388++ } else if (errno == EAGAIN || errno == EWOULDBLOCK) {
389+ #ifndef BROKEN_READ_COMPARISON
390+ (void)poll(&pfd, 1, -1);
391+ #endif
392+@@ -122,9 +127,14 @@ atomiciov6(ssize_t (*f) (int, const stru
393+ res = (f) (fd, iov, iovcnt);
394+ switch (res) {
395+ case -1:
396+- if (errno == EINTR)
397++ if (errno == EINTR) {
398++ /* possible SIGALARM, update callback */
399++ if (cb != NULL && cb(cb_arg, 0) == -1) {
400++ errno = EINTR;
401++ return pos;
402++ }
403+ continue;
404+- if (errno == EAGAIN || errno == EWOULDBLOCK) {
405++ } else if (errno == EAGAIN || errno == EWOULDBLOCK) {
406+ #ifndef BROKEN_READV_COMPARISON
407+ (void)poll(&pfd, 1, -1);
408+ #endif
409+Index: openssh-7.6p1/progressmeter.c
410+===================================================================
411+--- openssh-7.6p1.orig/progressmeter.c 2019-01-31 08:58:23.885841566 -0500
412++++ openssh-7.6p1/progressmeter.c 2019-01-31 08:58:23.881841557 -0500
413+@@ -31,6 +31,7 @@
414+
415+ #include <errno.h>
416+ #include <signal.h>
417++#include <stdarg.h>
418+ #include <stdio.h>
419+ #include <string.h>
420+ #include <time.h>
421+@@ -39,6 +40,7 @@
422+ #include "progressmeter.h"
423+ #include "atomicio.h"
424+ #include "misc.h"
425++#include "utf8.h"
426+
427+ #define DEFAULT_WINSIZE 80
428+ #define MAX_WINSIZE 512
429+@@ -61,7 +63,7 @@ static void setscreensize(void);
430+ void refresh_progress_meter(void);
431+
432+ /* signal handler for updating the progress meter */
433+-static void update_progress_meter(int);
434++static void sig_alarm(int);
435+
436+ static double start; /* start progress */
437+ static double last_update; /* last progress update */
438+@@ -74,6 +76,7 @@ static long stalled; /* how long we hav
439+ static int bytes_per_second; /* current speed in bytes per second */
440+ static int win_size; /* terminal window size */
441+ static volatile sig_atomic_t win_resized; /* for window resizing */
442++static volatile sig_atomic_t alarm_fired;
443+
444+ /* units for format_size */
445+ static const char unit[] = " KMGT";
446+@@ -126,9 +129,17 @@ refresh_progress_meter(void)
447+ off_t bytes_left;
448+ int cur_speed;
449+ int hours, minutes, seconds;
450+- int i, len;
451+ int file_len;
452+
453++ if ((!alarm_fired && !win_resized) || !can_output())
454++ return;
455++ alarm_fired = 0;
456++
457++ if (win_resized) {
458++ setscreensize();
459++ win_resized = 0;
460++ }
461++
462+ transferred = *counter - (cur_pos ? cur_pos : start_pos);
463+ cur_pos = *counter;
464+ now = monotime_double();
465+@@ -158,16 +169,11 @@ refresh_progress_meter(void)
466+
467+ /* filename */
468+ buf[0] = '\0';
469+- file_len = win_size - 35;
470++ file_len = win_size - 36;
471+ if (file_len > 0) {
472+- len = snprintf(buf, file_len + 1, "\r%s", file);
473+- if (len < 0)
474+- len = 0;
475+- if (len >= file_len + 1)
476+- len = file_len;
477+- for (i = len; i < file_len; i++)
478+- buf[i] = ' ';
479+- buf[file_len] = '\0';
480++ buf[0] = '\r';
481++ snmprintf(buf+1, sizeof(buf)-1 , &file_len, "%*s",
482++ file_len * -1, file);
483+ }
484+
485+ /* percent of transfer done */
486+@@ -228,22 +234,11 @@ refresh_progress_meter(void)
487+
488+ /*ARGSUSED*/
489+ static void
490+-update_progress_meter(int ignore)
491++sig_alarm(int ignore)
492+ {
493+- int save_errno;
494+-
495+- save_errno = errno;
496+-
497+- if (win_resized) {
498+- setscreensize();
499+- win_resized = 0;
500+- }
501+- if (can_output())
502+- refresh_progress_meter();
503+-
504+- signal(SIGALRM, update_progress_meter);
505++ signal(SIGALRM, sig_alarm);
506++ alarm_fired = 1;
507+ alarm(UPDATE_INTERVAL);
508+- errno = save_errno;
509+ }
510+
511+ void
512+@@ -259,10 +254,9 @@ start_progress_meter(const char *f, off_
513+ bytes_per_second = 0;
514+
515+ setscreensize();
516+- if (can_output())
517+- refresh_progress_meter();
518++ refresh_progress_meter();
519+
520+- signal(SIGALRM, update_progress_meter);
521++ signal(SIGALRM, sig_alarm);
522+ signal(SIGWINCH, sig_winch);
523+ alarm(UPDATE_INTERVAL);
524+ }
525+@@ -286,6 +280,7 @@ stop_progress_meter(void)
526+ static void
527+ sig_winch(int sig)
528+ {
529++ signal(SIGWINCH, sig_winch);
530+ win_resized = 1;
531+ }
532+
533+Index: openssh-7.6p1/progressmeter.h
534+===================================================================
535+--- openssh-7.6p1.orig/progressmeter.h 2019-01-31 08:58:23.885841566 -0500
536++++ openssh-7.6p1/progressmeter.h 2019-01-31 08:58:23.881841557 -0500
537+@@ -24,4 +24,5 @@
538+ */
539+
540+ void start_progress_meter(const char *, off_t, off_t *);
541++void refresh_progress_meter(void);
542+ void stop_progress_meter(void);
543+Index: openssh-7.6p1/scp.c
544+===================================================================
545+--- openssh-7.6p1.orig/scp.c 2019-01-31 08:58:23.885841566 -0500
546++++ openssh-7.6p1/scp.c 2019-01-31 08:58:23.881841557 -0500
547+@@ -580,6 +580,7 @@ scpio(void *_cnt, size_t s)
548+ off_t *cnt = (off_t *)_cnt;
549+
550+ *cnt += s;
551++ refresh_progress_meter();
552+ if (limit_kbps > 0)
553+ bandwidth_limit(&bwlimit, s);
554+ return 0;
555+Index: openssh-7.6p1/sftp-client.c
556+===================================================================
557+--- openssh-7.6p1.orig/sftp-client.c 2019-01-31 08:58:23.885841566 -0500
558++++ openssh-7.6p1/sftp-client.c 2019-01-31 08:58:23.881841557 -0500
559+@@ -101,7 +101,9 @@ sftpio(void *_bwlimit, size_t amount)
560+ {
561+ struct bwlimit *bwlimit = (struct bwlimit *)_bwlimit;
562+
563+- bandwidth_limit(bwlimit, amount);
564++ refresh_progress_meter();
565++ if (bwlimit != NULL)
566++ bandwidth_limit(bwlimit, amount);
567+ return 0;
568+ }
569+
570+@@ -121,8 +123,8 @@ send_msg(struct sftp_conn *conn, struct
571+ iov[1].iov_base = (u_char *)sshbuf_ptr(m);
572+ iov[1].iov_len = sshbuf_len(m);
573+
574+- if (atomiciov6(writev, conn->fd_out, iov, 2,
575+- conn->limit_kbps > 0 ? sftpio : NULL, &conn->bwlimit_out) !=
576++ if (atomiciov6(writev, conn->fd_out, iov, 2, sftpio,
577++ conn->limit_kbps > 0 ? &conn->bwlimit_out : NULL) !=
578+ sshbuf_len(m) + sizeof(mlen))
579+ fatal("Couldn't send packet: %s", strerror(errno));
580+
581+@@ -138,8 +140,8 @@ get_msg(struct sftp_conn *conn, struct s
582+
583+ if ((r = sshbuf_reserve(m, 4, &p)) != 0)
584+ fatal("%s: buffer error: %s", __func__, ssh_err(r));
585+- if (atomicio6(read, conn->fd_in, p, 4,
586+- conn->limit_kbps > 0 ? sftpio : NULL, &conn->bwlimit_in) != 4) {
587++ if (atomicio6(read, conn->fd_in, p, 4, sftpio,
588++ conn->limit_kbps > 0 ? &conn->bwlimit_in : NULL) != 4) {
589+ if (errno == EPIPE || errno == ECONNRESET)
590+ fatal("Connection closed");
591+ else
592+@@ -153,8 +155,8 @@ get_msg(struct sftp_conn *conn, struct s
593+
594+ if ((r = sshbuf_reserve(m, msg_len, &p)) != 0)
595+ fatal("%s: buffer error: %s", __func__, ssh_err(r));
596+- if (atomicio6(read, conn->fd_in, p, msg_len,
597+- conn->limit_kbps > 0 ? sftpio : NULL, &conn->bwlimit_in)
598++ if (atomicio6(read, conn->fd_in, p, msg_len, sftpio,
599++ conn->limit_kbps > 0 ? &conn->bwlimit_in : NULL)
600+ != msg_len) {
601+ if (errno == EPIPE)
602+ fatal("Connection closed");
603diff --git a/debian/patches/CVE-2019-6109-2.patch b/debian/patches/CVE-2019-6109-2.patch
604new file mode 100644
605index 0000000..0cdc6d3
606--- /dev/null
607+++ b/debian/patches/CVE-2019-6109-2.patch
608@@ -0,0 +1,106 @@
609+Backport of:
610+
611+From bdc6c63c80b55bcbaa66b5fde31c1cb1d09a41eb Mon Sep 17 00:00:00 2001
612+From: "dtucker@openbsd.org" <dtucker@openbsd.org>
613+Date: Thu, 24 Jan 2019 16:52:17 +0000
614+Subject: [PATCH] upstream: Have progressmeter force an update at the beginning
615+ and
616+
617+end of each transfer. Fixes the problem recently introduces where very quick
618+transfers do not display the progressmeter at all. Spotted by naddy@
619+
620+OpenBSD-Commit-ID: 68dc46c259e8fdd4f5db3ec2a130f8e4590a7a9a
621+---
622+ progressmeter.c | 13 +++++--------
623+ progressmeter.h | 4 ++--
624+ scp.c | 4 ++--
625+ sftp-client.c | 4 ++--
626+ 4 files changed, 11 insertions(+), 14 deletions(-)
627+
628+Index: openssh-7.6p1/progressmeter.c
629+===================================================================
630+--- openssh-7.6p1.orig/progressmeter.c 2019-01-31 08:58:29.833855684 -0500
631++++ openssh-7.6p1/progressmeter.c 2019-01-31 08:58:29.833855684 -0500
632+@@ -59,9 +59,6 @@ static void format_rate(char *, int, off
633+ static void sig_winch(int);
634+ static void setscreensize(void);
635+
636+-/* updates the progressmeter to reflect the current state of the transfer */
637+-void refresh_progress_meter(void);
638+-
639+ /* signal handler for updating the progress meter */
640+ static void sig_alarm(int);
641+
642+@@ -120,7 +117,7 @@ format_size(char *buf, int size, off_t b
643+ }
644+
645+ void
646+-refresh_progress_meter(void)
647++refresh_progress_meter(int force_update)
648+ {
649+ char buf[MAX_WINSIZE + 1];
650+ off_t transferred;
651+@@ -131,7 +128,7 @@ refresh_progress_meter(void)
652+ int hours, minutes, seconds;
653+ int file_len;
654+
655+- if ((!alarm_fired && !win_resized) || !can_output())
656++ if ((!force_update && !alarm_fired && !win_resized) || !can_output())
657+ return;
658+ alarm_fired = 0;
659+
660+@@ -254,7 +251,7 @@ start_progress_meter(const char *f, off_
661+ bytes_per_second = 0;
662+
663+ setscreensize();
664+- refresh_progress_meter();
665++ refresh_progress_meter(1);
666+
667+ signal(SIGALRM, sig_alarm);
668+ signal(SIGWINCH, sig_winch);
669+@@ -271,7 +268,7 @@ stop_progress_meter(void)
670+
671+ /* Ensure we complete the progress */
672+ if (cur_pos != end_pos)
673+- refresh_progress_meter();
674++ refresh_progress_meter(1);
675+
676+ atomicio(vwrite, STDOUT_FILENO, "\n", 1);
677+ }
678+Index: openssh-7.6p1/progressmeter.h
679+===================================================================
680+--- openssh-7.6p1.orig/progressmeter.h 2019-01-31 08:58:29.833855684 -0500
681++++ openssh-7.6p1/progressmeter.h 2019-01-31 08:58:29.833855684 -0500
682+@@ -24,5 +24,5 @@
683+ */
684+
685+ void start_progress_meter(const char *, off_t, off_t *);
686+-void refresh_progress_meter(void);
687++void refresh_progress_meter(int);
688+ void stop_progress_meter(void);
689+Index: openssh-7.6p1/scp.c
690+===================================================================
691+--- openssh-7.6p1.orig/scp.c 2019-01-31 08:58:29.833855684 -0500
692++++ openssh-7.6p1/scp.c 2019-01-31 08:58:29.833855684 -0500
693+@@ -580,7 +580,7 @@ scpio(void *_cnt, size_t s)
694+ off_t *cnt = (off_t *)_cnt;
695+
696+ *cnt += s;
697+- refresh_progress_meter();
698++ refresh_progress_meter(0);
699+ if (limit_kbps > 0)
700+ bandwidth_limit(&bwlimit, s);
701+ return 0;
702+Index: openssh-7.6p1/sftp-client.c
703+===================================================================
704+--- openssh-7.6p1.orig/sftp-client.c 2019-01-31 08:58:29.833855684 -0500
705++++ openssh-7.6p1/sftp-client.c 2019-01-31 08:58:29.833855684 -0500
706+@@ -101,7 +101,7 @@ sftpio(void *_bwlimit, size_t amount)
707+ {
708+ struct bwlimit *bwlimit = (struct bwlimit *)_bwlimit;
709+
710+- refresh_progress_meter();
711++ refresh_progress_meter(0);
712+ if (bwlimit != NULL)
713+ bandwidth_limit(bwlimit, amount);
714+ return 0;
715diff --git a/debian/patches/CVE-2019-6111-2.patch b/debian/patches/CVE-2019-6111-2.patch
716new file mode 100644
717index 0000000..21aa8fc
718--- /dev/null
719+++ b/debian/patches/CVE-2019-6111-2.patch
720@@ -0,0 +1,348 @@
721+From 3d896c157c722bc47adca51a58dca859225b5874 Mon Sep 17 00:00:00 2001
722+From: "djm@openbsd.org" <djm@openbsd.org>
723+Date: Sun, 10 Feb 2019 11:15:52 +0000
724+Subject: [PATCH] upstream: when checking that filenames sent by the server
725+ side
726+
727+match what the client requested, be prepared to handle shell-style brace
728+alternations, e.g. "{foo,bar}".
729+
730+"looks good to me" millert@ + in snaps for the last week courtesy
731+deraadt@
732+
733+OpenBSD-Commit-ID: 3b1ce7639b0b25b2248e3a30f561a548f6815f3e
734+---
735+ scp.c | 282 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---
736+ 1 file changed, 270 insertions(+), 12 deletions(-)
737+
738+Index: openssh-7.6p1/scp.c
739+===================================================================
740+--- openssh-7.6p1.orig/scp.c 2019-03-04 07:17:32.294099797 -0500
741++++ openssh-7.6p1/scp.c 2019-03-04 07:17:32.294099797 -0500
742+@@ -604,6 +604,253 @@ do_times(int fd, int verb, const struct
743+ return (response());
744+ }
745+
746++/* Appends a string to an array; returns 0 on success, -1 on alloc failure */
747++static int
748++append(char *cp, char ***ap, size_t *np)
749++{
750++ char **tmp;
751++
752++ if ((tmp = reallocarray(*ap, *np + 1, sizeof(*tmp))) == NULL)
753++ return -1;
754++ tmp[(*np)] = cp;
755++ (*np)++;
756++ *ap = tmp;
757++ return 0;
758++}
759++
760++/*
761++ * Finds the start and end of the first brace pair in the pattern.
762++ * returns 0 on success or -1 for invalid patterns.
763++ */
764++static int
765++find_brace(const char *pattern, int *startp, int *endp)
766++{
767++ int i;
768++ int in_bracket, brace_level;
769++
770++ *startp = *endp = -1;
771++ in_bracket = brace_level = 0;
772++ for (i = 0; i < INT_MAX && *endp < 0 && pattern[i] != '\0'; i++) {
773++ switch (pattern[i]) {
774++ case '\\':
775++ /* skip next character */
776++ if (pattern[i + 1] != '\0')
777++ i++;
778++ break;
779++ case '[':
780++ in_bracket = 1;
781++ break;
782++ case ']':
783++ in_bracket = 0;
784++ break;
785++ case '{':
786++ if (in_bracket)
787++ break;
788++ if (pattern[i + 1] == '}') {
789++ /* Protect a single {}, for find(1), like csh */
790++ i++; /* skip */
791++ break;
792++ }
793++ if (*startp == -1)
794++ *startp = i;
795++ brace_level++;
796++ break;
797++ case '}':
798++ if (in_bracket)
799++ break;
800++ if (*startp < 0) {
801++ /* Unbalanced brace */
802++ return -1;
803++ }
804++ if (--brace_level <= 0)
805++ *endp = i;
806++ break;
807++ }
808++ }
809++ /* unbalanced brackets/braces */
810++ if (*endp < 0 && (*startp >= 0 || in_bracket))
811++ return -1;
812++ return 0;
813++}
814++
815++/*
816++ * Assembles and records a successfully-expanded pattern, returns -1 on
817++ * alloc failure.
818++ */
819++static int
820++emit_expansion(const char *pattern, int brace_start, int brace_end,
821++ int sel_start, int sel_end, char ***patternsp, size_t *npatternsp)
822++{
823++ char *cp;
824++ int o = 0, tail_len = strlen(pattern + brace_end + 1);
825++
826++ if ((cp = malloc(brace_start + (sel_end - sel_start) +
827++ tail_len + 1)) == NULL)
828++ return -1;
829++
830++ /* Pattern before initial brace */
831++ if (brace_start > 0) {
832++ memcpy(cp, pattern, brace_start);
833++ o = brace_start;
834++ }
835++ /* Current braced selection */
836++ if (sel_end - sel_start > 0) {
837++ memcpy(cp + o, pattern + sel_start,
838++ sel_end - sel_start);
839++ o += sel_end - sel_start;
840++ }
841++ /* Remainder of pattern after closing brace */
842++ if (tail_len > 0) {
843++ memcpy(cp + o, pattern + brace_end + 1, tail_len);
844++ o += tail_len;
845++ }
846++ cp[o] = '\0';
847++ if (append(cp, patternsp, npatternsp) != 0) {
848++ free(cp);
849++ return -1;
850++ }
851++ return 0;
852++}
853++
854++/*
855++ * Expand the first encountered brace in pattern, appending the expanded
856++ * patterns it yielded to the *patternsp array.
857++ *
858++ * Returns 0 on success or -1 on allocation failure.
859++ *
860++ * Signals whether expansion was performed via *expanded and whether
861++ * pattern was invalid via *invalid.
862++ */
863++static int
864++brace_expand_one(const char *pattern, char ***patternsp, size_t *npatternsp,
865++ int *expanded, int *invalid)
866++{
867++ int i;
868++ int in_bracket, brace_start, brace_end, brace_level;
869++ int sel_start, sel_end;
870++
871++ *invalid = *expanded = 0;
872++
873++ if (find_brace(pattern, &brace_start, &brace_end) != 0) {
874++ *invalid = 1;
875++ return 0;
876++ } else if (brace_start == -1)
877++ return 0;
878++
879++ in_bracket = brace_level = 0;
880++ for (i = sel_start = brace_start + 1; i < brace_end; i++) {
881++ switch (pattern[i]) {
882++ case '{':
883++ if (in_bracket)
884++ break;
885++ brace_level++;
886++ break;
887++ case '}':
888++ if (in_bracket)
889++ break;
890++ brace_level--;
891++ break;
892++ case '[':
893++ in_bracket = 1;
894++ break;
895++ case ']':
896++ in_bracket = 0;
897++ break;
898++ case '\\':
899++ if (i < brace_end - 1)
900++ i++; /* skip */
901++ break;
902++ }
903++ if (pattern[i] == ',' || i == brace_end - 1) {
904++ if (in_bracket || brace_level > 0)
905++ continue;
906++ /* End of a selection, emit an expanded pattern */
907++
908++ /* Adjust end index for last selection */
909++ sel_end = (i == brace_end - 1) ? brace_end : i;
910++ if (emit_expansion(pattern, brace_start, brace_end,
911++ sel_start, sel_end, patternsp, npatternsp) != 0)
912++ return -1;
913++ /* move on to the next selection */
914++ sel_start = i + 1;
915++ continue;
916++ }
917++ }
918++ if (in_bracket || brace_level > 0) {
919++ *invalid = 1;
920++ return 0;
921++ }
922++ /* success */
923++ *expanded = 1;
924++ return 0;
925++}
926++
927++/* Expand braces from pattern. Returns 0 on success, -1 on failure */
928++static int
929++brace_expand(const char *pattern, char ***patternsp, size_t *npatternsp)
930++{
931++ char *cp, *cp2, **active = NULL, **done = NULL;
932++ size_t i, nactive = 0, ndone = 0;
933++ int ret = -1, invalid = 0, expanded = 0;
934++
935++ *patternsp = NULL;
936++ *npatternsp = 0;
937++
938++ /* Start the worklist with the original pattern */
939++ if ((cp = strdup(pattern)) == NULL)
940++ return -1;
941++ if (append(cp, &active, &nactive) != 0) {
942++ free(cp);
943++ return -1;
944++ }
945++ while (nactive > 0) {
946++ cp = active[nactive - 1];
947++ nactive--;
948++ if (brace_expand_one(cp, &active, &nactive,
949++ &expanded, &invalid) == -1) {
950++ free(cp);
951++ goto fail;
952++ }
953++ if (invalid)
954++ fatal("%s: invalid brace pattern \"%s\"", __func__, cp);
955++ if (expanded) {
956++ /*
957++ * Current entry expanded to new entries on the
958++ * active list; discard the progenitor pattern.
959++ */
960++ free(cp);
961++ continue;
962++ }
963++ /*
964++ * Pattern did not expand; append the finename component to
965++ * the completed list
966++ */
967++ if ((cp2 = strrchr(cp, '/')) != NULL)
968++ *cp2++ = '\0';
969++ else
970++ cp2 = cp;
971++ if (append(xstrdup(cp2), &done, &ndone) != 0) {
972++ free(cp);
973++ goto fail;
974++ }
975++ free(cp);
976++ }
977++ /* success */
978++ *patternsp = done;
979++ *npatternsp = ndone;
980++ done = NULL;
981++ ndone = 0;
982++ ret = 0;
983++ fail:
984++ for (i = 0; i < nactive; i++)
985++ free(active[i]);
986++ free(active);
987++ for (i = 0; i < ndone; i++)
988++ free(done[i]);
989++ free(done);
990++ return ret;
991++}
992++
993+ void
994+ toremote(char *targ, int argc, char **argv)
995+ {
996+@@ -959,7 +1206,8 @@ sink(int argc, char **argv, const char *
997+ unsigned long long ull;
998+ int setimes, targisdir, wrerrno = 0;
999+ char ch, *cp, *np, *targ, *why, *vect[1], buf[2048], visbuf[2048];
1000+- char *src_copy = NULL, *restrict_pattern = NULL;
1001++ char **patterns = NULL;
1002++ size_t n, npatterns = 0;
1003+ struct timeval tv[2];
1004+
1005+ #define atime tv[0]
1006+@@ -989,16 +1237,13 @@ sink(int argc, char **argv, const char *
1007+ * Prepare to try to restrict incoming filenames to match
1008+ * the requested destination file glob.
1009+ */
1010+- if ((src_copy = strdup(src)) == NULL)
1011+- fatal("strdup failed");
1012+- if ((restrict_pattern = strrchr(src_copy, '/')) != NULL) {
1013+- *restrict_pattern++ = '\0';
1014+- }
1015++ if (brace_expand(src, &patterns, &npatterns) != 0)
1016++ fatal("%s: could not expand pattern", __func__);
1017+ }
1018+ for (first = 1;; first = 0) {
1019+ cp = buf;
1020+ if (atomicio(read, remin, cp, 1) != 1)
1021+- return;
1022++ goto done;
1023+ if (*cp++ == '\n')
1024+ SCREWUP("unexpected <newline>");
1025+ do {
1026+@@ -1024,7 +1269,7 @@ sink(int argc, char **argv, const char *
1027+ }
1028+ if (buf[0] == 'E') {
1029+ (void) atomicio(vwrite, remout, "", 1);
1030+- return;
1031++ goto done;
1032+ }
1033+ if (ch == '\n')
1034+ *--cp = 0;
1035+@@ -1097,9 +1342,14 @@ sink(int argc, char **argv, const char *
1036+ run_err("error: unexpected filename: %s", cp);
1037+ exit(1);
1038+ }
1039+- if (restrict_pattern != NULL &&
1040+- fnmatch(restrict_pattern, cp, 0) != 0)
1041+- SCREWUP("filename does not match request");
1042++ if (npatterns > 0) {
1043++ for (n = 0; n < npatterns; n++) {
1044++ if (fnmatch(patterns[n], cp, 0) == 0)
1045++ break;
1046++ }
1047++ if (n >= npatterns)
1048++ SCREWUP("filename does not match request");
1049++ }
1050+ if (targisdir) {
1051+ static char *namebuf;
1052+ static size_t cursize;
1053+@@ -1258,7 +1508,15 @@ bad: run_err("%s: %s", np, strerror(er
1054+ break;
1055+ }
1056+ }
1057++done:
1058++ for (n = 0; n < npatterns; n++)
1059++ free(patterns[n]);
1060++ free(patterns);
1061++ return;
1062+ screwup:
1063++ for (n = 0; n < npatterns; n++)
1064++ free(patterns[n]);
1065++ free(patterns);
1066+ run_err("protocol error: %s", why);
1067+ exit(1);
1068+ }
1069diff --git a/debian/patches/CVE-2019-6111.patch b/debian/patches/CVE-2019-6111.patch
1070new file mode 100644
1071index 0000000..72b8bde
1072--- /dev/null
1073+++ b/debian/patches/CVE-2019-6111.patch
1074@@ -0,0 +1,182 @@
1075+Backport of:
1076+
1077+From 391ffc4b9d31fa1f4ad566499fef9176ff8a07dc Mon Sep 17 00:00:00 2001
1078+From: "djm@openbsd.org" <djm@openbsd.org>
1079+Date: Sat, 26 Jan 2019 22:41:28 +0000
1080+Subject: [PATCH] upstream: check in scp client that filenames sent during
1081+
1082+remote->local directory copies satisfy the wildcard specified by the user.
1083+
1084+This checking provides some protection against a malicious server
1085+sending unexpected filenames, but it comes at a risk of rejecting wanted
1086+files due to differences between client and server wildcard expansion rules.
1087+
1088+For this reason, this also adds a new -T flag to disable the check.
1089+
1090+reported by Harry Sintonen
1091+fix approach suggested by markus@;
1092+has been in snaps for ~1wk courtesy deraadt@
1093+
1094+OpenBSD-Commit-ID: 00f44b50d2be8e321973f3c6d014260f8f7a8eda
1095+---
1096+ scp.1 | 16 +++++++++++++---
1097+ scp.c | 39 ++++++++++++++++++++++++++++++---------
1098+ 2 files changed, 43 insertions(+), 12 deletions(-)
1099+
1100+Index: openssh-7.6p1/scp.1
1101+===================================================================
1102+--- openssh-7.6p1.orig/scp.1 2019-01-31 08:57:08.113664456 -0500
1103++++ openssh-7.6p1/scp.1 2019-01-31 08:57:44.625749147 -0500
1104+@@ -19,7 +19,7 @@
1105+ .Sh SYNOPSIS
1106+ .Nm scp
1107+ .Bk -words
1108+-.Op Fl 346BCpqrv
1109++.Op Fl 346BCpqrTv
1110+ .Op Fl c Ar cipher
1111+ .Op Fl F Ar ssh_config
1112+ .Op Fl i Ar identity_file
1113+@@ -202,6 +202,16 @@ to use for the encrypted connection.
1114+ The program must understand
1115+ .Xr ssh 1
1116+ options.
1117++.It Fl T
1118++Disable strict filename checking.
1119++By default when copying files from a remote host to a local directory
1120++.Nm
1121++checks that the received filenames match those requested on the command-line
1122++to prevent the remote end from sending unexpected or unwanted files.
1123++Because of differences in how various operating systems and shells interpret
1124++filename wildcards, these checks may cause wanted files to be rejected.
1125++This option disables these checks at the expense of fully trusting that
1126++the server will not send unexpected filenames.
1127+ .It Fl v
1128+ Verbose mode.
1129+ Causes
1130+Index: openssh-7.6p1/scp.c
1131+===================================================================
1132+--- openssh-7.6p1.orig/scp.c 2019-01-31 08:57:08.113664456 -0500
1133++++ openssh-7.6p1/scp.c 2019-01-31 08:57:08.109664446 -0500
1134+@@ -94,6 +94,7 @@
1135+ #include <dirent.h>
1136+ #include <errno.h>
1137+ #include <fcntl.h>
1138++#include <fnmatch.h>
1139+ #include <limits.h>
1140+ #include <locale.h>
1141+ #include <pwd.h>
1142+@@ -365,14 +366,14 @@ void verifydir(char *);
1143+ struct passwd *pwd;
1144+ uid_t userid;
1145+ int errs, remin, remout;
1146+-int pflag, iamremote, iamrecursive, targetshouldbedirectory;
1147++int Tflag, pflag, iamremote, iamrecursive, targetshouldbedirectory;
1148+
1149+ #define CMDNEEDS 64
1150+ char cmd[CMDNEEDS]; /* must hold "rcp -r -p -d\0" */
1151+
1152+ int response(void);
1153+ void rsource(char *, struct stat *);
1154+-void sink(int, char *[]);
1155++void sink(int, char *[], const char *);
1156+ void source(int, char *[]);
1157+ void tolocal(int, char *[]);
1158+ void toremote(char *, int, char *[]);
1159+@@ -409,8 +410,9 @@ main(int argc, char **argv)
1160+ addargs(&args, "-oPermitLocalCommand=no");
1161+ addargs(&args, "-oClearAllForwardings=yes");
1162+
1163+- fflag = tflag = 0;
1164+- while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q12346S:o:F:")) != -1)
1165++ fflag = Tflag = tflag = 0;
1166++ while ((ch = getopt(argc, argv,
1167++ "dfl:prtTvBCc:i:P:q12346S:o:F:")) != -1) {
1168+ switch (ch) {
1169+ /* User-visible flags. */
1170+ case '1':
1171+@@ -490,9 +492,13 @@ main(int argc, char **argv)
1172+ setmode(0, O_BINARY);
1173+ #endif
1174+ break;
1175++ case 'T':
1176++ Tflag = 1;
1177++ break;
1178+ default:
1179+ usage();
1180+ }
1181++ }
1182+ argc -= optind;
1183+ argv += optind;
1184+
1185+@@ -523,7 +529,7 @@ main(int argc, char **argv)
1186+ }
1187+ if (tflag) {
1188+ /* Receive data. */
1189+- sink(argc, argv);
1190++ sink(argc, argv, NULL);
1191+ exit(errs != 0);
1192+ }
1193+ if (argc < 2)
1194+@@ -763,7 +769,7 @@ tolocal(int argc, char **argv)
1195+ continue;
1196+ }
1197+ free(bp);
1198+- sink(1, argv + argc - 1);
1199++ sink(1, argv + argc - 1, src);
1200+ (void) close(remin);
1201+ remin = remout = -1;
1202+ }
1203+@@ -936,7 +942,7 @@ rsource(char *name, struct stat *statp)
1204+ (sizeof(type) != 4 && sizeof(type) != 8))
1205+
1206+ void
1207+-sink(int argc, char **argv)
1208++sink(int argc, char **argv, const char *src)
1209+ {
1210+ static BUF buffer;
1211+ struct stat stb;
1212+@@ -952,6 +958,7 @@ sink(int argc, char **argv)
1213+ unsigned long long ull;
1214+ int setimes, targisdir, wrerrno = 0;
1215+ char ch, *cp, *np, *targ, *why, *vect[1], buf[2048], visbuf[2048];
1216++ char *src_copy = NULL, *restrict_pattern = NULL;
1217+ struct timeval tv[2];
1218+
1219+ #define atime tv[0]
1220+@@ -976,6 +983,17 @@ sink(int argc, char **argv)
1221+ (void) atomicio(vwrite, remout, "", 1);
1222+ if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode))
1223+ targisdir = 1;
1224++ if (src != NULL && !iamrecursive && !Tflag) {
1225++ /*
1226++ * Prepare to try to restrict incoming filenames to match
1227++ * the requested destination file glob.
1228++ */
1229++ if ((src_copy = strdup(src)) == NULL)
1230++ fatal("strdup failed");
1231++ if ((restrict_pattern = strrchr(src_copy, '/')) != NULL) {
1232++ *restrict_pattern++ = '\0';
1233++ }
1234++ }
1235+ for (first = 1;; first = 0) {
1236+ cp = buf;
1237+ if (atomicio(read, remin, cp, 1) != 1)
1238+@@ -1078,6 +1096,9 @@ sink(int argc, char **argv)
1239+ run_err("error: unexpected filename: %s", cp);
1240+ exit(1);
1241+ }
1242++ if (restrict_pattern != NULL &&
1243++ fnmatch(restrict_pattern, cp, 0) != 0)
1244++ SCREWUP("filename does not match request");
1245+ if (targisdir) {
1246+ static char *namebuf;
1247+ static size_t cursize;
1248+@@ -1115,7 +1136,7 @@ sink(int argc, char **argv)
1249+ goto bad;
1250+ }
1251+ vect[0] = xstrdup(np);
1252+- sink(1, vect);
1253++ sink(1, vect, src);
1254+ if (setimes) {
1255+ setimes = 0;
1256+ if (utimes(vect[0], tv) < 0)
1257diff --git a/debian/patches/lp-1863930-Fix-logic-bug-in-sshd_exchange_identification.patch b/debian/patches/lp-1863930-Fix-logic-bug-in-sshd_exchange_identification.patch
1258new file mode 100644
1259index 0000000..5f9fc47
1260--- /dev/null
1261+++ b/debian/patches/lp-1863930-Fix-logic-bug-in-sshd_exchange_identification.patch
1262@@ -0,0 +1,31 @@
1263+From c9c1bba06ad1c7cad8548549a68c071bd807af60 Mon Sep 17 00:00:00 2001
1264+From: "stsp@openbsd.org" <stsp@openbsd.org>
1265+Date: Tue, 23 Jan 2018 20:00:58 +0000
1266+Subject: [PATCH] upstream commit
1267+
1268+Fix a logic bug in sshd_exchange_identification which
1269+prevented clients using major protocol version 2 from connecting to the
1270+server. ok millert@
1271+
1272+OpenBSD-Commit-ID: 8668dec04586e27f1c0eb039ef1feb93d80a5ee9
1273+
1274+Backport-Note: dropped the no-op file header change
1275+Origin: backport, https://anongit.mindrot.org/openssh.git/commit/?id=c9c1bba06
1276+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1863930
1277+Last-Update: 2020-03-03
1278+
1279+---
1280+ sshd.c | 4 ++--
1281+ 1 file changed, 2 insertions(+), 2 deletions(-)
1282+
1283+--- a/sshd.c
1284++++ b/sshd.c
1285+@@ -465,7 +465,7 @@ sshd_exchange_identification(struct ssh
1286+ chop(server_version_string);
1287+ debug("Local version string %.200s", server_version_string);
1288+
1289+- if (remote_major != 2 ||
1290++ if (remote_major != 2 &&
1291+ !(remote_major == 1 && remote_minor == 99)) {
1292+ s = "Protocol major versions differ.\n";
1293+ (void) atomicio(vwrite, sock_out, s, strlen(s));
1294diff --git a/debian/patches/lp-1863930-unbreak-clients-that-advertise-protocol.patch b/debian/patches/lp-1863930-unbreak-clients-that-advertise-protocol.patch
1295new file mode 100644
1296index 0000000..dbb035d
1297--- /dev/null
1298+++ b/debian/patches/lp-1863930-unbreak-clients-that-advertise-protocol.patch
1299@@ -0,0 +1,31 @@
1300+From 9e9c4a7e57b96ab29fe6d7545ed09d2e5bddbdec Mon Sep 17 00:00:00 2001
1301+From: "djm@openbsd.org" <djm@openbsd.org>
1302+Date: Tue, 23 Jan 2018 05:12:12 +0000
1303+Subject: [PATCH] upstream commit
1304+
1305+unbreak support for clients that advertise a protocol
1306+version of "1.99" (indicating both v2 and v1 support). Busted by me during
1307+SSHv1 purge in r1.358; bz2810, ok dtucker
1308+
1309+OpenBSD-Commit-ID: e8f9c2bee11afc16c872bb79d6abe9c555bd0e4b
1310+
1311+Backport-Note: dropped the no-op file header change
1312+Origin: backport, https://anongit.mindrot.org/openssh.git/commit/?id=9e9c4a7e5
1313+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1863930
1314+Last-Update: 2020-03-03
1315+
1316+---
1317+ sshd.c | 4 ++--
1318+ 1 file changed, 2 insertions(+), 2 deletions(-)
1319+
1320+--- a/sshd.c
1321++++ b/sshd.c
1322+@@ -466,7 +466,7 @@ sshd_exchange_identification(struct ssh
1323+ debug("Local version string %.200s", server_version_string);
1324+
1325+ if (remote_major != 2 ||
1326+- (remote_major == 1 && remote_minor != 99)) {
1327++ !(remote_major == 1 && remote_minor == 99)) {
1328+ s = "Protocol major versions differ.\n";
1329+ (void) atomicio(vwrite, sock_out, s, strlen(s));
1330+ close(sock_in);
1331diff --git a/debian/patches/regress-2020.patch b/debian/patches/regress-2020.patch
1332new file mode 100644
1333index 0000000..b46e0df
1334--- /dev/null
1335+++ b/debian/patches/regress-2020.patch
1336@@ -0,0 +1,44 @@
1337+From df3ad29af495185aa9b051028ae94b965a4b1659 Mon Sep 17 00:00:00 2001
1338+From: "djm@openbsd.org" <djm@openbsd.org>
1339+Date: Fri, 3 Jan 2020 03:02:26 +0000
1340+Subject: upstream: what bozo decided to use 2020 as a future date in a regress
1341+
1342+test?
1343+
1344+OpenBSD-Regress-ID: 3b953df5a7e14081ff6cf495d4e8d40e153cbc3a
1345+
1346+Origin: upstream, https://anongit.mindrot.org/openssh.git/commit/?id=ff31f15773ee173502eec4d7861ec56f26bba381
1347+Last-Update: 2020-01-09
1348+
1349+Patch-Name: regress-2020.patch
1350+---
1351+ regress/cert-hostkey.sh | 2 +-
1352+ regress/cert-userkey.sh | 2 +-
1353+ 2 files changed, 2 insertions(+), 2 deletions(-)
1354+
1355+diff --git a/regress/cert-hostkey.sh b/regress/cert-hostkey.sh
1356+index 86ea62504..844adabcc 100644
1357+--- a/regress/cert-hostkey.sh
1358++++ b/regress/cert-hostkey.sh
1359+@@ -252,7 +252,7 @@ test_one() {
1360+ test_one "user-certificate" failure "-n $HOSTS"
1361+ test_one "empty principals" success "-h"
1362+ test_one "wrong principals" failure "-h -n foo"
1363+-test_one "cert not yet valid" failure "-h -V20200101:20300101"
1364++test_one "cert not yet valid" failure "-h -V20300101:20320101"
1365+ test_one "cert expired" failure "-h -V19800101:19900101"
1366+ test_one "cert valid interval" success "-h -V-1w:+2w"
1367+ test_one "cert has constraints" failure "-h -Oforce-command=false"
1368+diff --git a/regress/cert-userkey.sh b/regress/cert-userkey.sh
1369+index 38c14a698..5cd02fc3f 100644
1370+--- a/regress/cert-userkey.sh
1371++++ b/regress/cert-userkey.sh
1372+@@ -338,7 +338,7 @@ test_one() {
1373+ test_one "correct principal" success "-n ${USER}"
1374+ test_one "host-certificate" failure "-n ${USER} -h"
1375+ test_one "wrong principals" failure "-n foo"
1376+-test_one "cert not yet valid" failure "-n ${USER} -V20200101:20300101"
1377++test_one "cert not yet valid" failure "-n ${USER} -V20300101:20320101"
1378+ test_one "cert expired" failure "-n ${USER} -V19800101:19900101"
1379+ test_one "cert valid interval" success "-n ${USER} -V-1w:+2w"
1380+ test_one "wrong source-address" failure "-n ${USER} -Osource-address=10.0.0.0/8"
1381diff --git a/debian/patches/series b/debian/patches/series
1382index 580b919..d8dd5ae 100644
1383--- a/debian/patches/series
1384+++ b/debian/patches/series
1385@@ -21,8 +21,26 @@ gnome-ssh-askpass2-icon.patch
1386 systemd-readiness.patch
1387 debian-config.patch
1388 restore-authorized_keys2.patch
1389+<<<<<<< debian/patches/series
1390 revert-ipqos-defaults.patch
1391 maxhostnamelen.patch
1392 conch-ssh-rsa.patch
1393 improve-zero-call-used-regs-detection.patch
1394 sandbox-ppoll_time64.patch
1395+=======
1396+seccomp-s390-flock-ipc.patch
1397+seccomp-getuid-geteuid.patch
1398+seccomp-s390-ioctl-ep11-crypto.patch
1399+permitopen-argument-handling.patch
1400+fix-regress-putty-transfer.patch
1401+CVE-2018-15473.patch
1402+CVE-2018-20685.patch
1403+CVE-2019-6111.patch
1404+CVE-2019-6109-1.patch
1405+CVE-2019-6109-2.patch
1406+CVE-2019-6111-2.patch
1407+regress-2020.patch
1408+lp-1863930-unbreak-clients-that-advertise-protocol.patch
1409+lp-1863930-Fix-logic-bug-in-sshd_exchange_identification.patch
1410+0001-upstream-preserve-group-world-read-permission-on-kno.patch
1411+>>>>>>> debian/patches/series

Subscribers

People subscribed via source and target branches