1 /* tool/set_disclose.c -- Setup disclosure for local identities
3 * Provide a config, a selector for remote peers and a list of local DoNAIs.
4 * The command erases all matching old entries, and installs any new ones.
6 * From: Rick van Rein <rick@openfortress.nl>
15 #include <sys/types.h>
23 #include <tlspool/internal.h>
26 const char const *usage =
27 "Usage: %s tlspool.conf selector [[user@]domain...]\n"
28 " - tlspool.conf is the configuration file for the TLS Pool\n"
29 " - selector is a matcher for remote peer identities\n"
30 " - user@domain or domain is a local client network access identifier\n"
31 "The list of client identities replaces the old list. An empty list is nothing\n"
32 "special; it replaces the old content with zero entries.\n"
33 "The selector may take the following forms:\n"
34 " - domain matches remote peer DoNAI completely but with no username\n"
35 " - .domain matches remote peer DoNAIs ending in .domain with no username\n"
36 " - . matches any remote peer with no username\n"
37 " - user@domain matches remote peer DoNAI with the username given\n"
38 " - @domain matches remote peer DoNAIs with any username\n"
39 " - @.domain matches remote peer DoNAIs with any username ending in .domain\n"
40 " - @. matches remote peer DoNAIs with any username and any domain\n"
41 "When multiple selectors match a remote DoNAI, only the most concrete applies.\n"
42 "When no selector matches a remote DoNAI, the default policy is to reject.\n"
43 "An empty [[user@]domain] list is nothing special; it removes old content.\n";
46 /* Setup and tear down management */
47 int setup_management (DB_ENV **dbenv, DB_TXN **txn, DB **dbh_disc, DB **dbh_lid) {
48 char *dbenv_dir = cfg_dbenv_dir ();
49 char *dblid_fnm = cfg_db_localid ();
50 char *dbdisc_fnm = cfg_db_disclose ();
51 if (dbenv_dir == NULL) {
52 fprintf (stderr, "Please configure database environment directory\n");
55 if (dbdisc_fnm == NULL) {
56 fprintf (stderr, "Please configure disclose database name\n");
59 if (dblid_fnm == NULL) {
60 fprintf (stderr, "Please configure localid database name\n");
63 if (db_env_create (dbenv, 0) != 0) {
64 fprintf (stderr, "Failed to create database environment");
67 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) {
68 fprintf (stderr, "Failed to open database environment");
71 if ((*dbenv)->txn_begin (*dbenv, NULL, txn, 0) != 0) {
72 fprintf (stderr, "Failed to start transaction\n");
75 if (db_create (dbh_disc, *dbenv, 0) != 0) {
76 fprintf (stderr, "Failed to create disclose database\n");
79 if (db_create (dbh_lid, *dbenv, 0) != 0) {
80 fprintf (stderr, "Failed to create localid database\n");
83 if ((*dbh_disc)->set_flags (*dbh_disc, DB_DUP) != 0) {
84 fprintf (stderr, "Failed to setup disclose database for duplicate entries\n");
87 if ((*dbh_lid)->set_flags (*dbh_lid, DB_DUP) != 0) {
88 fprintf (stderr, "Failed to setup localid database for duplicate entries\n");
91 if ((*dbh_disc)->open (*dbh_disc, *txn, dbdisc_fnm, NULL, DB_HASH, DB_CREATE | DB_THREAD, 0) != 0) {
92 fprintf (stderr, "Failed to open disclose database\n");
95 if ((*dbh_lid)->open (*dbh_lid, *txn, dblid_fnm, NULL, DB_HASH, DB_CREATE | DB_THREAD, 0) != 0) {
96 fprintf (stderr, "Failed to open disclose database\n");
102 /* Cleanup maangement structures */
103 void cleanup_management (DB_ENV *dbenv, DB *db_disc, DB *db_lid) {
104 db_lid->close (db_lid, 0);
105 db_disc->close (db_disc, 0);
106 dbenv->close (dbenv, 0);
109 int main (int argc, char *argv []) {
110 char *selector = NULL;
111 char *partstr = NULL;
112 char *saveptr = NULL;
114 uint8_t e_buf [5000];
133 fprintf (stderr, usage, argv [0]);
137 // Initialise the modules taken from the src directory
138 parse_cfgfile (argv [1], 0);
140 // Prepare variables from arguments
143 // Now prepare the database for changes
144 if (!setup_management (&dbenv, &txn, &dbh_disc, &dbh_lid)) {
148 // Verify that the to-be-introduced localid values occur in localid.db
150 if (dbh_lid->cursor (dbh_lid, txn, &crs, 0) != 0) {
151 fprintf (stderr, "Failed to open cursor on localid.db\n");
154 while (argi < argc) {
155 memset (&k_localid, 0, sizeof (k_localid));
156 k_localid.data = argv [argi];
157 k_localid.size = strlen (argv [argi]);
158 if (crs->get (crs, &k_localid, &e_value, DB_SET) != 0) {
159 fprintf (stderr, "Unknown local identity: %s\n", argv [argi]);
167 // We now know that all localid values are present in this transaction
168 // We can safely continue into removal of the old values and add new ones
169 if (dbh_disc->cursor (dbh_disc, txn, &crs, 0) != 0) {
170 fprintf (stderr, "Failed to open cursor on disclose.db\n");
173 memset (&k_selector, 0, sizeof (k_selector));
174 k_selector.data = selector;
175 k_selector.size = strlen (selector);
176 nomore = crs->get (crs, &k_selector, &e_value, DB_SET);
177 while (nomore == 0) {
178 printf ("Removing local identity %.*s\n",
179 e_value.size, e_value.data);
180 if (crs->del (crs, 0) != 0) {
181 fprintf (stderr, "Failed to delete record\n");
185 nomore = crs->get (crs, &k_selector, &e_value, DB_NEXT_DUP);
188 if (nomore != DB_NOTFOUND) {
189 fprintf (stderr, "Database error encountered while iterating\n");
193 // Now append the new loclid values
195 while (argi < argc) {
196 k_localid.data = argv [argi];
197 k_localid.size = strlen (argv [argi]);
198 printf ("Adding local identity %.*s\n",
199 k_localid.size, k_localid.data);
200 if (dbh_disc->put (dbh_disc, txn, &k_selector, &k_localid, 0) != 0) {
201 fprintf (stderr, "Failed to write record\n");
208 // Finally, commit the transaction
209 if (txn->commit (txn, 0) != 0) {
210 fprintf (stderr, "Failed to commit transaction\n");
213 fprintf (stderr, "Committed transaction\n");
216 // Finish up and report success
218 cleanup_management (dbenv, dbh_disc, dbh_lid);
221 // Handle failure during database interactions
223 fprintf (stderr, "Rolling back transaction\n");
225 cleanup_management (dbenv, dbh_disc, dbh_lid);