Skip to content

Commit ec67681

Browse files
committed
Clean up certifier plugin debug messages.
The certifier plugin manually write out the function name in debug messages, and these were wrong in some cases. Clean this up to use __func__ and a more consistent message format. Remove the "t" mode from fopen call, which is a Windows-ism. Signed-off-by: James Peach <jpeach@apache.org>
1 parent 3194b60 commit ec67681

File tree

2 files changed

+104
-90
lines changed

2 files changed

+104
-90
lines changed

plugins/certifier/certifier.cc

Lines changed: 101 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ class SslLRUList
211211

212212
// Remove oldest node if size exceeds limit
213213
if (++size > limit) {
214-
TSDebug(PLUGIN_NAME, "Removing %s", tail->commonName.c_str());
214+
TSDebug(PLUGIN_NAME, "%s: removing '%s'", __func__, tail->commonName.c_str());
215215
auto iter = cnDataMap.find(tail->commonName);
216216
if (iter != cnDataMap.end()) {
217217
local = std::move(iter->second); // copy ownership
@@ -224,7 +224,7 @@ class SslLRUList
224224
}
225225
}
226226
}
227-
TSDebug(PLUGIN_NAME, "%s Prepend to LRU list...List Size:%d Map Size: %d", data->commonName.c_str(), size,
227+
TSDebug(PLUGIN_NAME, "%s: prepending '%s' to LRU ... list size: %d, map size: %d", __func__, data->commonName.c_str(), size,
228228
static_cast<int>(cnDataMap.size()));
229229

230230
TSMutexUnlock(list_mutex);
@@ -344,44 +344,46 @@ addSANExtToCert(X509 *cert, std::string_view dnsName)
344344
static scoped_X509
345345
mkcrt(const std::string &commonName, int serial)
346346
{
347-
TSDebug(PLUGIN_NAME, "Entering mkcrt()...");
348347
scoped_EVP_PKEY pktmp;
349348
scoped_X509 cert;
350349

351350
cert.reset(X509_new());
352351

353-
/// Set X509V3
352+
// Set X509V3
354353
if (X509_set_version(cert.get(), 2) == 0) {
355-
TSError("[%s] mkcrt(): Failed to set X509V3.", PLUGIN_NAME);
354+
TSError("[%s] %s: failed to set X509V3", PLUGIN_NAME, __func__);
356355
return nullptr;
357356
}
358357

359-
/// Set serial number
358+
// Set serial number
360359
// TSDebug("txn_monitor", "serial: %d", serial);
361360
ASN1_INTEGER_set(X509_get_serialNumber(cert.get()), serial);
362361

363-
/// Set issuer from CA cert
362+
// Set issuer from CA cert
364363
if (X509_set_issuer_name(cert.get(), X509_get_subject_name(ca_cert_scoped.get())) == 0) {
365-
TSError("[%s] mkcrt(): Failed to set issuer.", PLUGIN_NAME);
364+
TSError("[%s] %s: failed to set certificate issuer", PLUGIN_NAME, __func__);
366365
return nullptr;
367366
}
368-
/// Set certificate time
367+
368+
// Set certificate time
369369
X509_gmtime_adj(X509_get_notBefore(cert.get()), 0);
370370
X509_gmtime_adj(X509_get_notAfter(cert.get()), static_cast<long>(3650) * 24 * 3600);
371371

372-
/// Get handle to subject name
372+
// Get handle to subject name
373373
X509_NAME *n = X509_get_subject_name(cert.get());
374-
/// Set common name field
374+
// Set common name field
375375
if (X509_NAME_add_entry_by_txt(n, "CN", MBSTRING_ASC, (unsigned char *)commonName.c_str(), -1, -1, 0) != 1) {
376-
TSError("[%s] mkcsr(): Failed to add entry.", PLUGIN_NAME);
376+
TSError("[%s] %s: failed to add certificate subject CN", PLUGIN_NAME, __func__);
377377
return nullptr;
378378
}
379-
/// Set Traffic Server public key
379+
380+
// Set Traffic Server public key
380381
if (X509_set_pubkey(cert.get(), ca_pkey_scoped.get()) == 0) {
381-
TSDebug(PLUGIN_NAME, "mkcrt(): Failed to set X509 public key.");
382+
TSError("[%s] %s: failed to set certificate public key", PLUGIN_NAME, __func__);
382383
return nullptr;
383384
}
384-
/// Add the Subject Alternative Name (SAN) extension
385+
386+
// Add the Subject Alternative Name (SAN) extension
385387
addSANExtToCert(cert.get(), commonName);
386388

387389
// Sign the certificate
@@ -419,25 +421,24 @@ shadow_cert_generator(TSCont contp, TSEvent event, void *edata)
419421
/// Try open the file if directory exists
420422
fp = fopen(cert_filename.c_str(), "rt");
421423
}
422-
TSDebug(PLUGIN_NAME, "shadow_cert_generator(): Cert file is expected at %s", cert_filename.c_str());
424+
TSDebug(PLUGIN_NAME, "%s: cert file is expected at %s", __func__, cert_filename.c_str());
423425
/// If cert file exists and is readable
424426
if (fp != nullptr) {
425427
cert.reset(PEM_read_X509(fp, nullptr, nullptr, nullptr));
426428
fclose(fp);
427429

428430
if (cert == nullptr) {
429431
/// Problem with cert file / openssl read
430-
TSError("[%s] [shadow_cert_generator] Problem with loading certs", PLUGIN_NAME);
431-
std::remove(cert_filename.c_str());
432+
TSError("[%s] %s: failed o load certificate from '%s'", PLUGIN_NAME, __func__, cert_filename.c_str());
432433
} else {
433-
TSDebug(PLUGIN_NAME, "shadow_cert_generator(): Loaded cert from file");
434+
TSDebug(PLUGIN_NAME, "%s: loaded certificate from '%s'", __func__, cert_filename.c_str());
434435
}
435436
}
436437

437438
/// No valid certs available from disk, create one and write to file
438439
if (cert == nullptr) {
439440
if (!sign_enabled) {
440-
TSDebug(PLUGIN_NAME, "shadow_cert_generator(): No certs found and dynamic generation disabled. Marked as wontdo.");
441+
TSDebug(PLUGIN_NAME, "%s: no certs found and dynamic generation disabled; marked as wontdo", __func__);
441442
// There won't be certs available. Mark this servername as wontdo
442443
// Pass on as if plugin doesn't exist
443444
ssl_list->setup_data_ctx(commonName, localQ, nullptr, nullptr, true);
@@ -450,7 +451,7 @@ shadow_cert_generator(TSCont contp, TSEvent event, void *edata)
450451
TSContDestroy(contp);
451452
return TS_SUCCESS;
452453
}
453-
TSDebug(PLUGIN_NAME, "shadow_cert_generator(): Creating shadow certs");
454+
TSDebug(PLUGIN_NAME, "%s: creating shadow certs", __func__);
454455

455456
/// Get serial number
456457
TSMutexLock(serial_mutex);
@@ -467,18 +468,18 @@ shadow_cert_generator(TSCont contp, TSEvent event, void *edata)
467468
/// Create cert
468469
cert = mkcrt(commonName, serial);
469470
if (cert == nullptr) {
470-
TSDebug(PLUGIN_NAME, "[shadow_cert_generator] Cert generation failed");
471+
TSDebug(PLUGIN_NAME, "%s: cert generation failed", __func__);
471472
TSContDestroy(contp);
472473
ssl_list->set_schedule(commonName, false);
473474
return TS_ERROR;
474475
}
475476

476477
/// Write certs to file
477478
if ((fp = fopen(cert_filename.c_str(), "w+")) == nullptr) {
478-
TSDebug(PLUGIN_NAME, "shadow_cert_generator(): Error opening file: %s\n", strerror(errno));
479+
TSDebug(PLUGIN_NAME, "%s: error opening file: %s", __func__, strerror(errno));
479480
} else {
480481
if (!PEM_write_X509(fp, cert.get())) {
481-
TSDebug(PLUGIN_NAME, "shadow_cert_generator(): Error writing cert to disk");
482+
TSDebug(PLUGIN_NAME, "%s: error writing cert to disk", __func__);
482483
}
483484
fclose(fp);
484485
}
@@ -489,23 +490,23 @@ shadow_cert_generator(TSCont contp, TSEvent event, void *edata)
489490
ctx.reset(ref_ctx);
490491

491492
if (SSL_CTX_use_certificate(ref_ctx, cert.get()) < 1) {
492-
TSError("[%s] shadow_cert_handler(): Failed to use certificate in SSL_CTX.", PLUGIN_NAME);
493+
TSError("[%s] %s: failed to use certificate in SSL_CTX", PLUGIN_NAME, __func__);
493494
TSContDestroy(contp);
494495
ssl_list->set_schedule(commonName, false);
495496
return TS_ERROR;
496497
}
497498
if (SSL_CTX_use_PrivateKey(ref_ctx, ca_pkey_scoped.get()) < 1) {
498-
TSError("[%s] shadow_cert_handler(): Failed to use private key in SSL_CTX.", PLUGIN_NAME);
499+
TSError("[%s] %s: failed to use private key in SSL_CTX", PLUGIN_NAME, __func__);
499500
TSContDestroy(contp);
500501
ssl_list->set_schedule(commonName, false);
501502
return TS_ERROR;
502503
}
503-
TSDebug(PLUGIN_NAME, "shadow_cert_generator(): cert and context ready, clearing the queue");
504+
TSDebug(PLUGIN_NAME, "%s: cert and context ready, clearing the queue", __func__);
504505
ssl_list->setup_data_ctx(commonName, localQ, std::move(ctx), std::move(cert), false);
505506

506507
/// Clear the queue by setting context for each and reenable them
507508
while (!localQ.empty()) {
508-
TSDebug(PLUGIN_NAME, "\tClearing the queue size %lu", localQ.size());
509+
TSDebug(PLUGIN_NAME, "%s: clearing the queue size %lu", __func__, localQ.size());
509510
TSVConn ssl_vc = reinterpret_cast<TSVConn>(localQ.front());
510511
localQ.pop();
511512
TSSslConnection sslobj = TSVConnSslConnectionGet(ssl_vc);
@@ -529,28 +530,33 @@ cert_retriever(TSCont contp, TSEvent event, void *edata)
529530
SSL_CTX *ref_ctx = nullptr;
530531

531532
if (servername == nullptr) {
532-
TSError("[%s] cert_retriever(): No SNI available.", PLUGIN_NAME);
533+
TSError("[%s] %s: no SNI available", __func__, PLUGIN_NAME);
533534
return TS_ERROR;
534535
}
536+
535537
bool wontdo = false;
536538
ref_ctx = ssl_list->lookup_and_create(servername, edata, wontdo);
539+
537540
if (wontdo) {
538-
TSDebug(PLUGIN_NAME, "cert_retriever(): Won't generate cert for %s", servername);
541+
TSDebug(PLUGIN_NAME, "%s: won't generate cert for %s", __func__, servername);
539542
TSVConnReenable(ssl_vc);
540-
} else if (nullptr == ref_ctx) {
541-
// If no existing context, schedule TASK thread to generate
542-
TSDebug(PLUGIN_NAME, "cert_retriever(): schedule thread to generate/retrieve cert for %s", servername);
543-
TSCont schedule_cont = TSContCreate(shadow_cert_generator, TSMutexCreate());
544-
TSContDataSet(schedule_cont, (void *)servername);
545-
TSContScheduleOnPool(schedule_cont, 0, TS_THREAD_POOL_TASK);
546-
} else {
547-
// Use existing context
548-
TSDebug(PLUGIN_NAME, "cert_retriever(): Reuse existing cert and context for %s", servername);
543+
return TS_SUCCESS;
544+
}
545+
546+
if (ref_ctx) {
547+
// Use existing context.
548+
TSDebug(PLUGIN_NAME, "%s: reusing existing cert and context for %s", __func__, servername);
549549
SSL_set_SSL_CTX(ssl, ref_ctx);
550550
TSVConnReenable(ssl_vc);
551+
return TS_SUCCESS;
551552
}
552553

553-
/// For scheduled connections, the scheduled continuation will handle the reenabling
554+
// If no existing context, schedule TASK thread to generate.
555+
TSDebug(PLUGIN_NAME, "%s: scheduling thread to generate/retrieve cert for %s", __func__, servername);
556+
TSCont schedule_cont = TSContCreate(shadow_cert_generator, TSMutexCreate());
557+
TSContDataSet(schedule_cont, servername);
558+
TSContScheduleOnPool(schedule_cont, 0, TS_THREAD_POOL_TASK);
559+
554560
return TS_SUCCESS;
555561
}
556562

@@ -607,66 +613,73 @@ TSPluginInit(int argc, const char *argv[])
607613
case '?':
608614
break;
609615
default:
610-
TSDebug(PLUGIN_NAME, "Unexpected options.");
611-
TSError("[%s] Unexpected options error.", PLUGIN_NAME);
616+
TSDebug(PLUGIN_NAME, "unexpected options");
617+
TSError("[%s] unexpected options error", PLUGIN_NAME);
612618
return;
613619
}
614620
}
615621

