aboutsummaryrefslogtreecommitdiffstats
path: root/dirmngr/ldap-misc.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2023-04-04 06:49:55 +0000
committerWerner Koch <[email protected]>2023-04-04 06:49:55 +0000
commit56d309133f0e54ac5e2f95871fb74f8cb97e2636 (patch)
tree79624645582e9dbe72b16287b553b37abfcfc724 /dirmngr/ldap-misc.c
parentagent: Add trustlist flag "de-vs". (diff)
downloadgnupg-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.c87
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;
+}