UNIXworkcode

1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright 2024 Olaf Wintermann. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #ifndef LIBIDAV_PWDSTORE_H 30 #define LIBIDAV_PWDSTORE_H 31 32 #ifdef __cplusplus 33 extern "C" { 34 #endif 35 36 #include <stdlib.h> 37 #include <inttypes.h> 38 39 #include <cx/map.h> 40 #include <cx/buffer.h> 41 #include <cx/linked_list.h> 42 #include "crypto.h" 43 44 #ifdef __cplusplus 45 extern "C" { 46 #endif 47 48 #define PWDSTORE_MAX_LEN 4096 49 50 /* 51 * File Format: 52 * 53 * file = header, index, enc_content 54 * header = magic, version, enc, pwfunc, salt, indexlen 55 * magic = 1 byte 56 * version = 1 byte 57 * enc = 1 byte 58 * pwfunc = 1 byte 59 * salt = 16 bytes 60 * indexlen = uint32 61 * index = { itype length id locations zero } 62 * enc_content = iv bytes 63 * iv = 16 bytes 64 * content = { entry } 65 * entry = itype length id length username length password 66 * length = uint32 67 * zero = 4 zero bytes 68 * itype = 1 byte 69 * id = string 70 * locations = { length string } 71 * username = string 72 * password = string 73 * 74 * The content is AES encrypted with a key derived from a password 75 * and the salt. The first 16 bytes are the aes iv. 76 * 77 * All integers are big endian 78 */ 79 80 #define PWDS_HEADER_SIZE 24 81 82 typedef struct PwdStore PwdStore; 83 typedef struct PwdEntry PwdEntry; 84 typedef struct PwdIndexEntry PwdIndexEntry; 85 86 struct PwdStore { 87 /* 88 * map of all credentials 89 * key is the username 90 * value is PwdEntry* 91 */ 92 CxMap *ids; 93 94 /* 95 * list of all credentials with location 96 * value is PwdIndexEntry* 97 */ 98 CxList *locations; 99 100 /* 101 * list of all credentials without location 102 * value is PwdIndexEntry* 103 */ 104 CxList *noloc; 105 106 /* 107 * index map that contains all elements from the lists 108 * 'locations' and 'noloc' 109 */ 110 CxMap *index; 111 112 /* 113 * a buffer containing the complete file content 114 */ 115 CxBuffer *content; 116 117 /* 118 * key used for encryption/decryption 119 */ 120 DavKey *key; 121 122 /* 123 * optional shell command, that is used for getting the master password 124 */ 125 char *unlock_cmd; 126 127 /* 128 * optional shell command, that is exected when the secretstore is closed 129 */ 130 char *lock_cmd; 131 132 /* 133 * start offset of the encrypted buffer 134 */ 135 uint32_t encoffset; 136 137 /* 138 * indicates if the PwdStore is decrypted with pwdstore_decrypt 139 */ 140 uint8_t isdecrypted; 141 }; 142 143 #define PWDS_MAGIC(p) (p)->content->space[0] 144 #define PWDS_VERSION(p) (p)->content->space[1] 145 #define PWDS_ENC(p) (p)->content->space[2] 146 #define PWDS_PWFUNC(p) (p)->content->space[3] 147 148 #define PWDS_MAGIC_CHAR 'P' 149 150 struct PwdEntry { 151 char *id; 152 char *user; 153 char *password; 154 }; 155 156 struct PwdIndexEntry { 157 char *id; 158 CxList *locations; 159 }; 160 161 /* 162 * opens the password store 163 * the content is still encrypted and must be decrypted using pwdstore_decrypt 164 */ 165 PwdStore* pwdstore_open(const char *file); 166 167 PwdStore* pwdstore_new(void); 168 169 PwdStore* pwdstore_clone(PwdStore *p); 170 171 /* 172 * decrypts the password store with the previously set password 173 */ 174 int pwdstore_decrypt(PwdStore *p); 175 176 int pwdstore_setpassword(PwdStore *p, const char *password); 177 178 void pwdstore_encsettings(PwdStore *p, uint8_t enc, uint8_t pwfunc); 179 180 void pwdstore_free_entry(PwdEntry *e); 181 void pwdstore_free(PwdStore* p); 182 183 int pwdstore_has_id(PwdStore *s, const char *id); 184 185 PwdEntry* pwdstore_get(PwdStore *p, const char *id); 186 187 void pwdstore_put(PwdStore *p, const char *id, const char *username, const char *password); 188 void pwdstore_put_index(PwdStore *p, char *id, CxList *locations); 189 190 void pwdstore_remove_entry(PwdStore *s, const char *id); 191 192 int pwdstore_store(PwdStore *p, const char *file); 193 194 195 int pwdstore_decrypt_secrets(PwdStore *secrets); 196 197 198 199 200 201 202 typedef char*(*pwdstore_pwinput_func)(void *userdata); 203 204 void pwdstore_set_pwinput_func(pwdstore_pwinput_func func, void *userdata); 205 206 char * pwdstore_default_pwinput(char *prompt); 207 208 209 210 /* private */ 211 int pwdstore_getindex(PwdStore *s); 212 213 #ifdef __cplusplus 214 } 215 #endif 216 217 #endif /* LIBIDAV_PWDSTORE_H */ 218 219