}
// check db size while trying to minimize calls to size()
- while (size() > max_db_size) {
- if (deleteInvalidCertificate())
- continue; // try to find another invalid certificate if needed
-
- // there are no more invalid ones, but there must be valid certificates
- do {
- if (!deleteOldestCertificate()) {
- save(); // Some entries may have been removed. Update the index file.
- return false; // errors prevented us from freeing enough space
- }
- } while (size() > max_db_size);
- break;
+ size_t dbSize = size();
+ if ((dbSize == 0 && hasRows()) ||
+ (dbSize > 0 && !hasRows()) ||
+ (dbSize > 10 * max_db_size)) {
+ // Invalid database size, rebuild
+ dbSize = rebuildSize();
+ }
+ while (dbSize > max_db_size && deleteInvalidCertificate()) {
+ dbSize = size(); // get the current database size
+ // and try to find another invalid certificate if needed
+ }
+ // there are no more invalid ones, but there must be valid certificates
+ while (dbSize > max_db_size){
+ if (!deleteOldestCertificate()) {
+ rebuildSize(); // No certificates in database.Update the size file.
+ save(); // Some entries may have been removed. Update the index file.
+ return false; // errors prevented us from freeing enough space
+ }
+ dbSize = size(); // get the current database size
}
row.setValue(cnlType, "V");
void Ssl::CertificateDb::subSize(std::string const & filename) {
// readSize will rebuild 'size' file if missing or it is corrupted
size_t dbSize = readSize();
- dbSize -= getFileSize(filename);
+ const size_t fileSize = getFileSize(filename);
+ dbSize = dbSize > fileSize ? dbSize - fileSize : 0;
writeSize(dbSize);
}
if (!file)
return 0;
file.seekg(0, std::ios_base::end);
- size_t file_size = file.tellg();
- return ((file_size + fs_block_size - 1) / fs_block_size) * fs_block_size;
+ const std::streampos file_size = file.tellg();
+ if (file_size < 0)
+ return 0;
+ return ((static_cast<size_t>(file_size) + fs_block_size - 1) / fs_block_size) * fs_block_size;
}
void Ssl::CertificateDb::load() {
return true;
}
-bool Ssl::CertificateDb::deleteOldestCertificate() {
- if (!db)
- return false;
-
-#if SQUID_SSLTXTDB_PSTRINGDATA
- if (sk_OPENSSL_PSTRING_num(db.get()->data) == 0)
-#else
- if (sk_num(db.get()->data) == 0)
-#endif
+bool Ssl::CertificateDb::deleteOldestCertificate()
+{
+ if (!hasRows())
return false;
#if SQUID_SSLTXTDB_PSTRINGDATA
return false;
}
+bool Ssl::CertificateDb::hasRows() const
+{
+ if (!db)
+ return false;
+
+#if SQUID_SSLTXTDB_PSTRINGDATA
+ if (sk_OPENSSL_PSTRING_num(db.get()->data) == 0)
+#else
+ if (sk_num(db.get()->data) == 0)
+#endif
+ return false;
+ return true;
+}
+
bool Ssl::CertificateDb::IsEnabledDiskStore() const {
return enabled_disk_store;
}
Ssl::EVP_PKEY_Pointer pkey;
std::string &cert_subject = certProperties.dbKey();
- db.find(cert_subject, cert, pkey);
+ bool dbFailed = false;
+ try {
+ db.find(cert_subject, cert, pkey);
+ } catch (std::runtime_error &err) {
+ dbFailed = true;
+ error = err.what();
+ }
if (cert.get()) {
if (!Ssl::certificateMatchesProperties(cert.get(), certProperties)) {
if (!Ssl::generateSslCertificate(cert, pkey, certProperties))
throw std::runtime_error("Cannot create ssl certificate or private key.");
- if (!db.addCertAndPrivateKey(cert, pkey, cert_subject) && db.IsEnabledDiskStore())
- throw std::runtime_error("Cannot add certificate to db.");
+ if (!dbFailed && db.IsEnabledDiskStore()) {
+ try {
+ if (!db.addCertAndPrivateKey(cert, pkey, cert_subject)) {
+ dbFailed = true;
+ error = "Cannot add certificate to db.";
+ }
+ } catch (const std::runtime_error &err) {
+ dbFailed = true;
+ error = err.what();
+ }
+ }
}
+ if (dbFailed)
+ std::cerr << "ssl_crtd helper database '" << db_path << "' failed: " << error << std::endl;
+
std::string bufferToWrite;
if (!Ssl::writeCertAndPrivateKeyToMemory(cert, pkey, bufferToWrite))
throw std::runtime_error("Cannot write ssl certificate or/and private key to memory.");