aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--changes/feature300456
-rw-r--r--doc/man/tor.1.txt14
-rw-r--r--scripts/maint/practracker/exceptions.txt4
-rw-r--r--src/app/config/config.c35
-rw-r--r--src/app/config/or_options_st.h5
-rw-r--r--src/feature/relay/routerkeys.c28
-rwxr-xr-xsrc/test/test_key_expiration.sh70
7 files changed, 147 insertions, 15 deletions
diff --git a/changes/feature30045 b/changes/feature30045
new file mode 100644
index 0000000000..9a0b8c041a
--- /dev/null
+++ b/changes/feature30045
@@ -0,0 +1,6 @@
+ o Minor features (admin tools):
+ - Add new --format argument to -key-expiration option to allow
+ specifying the time format of expiration date. Adds Unix
+ timestamp format support. Patch by Daniel Pinto. Closes
+ ticket 30045.
+
diff --git a/doc/man/tor.1.txt b/doc/man/tor.1.txt
index edb8593142..6e504c8a82 100644
--- a/doc/man/tor.1.txt
+++ b/doc/man/tor.1.txt
@@ -174,16 +174,22 @@ The following options in this section are only recognized on the
If the file descriptor is not specified, the passphrase is read
from the terminal by default.
-[[opt-key-expiration]] **`--key-expiration`** [__purpose__]::
+[[opt-key-expiration]] **`--key-expiration`** [__purpose__] [**`--format`** **`iso8601`**|**`timestamp`**]::
The __purpose__ specifies which type of key certificate to determine
the expiration of. The only currently recognised __purpose__ is
"sign". +
+
Running **`tor --key-expiration sign`** will attempt to find your
signing key certificate and will output, both in the logs as well
- as to stdout, the signing key certificate's expiration time in
- ISO-8601 format. For example, the output sent to stdout will be
- of the form: "signing-cert-expiry: 2017-07-25 08:30:15 UTC"
+ as to stdout. The optional **`--format`** argument lets you specify
+ the time format. Currently, **`iso8601`** and **`timestamp`** are
+ supported. If **`--format`** is not specified, the signing key
+ certificate's expiration time will be in ISO-8601 format. For example,
+ the output sent to stdout will be of the form:
+ "signing-cert-expiry: 2017-07-25 08:30:15 UTC". If **`--format`** **`timestamp`**
+ is specified, the signing key certificate's expiration time will be in
+ Unix timestamp format. For example, the output sent to stdout will be of the form:
+ "signing-cert-expiry: 1500971415".
[[opt-dbg]] **--dbg-**...::
Tor may support other options beginning with the string "dbg". These
diff --git a/scripts/maint/practracker/exceptions.txt b/scripts/maint/practracker/exceptions.txt
index b2a34b808a..95c5665fb3 100644
--- a/scripts/maint/practracker/exceptions.txt
+++ b/scripts/maint/practracker/exceptions.txt
@@ -37,7 +37,7 @@ problem file-size /src/app/config/config.c 7525
problem include-count /src/app/config/config.c 81
problem function-size /src/app/config/config.c:options_act() 381
problem function-size /src/app/config/config.c:options_validate_cb() 794
-problem function-size /src/app/config/config.c:options_init_from_torrc() 198
+problem function-size /src/app/config/config.c:options_init_from_torrc() 231
problem function-size /src/app/config/config.c:options_init_from_string() 103
problem function-size /src/app/config/config.c:options_init_logs() 125
problem function-size /src/app/config/config.c:parse_bridge_line() 104
@@ -47,7 +47,7 @@ problem function-size /src/app/config/config.c:parse_dir_fallback_line() 101
problem function-size /src/app/config/config.c:port_parse_config() 435
problem function-size /src/app/config/config.c:parse_ports() 132
problem function-size /src/app/config/resolve_addr.c:resolve_my_address_v4() 197
-problem file-size /src/app/config/or_options_st.h 1050
+problem file-size /src/app/config/or_options_st.h 1069
problem include-count /src/app/main/main.c 71
problem function-size /src/app/main/main.c:dumpstats() 102
problem function-size /src/app/main/main.c:tor_init() 109
diff --git a/src/app/config/config.c b/src/app/config/config.c
index a70c1d651e..1c6d4acd3e 100644
--- a/src/app/config/config.c
+++ b/src/app/config/config.c
@@ -2468,6 +2468,8 @@ static const struct {
{ .name="--key-expiration",
.takes_argument=ARGUMENT_OPTIONAL,
.command=CMD_KEY_EXPIRATION },
+ { .name="--format",
+ .takes_argument=ARGUMENT_NECESSARY },
{ .name="--newpass" },
{ .name="--no-passphrase" },
{ .name="--passphrase-fd",
@@ -4425,6 +4427,39 @@ options_init_from_torrc(int argc, char **argv)
}
}
+ const config_line_t *format_line = config_line_find(cmdline_only_options,
+ "--format");
+ if (format_line) {
+ if (command == CMD_KEY_EXPIRATION) {
+ const char *v = format_line->value;
+ // keep the same order as enum key_expiration_format
+ const char *formats[] = { "iso8601", "timestamp" };
+ const int formats_len = sizeof(formats) / sizeof(formats[0]);
+ int format = -1;
+ for (int i = 0; i < formats_len; i++) {
+ if (!strcmp(v, formats[i])) {
+ format = i;
+ break;
+ }
+ }
+
+ if (format < 0) {
+ log_err(LD_CONFIG, "Invalid --format value %s", escaped(v));
+ retval = -1;
+ goto err;
+ } else {
+ get_options_mutable()->key_expiration_format = format;
+ }
+ } else {
+ log_err(LD_CONFIG, "--format specified without --key-expiration!");
+ retval = -1;
+ goto err;
+ }
+ } else {
+ get_options_mutable()->key_expiration_format =
+ KEY_EXPIRATION_FORMAT_ISO8601;
+ }
+
if (config_line_find(cmdline_only_options, "--newpass")) {
if (command == CMD_KEYGEN) {
get_options_mutable()->change_key_passphrase = 1;
diff --git a/src/app/config/or_options_st.h b/src/app/config/or_options_st.h
index 68be5711ce..774b476476 100644
--- a/src/app/config/or_options_st.h
+++ b/src/app/config/or_options_st.h
@@ -945,6 +945,11 @@ struct or_options_t {
int OfflineMasterKey;
enum {
+ KEY_EXPIRATION_FORMAT_ISO8601 = 0,
+ KEY_EXPIRATION_FORMAT_TIMESTAMP
+ } key_expiration_format;
+
+ enum {
FORCE_PASSPHRASE_AUTO=0,
FORCE_PASSPHRASE_ON,
FORCE_PASSPHRASE_OFF
diff --git a/src/feature/relay/routerkeys.c b/src/feature/relay/routerkeys.c
index d3de83cb86..f0fd101efd 100644
--- a/src/feature/relay/routerkeys.c
+++ b/src/feature/relay/routerkeys.c
@@ -519,19 +519,34 @@ print_cert_expiration(const char *expiration,
/**
* Log when a certificate, <b>cert</b>, with some <b>description</b> and
- * stored in a file named <b>fname</b>, is going to expire.
+ * stored in a file named <b>fname</b>, is going to expire. Formats the expire
+ * time according to <b>time_format</b>. Valid time formats are in the
+ * key_expiration_format enum, in or_options_t.
*/
static void
log_ed_cert_expiration(const tor_cert_t *cert,
const char *description,
- const char *fname) {
- char expiration[ISO_TIME_LEN+1];
-
+ const char *fname,
+ int time_format) {
if (BUG(!cert)) { /* If the specified key hasn't been loaded */
log_warn(LD_OR, "No %s key loaded; can't get certificate expiration.",
description);
} else {
- format_local_iso_time(expiration, cert->valid_until);
+ char expiration[ISO_TIME_LEN+1];
+ switch (time_format) {
+ case KEY_EXPIRATION_FORMAT_ISO8601:
+ format_local_iso_time(expiration, cert->valid_until);
+ break;
+
+ case KEY_EXPIRATION_FORMAT_TIMESTAMP:
+ tor_snprintf(expiration, sizeof(expiration), "%"PRId64,
+ (int64_t) cert->valid_until);
+ break;
+
+ default:
+ log_err(LD_BUG, "Unknown time format value: %d.", time_format);
+ return;
+ }
log_notice(LD_OR, "The %s certificate stored in %s is valid until %s.",
description, fname, expiration);
print_cert_expiration(expiration, description);
@@ -567,7 +582,8 @@ log_master_signing_key_cert_expiration(const or_options_t *options)
/* If we do have a signing key, log the expiration time. */
if (signing_key) {
- log_ed_cert_expiration(signing_key, "signing", fn);
+ int time_format = options->key_expiration_format;
+ log_ed_cert_expiration(signing_key, "signing", fn, time_format);
} else {
log_warn(LD_OR, "Could not load signing key certificate from %s, so " \
"we couldn't learn anything about certificate expiration.", fn);
diff --git a/src/test/test_key_expiration.sh b/src/test/test_key_expiration.sh
index 2238f7aa78..1ba8179aa1 100755
--- a/src/test/test_key_expiration.sh
+++ b/src/test/test_key_expiration.sh
@@ -61,6 +61,11 @@ fi
CASE1=$dflt
CASE2=$dflt
CASE3=$dflt
+CASE4=$dflt
+CASE5=$dflt
+CASE6=$dflt
+CASE7=$dflt
+CASE8=$dflt
if [ $# -ge 1 ]; then
eval "CASE${1}"=1
@@ -125,16 +130,17 @@ if [ "$CASE1" = 1 ]; then
${TOR} ${QUIETLY} --key-expiration 2>"$FN" || true
grep "No valid argument to --key-expiration found!" "$FN" >/dev/null || \
- die "Tor didn't mention supported --key-expiration argmuents"
+ die "Tor didn't mention supported --key-expiration arguments"
echo "==== Case 1: ok"
fi
if [ "$CASE2" = 1 ]; then
- echo "==== Case 2: Start Tor with --key-expiration 'sign' and make sure it prints an expiration."
+ echo "==== Case 2: Start Tor with --key-expiration 'sign' and make sure it"
+ echo " prints an expiration using ISO8601 date format."
${TOR} ${QUIETLY} --key-expiration sign 2>"$FN"
- grep "signing-cert-expiry:" "$FN" >/dev/null || \
+ grep "signing-cert-expiry: [0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\} [0-9]\{2\}:[0-9]\{2\}:[0-9]\{2\}" "$FN" >/dev/null || \
die "Tor didn't print an expiration"
echo "==== Case 2: ok"
@@ -160,3 +166,61 @@ if [ "$CASE3" = 1 ]; then
echo "==== Case 3: ok"
fi
+
+if [ "$CASE4" = 1 ]; then
+ echo "==== Case 4: Start Tor with --format iso8601 and make sure it prints an"
+ echo " error message due to missing --key-expiration argument."
+
+ ${TOR} --format iso8601 > "$FN" 2>&1 || true
+ grep -- "--format specified without --key-expiration!" "$FN" >/dev/null || \
+ die "Tor didn't print a missing --key-expiration error message"
+
+ echo "==== Case 4: ok"
+fi
+
+if [ "$CASE5" = 1 ]; then
+ echo "==== Case 5: Start Tor with --key-expiration 'sign' --format '' and"
+ echo " make sure it prints an error message due to missing value."
+
+ ${TOR} --key-expiration sign --format > "$FN" 2>&1 || true
+ grep "Command-line option '--format' with no value. Failing." "$FN" >/dev/null || \
+ die "Tor didn't print a missing format value error message"
+
+ echo "==== Case 5: ok"
+fi
+
+if [ "$CASE6" = 1 ]; then
+ echo "==== Case 6: Start Tor with --key-expiration 'sign' --format 'invalid'"
+ echo " and make sure it prints an error message due to invalid"
+ echo " value."
+
+ ${TOR} --key-expiration sign --format invalid > "$FN" 2>&1 || true
+ grep "Invalid --format value" "$FN" >/dev/null || \
+ die "Tor didn't print an invalid format value error message"
+
+ echo "==== Case 6: ok"
+fi
+
+if [ "$CASE7" = 1 ]; then
+ echo "==== Case 7: Start Tor with --key-expiration 'sign' --format 'iso8601'"
+ echo " and make sure it prints an expiration using ISO8601 date"
+ echo " format."
+
+ ${TOR} ${QUIETLY} --key-expiration sign --format iso8601 2>"$FN"
+ grep "signing-cert-expiry: [0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\} [0-9]\{2\}:[0-9]\{2\}:[0-9]\{2\}" "$FN" >/dev/null || \
+ die "Tor didn't print an expiration"
+
+ echo "==== Case 7: ok"
+fi
+
+if [ "$CASE8" = 1 ]; then
+ echo "==== Case 8: Start Tor with --key-expiration 'sign' --format 'timestamp'"
+ echo " and make sure it prints an expiration using timestamp date"
+ echo " format."
+
+ ${TOR} ${QUIETLY} --key-expiration sign --format timestamp 2>"$FN"
+ grep "signing-cert-expiry: [0-9]\{5,\}" "$FN" >/dev/null || \
+ die "Tor didn't print an expiration"
+
+ echo "==== Case 8: ok"
+fi