swtpm: Add support for --print-profiles option

Add support for --print-profiles option to print all profiles
supported by libtpms.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
diff --git a/man/man8/swtpm.pod b/man/man8/swtpm.pod
index 93e7426..579b043 100644
--- a/man/man8/swtpm.pod
+++ b/man/man8/swtpm.pod
@@ -334,7 +334,8 @@
         "rsa-keysize-1024",
         "rsa-keysize-2048",
         "rsa-keysize-3072",
-        "cmdarg-profile"
+        "cmdarg-profile",
+        "cmdarg-print-profile"
       ],
       "version": "0.7.0"
     }
@@ -415,6 +416,10 @@
 the option parameter I<name=> to select a profile by its name or I<profile=>
 to provide a JSON-formatted profile.
 
+=item B<cmdarg-print-profiles> (since v0.9)
+
+The option <--print-profiles> is supported.
+
 =back
 
 =item B<--print-states> (since v0.7)
@@ -542,6 +547,10 @@
       }
     }
 
+=item B<--print-profiles>
+
+Display the profiles supported by libtpms.
+
 =item B<-h|--help>
 
 Display usage info.
diff --git a/src/swtpm/capabilities.c b/src/swtpm/capabilities.c
index 3236884..b742dce 100644
--- a/src/swtpm/capabilities.c
+++ b/src/swtpm/capabilities.c
@@ -229,6 +229,18 @@
 
 #endif
 
+int print_profiles(void)
+{
+    char *info_data = TPMLIB_GetInfo(64 /*TPMLIB_INFO_AVAILABLE_PROFILES*/);
+
+    if (info_data)
+        printf("%s", info_data);
+
+    free(info_data);
+
+    return 0;
+}
+
 int capabilities_print_json(bool cusetpm, TPMLIB_TPMVersion tpmversion)
 {
     char *string = NULL;
diff --git a/src/swtpm/capabilities.h b/src/swtpm/capabilities.h
index 46dbebc..2ee6937 100644
--- a/src/swtpm/capabilities.h
+++ b/src/swtpm/capabilities.h
@@ -44,4 +44,6 @@
 
 int capabilities_print_json(bool cusetpm, TPMLIB_TPMVersion tpmversion);
 
+int print_profiles(void);
+
 #endif /* SWTPM_CAPABILITIES_H */
diff --git a/src/swtpm/cuse_tpm.c b/src/swtpm/cuse_tpm.c
index f54cc8a..01e194e 100644
--- a/src/swtpm/cuse_tpm.c
+++ b/src/swtpm/cuse_tpm.c
@@ -280,6 +280,8 @@
 #ifdef HAVE_LIBTPMS_SETPROFILE_API
 "--profile name=<name>|profile=<json-profile>\n"
 "                    : Set a profile on the TPM 2\n"
+"--print-profiles\n"
+"                    : print full profiles supported by libtpms\n"
 #endif
 "-h|--help           :  display this help screen and terminate\n"
 "\n";
@@ -1613,6 +1615,7 @@
 #ifdef HAVE_LIBTPMS_SETPROFILE_API
         {"profile"       , required_argument, 0, 'I'},
 #endif
+        {"print-profiles",       no_argument, 0, 'N'},
         {NULL            , 0                , 0, 0  },
     };
     struct cuse_info cinfo;
@@ -1629,6 +1632,7 @@
     int ret = 0;
     bool printcapabilities = false;
     bool printstates = false;
+    bool printprofiles = false;
     bool need_init_cmd = true;
     TPM_RESULT res;
 
@@ -1739,6 +1743,9 @@
         case 'e':
             printstates = true;
             break;
+        case 'N': /* --print-profiles */
+            printprofiles = true;
+            break;
         case 'v': /* version */
             fprintf(stdout, "TPM emulator CUSE interface version %d.%d.%d, "
                     "Copyright (c) 2014-2015 IBM Corp.\n",
@@ -1816,6 +1823,11 @@
         goto exit;
     }
 
+    if (printprofiles) {
+        print_profiles();
+        goto exit;
+    }
+
     if (!cinfo.dev_info_argv) {
         logprintf(STDERR_FILENO, "Error: device name missing\n");
         ret = -2;
diff --git a/src/swtpm/swtpm.c b/src/swtpm/swtpm.c
index 2b103dd..6a2527a 100644
--- a/src/swtpm/swtpm.c
+++ b/src/swtpm/swtpm.c
@@ -200,6 +200,8 @@
 #ifdef HAVE_LIBTPMS_SETPROFILE_API
     "--profile name=<name>|profile=<json-profile>\n"
     "                 : Set a profile on the TPM 2\n"
+    "--print-profiles\n"
+    "                 : print full profiles supported by libtpms\n"
 #endif
     "-h|--help        : display this help screen and terminate\n"
     "\n",
@@ -260,6 +262,7 @@
     unsigned int seccomp_action;
     bool printcapabilities = false;
     bool printstates = false;
+    bool printprofiles = false;
     static struct option longopts[] = {
         {"daemon"    ,       no_argument, 0, 'd'},
         {"help"      ,       no_argument, 0, 'h'},
@@ -287,6 +290,7 @@
         {"print-states",     no_argument, 0, 'e'},
 #ifdef HAVE_LIBTPMS_SETPROFILE_API
         {"profile"   , required_argument, 0, 'I'},
+        {"print-profiles",   no_argument, 0, 'N'},
 #endif
         {NULL        , 0                , 0, 0  },
     };
@@ -438,6 +442,10 @@
             profiledata = optarg;
             break;
 
+        case 'N': /* --print-profiles */
+            printprofiles = true;
+            break;
+
         default:
             usage(stderr, prgname, iface);
             exit(EXIT_FAILURE);
@@ -505,6 +513,11 @@
             goto exit_failure;
     }
 
+    if (printprofiles) {
+        print_profiles();
+        goto exit_success;
+    }
+
     if (handle_key_options(keydata) < 0 ||
         handle_migration_key_options(migkeydata) < 0 ||
         handle_pid_options(piddata) < 0 ||
diff --git a/src/swtpm/swtpm_chardev.c b/src/swtpm/swtpm_chardev.c
index 126d1cb..063d51f 100644
--- a/src/swtpm/swtpm_chardev.c
+++ b/src/swtpm/swtpm_chardev.c
@@ -221,6 +221,8 @@
 #ifdef HAVE_LIBTPMS_SETPROFILE_API
     "--profile name=<name>|profile=<json-profile>\n"
     "                 : Set a profile on the TPM 2\n"
+    "--print-profiles\n"
+    "                 : print full profiles supported by libtpms\n"
 #endif
     "-h|--help        : display this help screen and terminate\n"
     "\n",
@@ -318,6 +320,7 @@
     unsigned int seccomp_action;
     bool printcapabilities = false;
     bool printstates = false;
+    bool printprofiles = false;
     static struct option longopts[] = {
         {"daemon"    ,       no_argument, 0, 'd'},
         {"help"      ,       no_argument, 0, 'h'},
@@ -346,6 +349,7 @@
         {"print-states",     no_argument, 0, 'e'},
 #ifdef HAVE_LIBTPMS_SETPROFILE_API
         {"profile"   , required_argument, 0, 'I'},
+        {"print-profiles",   no_argument, 0, 'N'},
 #endif
         {NULL        , 0                , 0, 0  },
     };
@@ -488,6 +492,10 @@
             profiledata = optarg;
             break;
 
+        case 'N': /* --print-profiles */
+            printprofiles = true;
+            break;
+
         default:
             usage(stderr, prgname, iface);
             exit(EXIT_FAILURE);
@@ -553,6 +561,11 @@
             goto exit_success;
     }
 
+    if (printprofiles) {
+        print_profiles();
+        goto exit_success;
+    }
+
     if (mlp.fd < 0) {
         logprintf(STDERR_FILENO,
                   "Error: Missing character device or file descriptor\n");