Support backup/restore of FBE policies

Change-Id: Iba8ef20f57b0fb57bb9406c53148a806441d0b59
diff --git a/libtar/append.c b/libtar/append.c
index 4be679c..4388297 100644
--- a/libtar/append.c
+++ b/libtar/append.c
@@ -20,6 +20,7 @@
 #include <time.h>
 #include <sys/param.h>
 #include <sys/types.h>
+#include <stdbool.h>
 
 #ifdef STDC_HEADERS
 # include <stdlib.h>
@@ -34,6 +35,10 @@
 # include "selinux/selinux.h"
 #endif
 
+#ifdef HAVE_EXT4_CRYPT
+# include "ext4crypt_tar.h"
+#endif
+
 struct tar_dev
 {
 	dev_t td_dev;
@@ -122,6 +127,33 @@
 	}
 #endif
 
+#ifdef HAVE_EXT4_CRYPT
+	if (TH_ISDIR(t) && t->options & TAR_STORE_EXT4_POL)
+	{
+		if (t->th_buf.e4crypt_policy != NULL)
+		{
+			free(t->th_buf.e4crypt_policy);
+			t->th_buf.e4crypt_policy = NULL;
+		}
+
+		char e4crypt_policy[EXT4_KEY_DESCRIPTOR_SIZE];
+		if (e4crypt_policy_get(realname, e4crypt_policy, EXT4_KEY_DESCRIPTOR_SIZE, 0))
+		{
+			char tar_policy[EXT4_KEY_DESCRIPTOR_SIZE];
+			memset(tar_policy, 0, sizeof(tar_policy));
+			char policy_hex[EXT4_KEY_DESCRIPTOR_HEX];
+			policy_to_hex(e4crypt_policy, policy_hex);
+			if (lookup_ref_key(e4crypt_policy, &tar_policy)) {
+				printf("found policy '%s' - '%s' - '%s'\n", realname, tar_policy, policy_hex);
+				t->th_buf.e4crypt_policy = strdup(tar_policy);
+			} else {
+				printf("failed to lookup tar policy for '%s' - '%s'\n", realname, policy_hex);
+				return -1;
+			}
+		} // else no policy found, but this is not an error as not all dirs will have a policy
+	}
+#endif
+
 	/* check if it's a hardlink */
 #ifdef DEBUG
 	puts("tar_append_file(): checking inode cache for hardlink...");