616622
// Register plugin and create callback
617623
if (TSPluginRegister(&info) != TS_SUCCESS) {
618-
TSError("[%s] Unable to initialize plugin (disabled). Failed to register plugin.", PLUGIN_NAME);
619-
} else if ((cb_shadow = TSContCreate(cert_retriever, nullptr)) == nullptr) {
620-
TSError("[%s] Unable to initialize plugin (disabled). Failed to create shadow cert cb.", PLUGIN_NAME);
621-
} else {
622-
if ((sign_enabled = cert && key && serial)) {
623-
// Dynamic cert generation enabled. Initialize CA key, cert and serial
624-
// To comply to openssl, key and cert file are opened as FILE*
625-
FILE *fp = nullptr;
626-
if ((fp = fopen(cert, "rt")) == nullptr) {
627-
TSDebug(PLUGIN_NAME, "fopen() error is %d: %s for %s", errno, strerror(errno), cert);
628-
TSError("[%s] Unable to initialize plugin. Failed to open ca cert.", PLUGIN_NAME);
629-
return;
630-
}
631-
ca_cert_scoped.reset(PEM_read_X509(fp, nullptr, nullptr, nullptr));
632-
fclose(fp);
624+
TSError("[%s] unable to initialize plugin (disabled): failed to register plugin", PLUGIN_NAME);
625+
return;
626+
}
633627

634-
if ((fp = fopen(key, "rt")) == nullptr) {
635-
TSDebug(PLUGIN_NAME, "fopen() error is %d: %s for %s", errno, strerror(errno), key);
636-
TSError("[%s] Unable to initialize plugin. Failed to open ca key.", PLUGIN_NAME);
637-
return;
638-
}
639-
ca_pkey_scoped.reset(PEM_read_PrivateKey(fp, nullptr, nullptr, nullptr));
640-
fclose(fp);
628+
if ((cb_shadow = TSContCreate(cert_retriever, nullptr)) == nullptr) {
629+
TSError("[%s] unable to initialize plugin (disabled): failed to create shadow cert cb", PLUGIN_NAME);
630+
return;
631+
}
641632

642-
if (ca_pkey_scoped == nullptr || ca_cert_scoped == nullptr) {
643-
TSDebug(PLUGIN_NAME, "PEM_read failed to read %s %s", ca_pkey_scoped ? "" : "pkey", ca_cert_scoped ? "" : "cert");
644-
TSError("[%s] Unable to initialize plugin. Failed to read ca key/cert.", PLUGIN_NAME);
645-
return;
646-
}
633+
if (cert && key && serial) {
634+
sign_enabled = true;
647635

648-
// Read serial file
649-
serial_file.open(serial, std::fstream::in | std::fstream::out);
650-
if (!serial_file.is_open()) {
651-
TSDebug(PLUGIN_NAME, "Failed to open serial file.");
652-
TSError("[%s] Unable to initialize plugin. Failed to open serial.", PLUGIN_NAME);
653-
return;
654-
}
655-
/// Initialize mutex and serial number
656-
serial_mutex = TSMutexCreate();
657-
ca_serial = 0;
658-
659-
serial_file.seekg(0, serial_file.beg);
660-
serial_file >> ca_serial;
661-
if (serial_file.bad() || serial_file.fail()) {
662-
ca_serial = 0;
663-
}
636+
// Dynamic cert generation enabled. Initialize CA key, cert and serial
637+
// To comply to openssl, key and cert file are opened as FILE*
638+
FILE *fp = nullptr;
639+
if ((fp = fopen(cert, "r")) == nullptr) {
640+
TSDebug(PLUGIN_NAME, "fopen() error is %d: %s for %s", errno, strerror(errno), cert);
641+
TSError("[%s] unable to initialize plugin: failed to open CA certificate '%s'", PLUGIN_NAME, cert);
642+
return;
643+
}
644+
ca_cert_scoped.reset(PEM_read_X509(fp, nullptr, nullptr, nullptr));
645+
fclose(fp);
646+
647+
if ((fp = fopen(key, "r")) == nullptr) {
648+
TSDebug(PLUGIN_NAME, "fopen() error is %d: %s for %s", errno, strerror(errno), key);
649+
TSError("[%s] unable to initialize plugin: failed to open CA key '%s'", PLUGIN_NAME, key);
650+
return;
651+
}
652+
ca_pkey_scoped.reset(PEM_read_PrivateKey(fp, nullptr, nullptr, nullptr));
653+
fclose(fp);
654+
655+
if (ca_pkey_scoped == nullptr || ca_cert_scoped == nullptr) {
656+
TSDebug(PLUGIN_NAME, "PEM_read failed to read %s %s", ca_pkey_scoped ? "" : "pkey", ca_cert_scoped ? "" : "cert");
657+
TSError("[%s] unable to initialize plugin: failed to parse ca key or certificate", PLUGIN_NAME);
658+
return;
664659
}
665-
TSDebug(PLUGIN_NAME, "Dynamic cert generation %s", sign_enabled ? "enabled" : "disabled");
666660

667-
/// Add global hooks
668-
TSHttpHookAdd(TS_SSL_CERT_HOOK, cb_shadow);
661+
// Read serial file
662+
serial_file.open(serial, std::fstream::in | std::fstream::out);
663+
if (!serial_file.is_open()) {
664+
TSDebug(PLUGIN_NAME, "failed to open serial file '%s'", serial);
665+
TSError("[%s] unable to initialize plugin: failed to open serial file '%s'", PLUGIN_NAME, serial);
666+
return;
667+
}
668+
/// Initialize mutex and serial number
669+
serial_mutex = TSMutexCreate();
670+
ca_serial = 0;
671+
672+
serial_file.seekg(0, serial_file.beg);
673+
serial_file >> ca_serial;
674+
if (serial_file.bad() || serial_file.fail()) {
675+
ca_serial = 0;
676+
}
669677
}
670678

679+
TSDebug(PLUGIN_NAME, "dynamic certificate generation %s", sign_enabled ? "enabled" : "disabled");
680+
681+
/// Add global hooks
682+
TSHttpHookAdd(TS_SSL_CERT_HOOK, cb_shadow);
683+
671684
return;
672685
}

