1 /* tool/get_localid.c -- Retrieve local identity credentials
3 * Provide a config, a NAI and see what types of credentials are available
6 * From: Rick van Rein <rick@openfortress.nl>
15 #include <sys/types.h>
22 #include <arpa/inet.h>
26 #include <tlspool/internal.h>
29 const char const *usage =
30 "Usage: %s tlspool.conf [user@]fqdn type [outfile.der]\n"
31 " - tlspool.conf is the configuration file for the TLS Pool\n"
32 " - user@fqdn or fqdn is a network access identifier\n"
33 " - type X.509,OpenPGP,valexp,client,server,noP11,chained\n"
34 " - outfile.der optional output file for binary encoded public data\n"
35 "Since the public data is stored in a binary format, it will never be printed\n"
36 "on stdout; in absense of outfile.der the value is simply not output.\n";
44 struct typemap_t typemap [] = {
56 /* Setup and tear down management */
57 int setup_management (DB_ENV **dbenv, DB_TXN **txn, DB **dbh) {
58 char *dbenv_dir = cfg_dbenv_dir ();
59 char *dblid_fnm = cfg_db_localid ();
60 if (dbenv_dir == NULL) {
61 fprintf (stderr, "Please configure database environment directory\n");
64 if (dblid_fnm == NULL) {
65 fprintf (stderr, "Please configure localid database name\n");
68 if (db_env_create (dbenv, 0) != 0) {
69 fprintf (stderr, "Failed to create database environment");
72 if ((*dbenv)->open (*dbenv, dbenv_dir, DB_CREATE | DB_RECOVER | DB_INIT_TXN | DB_INIT_LOG | DB_INIT_LOCK | DB_THREAD | DB_INIT_MPOOL, S_IRUSR | S_IWUSR) != 0) {
73 fprintf (stderr, "Failed to open database environment");
76 if ((*dbenv)->txn_begin (*dbenv, NULL, txn, 0) != 0) {
77 fprintf (stderr, "Failed to start transaction\n");
80 if (db_create (dbh, *dbenv, 0) != 0) {
81 fprintf (stderr, "Failed to create localid database\n");
84 if ((*dbh)->set_flags (*dbh, DB_DUP) != 0) {
85 fprintf (stderr, "Failed to setup localid database for duplicate entries\n");
88 if ((*dbh)->open (*dbh, *txn, dblid_fnm, NULL, DB_HASH, DB_THREAD | DB_RDONLY, 0) != 0) {
89 fprintf (stderr, "Failed to open localid database\n");
95 /* Cleanup maangement structures */
96 void cleanup_management (DB_ENV *dbenv, DB *db) {
98 dbenv->close (dbenv, 0);
101 int main (int argc, char *argv []) {
102 char *localid = NULL;
103 char *partstr = NULL;
104 char *saveptr = NULL;
106 uint8_t e_buf [5000];
124 if ((argc < 4) || (argc > 5)) {
125 fprintf (stderr, usage, argv [0]);
129 outfile = open (argv [4], O_WRONLY | O_CREAT | O_TRUNC, 0644);
131 perror ("Failed to open output file");
136 // Initialise the modules taken from the src directory
137 parse_cfgfile (argv [1], 0);
139 // Prepare variables from arguments
141 partstr = strtok_r (argv [3], ",", &saveptr);
142 if (partstr == NULL) {
143 fprintf (stderr, "Flags must not be empty\n");
146 while (partstr != NULL) {
147 struct typemap_t *walker = typemap;
148 while (walker->name != NULL) {
149 if (strcasecmp (walker->name, partstr) == 0) {
150 flags |= walker->bits;
155 if (walker->name == NULL) {
156 fprintf (stderr, "Flag name %s not recognised\n", partstr);
159 partstr = strtok_r (NULL, ",", &saveptr);
162 // Now retrieve the matching entries
163 if (!setup_management (&dbenv, &txn, &dbh)) {
166 if (dbh->cursor (dbh, txn, &crs, 0) != 0) {
167 fprintf (stderr, "Failed to open cursor on localid.db\n");
170 memset (&k_localid, 0, sizeof (k_localid));
171 k_localid.data = localid;
172 k_localid.size = strlen (localid);
173 nomore = crs->get (crs, &k_localid, &e_value, DB_SET);
174 while (nomore == 0) {
175 uint32_t e_flags = 0;
176 char *e_p11uri = NULL;
179 if (e_value.size < 4) {
180 fprintf (stderr, "Found too-short entry?!?\n");
184 e_flags = ntohl (* (uint32_t *) e_value.data);
185 e_p11uri = (char *) & ((uint32_t *) e_value.data) [1];
186 e_bindata = e_p11uri + strnlen (e_p11uri, e_value.size - 4) + 1;
187 e_binlen = e_value.size - 4 - strnlen (e_p11uri, e_value.size - 4) - 1;
189 fprintf (stderr, "Error retrieving binary data\n");
193 if ((e_flags & 0xff) == (flags & 0xff)) {
194 uint32_t todo_flags = e_flags;
195 struct typemap_t *tm = typemap;
196 printf ("Flags: 0x%x:", e_flags);
197 while (tm->name != NULL) {
198 if (todo_flags & tm->bits) {
199 printf (" %s", tm->name);
200 todo_flags = todo_flags & ~tm->bits;
204 if (todo_flags != 0) {
205 printf (" UNKNOWN_%d", todo_flags);
207 printf ("\nPrivate: %s\n", e_p11uri);
210 if (write (outfile, e_bindata, e_binlen) == e_binlen) {
211 printf ("Written %d bytes\n", e_binlen);
215 outfile = -1; // No more than one binary write
217 printf ("Public: %02x %02x...%02x %02x (length %d)%s\n",
218 e_bindata [0], e_bindata [1],
219 e_bindata [e_binlen-2], e_bindata [e_binlen-1],
221 written? " (written)": "");
223 nomore = crs->get (crs, &k_localid, &e_value, DB_NEXT_DUP);
226 if (nomore != DB_NOTFOUND) {
227 fprintf (stderr, "Database error encountered while iterating\n");
230 if (txn->commit (txn, 0) != 0) {
232 fprintf (stderr, "Failed to commit readonly transaction\n");
236 // Finish up and report success
238 cleanup_management (dbenv, dbh);
241 // Handle failure during database interactions
243 fprintf (stderr, "Rolling back transaction\n");
245 cleanup_management (dbenv, dbh);