X-Git-Url: https://git.distorted.org.uk/u/mdw/catacomb/blobdiff_plain/6f51228e8b99c2f0cbec5cb9d77925e0031eacd8..d11a0bf77a5230387d222ec727865a898767ff3e:/key-attr.c diff --git a/key-attr.c b/key-attr.c new file mode 100644 index 0000000..3737a5d --- /dev/null +++ b/key-attr.c @@ -0,0 +1,292 @@ +/* -*-c-*- + * + * $Id: key-attr.c,v 1.1 1999/12/22 15:47:48 mdw Exp $ + * + * Key attribute manipulation + * + * (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. + */ + +/*----- Revision history --------------------------------------------------* + * + * $Log: key-attr.c,v $ + * Revision 1.1 1999/12/22 15:47:48 mdw + * Major key-management revision. + * + */ + +/*----- Header files ------------------------------------------------------*/ + +#include +#include +#include +#include +#include + +#include +#include + +#include "key.h" + +/*----- Main code ---------------------------------------------------------*/ + +/* --- @key_chkident@ --- * + * + * Arguments: @const char *p@ = pointer to a type string + * + * Returns: Zero if OK, -1 on error. + * + * Use: Checks whether an identification component string is OK. + */ + +int key_chkident(const char *p) +{ + if (!p || !*p) + return (-1); + while (*p) { + if (*p == ':' || *p == '.' || isspace((unsigned char)*p)) + return (-1); + p++; + } + return (0); +} + +/* --- @key_chkcomment@ --- * + * + * Arguments: @const char *p@ = pointer to a comment string + * + * Returns: Zero if OK, -1 on error. + * + * Use: Checks whether a comment string is OK. + */ + +int key_chkcomment(const char *p) +{ + if (!p) + return (0); + if (!*p) + return (-1); + while (*p) { + if (*p == '\n') + return (-1); + p++; + } + return (0); +} + +/* --- @key_mkattriter@ --- * + * + * Arguments: @key_attriter *i@ = pointer to attribute iterator + * @key *k@ = pointer to key + * + * Returns: --- + * + * Use: Initializes an attribute iterator. The attributes are + * returned by @key_nextattr@. + */ + +void key_mkattriter(key_attriter *i, key *k) +{ + sym_mkiter(&i->i, &k->a); +} + +/* --- @key_nextattr@ --- * + * + * Arguments: @key_attriter *i@ = pointer to attribute iterator + * @const char **n, **v@ = pointers to name and value + * + * Returns: Zero if no attribute available, or nonzero if returned OK. + * + * Use: Returns the next attribute. + */ + +int key_nextattr(key_attriter *i, const char **n, const char **v) +{ + key_attr *a = sym_next(&i->i); + if (!a) + return (0); + *n = SYM_NAME(a); + *v = a->p; + return (1); +} + +/* --- @key_getattr@ --- * + * + * Arguments: @key_file *f@ = pointer to file + * @key *k@ = pointer to key + * @const char *n@ = pointer to attribute name + * + * Returns: Pointer to attribute value, or null if not found. + * + * Use: Returns the value of a key attribute. + */ + +const char *key_getattr(key_file *f, key *k, const char *n) +{ + key_attr *a; + if ((a = sym_find(&k->a, n, -1, 0, 0)) == 0) + return (0); + return (a->p); +} + +/* --- @key_putattr@ --- * + * + * Arguments: @key_file *f@ = pointer to file + * @key *k@ = pointer to key + * @const char *n@ = pointer to attribute name + * @const char *v@ = pointer to attribute value or null + * + * Returns: Error code (one of the @KERR@ constants). + * + * Use: Inserts an attribute on a key. If an attribute with the same + * name already exists, it is deleted. Setting a null value + * removes the attribute. + */ + +int key_putattr(key_file *f, key *k, const char *n, const char *v) +{ + key_attr *a; + unsigned found; + + if (!(f->f & KF_WRITE)) + return (KERR_READONLY); + + if (v) { + a = sym_find(&k->a, n, -1, sizeof(*a), &found); + if (found) + free(a->p); + a->p = xstrdup(v); + } else if ((a = sym_find(&k->a, n, -1, 0, 0)) != 0) { + free(a->p); + sym_remove(&k->a, a); + } + + f->f |= KF_MODIFIED; + return (0); +} + +/* --- @key_setcomment@ --- * + * + * Arguments: @key_file *f@ = pointer to key file block + * @key *k@ = pointer to key block + * @const char *c@ = pointer to comment to set, or zero + * + * Returns: Error code (one of the @KERR@ constants). + * + * Use: Replaces the key's current comment with a new one. + */ + +int key_setcomment(key_file *f, key *k, const char *c) +{ + if (!(f->f & KF_WRITE)) + return (KERR_READONLY); + if (key_chkcomment(c)) + return (KERR_BADCOMMENT); + if (k->c) + free(k->c); + if (c) + k->c = xstrdup(c); + else + k->c = 0; + f->f |= KF_MODIFIED; + return (0); +} + +/* --- @key_settag@ --- * + * + * Arguments: @key_file *f@ = pointer to key file block + * @key *k@ = pointer to key block + * @const char *tag@ = pointer to comment to set, or zero + * + * Returns: Error code (one of the @KERR@ constants). + * + * Use: Replaces the key's current tag with a new one. + */ + +int key_settag(key_file *f, key *k, const char *tag) +{ + key_ref *kr; + unsigned found; + + if (!(f->f & KF_WRITE)) + return (KERR_READONLY); + + /* --- Make sure the tag is OK --- */ + + if (tag && key_chkident(tag)) + return (KERR_BADTAG); + + /* --- See if the new tag is the same as the old one --- */ + + if ((!tag && !k->tag) || + (tag && k->tag && strcmp(tag, k->tag) == 0)) + return (0); + + /* --- Allocate an entry for the new tag --- */ + + if (tag) { + kr = sym_find(&f->bytag, tag, -1, sizeof(*kr), &found); + if (found) + return (KERR_DUPTAG); + kr->k = k; + } + + /* --- Remove any existing tag --- */ + + if (k->tag) { + kr = sym_find(&f->bytag, k->tag, -1, 0, 0); + assert(((void)"No bytag link", kr)); + sym_remove(&f->bytag, kr); + free(k->tag); + } + + /* --- Done --- */ + + f->f |= KF_MODIFIED; + if (tag) + k->tag = xstrdup(tag); + else + k->tag = 0; + return (0); +} + +/* --- @key_fulltag@ --- * + * + * Arguments: @key *k@ = pointer to key + * @dstr *d@ = pointer to destination string + * + * Returns: --- + * + * Use: Emits the key's full tag, which has the form + * `ID:TYPE[:TAG]'. This is used in the textual file format, + * and to identify passphrases for locked keys. + */ + +void key_fulltag(key *k, dstr *d) +{ + dstr_putf(d, "%08lx:%s", (unsigned long)k->id, k->type); + if (k->tag) + dstr_putf(d, ":%s", k->tag); +} + +/*----- That's all, folks -------------------------------------------------*/