X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb/blobdiff_plain/ba6e6b64033b1f9de49feccb5c9cd438354481f7..0f00dc4c8eb47e67bc0f148c2dd109f73a451e0a:/key/key-flags.c diff --git a/key/key-flags.c b/key/key-flags.c new file mode 100644 index 00000000..169de2c5 --- /dev/null +++ b/key/key-flags.c @@ -0,0 +1,202 @@ +/* -*-c-*- + * + * Reading and writing key flag strings + * + * (c) 1999 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +/*----- Header files ------------------------------------------------------*/ + +#include +#include + +#include +#include + +#include "key-data.h" + +/*----- Data structures ---------------------------------------------------*/ + +typedef struct key_flags { + unsigned f; + unsigned m; +} key_flags; + +/*----- Flags table -------------------------------------------------------*/ + +typedef struct flagent { + const char *name; + unsigned f; + unsigned m; +} flagent; + +static const flagent flagtab[] = { + + /* --- Encoding types --- */ + + { "binary", KENC_BINARY, KF_ENCMASK }, + { "integer", KENC_MP, KF_ENCMASK }, + { "struct", KENC_STRUCT, KF_ENCMASK }, + { "encrypt", KENC_ENCRYPT, KF_ENCMASK }, + { "string", KENC_STRING, KF_ENCMASK }, + { "ec", KENC_EC, KF_ENCMASK }, + + /* --- Classes of keys --- */ + + { "shared", KCAT_SHARE, KF_CATMASK }, + { "public", KCAT_PUB, KF_CATMASK }, + { "private", KCAT_PRIV, KF_CATMASK }, + { "symmetric", KCAT_SYMM, KF_CATMASK }, + { "secret", 0, KF_NONSECRET }, + { "-secret", KF_NONSECRET, KF_NONSECRET }, + + /* --- Other flags --- */ + + { "burn", KF_BURN, KF_BURN }, + { "-burn", 0, KF_BURN }, + + /* --- End marker --- */ + + { 0, 0, 0 } +}; + +/*----- Main code ---------------------------------------------------------*/ + +/* --- @key_readflags@ --- * + * + * Arguments: @const char *p@ = pointer to string to read + * @char **pp@ = where to store the end pointer + * @unsigned *ff@ = where to store the flags + * @unsigned *mm@ = where to store the mask + * + * Returns: Zero if all went well, nonzero if there was an error. + * + * Use: Reads a flag string. + */ + +int key_readflags(const char *p, char **pp, unsigned *ff, unsigned *mm) +{ + unsigned f = 0, m = 0; + + for (;;) { + size_t sz = strcspn(p, ",:"); + const flagent *e, *ee = 0; + + /* --- Look up the string in the flags table --- */ + + if (sz == 4 && strncmp(p, "none", 4) == 0) + goto next; + for (e = flagtab; e->name; e++) { + if (strncmp(e->name, p, sz) == 0) { + if (e->name[sz] == 0) { + ee = e; + break; + } else if (ee) + return (KERR_BADFLAGS); + else + ee = e; + } + } + if (!ee) + return (KERR_BADFLAGS); + + /* --- Adjust the flag words --- * + * + * Ensure that the flags set are disjoint. + */ + + if (m & ee->m) + return (KERR_BADFLAGS); + m |= ee->m; + f |= ee->f; + next: + p += sz; + if (*p == 0 || *p == ':') + break; + p++; + } + + /* --- Report the results --- */ + + if (ff) *ff = f; + if (mm) *mm = m; + if (pp) *pp = (char *)p; + return (0); +} + +/* --- @key_writeflags@ --- * + * + * Arguments: @unsigned f@ = flags to write + * @dstr *d@ = pointer to destination string + * + * Returns: --- + * + * Use: Emits a flags word as a string representation. + */ + +void key_writeflags(unsigned f, dstr *d) +{ + int del = 0; + const flagent *e; + unsigned m = 0; + + for (e = flagtab; e->name; e++) { + if (m & e->m || e->name[0] == '-' || (f & e->m) != e->f) + continue; + if (del) + DPUTC(d, ','); + DPUTS(d, e->name); + m |= e->m; + del = 1; + } +} + +/* --- @key_match@ --- * + * + * Arguments: @key_data *k@ = pointer to key data block + * @const key_filter *kf@ = pointer to filter block + * + * Returns: Nonzero if the key matches the filter. + * + * Use: Checks whether a key matches a filter. + */ + +int key_match(key_data *k, const key_filter *kf) +{ + key_subkeyiter i; + const char *tag; + key_data *kd; + + if (!kf) + return (1); + if ((k->e & KF_ENCMASK) != KENC_STRUCT) + return ((k->e & kf->m) == kf->f); + + for (key_mksubkeyiter(&i, k); key_nextsubkey(&i, &tag, &kd); ) { + if (key_match(kd, kf)) + return (1); + } + return (0); +} + +/*----- That's all, folks -------------------------------------------------*/