UNIXworkcode

1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright 2018 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 PWD_H 30 #define PWD_H 31 32 #include <stdlib.h> 33 #include <inttypes.h> 34 35 #include <cx/map.h> 36 #include <cx/buffer.h> 37 #include <cx/linked_list.h> 38 #include <libidav/crypto.h> 39 40 #ifdef __cplusplus 41 extern "C" { 42 #endif 43 44 #define PWDSTORE_MAX_LEN 4096 45 46 /* 47 * File Format: 48 * 49 * file = header, index, enc_content 50 * header = magic, version, enc, pwfunc, salt, indexlen 51 * magic = 1 byte 52 * version = 1 byte 53 * enc = 1 byte 54 * pwfunc = 1 byte 55 * salt = 16 bytes 56 * indexlen = uint32 57 * index = { itype length id locations zero } 58 * enc_content = iv bytes 59 * iv = 16 bytes 60 * content = { entry } 61 * entry = itype length id length username length password 62 * length = uint32 63 * zero = 4 zero bytes 64 * itype = 1 byte 65 * id = string 66 * locations = { length string } 67 * username = string 68 * password = string 69 * 70 * The content is AES encrypted with a key derived from a password 71 * and the salt. The first 16 bytes are the aes iv. 72 * 73 * All integers are big endian 74 */ 75 76 #define PWDS_HEADER_SIZE 24 77 78 typedef struct PwdStore PwdStore; 79 typedef struct PwdEntry PwdEntry; 80 typedef struct PwdIndexEntry PwdIndexEntry; 81 82 struct PwdStore { 83 /* 84 * map of all credentials 85 * key is the username 86 * value is PwdEntry* 87 */ 88 CxMap *ids; 89 90 /* 91 * list of all credentials with location 92 * value is PwdIndexEntry* 93 */ 94 CxList *locations; 95 96 /* 97 * list of all credentials without location 98 * value is PwdIndexEntry* 99 */ 100 CxList *noloc; 101 102 /* 103 * index map that contains all elements from the lists 104 * 'locations' and 'noloc' 105 */ 106 CxMap *index; 107 108 /* 109 * a buffer containing the complete file content 110 */ 111 CxBuffer *content; 112 113 /* 114 * key used for encryption/decryption 115 */ 116 DavKey *key; 117 118 /* 119 * optional shell command, that is used for getting the master password 120 */ 121 char *unlock_cmd; 122 123 /* 124 * optional shell command, that is exected when the secretstore is closed 125 */ 126 char *lock_cmd; 127 128 /* 129 * start offset of the encrypted buffer 130 */ 131 uint32_t encoffset; 132 133 /* 134 * indicates if the PwdStore is decrypted with pwdstore_decrypt 135 */ 136 uint8_t isdecrypted; 137 }; 138 139 #define PWDS_MAGIC(p) (p)->content->space[0] 140 #define PWDS_VERSION(p) (p)->content->space[1] 141 #define PWDS_ENC(p) (p)->content->space[2] 142 #define PWDS_PWFUNC(p) (p)->content->space[3] 143 144 #define PWDS_MAGIC_CHAR 'P' 145 146 struct PwdEntry { 147 char *id; 148 char *user; 149 char *password; 150 }; 151 152 struct PwdIndexEntry { 153 char *id; 154 CxList *locations; 155 }; 156 157 /* 158 * opens the password store 159 * the content is still encrypted and must be decrypted using pwdstore_decrypt 160 */ 161 PwdStore* pwdstore_open(const char *file); 162 163 PwdStore* pwdstore_new(void); 164 165 /* 166 * decrypts the password store with a password 167 */ 168 int pwdstore_decrypt(PwdStore *p); 169 170 int pwdstore_setpassword(PwdStore *p, const char *password); 171 172 void pwdstore_encsettings(PwdStore *p, uint8_t enc, uint8_t pwfunc); 173 174 void pwdstore_free_entry(PwdEntry *e); 175 void pwdstore_free(PwdStore* p); 176 177 int pwdstore_has_id(PwdStore *s, const char *id); 178 int pwdstore_has_location(PwdStore *s, const char *location); 179 180 PwdEntry* pwdstore_get(PwdStore *p, const char *id); 181 182 void pwdstore_put(PwdStore *p, const char *id, const char *username, const char *password); 183 void pwdstore_put_index(PwdStore *p, char *id, CxList *locations); 184 185 void pwdstore_remove_entry(PwdStore *s, const char *id); 186 187 int pwdstore_store(PwdStore *p, const char *file); 188 189 /* private */ 190 int pwdstore_getindex(PwdStore *s); 191 192 #ifdef __cplusplus 193 } 194 #endif 195 196 #endif /* PWD_H */ 197 198