Handle terminal control characters in scp progressmeter (#1247204)

This commit is contained in:
Jakub Jelen 2015-07-28 11:23:51 +02:00
parent 83bfb1fce5
commit 67938e0c00
4 changed files with 88 additions and 60 deletions

View File

@ -13,77 +13,24 @@ diff -up openssh-6.8p1/Makefile.in.utf8-banner openssh-6.8p1/Makefile.in
diff -up openssh-6.8p1/misc.h.utf8-banner openssh-6.8p1/misc.h diff -up openssh-6.8p1/misc.h.utf8-banner openssh-6.8p1/misc.h
--- openssh-6.8p1/misc.h.utf8-banner 2015-03-17 06:49:20.000000000 +0100 --- openssh-6.8p1/misc.h.utf8-banner 2015-03-17 06:49:20.000000000 +0100
+++ openssh-6.8p1/misc.h 2015-03-18 12:41:28.175713185 +0100 +++ openssh-6.8p1/misc.h 2015-03-18 12:41:28.175713185 +0100
@@ -135,4 +135,7 @@ char *read_passphrase(const char *, int) @@ -135,4 +135,8 @@ char *read_passphrase(const char *, int)
int ask_permission(const char *, ...) __attribute__((format(printf, 1, 2))); int ask_permission(const char *, ...) __attribute__((format(printf, 1, 2)));
int read_keyfile_line(FILE *, const char *, char *, size_t, u_long *); int read_keyfile_line(FILE *, const char *, char *, size_t, u_long *);
+/* utf8_stringprep.c */ +/* utf8_stringprep.c */
+int utf8_stringprep(const char *, char *, size_t); +int utf8_stringprep(const char *, char *, size_t);
+void sanitize_utf8(char *, const char *, size_t);
+ +
#endif /* _MISC_H */ #endif /* _MISC_H */
diff -up openssh-6.8p1/sshconnect2.c.utf8-banner openssh-6.8p1/sshconnect2.c diff -up openssh-6.8p1/sshconnect2.c.utf8-banner openssh-6.8p1/sshconnect2.c
--- openssh-6.8p1/sshconnect2.c.utf8-banner 2015-03-18 12:41:28.161713220 +0100 --- openssh-6.8p1/sshconnect2.c.utf8-banner 2015-03-18 12:41:28.161713220 +0100
+++ openssh-6.8p1/sshconnect2.c 2015-03-18 12:44:05.483317714 +0100 +++ openssh-6.8p1/sshconnect2.c 2015-03-18 12:44:05.483317714 +0100
@@ -33,6 +33,8 @@ @@ -532,7 +534,7 @@ input_userauth_error(int type, u_int32_t
#include <errno.h>
#include <fcntl.h>
+#include <langinfo.h>
+#include <locale.h>
#include <netdb.h>
#include <pwd.h>
#include <signal.h>
@@ -532,21 +534,51 @@ input_userauth_error(int type, u_int32_t
return 0;
}
+/* Check whether we can display UTF-8 safely */
+static int
+utf8_ok(void)
+{
+ static int ret = -1;
+ char *cp;
+
+ if (ret == -1) {
+ setlocale(LC_CTYPE, "");
+ cp = nl_langinfo(CODESET);
+ ret = strcmp(cp, "UTF-8") == 0;
+ }
+ return ret;
+}
+
/* ARGSUSED */
int
input_userauth_banner(int type, u_int32_t seq, void *ctxt)
{
char *msg, *raw, *lang;
- u_int len;
+ u_int done, len;
debug3("input_userauth_banner");
+
raw = packet_get_string(&len);
lang = packet_get_string(NULL);
if (len > 0 && options.log_level >= SYSLOG_LEVEL_INFO) {
if (len > 65536) if (len > 65536)
len = 65536; len = 65536;
msg = xmalloc(len * 4 + 1); /* max expansion from strnvis() */ msg = xmalloc(len * 4 + 1); /* max expansion from strnvis() */
- strnvis(msg, raw, len * 4 + 1, VIS_SAFE|VIS_OCTAL|VIS_NOSLASH); - strnvis(msg, raw, len * 4 + 1, VIS_SAFE|VIS_OCTAL|VIS_NOSLASH);
+ done = 0; + sanitize_utf8(msg, raw, len);
+ if (utf8_ok()) {
+ if (utf8_stringprep(raw, msg, len * 4 + 1) == 0)
+ done = 1;
+ else
+ debug2("%s: UTF8 stringprep failed", __func__);
+ }
+ /*
+ * Fallback to strnvis if UTF8 display not supported or
+ * conversion failed.
+ */
+ if (!done) {
+ strnvis(msg, raw, len * 4 + 1,
+ VIS_SAFE|VIS_OCTAL|VIS_NOSLASH);
+ }
fprintf(stderr, "%s", msg); fprintf(stderr, "%s", msg);
free(msg); free(msg);
} }
@ -755,7 +702,7 @@ diff -up openssh-6.8p1/stringprep-tables.c.utf8-banner openssh-6.8p1/stringprep-
diff -up openssh-6.8p1/utf8_stringprep.c.utf8-banner openssh-6.8p1/utf8_stringprep.c diff -up openssh-6.8p1/utf8_stringprep.c.utf8-banner openssh-6.8p1/utf8_stringprep.c
--- openssh-6.8p1/utf8_stringprep.c.utf8-banner 2015-03-18 12:41:28.175713185 +0100 --- openssh-6.8p1/utf8_stringprep.c.utf8-banner 2015-03-18 12:41:28.175713185 +0100
+++ openssh-6.8p1/utf8_stringprep.c 2015-03-18 12:41:28.175713185 +0100 +++ openssh-6.8p1/utf8_stringprep.c 2015-03-18 12:41:28.175713185 +0100
@@ -0,0 +1,229 @@ @@ -0,0 +1,265 @@
+/* +/*
+ * Copyright (c) 2013 Damien Miller <djm@mindrot.org> + * Copyright (c) 2013 Damien Miller <djm@mindrot.org>
+ * + *
@ -796,8 +743,12 @@ diff -up openssh-6.8p1/utf8_stringprep.c.utf8-banner openssh-6.8p1/utf8_stringpr
+#include <string.h> +#include <string.h>
+#include <limits.h> +#include <limits.h>
+#include <ctype.h> +#include <ctype.h>
+#include <langinfo.h>
+#include <locale.h>
+ +
+#include "includes.h"
+#include "misc.h" +#include "misc.h"
+#include "log.h"
+ +
+struct u32_range { +struct u32_range {
+ u_int32_t lo, hi; /* Inclusive */ + u_int32_t lo, hi; /* Inclusive */
@ -985,3 +936,35 @@ diff -up openssh-6.8p1/utf8_stringprep.c.utf8-banner openssh-6.8p1/utf8_stringpr
+ return 0; + return 0;
+} +}
+ +
+/* Check whether we can display UTF-8 safely */
+int
+utf8_ok(void)
+{
+ static int ret = -1;
+ char *cp;
+
+ if (ret == -1) {
+ setlocale(LC_CTYPE, "");
+ cp = nl_langinfo(CODESET);
+ ret = strcmp(cp, "UTF-8") == 0;
+ }
+ return ret;
+}
+
+void
+sanitize_utf8(char *target, const char *source, size_t length)
+{
+ u_int done = 0;
+ if (utf8_ok()) {
+ if (utf8_stringprep(source, target, length * 4 + 1) == 0)
+ done = 1;
+ else
+ debug2("%s: UTF8 stringprep failed", __func__);
+ }
+ /*
+ * Fallback to strnvis if UTF8 display not supported or
+ * conversion failed.
+ */
+ if (!done)
+ strnvis(target, source, length * 4 + 1, VIS_SAFE|VIS_OCTAL|VIS_NOSLASH);
+}

