diff options
author | Werner Koch <[email protected]> | 2023-04-04 06:49:55 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2023-04-04 06:49:55 +0000 |
commit | 56d309133f0e54ac5e2f95871fb74f8cb97e2636 (patch) | |
tree | 79624645582e9dbe72b16287b553b37abfcfc724 /dirmngr/ldap-misc.c | |
parent | agent: Add trustlist flag "de-vs". (diff) | |
download | gnupg-56d309133f0e54ac5e2f95871fb74f8cb97e2636.tar.gz gnupg-56d309133f0e54ac5e2f95871fb74f8cb97e2636.zip |
dirmngr: Return modifyTimestamp and add server option --newer.
* dirmngr/server.c (cmd_ks_get): Add option --newer.
(cmd_ad_query): Ditto.
* dirmngr/ldap-misc.c (isotime2rfc4517): New.
(rfc4517toisotime): New.
* dirmngr/ks-action.c (ks_action_get): Add arg newer and pass on.
(ks_action_query): Ditto.
* dirmngr/ks-engine-ldap.c (extract_keys): Print new "chg" record.
(ks_ldap_get): Add arg newer. Modify filter with newer arg.
(ks_ldap_search): Print the modifyTimestamp.
(ks_ldap_query): Add arg newer. Modify filter with newer arg.
--
Note that the modifyTimestamp is also available on Windows, where its
value is more commonly known as whenChanged. Both are constructed
attributes.
Note that the --newer option is a bit of a misnomer because LDAP has
only a greater-or-equal and no greater-than operator.
Diffstat (limited to 'dirmngr/ldap-misc.c')
-rw-r--r-- | dirmngr/ldap-misc.c | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/dirmngr/ldap-misc.c b/dirmngr/ldap-misc.c index 90f1d1f3c..6b0939a3b 100644 --- a/dirmngr/ldap-misc.c +++ b/dirmngr/ldap-misc.c @@ -332,3 +332,90 @@ ldap_parse_extfilter (const char *string, int silent, } return err; } + + + +/* Scan an ISO timestamp and return a Generalized Time according to + * RFC-4517. The only supported format is "yyyymmddThhmmss[Z]" + * delimited by white space, nul, a colon or a comma. Returns a + * malloced string or NULL for an invalid string or on memory + * error. */ +char * +isotime2rfc4517 (const char *string) +{ + int year, month, day, hour, minu, sec; + + if (!isotime_p (string)) + { + errno = 0; + return NULL; + } + + year = atoi_4 (string); + month = atoi_2 (string + 4); + day = atoi_2 (string + 6); + hour = atoi_2 (string + 9); + minu = atoi_2 (string + 11); + sec = atoi_2 (string + 13); + + /* Basic checks (1600 due to the LDAP time format base) */ + if (year < 1600 || month < 1 || month > 12 || day < 1 || day > 31 + || hour > 23 || minu > 59 || sec > 61 ) + { + errno = 0; + return NULL; + } + + return gpgrt_bsprintf ("%04d%02d%02d%02d%02d%02d.0Z", + year, month, day, hour, minu, sec); +} + + +/* Parse an LDAP Generalized Time string and update the provided + * isotime buffer. On error return and error code. */ +gpg_error_t +rfc4517toisotime (gnupg_isotime_t timebuf, const char *string) +{ + int i; + int year, month, day, hour, minu, sec; + const char *s; + + for (i=0, s=string; i < 10; i++, s++) /* Need yyyymmddhh */ + if (!digitp (s)) + return gpg_error (GPG_ERR_INV_TIME); + year = atoi_4 (string); + month = atoi_2 (string + 4); + day = atoi_2 (string + 6); + hour = atoi_2 (string + 9); + minu = 0; + sec = 0; + if (digitp (s) && digitp (s+1)) + { + minu = atoi_2 (s); + s += 2; + if (digitp (s) && digitp (s+1)) + { + sec = atoi_2 (s); + s += 2; + } + } + if (*s == '.' || *s == ',') + { + s++; + if (!digitp (s)) /* At least one digit of the fraction required. */ + return gpg_error (GPG_ERR_INV_TIME); + s++; + while (digitp (s)) + s++; + } + if (*s == 'Z' && (!s[1] || spacep (s+1))) + ; /* stop here. */ + else if (*s == '-' || *s == '+') + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); /* FIXME */ + else + return gpg_error (GPG_ERR_INV_TIME); + + snprintf (timebuf, sizeof (gnupg_isotime_t), "%04d%02d%02dT%02d%02d%02d", + year, month, day, hour, minu, sec); + return 0; +} |