]>
Commit | Line | Data |
---|---|---|
bbc27441 | 1 | /* |
ef57eb7b | 2 | * Copyright (C) 1996-2016 The Squid Software Foundation and contributors |
bbc27441 AJ |
3 | * |
4 | * Squid software is distributed under GPLv2+ license and includes | |
5 | * contributions from numerous individuals and organizations. | |
6 | * Please see the COPYING and CONTRIBUTORS files for details. | |
7 | */ | |
8 | ||
95d2589c CT |
9 | #ifndef SQUID_SSL_CERTIFICATE_DB_H |
10 | #define SQUID_SSL_CERTIFICATE_DB_H | |
11 | ||
12 | #include "ssl/gadgets.h" | |
074d6a40 | 13 | |
3eee6040 CT |
14 | #if HAVE_OPENSSL_OPENSSLV_H |
15 | #include <openssl/opensslv.h> | |
16 | #endif | |
074d6a40 | 17 | #include <string> |
95d2589c CT |
18 | |
19 | namespace Ssl | |
20 | { | |
5b3d088d | 21 | /// maintains an exclusive blocking file-based lock |
e29ccb57 A |
22 | class Lock |
23 | { | |
95d2589c | 24 | public: |
5b3d088d CT |
25 | explicit Lock(std::string const &filename); ///< creates an unlocked lock |
26 | ~Lock(); ///< releases the lock if it is locked | |
27 | void lock(); ///< locks the lock, may block | |
28 | void unlock(); ///< unlocks locked lock or throws | |
29 | bool locked() const; ///< whether our lock is locked | |
30 | const char *name() const { return filename.c_str(); } | |
95d2589c | 31 | private: |
5b3d088d | 32 | std::string filename; |
7aa9bb3e | 33 | #if _SQUID_WINDOWS_ |
95d2589c CT |
34 | HANDLE hFile; ///< Windows file handle. |
35 | #else | |
36 | int fd; ///< Linux file descriptor. | |
37 | #endif | |
38 | }; | |
39 | ||
5b3d088d CT |
40 | /// an exception-safe way to obtain and release a lock |
41 | class Locker | |
42 | { | |
43 | public: | |
44 | /// locks the lock if the lock was unlocked | |
45 | Locker(Lock &lock, const char *aFileName, int lineNo); | |
46 | /// unlocks the lock if it was locked by us | |
47 | ~Locker(); | |
48 | private: | |
49 | bool weLocked; ///< whether we locked the lock | |
50 | Lock &lock; ///< the lock we are operating on | |
51 | const std::string fileName; ///< where the lock was needed | |
e29ccb57 | 52 | const int lineNo; ///< where the lock was needed |
5b3d088d CT |
53 | }; |
54 | ||
55 | /// convenience macro to pass source code location to Locker and others | |
56 | #define Here __FILE__, __LINE__ | |
57 | ||
95d2589c CT |
58 | /** |
59 | * Database class for storing SSL certificates and their private keys. | |
60 | * A database consist by: | |
61 | * - A disk file to store current serial number | |
62 | * - A disk file to store the current database size | |
63 | * - A disk file which is a normal TXT_DB openSSL database | |
64 | * - A directory under which the certificates and their private keys stored. | |
65 | * The database before used must initialized with CertificateDb::create static method. | |
66 | */ | |
67 | class CertificateDb | |
68 | { | |
69 | public: | |
70 | /// Names of db columns. | |
71 | enum Columns { | |
72 | cnlType = 0, | |
73 | cnlExp_date, | |
74 | cnlRev_date, | |
75 | cnlSerial, | |
76 | cnlFile, | |
77 | cnlName, | |
78 | cnlNumber | |
79 | }; | |
80 | ||
81 | /// A wrapper for OpenSSL database row of TXT_DB database. | |
82 | class Row | |
83 | { | |
84 | public: | |
85 | /// Create row wrapper. | |
86 | Row(); | |
f385ac29 CT |
87 | ///Create row wrapper for row with width items |
88 | Row(char **row, size_t width); | |
95d2589c CT |
89 | /// Delete all row. |
90 | ~Row(); | |
91 | void setValue(size_t number, char const * value); ///< Set cell's value in row | |
92 | char ** getRow(); ///< Raw row | |
93 | void reset(); ///< Abandon row and don't free memory | |
94 | private: | |
95 | char **row; ///< Raw row | |
96 | size_t width; ///< Number of cells in the row | |
97 | }; | |
98 | ||
99 | CertificateDb(std::string const & db_path, size_t aMax_db_size, size_t aFs_block_size); | |
100 | /// Find certificate and private key for host name | |
f97700a0 | 101 | bool find(std::string const & host_name, Security::CertPointer & cert, Ssl::EVP_PKEY_Pointer & pkey); |
4ece76b2 CT |
102 | /// Delete a certificate from database |
103 | bool purgeCert(std::string const & key); | |
95d2589c | 104 | /// Save certificate to disk. |
f97700a0 | 105 | bool addCertAndPrivateKey(Security::CertPointer & cert, Ssl::EVP_PKEY_Pointer & pkey, std::string const & useName); |
95d2589c | 106 | /// Create and initialize a database under the db_path |
a0b971d5 | 107 | static void create(std::string const & db_path); |
95d2589c | 108 | /// Check the database stored under the db_path. |
a066059b | 109 | static void check(std::string const & db_path, size_t max_db_size, size_t fs_block_size); |
95d2589c CT |
110 | bool IsEnabledDiskStore() const; ///< Check enabled of dist store. |
111 | private: | |
112 | void load(); ///< Load db from disk. | |
113 | void save(); ///< Save db to disk. | |
a066059b | 114 | size_t size(); ///< Get db size on disk in bytes. |
95d2589c CT |
115 | /// Increase db size by the given file size and update size_file |
116 | void addSize(std::string const & filename); | |
117 | /// Decrease db size by the given file size and update size_file | |
118 | void subSize(std::string const & filename); | |
a066059b | 119 | size_t readSize(); ///< Read size from file size_file |
95d2589c CT |
120 | void writeSize(size_t db_size); ///< Write size to file size_file. |
121 | size_t getFileSize(std::string const & filename); ///< get file size on disk. | |
a066059b | 122 | size_t rebuildSize(); ///< Rebuild size_file |
95d2589c | 123 | /// Only find certificate in current db and return it. |
f97700a0 | 124 | bool pure_find(std::string const & host_name, Security::CertPointer & cert, Ssl::EVP_PKEY_Pointer & pkey); |
95d2589c | 125 | |
1bf6c6e7 | 126 | void deleteRow(const char **row, int rowIndex); ///< Delete a row from TXT_DB |
95d2589c CT |
127 | bool deleteInvalidCertificate(); ///< Delete invalid certificate. |
128 | bool deleteOldestCertificate(); ///< Delete oldest certificate. | |
129 | bool deleteByHostname(std::string const & host); ///< Delete using host name. | |
541e6ab5 | 130 | bool hasRows() const; ///< Whether the TXT_DB has stored items. |
95d2589c | 131 | |
f385ac29 CT |
132 | /// Removes the first matching row from TXT_DB. Ignores failures. |
133 | static void sq_TXT_DB_delete(TXT_DB *db, const char **row); | |
134 | /// Remove the row on position idx from TXT_DB. Ignores failures. | |
135 | static void sq_TXT_DB_delete_row(TXT_DB *db, int idx); | |
136 | ||
95d2589c CT |
137 | /// Callback hash function for serials. Used to create TXT_DB index of serials. |
138 | static unsigned long index_serial_hash(const char **a); | |
139 | /// Callback compare function for serials. Used to create TXT_DB index of serials. | |
140 | static int index_serial_cmp(const char **a, const char **b); | |
141 | /// Callback hash function for names. Used to create TXT_DB index of names.. | |
142 | static unsigned long index_name_hash(const char **a); | |
143 | /// Callback compare function for names. Used to create TXT_DB index of names.. | |
144 | static int index_name_cmp(const char **a, const char **b); | |
145 | ||
146 | /// Definitions required by openSSL, to use the index_* functions defined above | |
147 | ///with TXT_DB_create_index. | |
fee5325b CT |
148 | #if SQUID_USE_SSLLHASH_HACK |
149 | static unsigned long index_serial_hash_LHASH_HASH(const void *a) { | |
3eee6040 CT |
150 | return index_serial_hash((const char **)a); |
151 | } | |
fee5325b | 152 | static int index_serial_cmp_LHASH_COMP(const void *arg1, const void *arg2) { |
3eee6040 CT |
153 | return index_serial_cmp((const char **)arg1, (const char **)arg2); |
154 | } | |
fee5325b | 155 | static unsigned long index_name_hash_LHASH_HASH(const void *a) { |
3eee6040 CT |
156 | return index_name_hash((const char **)a); |
157 | } | |
fee5325b | 158 | static int index_name_cmp_LHASH_COMP(const void *arg1, const void *arg2) { |
3eee6040 CT |
159 | return index_name_cmp((const char **)arg1, (const char **)arg2); |
160 | } | |
161 | #else | |
95d2589c CT |
162 | static IMPLEMENT_LHASH_HASH_FN(index_serial_hash,const char **) |
163 | static IMPLEMENT_LHASH_COMP_FN(index_serial_cmp,const char **) | |
164 | static IMPLEMENT_LHASH_HASH_FN(index_name_hash,const char **) | |
165 | static IMPLEMENT_LHASH_COMP_FN(index_name_cmp,const char **) | |
3eee6040 | 166 | #endif |
95d2589c | 167 | |
95d2589c CT |
168 | static const std::string db_file; ///< Base name of the database index file. |
169 | static const std::string cert_dir; ///< Base name of the directory to store the certs. | |
170 | static const std::string size_file; ///< Base name of the file to store db size. | |
171 | /// Min size of disk db. If real size < min_db_size the db will be disabled. | |
172 | static const size_t min_db_size; | |
173 | ||
174 | const std::string db_path; ///< The database directory. | |
95d2589c CT |
175 | const std::string db_full; ///< Full path of the database index file. |
176 | const std::string cert_full; ///< Full path of the directory to store the certs. | |
177 | const std::string size_full; ///< Full path of the file to store the db size. | |
178 | ||
179 | TXT_DB_Pointer db; ///< Database with certificates info. | |
180 | const size_t max_db_size; ///< Max size of db. | |
181 | const size_t fs_block_size; ///< File system block size. | |
5b3d088d | 182 | mutable Lock dbLock; ///< protects the database file |
95d2589c CT |
183 | |
184 | bool enabled_disk_store; ///< The storage on the disk is enabled. | |
185 | }; | |
186 | ||
187 | } // namespace Ssl | |
188 | #endif // SQUID_SSL_CERTIFICATE_DB_H | |
f53969cc | 189 |