]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Bug fix: "(ssl_crtd): Cannot add certificate to db" when updating expired cert
authorChristos Tsantilas <chtsanti@users.sourceforge.net>
Thu, 22 Sep 2011 16:37:55 +0000 (19:37 +0300)
committerChristos Tsantilas <chtsanti@users.sourceforge.net>
Thu, 22 Sep 2011 16:37:55 +0000 (19:37 +0300)
When ssl_crtd helper needs to add a fresh certificate to the database but
finds an expired certificate already stored, ssl_crtd deletes the expired
certificate file from disk before adding the fresh one. However, the addition
still fails because the expired certificate was not removed from database
indexes.

This fix:
  - Adds code to update database indexes upon deletion of a row.
  - Polishes certificates deletion code to avoid duplication.

TODO: Report failure details to Squid and make certificate-specific failures
not fatal for the ssl_crtd helper.

This is a Measurement Factory project.

src/ssl/certificate_db.cc
src/ssl/certificate_db.h

index 487d29ddf2f0c10b09578553ae4e586d6e7b8649..9f15ca3a4b07444d7186305551ce3b458572d210 100644 (file)
@@ -427,6 +427,35 @@ void Ssl::CertificateDb::save()
         throw std::runtime_error("Failed to write " + db_full + " file");
 }
 
+// Normally defined in defines.h file
+#define countof(arr) (sizeof(arr)/sizeof(*arr))
+void Ssl::CertificateDb::deleteRow(const char **row, int rowIndex)
+{
+    const std::string filename(cert_full + "/" + row[cnlSerial] + ".pem");
+    const FileLocker cert_locker(filename);
+#if OPENSSL_VERSION_NUMBER >= 0x1000004fL
+    sk_OPENSSL_PSTRING_delete(db.get()->data, rowIndex);
+#else
+    sk_delete(db.get()->data, rowIndex);
+#endif
+    
+    const Columns db_indexes[]={cnlSerial, cnlName};
+    for (unsigned int i = 0; i < countof(db_indexes); i++) {
+#if OPENSSL_VERSION_NUMBER >= 0x1000004fL
+        if (LHASH_OF(OPENSSL_STRING) *fieldIndex =  db.get()->index[db_indexes[i]])
+            lh_OPENSSL_STRING_delete(fieldIndex, (char **)row);
+#else
+        if (LHASH *fieldIndex = db.get()->index[db_indexes[i]])
+            lh_delete(fieldIndex, row);
+#endif
+    }
+    
+    subSize(filename);
+    int ret = remove(filename.c_str());
+    if (ret < 0)
+        throw std::runtime_error("Failed to remove certficate file " + filename + " from db");
+}
+
 bool Ssl::CertificateDb::deleteInvalidCertificate()
 {
     if (!db)
@@ -442,15 +471,7 @@ bool Ssl::CertificateDb::deleteInvalidCertificate()
 #endif
 
         if (!sslDateIsInTheFuture(current_row[cnlExp_date])) {
-            std::string filename(cert_full + "/" + current_row[cnlSerial] + ".pem");
-            FileLocker cert_locker(filename);
-#if OPENSSL_VERSION_NUMBER >= 0x1000004fL
-            sk_OPENSSL_PSTRING_delete(db.get()->data, i);
-#else
-            sk_delete(db.get()->data, i);
-#endif
-            subSize(filename);
-            remove(filename.c_str());
+            deleteRow(current_row, i);
             removed_one = true;
             break;
         }
@@ -478,17 +499,8 @@ bool Ssl::CertificateDb::deleteOldestCertificate()
 #else
     const char **row = (const char **)sk_value(db.get()->data, 0);
 #endif
-    std::string filename(cert_full + "/" + row[cnlSerial] + ".pem");
-    FileLocker cert_locker(filename);
 
-#if OPENSSL_VERSION_NUMBER >= 0x1000004fL
-    sk_OPENSSL_PSTRING_delete(db.get()->data, 0);
-#else
-    sk_delete(db.get()->data, 0);
-#endif
-
-    subSize(filename);
-    remove(filename.c_str());
+    deleteRow(row, 0);
 
     return true;
 }
@@ -506,15 +518,7 @@ bool Ssl::CertificateDb::deleteByHostname(std::string const & host)
         const char ** current_row = ((const char **)sk_value(db.get()->data, i));
 #endif
         if (host == current_row[cnlName]) {
-            std::string filename(cert_full + "/" + current_row[cnlSerial] + ".pem");
-            FileLocker cert_locker(filename);
-#if OPENSSL_VERSION_NUMBER >= 0x1000004fL
-            sk_OPENSSL_PSTRING_delete(db.get()->data, i);
-#else
-            sk_delete(db.get()->data, i);
-#endif
-            subSize(filename);
-            remove(filename.c_str());
+            deleteRow(current_row, i);
             return true;
         }
     }
index 4c301bb3dd87c4786b6e2dcff5bc5f94911bd949..0ed15d6fd7f8aa4bbbef4a03da1022098b457cf3 100644 (file)
@@ -98,6 +98,7 @@ private:
     /// Only find certificate in current db and return it.
     bool pure_find(std::string const & host_name, Ssl::X509_Pointer & cert, Ssl::EVP_PKEY_Pointer & pkey);
 
+    void deleteRow(const char **row, int rowIndex); ///< Delete a row from TXT_DB
     bool deleteInvalidCertificate(); ///< Delete invalid certificate.
     bool deleteOldestCertificate(); ///< Delete oldest certificate.
     bool deleteByHostname(std::string const & host); ///< Delete using host name.