Skip to content

Commit 6726fb9

Browse files
authored
Merge pull request #3 from canonical/feature/capture_server_cert
add certificate retrieval action
2 parents 6edeecf + ac880ba commit 6726fb9

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

actions.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,7 @@ get-session-ssl-cipher:
2323
- "disabled"
2424
description: Use ssl for connection
2525
default: enabled
26+
27+
get-server-certificate:
28+
description: Retrieve server certificate in pem format
29+

src/charm.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"""
1010

1111
import logging
12+
import re
1213
import secrets
1314
import string
1415
import subprocess
@@ -63,6 +64,10 @@ def __init__(self, *args):
6364
getattr(self.on, "get_session_ssl_cipher_action"), self._get_session_ssl_cipher
6465
)
6566

67+
self.framework.observe(
68+
getattr(self.on, "get_server_certificate_action"), self._get_server_certificate
69+
)
70+
6671
# Database related events
6772
self.database = DatabaseRequires(self, "database", DATABASE_NAME)
6873
self.framework.observe(
@@ -319,6 +324,37 @@ def _get_session_ssl_cipher(self, event: ActionEvent) -> None:
319324

320325
event.set_results({"cipher": cipher})
321326

327+
def _get_server_certificate(self, event: ActionEvent) -> None:
328+
"""Get the server certificate."""
329+
certificate = "error"
330+
if not self._database_config:
331+
event.fail()
332+
else:
333+
try:
334+
process = subprocess.run(
335+
[
336+
"openssl",
337+
"s_client",
338+
"-starttls",
339+
"mysql",
340+
"-connect",
341+
f"{self._database_config['host']}:{self._database_config['port']}",
342+
],
343+
capture_output=True,
344+
)
345+
# butchered stdout due non utf chars after the certificate
346+
raw_output = process.stdout[:2800].decode("utf8")
347+
matches = re.search(
348+
r"^(-----BEGIN C.*END CERTIFICATE-----[,\s])",
349+
raw_output,
350+
re.MULTILINE | re.DOTALL,
351+
)
352+
certificate = matches.group(0)
353+
except Exception:
354+
event.fail()
355+
356+
event.set_results({"certificate": certificate})
357+
322358

323359
if __name__ == "__main__":
324360
main(MySQLTestApplication)

0 commit comments

Comments
 (0)