Wed, 27 Nov 2024 16:42:19 +0100
add encryption and lock indicator, resolves #501
/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2024 Olaf Wintermann. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef LIBIDAV_PWDSTORE_H #define LIBIDAV_PWDSTORE_H #ifdef __cplusplus extern "C" { #endif #include <stdlib.h> #include <inttypes.h> #include <cx/map.h> #include <cx/buffer.h> #include <cx/linked_list.h> #include "crypto.h" #ifdef __cplusplus extern "C" { #endif #define PWDSTORE_MAX_LEN 4096 /* * File Format: * * file = header, index, enc_content * header = magic, version, enc, pwfunc, salt, indexlen * magic = 1 byte * version = 1 byte * enc = 1 byte * pwfunc = 1 byte * salt = 16 bytes * indexlen = uint32 * index = { itype length id locations zero } * enc_content = iv bytes * iv = 16 bytes * content = { entry } * entry = itype length id length username length password * length = uint32 * zero = 4 zero bytes * itype = 1 byte * id = string * locations = { length string } * username = string * password = string * * The content is AES encrypted with a key derived from a password * and the salt. The first 16 bytes are the aes iv. * * All integers are big endian */ #define PWDS_HEADER_SIZE 24 typedef struct PwdStore PwdStore; typedef struct PwdEntry PwdEntry; typedef struct PwdIndexEntry PwdIndexEntry; struct PwdStore { /* * map of all credentials * key is the username * value is PwdEntry* */ CxMap *ids; /* * list of all credentials with location * value is PwdIndexEntry* */ CxList *locations; /* * list of all credentials without location * value is PwdIndexEntry* */ CxList *noloc; /* * index map that contains all elements from the lists * 'locations' and 'noloc' */ CxMap *index; /* * a buffer containing the complete file content */ CxBuffer *content; /* * key used for encryption/decryption */ DavKey *key; /* * optional shell command, that is used for getting the master password */ char *unlock_cmd; /* * optional shell command, that is exected when the secretstore is closed */ char *lock_cmd; /* * start offset of the encrypted buffer */ uint32_t encoffset; /* * indicates if the PwdStore is decrypted with pwdstore_decrypt */ uint8_t isdecrypted; }; #define PWDS_MAGIC(p) (p)->content->space[0] #define PWDS_VERSION(p) (p)->content->space[1] #define PWDS_ENC(p) (p)->content->space[2] #define PWDS_PWFUNC(p) (p)->content->space[3] #define PWDS_MAGIC_CHAR 'P' struct PwdEntry { char *id; char *user; char *password; }; struct PwdIndexEntry { char *id; CxList *locations; }; /* * opens the password store * the content is still encrypted and must be decrypted using pwdstore_decrypt */ PwdStore* pwdstore_open(const char *file); PwdStore* pwdstore_new(void); PwdStore* pwdstore_clone(PwdStore *p); /* * decrypts the password store with the previously set password */ int pwdstore_decrypt(PwdStore *p); int pwdstore_setpassword(PwdStore *p, const char *password); void pwdstore_encsettings(PwdStore *p, uint8_t enc, uint8_t pwfunc); void pwdstore_free_entry(PwdEntry *e); void pwdstore_free(PwdStore* p); int pwdstore_has_id(PwdStore *s, const char *id); PwdEntry* pwdstore_get(PwdStore *p, const char *id); void pwdstore_put(PwdStore *p, const char *id, const char *username, const char *password); void pwdstore_put_index(PwdStore *p, char *id, CxList *locations); void pwdstore_remove_entry(PwdStore *s, const char *id); int pwdstore_store(PwdStore *p, const char *file); int pwdstore_decrypt_secrets(PwdStore *secrets); typedef char*(*pwdstore_pwinput_func)(void *userdata); void pwdstore_set_pwinput_func(pwdstore_pwinput_func func, void *userdata); char * pwdstore_default_pwinput(char *prompt); /* private */ int pwdstore_getindex(PwdStore *s); #ifdef __cplusplus } #endif #endif /* LIBIDAV_PWDSTORE_H */