From ca127bd653035018f0474ec7faf80a4666ce69d8 Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Aug 27 2012 18:45:29 +0000 Subject: generalize notifications a bit Add a parameter to the notification machinery which we can use to select what sort of message to send. This means that the current notify states need to be renamed so that we don't get confused when we add different sets of notifying states later. --- diff --git a/doc/design.txt b/doc/design.txt index cdf5b4f..11d6bf6 100644 --- a/doc/design.txt +++ b/doc/design.txt @@ -41,7 +41,7 @@ Now with some arbitrarily-named states for our per-certificate state machine: * Waiting for certificate to near expiration. States: MONITORING * Notifying the admin of impending/passed expiration. - States: NEED_TO_NOTIFY, NOTIFYING [*] + States: NEED_TO_NOTIFY_VALIDITY, NOTIFYING_VALIDITY [*] * Waiting for user input States: NEED_GUIDANCE [*] * Getting our bearings @@ -371,7 +371,7 @@ State logic: (expiration-time-is-below-notify-threshold-value and expiration-time-was-above-notify-threshold-value) update-template-values-based-on-cert - state_next = NEED_TO_NOTIFY + state_next = NEED_TO_NOTIFY_VALIDITY state_transition = now else if (expiration-time-is-below-renewal-threshold-value and @@ -383,19 +383,19 @@ State logic: state_transition = timeout break - NEED_TO_NOTIFY: + NEED_TO_NOTIFY_VALIDITY: if starting-up state_next = MONITORING state_transition = now else start-notifying - state_next = NOTIFYING + state_next = NOTIFYING_VALIDITY state_transition = now break - NOTIFYING: + NOTIFYING_VALIDITY: if starting-up - state_next = NEED_TO_NOTIFY + state_next = NEED_TO_NOTIFY_VALIDITY state_transition = now else if notification-completed diff --git a/src/getcert.c b/src/getcert.c index c333b8c..4ec0c7a 100644 --- a/src/getcert.c +++ b/src/getcert.c @@ -2219,8 +2219,8 @@ list(const char *argv0, int argc, char **argv) } break; case CM_MONITORING: - case CM_NEED_TO_NOTIFY: - case CM_NOTIFYING: + case CM_NEED_TO_NOTIFY_VALIDITY: + case CM_NOTIFYING_VALIDITY: if (requests_only) { continue; } diff --git a/src/iterate.c b/src/iterate.c index 9612ea4..687bf06 100644 --- a/src/iterate.c +++ b/src/iterate.c @@ -144,11 +144,11 @@ cm_entry_reset_state(struct cm_store_entry *entry) break; case CM_MONITORING: break; - case CM_NEED_TO_NOTIFY: + case CM_NEED_TO_NOTIFY_VALIDITY: entry->cm_state = CM_MONITORING; break; - case CM_NOTIFYING: - entry->cm_state = CM_NEED_TO_NOTIFY; + case CM_NOTIFYING_VALIDITY: + entry->cm_state = CM_NEED_TO_NOTIFY_VALIDITY; break; case CM_NEWLY_ADDED: break; @@ -996,7 +996,7 @@ cm_iterate(struct cm_store_entry *entry, struct cm_store_ca *ca, &cm_prefs_notify_ttls, &entry->cm_last_need_notify_check) == 0)) { /* Kick off a notification. */ - entry->cm_state = CM_NEED_TO_NOTIFY; + entry->cm_state = CM_NEED_TO_NOTIFY_VALIDITY; *when = cm_time_now; } else if (entry->cm_autorenew && @@ -1016,10 +1016,11 @@ cm_iterate(struct cm_store_entry *entry, struct cm_store_ca *ca, } break; - case CM_NEED_TO_NOTIFY: - state->cm_notify_state = cm_notify_start(entry); + case CM_NEED_TO_NOTIFY_VALIDITY: + state->cm_notify_state = cm_notify_start(entry, + cm_notify_event_validity_ending); if (state->cm_notify_state != NULL) { - entry->cm_state = CM_NOTIFYING; + entry->cm_state = CM_NOTIFYING_VALIDITY; /* Wait for status update, or poll. */ *readfd = cm_notify_get_fd(entry, state->cm_notify_state); @@ -1034,7 +1035,7 @@ cm_iterate(struct cm_store_entry *entry, struct cm_store_ca *ca, } break; - case CM_NOTIFYING: + case CM_NOTIFYING_VALIDITY: if (cm_notify_ready(entry, state->cm_notify_state) == 0) { cm_notify_done(entry, state->cm_notify_state); state->cm_notify_state = NULL; diff --git a/src/notify.c b/src/notify.c index b92e422..7e83881 100644 --- a/src/notify.c +++ b/src/notify.c @@ -40,11 +40,16 @@ struct cm_notify_state { struct cm_subproc_state *subproc; }; +struct cm_notify_details { + enum cm_notify_event event; +}; + /* Fire off the proper notification. */ static int cm_notify_main(int fd, struct cm_store_ca *ca, struct cm_store_entry *entry, void *userdata) { + struct cm_notify_details *details = userdata; enum cm_notification_method method; const char *dest, *p, *q, *message = NULL, *error; char *tok, t[15], **argv; @@ -84,67 +89,81 @@ cm_notify_main(int fd, struct cm_store_ca *ca, struct cm_store_entry *entry, {"debug", LOG_DEBUG}, }; unsigned int i; - if (entry->cm_cert_not_after > cm_time(NULL)) { - switch (entry->cm_cert_storage_type) { - case cm_cert_storage_nssdb: - if (entry->cm_cert_token != NULL) { - message = talloc_asprintf(entry, "Certificate " - "named \"%s\" " - "in token \"%s\" " - "in database \"%s\" " - "will not be valid " - "after %s.\n", - entry->cm_cert_nickname, - entry->cm_cert_token, - entry->cm_cert_storage_location, - cm_store_timestamp_from_time(entry->cm_cert_not_after, t)); - } else { + switch (details->event) { + case cm_notify_event_unknown: + message = talloc_asprintf(entry, "Something " + "happened with certiifcate " + "named \"%s\" " + "in token \"%s\" " + "in database \"%s\".", + entry->cm_cert_nickname, + entry->cm_cert_token, + entry->cm_cert_storage_location); + break; + case cm_notify_event_validity_ending: + if (entry->cm_cert_not_after > cm_time(NULL)) { + switch (entry->cm_cert_storage_type) { + case cm_cert_storage_nssdb: + if (entry->cm_cert_token != NULL) { + message = talloc_asprintf(entry, "Certificate " + "named \"%s\" " + "in token \"%s\" " + "in database \"%s\" " + "will not be valid " + "after %s.\n", + entry->cm_cert_nickname, + entry->cm_cert_token, + entry->cm_cert_storage_location, + cm_store_timestamp_from_time(entry->cm_cert_not_after, t)); + } else { + message = talloc_asprintf(entry, "Certificate " + "named \"%s\" " + "in database \"%s\" " + "will expire at " + "%s.\n", + entry->cm_cert_nickname, + entry->cm_cert_storage_location, + cm_store_timestamp_from_time(entry->cm_cert_not_after, t)); + } + break; + case cm_cert_storage_file: message = talloc_asprintf(entry, "Certificate " - "named \"%s\" " - "in database \"%s\" " - "will expire at " - "%s.\n", - entry->cm_cert_nickname, + "in file \"%s\" will not be " + "valid after %s.\n", entry->cm_cert_storage_location, cm_store_timestamp_from_time(entry->cm_cert_not_after, t)); + break; } - break; - case cm_cert_storage_file: - message = talloc_asprintf(entry, "Certificate " - "in file \"%s\" will not be " - "valid after %s.\n", - entry->cm_cert_storage_location, - cm_store_timestamp_from_time(entry->cm_cert_not_after, t)); - break; - } - } else { - switch (entry->cm_cert_storage_type) { - case cm_cert_storage_nssdb: - if (entry->cm_cert_token != NULL) { - message = talloc_asprintf(entry, "Certificate " - "named \"%s\" " - "in token \"%s\" " - "in database \"%s\" " - "is no longer valid.", - entry->cm_cert_nickname, - entry->cm_cert_token, - entry->cm_cert_storage_location); - } else { + } else { + switch (entry->cm_cert_storage_type) { + case cm_cert_storage_nssdb: + if (entry->cm_cert_token != NULL) { + message = talloc_asprintf(entry, "Certificate " + "named \"%s\" " + "in token \"%s\" " + "in database \"%s\" " + "is no longer valid.", + entry->cm_cert_nickname, + entry->cm_cert_token, + entry->cm_cert_storage_location); + } else { + message = talloc_asprintf(entry, "Certificate " + "named \"%s\" " + "in database \"%s\" " + "is no longer valid.", + entry->cm_cert_nickname, + entry->cm_cert_storage_location); + } + break; + case cm_cert_storage_file: message = talloc_asprintf(entry, "Certificate " - "named \"%s\" " - "in database \"%s\" " - "is no longer valid.", - entry->cm_cert_nickname, + "in file \"%s\" is no longer " + "valid.", entry->cm_cert_storage_location); + break; } - break; - case cm_cert_storage_file: - message = talloc_asprintf(entry, "Certificate " - "in file \"%s\" is no longer " - "valid.", - entry->cm_cert_storage_location); - break; } + break; } method = entry->cm_notification_method; if (method == cm_notification_unspecified) { @@ -225,13 +244,16 @@ cm_notify_main(int fd, struct cm_store_ca *ca, struct cm_store_entry *entry, /* Start notifying the user that the certificate will expire soon. */ struct cm_notify_state * -cm_notify_start(struct cm_store_entry *entry) +cm_notify_start(struct cm_store_entry *entry, enum cm_notify_event event) { struct cm_notify_state *state; + struct cm_notify_details details; state = talloc_ptrtype(entry, state); if (state != NULL) { + memset(&details, 0, sizeof(details)); + details.event = event; state->subproc = cm_subproc_start(cm_notify_main, - NULL, entry, NULL); + NULL, entry, &details); if (state->subproc == NULL) { talloc_free(state); state = NULL; diff --git a/src/notify.h b/src/notify.h index c22f388..173da94 100644 --- a/src/notify.h +++ b/src/notify.h @@ -21,8 +21,14 @@ struct cm_store_entry; struct cm_notify_state; +enum cm_notify_event { + cm_notify_event_unknown = 0, + cm_notify_event_validity_ending +}; + /* Start to notify the administrator or user that expiration is imminent. */ -struct cm_notify_state *cm_notify_start(struct cm_store_entry *entry); +struct cm_notify_state *cm_notify_start(struct cm_store_entry *entry, + enum cm_notify_event event); /* Get a selectable-for-read descriptor we can poll for status changes when * we're finished sending the notification. */ int cm_notify_get_fd(struct cm_store_entry *entry, diff --git a/src/store-gen.c b/src/store-gen.c index 3cf32ce..89606dc 100644 --- a/src/store-gen.c +++ b/src/store-gen.c @@ -64,8 +64,8 @@ static struct { {"SAVED_CERT", CM_SAVED_CERT}, {"POST_SAVED_CERT", CM_POST_SAVED_CERT}, {"MONITORING", CM_MONITORING}, - {"NEED_TO_NOTIFY", CM_NEED_TO_NOTIFY}, - {"NOTIFYING", CM_NOTIFYING}, + {"NEED_TO_NOTIFY_VALIDITY", CM_NEED_TO_NOTIFY_VALIDITY}, + {"NOTIFYING_VALIDITY", CM_NOTIFYING_VALIDITY}, {"NEED_GUIDANCE", CM_NEED_GUIDANCE}, {"NEWLY_ADDED", CM_NEWLY_ADDED}, {"NEWLY_ADDED_START_READING_KEYINFO", CM_NEWLY_ADDED_START_READING_KEYINFO}, diff --git a/src/store-int.h b/src/store-int.h index c6e94c8..18661fa 100644 --- a/src/store-int.h +++ b/src/store-int.h @@ -119,7 +119,8 @@ struct cm_store_entry { CM_START_SAVING_CERT, CM_SAVING_CERT, CM_NEED_TO_READ_CERT, CM_READING_CERT, CM_SAVED_CERT, CM_POST_SAVED_CERT, - CM_MONITORING, CM_NEED_TO_NOTIFY, CM_NOTIFYING, + CM_MONITORING, + CM_NEED_TO_NOTIFY_VALIDITY, CM_NOTIFYING_VALIDITY, CM_NEED_GUIDANCE, CM_NEWLY_ADDED, CM_NEWLY_ADDED_START_READING_KEYINFO, diff --git a/src/tdbush.c b/src/tdbush.c index 45b97c7..8c93eca 100644 --- a/src/tdbush.c +++ b/src/tdbush.c @@ -2945,8 +2945,8 @@ request_prop_get_stuck(struct cm_context *ctx, void *parent, case CM_SAVED_CERT: case CM_POST_SAVED_CERT: case CM_MONITORING: - case CM_NEED_TO_NOTIFY: - case CM_NOTIFYING: + case CM_NEED_TO_NOTIFY_VALIDITY: + case CM_NOTIFYING_VALIDITY: case CM_NEWLY_ADDED: case CM_NEWLY_ADDED_START_READING_KEYINFO: case CM_NEWLY_ADDED_READING_KEYINFO: