git: a4724ff48108 - main - unzip: sync with NetBSD upstream to add passphrase support

Yoshihiro Takahashi nyan at FreeBSD.org
Sat Sep 25 16:39:02 UTC 2021


The branch main has been updated by nyan:

URL: https://cgit.FreeBSD.org/src/commit/?id=a4724ff48108840416c83f10e15d666ac8d78937

commit a4724ff48108840416c83f10e15d666ac8d78937
Author:     Yoshihiro Takahashi <nyan at FreeBSD.org>
AuthorDate: 2021-09-25 16:32:42 +0000
Commit:     Yoshihiro Takahashi <nyan at FreeBSD.org>
CommitDate: 2021-09-25 16:32:42 +0000

    unzip: sync with NetBSD upstream to add passphrase support
    
    - Add support for password protected zip archives.
      We use memset_s() rather than explicit_bzero() for more portable
      (See PR).
    - Use success/failure macro in exit()
    - Mention ZIPX format in unzip(1)
    
    Submitted by:   Mingye Wang and Alex Kozlov (ak@)
    PR:             244181
    Reviewed by:    mizhka
    Obtained from:  NetBSD
    MFC after:      1 week
    Differential Revision:  https://reviews.freebsd.org/D28892
---
 usr.bin/unzip/unzip.1 | 10 ++++++--
 usr.bin/unzip/unzip.c | 66 ++++++++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 66 insertions(+), 10 deletions(-)

diff --git a/usr.bin/unzip/unzip.1 b/usr.bin/unzip/unzip.1
index b7c2d858f012..bb43abf43a85 100644
--- a/usr.bin/unzip/unzip.1
+++ b/usr.bin/unzip/unzip.1
@@ -25,7 +25,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd December 12, 2015
+.Dd September 25, 2021
 .Dt UNZIP 1
 .Os
 .Sh NAME
@@ -35,6 +35,8 @@
 .Nm
 .Op Fl aCcfjLlnopqtuvy
 .Op Fl d Ar dir
+.Op Fl x Ar pattern
+.Op Fl P Ar password
 .Ar zipfile
 .Sh DESCRIPTION
 .\" ...
@@ -81,6 +83,10 @@ When extracting files from the zipfile, they are written to stdout.
 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
@@ -172,7 +178,7 @@ utility is only able to process ZIP archives handled by
 .Xr libarchive 3 .
 Depending on the installed version of
 .Xr libarchive 3 ,
-this may or may not include self-extracting archives.
+this may or may not include self-extracting or ZIPX archives.
 .Sh SEE ALSO
 .Xr libarchive 3
 .Sh HISTORY
diff --git a/usr.bin/unzip/unzip.c b/usr.bin/unzip/unzip.c
index 937176111a02..e5ca1ff2c939 100644
--- a/usr.bin/unzip/unzip.c
+++ b/usr.bin/unzip/unzip.c
@@ -51,6 +51,7 @@
 
 #include <archive.h>
 #include <archive_entry.h>
+#include <readpassphrase.h>
 
 /* command-line options */
 static int		 a_opt;		/* convert EOL */
@@ -63,6 +64,7 @@ static int		 L_opt;		/* lowercase names */
 static int		 n_opt;		/* never overwrite */
 static int		 o_opt;		/* always overwrite */
 static int		 p_opt;		/* extract to stdout, quiet */
+static char		*P_arg;		/* passphrase */
 static int		 q_opt;		/* quiet */
 static int		 t_opt;		/* test */
 static int		 u_opt;		/* update */
@@ -95,6 +97,9 @@ static int		 tty;
  */
 static int noeol;
 
+/* for an interactive passphrase input */
+static char *passphrase_buf;
+
 /* fatal error message + errno */
 static void
 error(const char *fmt, ...)
@@ -109,7 +114,7 @@ error(const char *fmt, ...)
 	vfprintf(stderr, fmt, ap);
 	va_end(ap);
 	fprintf(stderr, ": %s\n", strerror(errno));
-	exit(1);
+	exit(EXIT_FAILURE);
 }
 
 /* fatal error message, no errno */
@@ -126,7 +131,7 @@ errorx(const char *fmt, ...)
 	vfprintf(stderr, fmt, ap);
 	va_end(ap);
 	fprintf(stderr, "\n");
-	exit(1);
+	exit(EXIT_FAILURE);
 }
 
 /* non-fatal error message + errno */
@@ -854,6 +859,36 @@ test(struct archive *a, struct archive_entry *e)
 	return error_count;
 }
 
+/*
+ * Callback function for reading passphrase.
+ * Originally from cpio.c and passphrase.c, libarchive.
+ */
+#define PPBUFF_SIZE 1024
+static const char *
+passphrase_callback(struct archive *a, void *_client_data)
+{
+	char *p;
+
+	(void)a; /* UNUSED */
+	(void)_client_data; /* UNUSED */
+
+	if (passphrase_buf == NULL) {
+		passphrase_buf = malloc(PPBUFF_SIZE);
+		if (passphrase_buf == NULL) {
+			errno = ENOMEM;
+			error("malloc()");
+		}
+	}
+
+	p = readpassphrase("\nEnter password: ", passphrase_buf,
+		PPBUFF_SIZE, RPP_ECHO_OFF);
+
+	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.
@@ -870,6 +905,13 @@ unzip(const char *fn)
 		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, NULL,
+			&passphrase_callback);
+
 	ac(archive_read_open_filename(a, fn, 8192));
 
 	if (!zipinfo_mode) {
@@ -925,6 +967,11 @@ unzip(const char *fn)
 
 	ac(archive_read_free(a));
 
+	if (passphrase_buf != NULL) {
+		memset_s(passphrase_buf, PPBUFF_SIZE, 0, PPBUFF_SIZE);
+		free(passphrase_buf);
+	}
+
 	if (t_opt) {
 		if (error_count > 0) {
 			errorx("%ju checksum error(s) found.", error_count);
@@ -940,9 +987,9 @@ static void
 usage(void)
 {
 
-	fprintf(stderr, "Usage: unzip [-aCcfjLlnopqtuvyZ1] [-d dir] [-x pattern] "
-		"zipfile\n");
-	exit(1);
+	fprintf(stderr, "Usage: unzip [-aCcfjLlnopqtuvyZ1] [-d dir] "
+		"[-x pattern] [-P password] zipfile\n");
+	exit(EXIT_FAILURE);
 }
 
 static int
@@ -951,7 +998,7 @@ getopts(int argc, char *argv[])
 	int opt;
 
 	optreset = optind = 1;
-	while ((opt = getopt(argc, argv, "aCcd:fjLlnopqtuvx:yZ1")) != -1)
+	while ((opt = getopt(argc, argv, "aCcd:fjLlnopP:qtuvx:yZ1")) != -1)
 		switch (opt) {
 		case '1':
 			Z1_opt = 1;
@@ -991,6 +1038,9 @@ getopts(int argc, char *argv[])
 		case 'p':
 			p_opt = 1;
 			break;
+		case 'P':
+			P_arg = optarg;
+			break;
 		case 'q':
 			q_opt = 1;
 			break;
@@ -1047,7 +1097,7 @@ main(int argc, char *argv[])
 	 */
 	if (zipinfo_mode && !Z1_opt) {
 		printf("Zipinfo mode needs additional options\n");
-		exit(1);
+		exit(EXIT_FAILURE);
 	}
 
 	if (argc <= nopts)
@@ -1068,5 +1118,5 @@ main(int argc, char *argv[])
 
 	unzip(zipfile);
 
-	exit(0);
+	exit(EXIT_SUCCESS);
 }


More information about the dev-commits-src-all mailing list