]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Add a new API, archive_write_set_passphrase_callback, for encryption.
authorMichihiro NAKAJIMA <ggcueroad@gmail.com>
Sun, 21 Sep 2014 06:00:45 +0000 (15:00 +0900)
committerMichihiro NAKAJIMA <ggcueroad@gmail.com>
Sun, 21 Sep 2014 06:00:45 +0000 (15:00 +0900)
libarchive/archive.h
libarchive/archive_write_private.h
libarchive/archive_write_set_passphrase.3
libarchive/archive_write_set_passphrase.c
libarchive/test/test_archive_write_set_passphrase.c

index aa1f8a14a7a2b1aadf5239437e815b371c76a4cb..81ed63a13f6746cbd2674a08ef1a286ac9599a98 100644 (file)
@@ -834,6 +834,8 @@ __LA_DECL int archive_write_set_options(struct archive *_a,
  * Set a encryption passphrase.
  */
 __LA_DECL int archive_write_set_passphrase(struct archive *_a, const char *p);
+__LA_DECL int archive_write_set_passphrase_callback(struct archive *,
+                           void *client_data, archive_passphrase_callback *);
 
 /*-
  * ARCHIVE_WRITE_DISK API
index a2b5c0f87e41551d697754ec72a2fc59336f329c..0c3cc0c6f4d0662f6482469f119003cac4631656 100644 (file)
@@ -124,6 +124,8 @@ struct archive_write {
         * Encryption passphrase.
         */
        char            *passphrase;
+       archive_passphrase_callback *passphrase_callback;
+       void            *passphrase_client_data;
 };
 
 /*
index b2e47d4a99f31a7939f0186e61496179a3b66f3f..ba517dd0f73d027755383321bb746497876c84b0 100644 (file)
 .\"
 .\" $FreeBSD$
 .\"
-.Dd September 13, 2014
+.Dd September 21, 2014
 .Dt ARCHIVE_WRITE_SET_PASSPHRASE 3
 .Os
 .Sh NAME
-.Nm archive_write_set_passphrase
+.Nm archive_write_set_passphrase ,
+.Nm archive_write_set_passphrase_callback
 .Nd functions for writing encrypted archives
 .Sh LIBRARY
 Streaming Archive Library (libarchive, -larchive)
@@ -39,7 +40,15 @@ Streaming Archive Library (libarchive, -larchive)
 .Fa "struct archive *"
 .Fa "const char *passphrase"
 .Fc
+.Ft int
+.Fo archive_write_set_passphrase_callback
+.Fa "struct archive *"
+.Fa "void *client_data"
+.Fa "archive_passphrase_callback *"
+.Fc
 .Sh DESCRIPTION
+.Bl -tag -width indent
+.It Fn archive_write_set_passphrase
 Set a passphrase for writing an encryption archive.
 If
 .Ar passphrase
@@ -51,6 +60,11 @@ will be returned.
 Otherwise,
 .Cm ARCHIVE_OK
 will be returned. 
+.It Fn archive_write_set_passphrase_callback
+Register callback function that will be invoked to get a passphrase
+for encrption if the passphrase was not set by the
+.Fn archive_write_set_passphrase
+function.
 .\" .Sh ERRORS
 .Sh SEE ALSO
 .Xr tar 1 ,
index 92f59898c80051fafa2e6644f434f44b18f2f1b3..710ecba52c3d6f4144cbabeaba9c0c016e15661b 100644 (file)
@@ -54,9 +54,42 @@ archive_write_set_passphrase(struct archive *_a, const char *p)
        return (ARCHIVE_OK);
 }
 
+
+int
+archive_write_set_passphrase_callback(struct archive *_a, void *client_data,
+    archive_passphrase_callback *cb)
+{
+       struct archive_write *a = (struct archive_write *)_a;
+
+       archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_NEW,
+               "archive_write_set_passphrase_callback");
+
+       a->passphrase_callback = cb;
+       a->passphrase_client_data = client_data;
+       return (ARCHIVE_OK);
+}
+
+
 const char *
 __archive_write_get_passphrase(struct archive_write *a)
 {
 
-       return (a->passphrase);
+       if (a->passphrase != NULL)
+               return (a->passphrase);
+
+       if (a->passphrase_callback != NULL) {
+               const char *p;
+               p = a->passphrase_callback(&a->archive,
+                   a->passphrase_client_data);
+               if (p != NULL) {
+                       a->passphrase = strdup(p);
+                       if (a->passphrase == NULL) {
+                               archive_set_error(&a->archive, ENOMEM,
+                                   "Can't allocate data for passphrase");
+                               return (NULL);
+                       }
+                       return (a->passphrase);
+               }
+       }
+       return (NULL);
 }
index 20171e2df8619a94537153d8badb256fa788e072..4bfcbb2c2dab6e7baf5c4907d791f3332f3fa60e 100644 (file)
@@ -60,3 +60,36 @@ DEFINE_TEST(test_archive_write_set_passphrase)
        test(1);
        test(0);
 }
+
+
+static const char *
+callback1(struct archive *a, void *_client_data)
+{
+       int *cnt;
+
+       (void)a; /* UNUSED */
+
+       cnt = (int *)_client_data;
+       *cnt += 1;
+       return ("passCallBack");
+}
+
+DEFINE_TEST(test_archive_write_set_passphrase_callback)
+{
+       struct archive* a = archive_write_new();
+       struct archive_write* aw = (struct archive_write *)a;
+       int cnt = 0;
+
+       archive_write_set_format_zip(a);
+
+       assertEqualInt(ARCHIVE_OK,
+           archive_write_set_passphrase_callback(a, &cnt, callback1));
+       /* Check a passphrase. */
+       assertEqualString("passCallBack", __archive_write_get_passphrase(aw));
+       assertEqualInt(1, cnt);
+       /* Callback function should be called just once. */
+       assertEqualString("passCallBack", __archive_write_get_passphrase(aw));
+       assertEqualInt(1, cnt);
+
+       archive_write_free(a);
+}