View File

@ -284,8 +284,8 @@ diff -up openssh/Makefile.in.fips openssh/Makefile.in
- $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) - $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS)
+ $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) + $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS)
scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o utf8_stringprep.o
$(LD) -o $@ scp.o progressmeter.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(LD) -o $@ scp.o progressmeter.o bufaux.o utf8_stringprep.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-add.o ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-add.o
- $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) - $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)

View File

@ -0,0 +1,42 @@
diff --git a/progressmeter.c b/progressmeter.c
index 319b747..b54738c 100644
--- a/progressmeter.c
+++ b/progressmeter.c
@@ -66,7 +66,8 @@ static void update_progress_meter(int);
static time_t start; /* start progress */
static time_t last_update; /* last progress update */
-static const char *file; /* name of the file being transferred */
+static char *file; /* name of the file being transferred */
+static size_t file_len = 0; /* allocated length of file */
static off_t start_pos; /* initial position of transfer */
static off_t end_pos; /* ending position of transfer */
static off_t cur_pos; /* transfer position as of last refresh */
@@ -250,7 +251,11 @@ update_progress_meter(int ignore)
start_progress_meter(const char *f, off_t filesize, off_t *ctr)
{
start = last_update = monotime();
- file = f;
+ if (strlen(f) > file_len) {
+ file_len = strlen(f);
+ file = realloc(file, file_len * 4 + 1);
+ }
+ sanitize_utf8(file, f, file_len);
start_pos = *ctr;
end_pos = filesize;
cur_pos = 0;
diff --git a/Makefile.in b/Makefile.in
index ac45b05..6978081 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -173,8 +173,8 @@ ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS)
sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS)
$(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS)
-scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o
- $(LD) -o $@ scp.o progressmeter.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
+scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o utf8_stringprep.o
+ $(LD) -o $@ scp.o progressmeter.o bufaux.o utf8_stringprep.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-add.o
$(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)

View File

@ -225,6 +225,8 @@ Patch928: openssh-6.8p1-memory-problems.patch
Patch929: openssh-6.9p1-permit-root-login.patch Patch929: openssh-6.9p1-permit-root-login.patch
# authentication limits (MaxAuthTries) bypass [security] (#1245971) # authentication limits (MaxAuthTries) bypass [security] (#1245971)
Patch930: openssh-6.9p1-authentication-limits-bypass.patch Patch930: openssh-6.9p1-authentication-limits-bypass.patch
# Handle terminal control characters in scp progressmeter (#1247204)
Patch931: openssh-6.9p1-scp-progressmeter.patch
@ -449,6 +451,7 @@ popd
%patch928 -p1 -b .memory %patch928 -p1 -b .memory
%patch929 -p1 -b .root-login %patch929 -p1 -b .root-login
%patch930 -p1 -b .kbd %patch930 -p1 -b .kbd
%patch931 -p1 -b .progressmeter
%patch200 -p1 -b .audit %patch200 -p1 -b .audit
%patch700 -p1 -b .fips %patch700 -p1 -b .fips