tests/gold_tests/pluginTest/certifier/certifier.test.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def setupTS(self):
6464
f'certifier.so -s {os.path.join(self.certPathDest, "store")} -m 1000 -c {os.path.join(self.certPathDest, "ca.cert")} -k {os.path.join(self.certPathDest, "ca.key")} -r {os.path.join(self.certPathDest, "ca-serial.txt")}')
6565
# Verify logs for dynamic generation of certs
6666
self.ts.Disk.traffic_out.Content += Testers.ContainsExpression(
67-
"Creating shadow certs",
67+
"creating shadow certs",
6868
"Verify the certifier plugin generates the certificate dynamically.")
6969

7070
def runHTTPSTraffic(self):
@@ -148,7 +148,8 @@ def setupTS(self):
148148
f'certifier.so -s {os.path.join(self.certPathDest, "store")} -m 1000 -c {os.path.join(self.certPathDest, "ca.cert")} -k {os.path.join(self.certPathDest, "ca.key")} -r {os.path.join(self.certPathDest, "ca-serial.txt")}')
149149
# Verify logs for reusing existing cert
150150
self.ts.Disk.traffic_out.Content += Testers.ContainsExpression(
151-
"Reuse existing cert and context for www.tls.com", "Should reuse the existing certificate")
151+
"reusing existing cert and context for www.tls.com",
152+
"Should reuse the existing certificate")
152153

153154
def runHTTPSTraffic(self):
154155
tr = Test.AddTestRun("Test dynamic generation of certs")

0 commit comments

Comments
 (0)