[Opendnssec-develop] HSM reopen

Siôn Lloyd sion at nominet.org.uk
Thu Aug 25 09:55:26 UTC 2011


 From the meeting yesterday I was going to find the patch for HSM 
connection fun.

This is code that I added in December last year, the patch is for the 
1.1 branch.

For my tests Rickard suggested adding the following:

for (int i = 0; i < ctx->session_count; i++)
{
     ctx->session[i]->session = 0;
}

which invalidates any HSM connections... It worked, but as I am not sure 
that this looks the same as a timed out connection I did not commit the 
code.

It validates a connection by counting the keys, which seems like a 
neutral operation. As the enforcer doesn't run so often this should be 
okay; I'm not sure that the overhead of this is acceptable for the 
signer though.

Sion



sion at sion:~/work/opendnssec/OpenDNSSEC-1.1$ svn diff
Index: enforcer/enforcerd/enforcer.c
===================================================================
--- enforcer/enforcerd/enforcer.c       (revision 4267)
+++ enforcer/enforcerd/enforcer.c       (working copy)
@@ -286,6 +286,10 @@
              log_msg(config, LOG_INFO, "Received SIGINT, exiting...");
              break;
          }
+
+        /* Make sure that we can still talk to the HSM; this call exits if
+           we can not */
+        check_hsm_connection(&ctx, config);
      }

      /*
@@ -1771,3 +1775,71 @@

      return status;
  }
+
+void check_hsm_connection(hsm_ctx_t **ctx, DAEMONCONFIG *config)
+{
+    int result = 0;
+    char *hsm_error_message = NULL;
+    int i;
+
+    for (i = 0; i < (*ctx)->session_count; i++) {
+        result = hsm_count_keys_session(*ctx, (*ctx)->session[i]);
+        if (result == 0) {
+            /* Either that HSM is empty or we could not talk to it,
+               assume that we need to reconnect */
+            break;
+        }
+    }
+
+    /* If we got zero then it probably means that we could not talk to 
an HSM
*/
+    if (result == 0) {
+
+        if (*ctx) {
+            hsm_destroy_context(*ctx);
+        }
+
+        result = hsm_close();
+
+        if (config->configfile != NULL) {
+            result = hsm_open(config->configfile, hsm_prompt_pin, NULL);
+        } else {
+            result = hsm_open(CONFIG_FILE, hsm_prompt_pin, NULL);
+        }
+        if (result) {
+            hsm_error_message = hsm_get_error(*ctx);
+            if (hsm_error_message) {
+                log_msg(config, LOG_ERR, hsm_error_message);
+                free(hsm_error_message);
+            } else {
+                /* decode the error code ourselves
+                   TODO find if there is a better way to do this (and 
can all
of these be returned? are there others?) */
+                switch (result) {
+                    case HSM_ERROR:
+                        log_msg(config, LOG_ERR, "hsm_open() result: HSM
error");
+                        break;
+                    case HSM_PIN_INCORRECT:
+                        log_msg(config, LOG_ERR, "hsm_open() result: 
incorrect
PIN");
+                        break;
+                    case HSM_CONFIG_FILE_ERROR:
+                        log_msg(config, LOG_ERR, "hsm_open() result: 
config file
error");
+                        break;
+                    case HSM_REPOSITORY_NOT_FOUND:
+                        log_msg(config, LOG_ERR, "hsm_open() result:
repository not found");
+                        break;
+                    case HSM_NO_REPOSITORIES:
+                        log_msg(config, LOG_ERR, "hsm_open() result: no
repositories");
+                        break;
+                    default:
+                        log_msg(config, LOG_ERR, "hsm_open() result: %d",
result);
+                }
+            }
+            unlink(config->pidfile);
+            exit(1);
+        }
+        log_msg(config, LOG_INFO, "HSM reopened successfully.");
+        *ctx = hsm_create_context();
+    } else {
+        log_msg(config, LOG_INFO, "HSM connection open.");
+    }
+
+}
Index: enforcer/enforcerd/enforcer.h
===================================================================
--- enforcer/enforcerd/enforcer.h       (revision 4267)
+++ enforcer/enforcerd/enforcer.h       (working copy)
@@ -51,5 +51,6 @@
  int read_zonelist_filename(const char* filename, char** 
zone_list_filename);
  int do_purge(int interval, int policy_id);
  int NewDSSet(int zone_id, const char* zone_name, const char* DSSubmitCmd);
+void check_hsm_connection(hsm_ctx_t **ctx, DAEMONCONFIG *config);

  #endif /* ENFORCER_H */



More information about the Opendnssec-develop mailing list