Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.bin/unzip Add support for password protected zip files (...
details: https://anonhg.NetBSD.org/src/rev/cd17ad9c4d57
branches: trunk
changeset: 980779:cd17ad9c4d57
user: christos <christos%NetBSD.org@localhost>
date: Thu Feb 18 17:58:51 2021 +0000
description:
Add support for password protected zip files (Alex Kozlov)
Also some KNF
diffstat:
usr.bin/unzip/unzip.1 | 5 ++-
usr.bin/unzip/unzip.c | 87 +++++++++++++++++++++++++++++++++++++++-----------
2 files changed, 72 insertions(+), 20 deletions(-)
diffs (259 lines):
diff -r 48bc5d7902c3 -r cd17ad9c4d57 usr.bin/unzip/unzip.1
--- a/usr.bin/unzip/unzip.1 Thu Feb 18 17:56:04 2021 +0000
+++ b/usr.bin/unzip/unzip.1 Thu Feb 18 17:58:51 2021 +0000
@@ -25,7 +25,7 @@
.\" SUCH DAMAGE.
.\"
.\" $FreeBSD: revision 180125$
-.\" $NetBSD: unzip.1,v 1.12 2021/02/18 17:04:39 christos Exp $
+.\" $NetBSD: unzip.1,v 1.13 2021/02/18 17:58:51 christos Exp $
.\"
.Dd February 18, 2021
.Dt UNZIP 1
@@ -83,6 +83,9 @@
The normal output is suppressed as if
.Fl q
was specified.
+.It Fl P Ar password
+Extract encrypted files using a password. Putting a password on
+the command line using this option can be insecure.
.It Fl q
Quiet: print less information while extracting.
.It Fl t
diff -r 48bc5d7902c3 -r cd17ad9c4d57 usr.bin/unzip/unzip.c
--- a/usr.bin/unzip/unzip.c Thu Feb 18 17:56:04 2021 +0000
+++ b/usr.bin/unzip/unzip.c Thu Feb 18 17:58:51 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: unzip.c,v 1.25 2021/02/18 17:05:51 christos Exp $ */
+/* $NetBSD: unzip.c,v 1.26 2021/02/18 17:58:51 christos Exp $ */
/*-
* Copyright (c) 2009, 2010 Joerg Sonnenberger <joerg%NetBSD.org@localhost>
@@ -37,10 +37,11 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: unzip.c,v 1.25 2021/02/18 17:05:51 christos Exp $");
+__RCSID("$NetBSD: unzip.c,v 1.26 2021/02/18 17:58:51 christos Exp $");
#ifdef __GLIBC__
#define _GNU_SOURCE
+#define explicit_memset memset_s
#endif
#include <sys/queue.h>
@@ -58,6 +59,9 @@
#include <archive.h>
#include <archive_entry.h>
+#ifdef __GLIBC__
+#include <readpassphrase.h>
+#endif
/* command-line options */
static int a_opt; /* convert EOL */
@@ -71,6 +75,7 @@
static int o_opt; /* always overwrite */
static int p_opt; /* extract to stdout, quiet */
static int q_opt; /* quiet */
+static char *P_arg; /* passphrase */
static int t_opt; /* test */
static int u_opt; /* update */
static int v_opt; /* verbose/list */
@@ -92,7 +97,7 @@
int acret = (call); \
if (acret != ARCHIVE_OK) \
errorx("%s", archive_error_string(a)); \
- } while (0)
+ } while (/*CONSTCONST*/0)
/*
* Indicates that last info() did not end with EOL. This helps error() et
@@ -101,6 +106,9 @@
*/
static int noeol;
+/* for an interactive passphrase input */
+static char passbuf[1024];
+
/* fatal error message + errno */
__dead __printflike(1, 2) static void
error(const char *fmt, ...)
@@ -110,12 +118,12 @@
if (noeol)
fprintf(stdout, "\n");
fflush(stdout);
- fprintf(stderr, "unzip: ");
+ fprintf(stderr, "%s: ", getprogname());
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
fprintf(stderr, ": %s\n", strerror(errno));
- exit(1);
+ exit(EXIT_FAILURE);
}
/* fatal error message, no errno */
@@ -127,12 +135,12 @@
if (noeol)
fprintf(stdout, "\n");
fflush(stdout);
- fprintf(stderr, "unzip: ");
+ fprintf(stderr, "%s: ", getprogname());
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
fprintf(stderr, "\n");
- exit(1);
+ exit(EXIT_FAILURE);
}
/* non-fatal error message + errno */
@@ -227,7 +235,7 @@
}
str[len] = '\0';
- return (str);
+ return str;
}
/* concatenate two path names */
@@ -249,7 +257,7 @@
}
memcpy(str + prelen, path, len); /* includes zero */
- return (str);
+ return str;
}
/*
@@ -293,9 +301,9 @@
STAILQ_FOREACH(entry, list, link) {
if (fnmatch(entry->pattern, str, C_opt ? FNM_CASEFOLD : 0) == 0)
- return (1);
+ return 1;
}
- return (0);
+ return 0;
}
/*
@@ -307,10 +315,10 @@
{
if (!STAILQ_EMPTY(&include) && !match_pattern(&include, pathname))
- return (0);
+ return 0;
if (!STAILQ_EMPTY(&exclude) && match_pattern(&exclude, pathname))
- return (0);
- return (1);
+ return 0;
+ return 1;
}
/*
@@ -853,6 +861,34 @@
}
/*
+ * Callback function for reading passphrase.
+ * Originally from cpio.c and passphrase.c, libarchive.
+ */
+static const char *
+passphrase_callback(struct archive *a, void *client_data)
+{
+ char *p;
+ static const char prompt[] = "\nEnter passphrase:";
+
+ (void)a; /* UNUSED */
+ (void)client_data; /* UNUSED */
+
+#if defined(RPP_ECHO_OFF)
+ p = readpassphrase(prompt, passbuf, sizeof(passbuf), RPP_ECHO_OFF);
+#elif defined(GETPASS_NEED_TTY)
+ p = getpass_r(prompt, passbuf, sizeof(passbuf));
+#else
+ p = getpass(prompt);
+ if (p != NULL)
+ strlcpy(passbuf, p, sizeof(passbuf));
+#endif
+ if (p == NULL && errno != EINTR)
+ error("Error reading password");
+
+ return p;
+}
+
+/*
* Main loop: open the zipfile, iterate over its contents and decide what
* to do with each entry.
*/
@@ -868,6 +904,12 @@
error("archive_read_new failed");
ac(archive_read_support_format_zip(a));
+
+ if (P_arg)
+ archive_read_add_passphrase(a, P_arg);
+ else
+ archive_read_set_passphrase_callback(a, passbuf, &passphrase_callback);
+
ac(archive_read_open_filename(a, fn, 8192));
if (!q_opt && !p_opt)
@@ -915,6 +957,7 @@
ac(archive_read_free(a));
+ explicit_memset(passbuf, 0, sizeof(passbuf));
if (t_opt) {
if (error_count > 0) {
errorx("%ju checksum error(s) found.", error_count);
@@ -930,15 +973,16 @@
usage(void)
{
- fprintf(stderr, "Usage: %s [-aCcfjLlnopqtuvy] [-d dir] [-x pattern] "
- "zipfile\n", getprogname());
- exit(1);
+ fprintf(stderr, "Usage: %s [-aCcfjLlnopqtuvy] [-d <dir>] "
+ "[-x <pattern>] [-P <passphrase>] <zipfile>\n", getprogname());
+ exit(EXIT_FAILURE);
}
static int
getopts(int argc, char *argv[])
{
int opt;
+ size_t len;
#ifdef __GLIBC__
optind = 0;
@@ -984,6 +1028,11 @@
case 'p':
p_opt = 1;
break;
+ case 'P':
+ len = strlcpy(passbuf, optarg, sizeof(passbuf));
+ memset(optarg, '*', len);
+ P_arg = passbuf;
+ break;
case 'q':
q_opt = 1;
break;
@@ -1006,7 +1055,7 @@
usage();
}
- return (optind);
+ return optind;
}
int
@@ -1051,5 +1100,5 @@
unzip(zipfile);
- exit(0);
+ exit(EXIT_SUCCESS);
}
Home |
Main Index |
Thread Index |
Old Index