From b73ee5d85d56790a44f0008208dc5de9a226835b Mon Sep 17 00:00:00 2001 From: DanielePalaia Date: Wed, 22 Jan 2025 10:33:28 +0100 Subject: [PATCH 1/3] ssl implementation --- .ci/certs/ca_certificate.pem | 21 +++++++++++++ .ci/certs/ca_key.pem | 28 ++++++++++++++++++ .ci/certs/client.p12 | Bin 0 -> 3715 bytes .ci/certs/client_certificate.pem | 24 +++++++++++++++ .ci/certs/client_key.pem | 28 ++++++++++++++++++ .ci/certs/server.p12 | Bin 0 -> 3715 bytes .ci/certs/server_certificate.pem | 24 +++++++++++++++ .ci/certs/server_key.pem | 28 ++++++++++++++++++ .ci/conf/enabled_plugins | 1 + .ci/conf/rabbitmq.conf | 9 ++++++ examples/getting_started/main.py | 6 ++-- rabbitmq_amqp_python_client/__init__.py | 2 ++ rabbitmq_amqp_python_client/connection.py | 22 ++++++++++++-- .../ssl_configuration.py | 15 ++++++++++ tests/conftest.py | 15 ++++++++++ tests/test_publisher.py | 23 ++++++++++++++ 16 files changed, 242 insertions(+), 4 deletions(-) create mode 100644 .ci/certs/ca_certificate.pem create mode 100644 .ci/certs/ca_key.pem create mode 100644 .ci/certs/client.p12 create mode 100644 .ci/certs/client_certificate.pem create mode 100644 .ci/certs/client_key.pem create mode 100644 .ci/certs/server.p12 create mode 100644 .ci/certs/server_certificate.pem create mode 100644 .ci/certs/server_key.pem create mode 100644 .ci/conf/enabled_plugins create mode 100644 .ci/conf/rabbitmq.conf create mode 100644 rabbitmq_amqp_python_client/ssl_configuration.py diff --git a/.ci/certs/ca_certificate.pem b/.ci/certs/ca_certificate.pem new file mode 100644 index 0000000..77f380a --- /dev/null +++ b/.ci/certs/ca_certificate.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDhjCCAm6gAwIBAgIUYqXLpnhFfIhE5o1qvs6gnL67IsQwDQYJKoZIhvcNAQEL +BQAwTDE7MDkGA1UEAwwyVExTR2VuU2VsZlNpZ25lZHRSb290Q0EgMjAyMy0wOS0x +MVQyMDo1MTozOS42MDMwMTMxDTALBgNVBAcMBCQkJCQwHhcNMjMwOTExMTg1MTM5 +WhcNMzMwOTA4MTg1MTM5WjBMMTswOQYDVQQDDDJUTFNHZW5TZWxmU2lnbmVkdFJv +b3RDQSAyMDIzLTA5LTExVDIwOjUxOjM5LjYwMzAxMzENMAsGA1UEBwwEJCQkJDCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJl6TmIdlTdZpd3ZJaTafrYi +0MAcHE5FEfDQgGkTJgbeXG83MTUD2NYjlGgrb1v793PiO3/iYSK2uGv5AAQdvUmI +jAP8yuJTFiIFpWvljERaDd3sg+RniUN4YaxI0xnM82A2UBWXpdAbS2ASMdPSY6+V +ZX+xbBaY/H7HDL7zhrQEkl1OGgybX+segjOTX1jkNJ7QQZ924DHLvJWDNIIBt8S8 +aYVbf6V2MFziwD98hsfIRgF22T2bgEMkI5M0H5jO4hLkeTYE7Mhpb7TfeZCSLeVD +/vmMbnOvgXJt0wvILwltH6MAviAQTjKIXiMbECTX81tmHInUQ+PKTiz8t5mVSLcC +AwEAAaNgMF4wDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYwHQYDVR0OBBYE +FCjyUnXFpZI5+zz7PJxHxDuulqqZMB8GA1UdIwQYMBaAFCjyUnXFpZI5+zz7PJxH +xDuulqqZMA0GCSqGSIb3DQEBCwUAA4IBAQAw6PFWRnMqVd9rYXHHagxDSlIPj8xm +0RoeSHNgl+G8w2c6tXY2gWU0LWdmrdEX4/OpIBcw7USBSwIBCsv6vBU+HGosMhlk +/K6arqvxENu/zafU1P0RMZnjiTmmzRObIsJiijFsgZQC2q6IjZetpPo6UfdHx0Xm +PRrv+SnbkMk93/QCJJAOlodYwAhZqAkishR2fwlDnNDdR2Aj7qQLYuFr3t5Z92ej +M7OPKbd6XudeWVR3FOxi7/fcNu8mttOtfXkFcUPigs8RJDHMEH1mLMrCzQsRMfA+ +BVZiA+hifJn/9KgZXFlsANT+uLuAWmcEimDAcU/xlAf8eZLcntTB2Oep +-----END CERTIFICATE----- diff --git a/.ci/certs/ca_key.pem b/.ci/certs/ca_key.pem new file mode 100644 index 0000000..ebbda3c --- /dev/null +++ b/.ci/certs/ca_key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCZek5iHZU3WaXd +2SWk2n62ItDAHBxORRHw0IBpEyYG3lxvNzE1A9jWI5RoK29b+/dz4jt/4mEitrhr ++QAEHb1JiIwD/MriUxYiBaVr5YxEWg3d7IPkZ4lDeGGsSNMZzPNgNlAVl6XQG0tg +EjHT0mOvlWV/sWwWmPx+xwy+84a0BJJdThoMm1/rHoIzk19Y5DSe0EGfduAxy7yV +gzSCAbfEvGmFW3+ldjBc4sA/fIbHyEYBdtk9m4BDJCOTNB+YzuIS5Hk2BOzIaW+0 +33mQki3lQ/75jG5zr4FybdMLyC8JbR+jAL4gEE4yiF4jGxAk1/NbZhyJ1EPjyk4s +/LeZlUi3AgMBAAECggEABfZ+hDsi5P69U3GpOofEcBVXh9EBjdx8rYKBnj4kNk1w +Ae6bdtC4x/kVdv+Drk7EPf94JovPSW37fvn5n4Smf142Tto9sJHR0sM7nhQ1fZQg +Vq9moGw8elhe/cTNq0mdaURr06rvUH4bbV3kC3rF+vFLbR6hxqffawvBoMtisbrY +xIp1MfsguOjHLhEDp9crJ+1N5XkqWKZPMpMgPI0mW4Yk+O409+hT5yg/ziNQ5a7o +o86tK3axtPNiaSTPkxoU+sCVu2ILZVTbfjMk2lh7OCgoAA3A9jQ3ulRz+Cl4sXqr +1Ze5pPuRseBL10xmOmoNHR5kvqSNG3Kp6bxyTGiqIQKBgQDPYT2VyaSD4NSA5Es3 +p1DjJa/gItWWIsSSDnpBm5zF908g9rAVxLvx3JLUI4YPFY82o57DCi34jDrE6O0k +SsjuZA2SiuqSqrHxP02RYdAh7/9S/LLM9kakj7QKUU2f92QoyQvKn8M3cygBBz3x +G0uwLE0EU2wgm58SBdnAR6zHuwKBgQC9deipcKT+OG6MZWGhjYsnBiaK8XxxPl9v +Kf2hBmImVDDdOkwthPLKJhP4VhjLETKo8Zi28Nxo6ueOpfn2Q5+0XrI18VNQZI/G +ip6adbezgdIKB0OcWvkXH0Fwl7P7fgNWAPdla9jznSvGj7UnSgt7tFp1xJkXzEfU +n1NEXDNdNQKBgDlOR7RimkGPGWncrCRe6e069tTbC2aHiQZLVeFXXQUfiBA12wbI +7J6zMyfIAT2d2Ythv3dqErYCGiNbslw7BjdKEq4SESwiWzWtJoQsIVWfelC2X7pf +u7mxtDC9stOni1fx5n5Bk7J48e8Gz0kXH905ALdXTiPcnSJf14JYzBgNAoGBAITB +dBAWkGZaYIwcFfc/2Tu1AZjmcY5gaDrar4//ixLUd5Ds4qgauo2PdPrUSXcxS9A5 +ygqWZ7tUroC0KJy48dVPbYyC1yBD9sLmKxCMX/Z2hxjj0ipjTJs5GX+trT4SJIBF +GRWGJnU9sojl9cfcCIPb8m8HHUchq0t/gLcr7AnpAoGARNnUh19fK+8ldKx/h9jN +svJZK1I615OXXRCAY2BWl4k7pbufseVVhtSHxkAfzhmv5gIqojfUGf4WCfcf0eZ9 +xWBXpuWgMwnWuMlPJLwIzlaU1phDsSaHdd2iuAYfZEKWmIIIxT7+vXDO4UaVpXs6 +kso6qBkSwQTymY4m5RATlK4= +-----END PRIVATE KEY----- diff --git a/.ci/certs/client.p12 b/.ci/certs/client.p12 new file mode 100644 index 0000000000000000000000000000000000000000..78f604eb7d6e889026cdf49cfa911b3f93c5caba GIT binary patch literal 3715 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 QXw!<|$H5t3`ft?!2hMcJ1ONa4 literal 0 HcmV?d00001 diff --git a/.ci/certs/client_certificate.pem b/.ci/certs/client_certificate.pem new file mode 100644 index 0000000..6a00436 --- /dev/null +++ b/.ci/certs/client_certificate.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIBAjANBgkqhkiG9w0BAQsFADBMMTswOQYDVQQDDDJUTFNH +ZW5TZWxmU2lnbmVkdFJvb3RDQSAyMDIzLTA5LTExVDIwOjUxOjM5LjYwMzAxMzEN +MAsGA1UEBwwEJCQkJDAeFw0yMzA5MTExODUxNDBaFw0zMzA5MDgxODUxNDBaMDYx +IzAhBgNVBAMMGmdzYW50b21hZ2c2TFZETS52bXdhcmUuY29tMQ8wDQYDVQQKDAZj +bGllbnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDQf+IB3RTjtvdY +3/Rii9zzrY3hCcFcG1k4aOwQAGnE3pgcpRzHaF+l6ZvFX8llP2hcix6ew/IZReDF +p8kuK93PxM0qsYxvCj5fywaGI2mL9sNibrs6CFtvPL+Rj57LSt5UJHSaH3LmY0CE +bV2OdBEuYEBR7eGtzmpupmA+PptHF/U0hTmfIaet6sVLjvJTmD2/3LcztNm/8ksH +iqeHgJDUE+ERWUVl7AEcBo1rHDJw+z/jsKEtKbmqoNxsfcdb2UdZw9cJkB5ojKMr +l73m35s9uIWZxf2iNd3/tqos7cXMLJcTpwr4x6n6F+PsMhBK5sVTw+kFkq+iyxsu +nSVpVT6nAgMBAAGjgfEwge4wCQYDVR0TBAIwADALBgNVHQ8EBAMCBaAwEwYDVR0l +BAwwCgYIKwYBBQUHAwIwTAYDVR0RBEUwQ4IaZ3NhbnRvbWFnZzZMVkRNLnZtd2Fy +ZS5jb22CGmdzYW50b21hZ2c2TFZETS52bXdhcmUuY29tgglsb2NhbGhvc3QwMQYD +VR0fBCowKDAmoCSgIoYgaHR0cDovL2NybC1zZXJ2ZXI6ODAwMC9iYXNpYy5jcmww +HQYDVR0OBBYEFF+biSCzxAazbay1NaTfGDWawU6dMB8GA1UdIwQYMBaAFCjyUnXF +pZI5+zz7PJxHxDuulqqZMA0GCSqGSIb3DQEBCwUAA4IBAQCREnq62BDzp61MRlzL +lsheI/13hkLutFl+OJAoNGcSgprys7d0zwQJGakCO5o05Csi1pQmP0MCKSyPN2Xb +CTEb1qeDBt3FQkgSzXUCAjVL2wvWoL1nIZaAkD5XDjDvGr5Yd4Eczc7WYwujlT5B +JausVa/ShyYatuiTfgPI7UKASW625fkdi+h30OxQ6vnP+X3FUjOV5NO5/GSrlyFN +Fk0M1YqcypUa9meFooDo2aSMTF8zUuZKsOhFLO9B1z7Io/iAiACdPvjdZWjcpJmI +m+gUWeyMH/R4ql6VlPaitUus+CUWkWtdNuQIZEH8HKR1CIOeCW3xwmIJCK9rnbvI +oGb4 +-----END CERTIFICATE----- diff --git a/.ci/certs/client_key.pem b/.ci/certs/client_key.pem new file mode 100644 index 0000000..ab60e2f --- /dev/null +++ b/.ci/certs/client_key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDQf+IB3RTjtvdY +3/Rii9zzrY3hCcFcG1k4aOwQAGnE3pgcpRzHaF+l6ZvFX8llP2hcix6ew/IZReDF +p8kuK93PxM0qsYxvCj5fywaGI2mL9sNibrs6CFtvPL+Rj57LSt5UJHSaH3LmY0CE +bV2OdBEuYEBR7eGtzmpupmA+PptHF/U0hTmfIaet6sVLjvJTmD2/3LcztNm/8ksH +iqeHgJDUE+ERWUVl7AEcBo1rHDJw+z/jsKEtKbmqoNxsfcdb2UdZw9cJkB5ojKMr +l73m35s9uIWZxf2iNd3/tqos7cXMLJcTpwr4x6n6F+PsMhBK5sVTw+kFkq+iyxsu +nSVpVT6nAgMBAAECggEAI86Cit1j9AN9ERdNCguJA5Q/tHEPcvkDZoumVs0rXPL5 +XpoAikJjgsPOy6O6m5e7HYGK3as7DZoRkwBQrYw9CKx8q6NYQc2Zjqv4T9sPCklz +npjzsHC0+zKMl7v5gmI2Mm8cU0epXOWYs+VwVsGaHcPL6AYZZtb3Mk+CYc4wrpGg +BBzkFhMMRDHAhdz5O0tiV/zawZyqxAXrlgBkIWb+lQZm+cZiC/NGEQNnSErNoHiN +mjaC86jjGaI6TXmn0bte0H+KSUSCfWm3xHJGKFIxV74GzWeS3ZtBOMOTZRwZ9qYU +MS/7YeV26J2tGeC3RhWTyuZm7zrn7ZqGp9QzVWbrSQKBgQD+O24nMmveW9yQnahX +rPWwRZ+E0DDblB0M+CjHfI8bn6JEi56B+akkYjjAYi2JgVWwiWJS9TCbWkk4wEmu +o8IxEL0SH0SuBjLXWwMt4vDM5AmxNqdOyoO3J+Ewapw9zKY6uz8b/FV1eZNPQ9+J +bXQxQODDs5GC3QeR+3uJr3uIEwKBgQDR8wq9SgsBfwuqKxSX3rBA7jx/Xxfl3Qbz +OraCCl8o00C7P1jTVk32K+JmzRB2I6lVhDNNjh0hQkc39P1o6SXWH5OAC98hdZDh +q14qGit/oTtQ3Ps9Sw7dt1AAcSbEpKfkIS0T/uf2c1uTvC7tPzAqHViEG+WUwMuD +gVssX5FpnQKBgDnXzb0vVKmX3vwsUsP3/0Jm5N9z+tnKvj1YLPcOWQUg8euElMDf +y+MSUfU7oT665YMwDuXvEWsXRLeb0GfirGk7dLkt0hOCJ4kmFPgYvU7wx1/Bnpln +rEY81ZiNeRT6fgu41KgKZms/CQws1ixPcfNO3pTIQ2Ax5+oH/Niby5BvAoGALDzK +yYG9ee48FfoH18w7VSMdqjTuQyfkXAHGDPaEgISqwgmh/L3VpYYvqTuSOWJgPr2h +VbkZGDXv7bF4Z8+gglKa8MMPm+w6v+Is8DAddEITzoERiyOymTMT71PoOEz9d0sq +RWlTlRFPfXyMYr8KtgUC7qs2H7bT6vypqlrkt90CgYEA1FtcmoIdj0aUH1Ph3ReQ +HSfG19UDmI0o0CaD0d6k8cjDZnxAMe7rHW9oejIzEB+fLOuQeyGpnWKtUXLTHxYz +HmGAlmshG6r4G0Vs7En0syXB7Kd8ZLAj+oRAobzRVTOj2opiF47mK5z4rO9ymUUS +09Wnq4lVGnpvuTeviY+fA3Y= +-----END PRIVATE KEY----- diff --git a/.ci/certs/server.p12 b/.ci/certs/server.p12 new file mode 100644 index 0000000000000000000000000000000000000000..561ebeea279274b73746e5ce42e7b98a772528b9 GIT binary patch literal 3715 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 VnTT;KkVZDU|HCI-3(bF{_CJ>y?$7`L literal 0 HcmV?d00001 diff --git a/.ci/certs/server_certificate.pem b/.ci/certs/server_certificate.pem new file mode 100644 index 0000000..dcab80d --- /dev/null +++ b/.ci/certs/server_certificate.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIBATANBgkqhkiG9w0BAQsFADBMMTswOQYDVQQDDDJUTFNH +ZW5TZWxmU2lnbmVkdFJvb3RDQSAyMDIzLTA5LTExVDIwOjUxOjM5LjYwMzAxMzEN +MAsGA1UEBwwEJCQkJDAeFw0yMzA5MTExODUxNDBaFw0zMzA5MDgxODUxNDBaMDYx +IzAhBgNVBAMMGmdzYW50b21hZ2c2TFZETS52bXdhcmUuY29tMQ8wDQYDVQQKDAZz +ZXJ2ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6H9gnMoGCmgDN +GXpqgLiIJBmDvbo64P+FsPOvKEYFNKj/Poz2UVVY96kOJRDTBXW3p42C0GCll/2z +/4RcOwN4Jcf4TIU+IsytOyQ39FYNVMDJpMzH4dQPYlvx9euyIqxUccTYCiXtHkrd +xw5cV3gs7HPQLcklQtBgoVNnlf1fPQcPgYPa5x95+oEki2yWhScXa9EP3W6G+KXE +guCi1enoIZ3+MfxbEkfdm+C9Yo47vh6LXcokyKpiuOYk2TGrfaw5JQb1tRwb4BOQ +ORriMCHi6+TkQf58yQ5GRZvJ5sjBeJgLtmCvRJXbdZXcw25jKXPwz74qS1Q728kD +c2k7lgKvAgMBAAGjgfEwge4wCQYDVR0TBAIwADALBgNVHQ8EBAMCBaAwEwYDVR0l +BAwwCgYIKwYBBQUHAwEwTAYDVR0RBEUwQ4IaZ3NhbnRvbWFnZzZMVkRNLnZtd2Fy +ZS5jb22CGmdzYW50b21hZ2c2TFZETS52bXdhcmUuY29tgglsb2NhbGhvc3QwHQYD +VR0OBBYEFG5VGCQucC7FqyOJOTzIYtclS9/SMB8GA1UdIwQYMBaAFCjyUnXFpZI5 ++zz7PJxHxDuulqqZMDEGA1UdHwQqMCgwJqAkoCKGIGh0dHA6Ly9jcmwtc2VydmVy +OjgwMDAvYmFzaWMuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQB3nWIIa+9Oo29gU0us +fvryYJo92A/mEGIBpixX2i4eQoPhgTSJvFWN3QCHDexbnccM6tRksQmKwn5Rrf+P +DdM8BiTLP/jOQWJXChZro8xpHLmNjlOGletsQ7wo7/p5hvD6Y7pB6FK6LdLcbwbI +Rmvy8olsfOMewEyyWLbKB7e7+iwDIO5lxxgNWXKspO+Kx7wgVeS3j2OhLaOBj1N4 +a+YAXVVaN3IkkdHwUHBTPfuvguXCD8fZxVW5RkYDiweeHAMuwpu3o2rd7y2dGzG7 +u5mLzNazq4Ki/FTSZMkMAloN4/vfXQfGUO4UJcGXB/c3XO9XURsF2N1k0T9ThIUh +bhmL +-----END CERTIFICATE----- diff --git a/.ci/certs/server_key.pem b/.ci/certs/server_key.pem new file mode 100644 index 0000000..b352f63 --- /dev/null +++ b/.ci/certs/server_key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC6H9gnMoGCmgDN +GXpqgLiIJBmDvbo64P+FsPOvKEYFNKj/Poz2UVVY96kOJRDTBXW3p42C0GCll/2z +/4RcOwN4Jcf4TIU+IsytOyQ39FYNVMDJpMzH4dQPYlvx9euyIqxUccTYCiXtHkrd +xw5cV3gs7HPQLcklQtBgoVNnlf1fPQcPgYPa5x95+oEki2yWhScXa9EP3W6G+KXE +guCi1enoIZ3+MfxbEkfdm+C9Yo47vh6LXcokyKpiuOYk2TGrfaw5JQb1tRwb4BOQ +ORriMCHi6+TkQf58yQ5GRZvJ5sjBeJgLtmCvRJXbdZXcw25jKXPwz74qS1Q728kD +c2k7lgKvAgMBAAECggEAA45fNA8wJUgpqBbgCA/nNrFbNsarERFCdedLHfd1hbJG +C6vCHWSxbkPmcX7ozYyxp+17c9qPtipAw9h9IBaqkCLx/qmrnrkjKFN/HiiSH6q/ +t4/pWmT+BxXjLtd624pJDktRg6qHTfqsWy9rSVK3LkM4SpZ4B45kFSyP6jnrP49j +vmSHzDISiN4G4GqFK12IbA0nioF5tbuacZVGEAoKcUFxEHQmq1e8b6sjg6uKSexk +GFEpvcBm8XgSYjiBPit/AHKxGqzuO0/BbjvQK7gSeSLLaV6DUdKFi9GFsOQjmedq +DLbxy0CIleCnK0hYwp1SN9gvNBLrOIT5lqZfv4+X0QKBgQDrlRjiNJ6rWwQZcidp +ncStV2f/RVuztAacSYHz+0ZZY72uQh+8+W/7+BDkKsZIV2Bswv2wN9/8mPluvyI8 +OLWf1MOwRC5RUsBJqykRuPzFCoe4aZksBVnQsx82bBpfzQFqspCXw3UAcZcM+dHg +jTkFVsSOeCoQxg2DFN0bwz8/vwKBgQDKQWogOStxgnJisxffSQYH0pHbMmVV/V8+ +OTIhx87YHV+cnWT9JGv+Qsnz2s18E9zj1FEYwBJqAbHd5qytATsvMYB4y3voR03G +AzPeDOdFBNZqQaJyGqYPD+HEuVKYlPx8NC2ew+CEh+h5kPUoO/DgCQJrYA3ZXZKw +dOpieR75EQKBgApgtArq9H5p8QFJ9RCDAbH9IritDoAZEx15Y38i95NigG2Xvhwu +BM/duqjCdZ+kMbw4zsIfg/91oa9OPizW9rFGxyQRrNSqR4w3PQTp2EC52Qa3qCa3 +SaCW824LTxIfTsureBEnbBUL6/KHYsZ4kiV5EAmSo4+/mcLHfYIGlNezAoGAMcw5 +XQW2dJQxpauCzS8llPd7ggS+fpWLxb4/YaHYg813pQ/7tXgqPsgjAS92OH6LfGzi +Kr3fysnwCTqqeU48TDpb72HqeB5WP9K6CooSxyORx0exv3ZgPIUkiVM3yumj4NDY +CqcfuIHd81CFjAp2HDMbrWRRBJvNajTfIK/BuIECgYBJPClPwYzJaXYMlc5rmAgL +lJ9rlbjxRffyLOG4BAsapfGYS789MpoP8WzFPkCNcweXWnI9ftKAE57R/o+a+ov6 +hMlnqI4fij2N9BZuFbVWvpf3th72WU8CE1wpzY10Gp//iePXntJqsiwkr+eStPSL +9H/WjV5NwVwqe+YYC6ABMw== +-----END PRIVATE KEY----- diff --git a/.ci/conf/enabled_plugins b/.ci/conf/enabled_plugins new file mode 100644 index 0000000..9d0383d --- /dev/null +++ b/.ci/conf/enabled_plugins @@ -0,0 +1 @@ +[rabbitmq_management, rabbitmq_stream, rabbitmq_stream_management]. \ No newline at end of file diff --git a/.ci/conf/rabbitmq.conf b/.ci/conf/rabbitmq.conf new file mode 100644 index 0000000..6d1d180 --- /dev/null +++ b/.ci/conf/rabbitmq.conf @@ -0,0 +1,9 @@ +loopback_users.guest = false + +ssl_options.cacertfile = /etc/rabbitmq/certs/ca_certificate.pem +ssl_options.certfile = /etc/rabbitmq/certs/server_certificate.pem +ssl_options.keyfile = /etc/rabbitmq/certs/server_key.pem +listeners.ssl.default = 5671 +stream.listeners.ssl.default = 5551 +ssl_options.verify = verify_peer +ssl_options.fail_if_no_peer_cert = false diff --git a/examples/getting_started/main.py b/examples/getting_started/main.py index 0bb4398..1e3b389 100644 --- a/examples/getting_started/main.py +++ b/examples/getting_started/main.py @@ -1,7 +1,7 @@ # type: ignore -from rabbitmq_amqp_python_client import ( +from rabbitmq_amqp_python_client import ( # SSlConfigurationContext, AddressHelper, AMQPMessagingHandler, BindingSpecification, @@ -59,7 +59,9 @@ def on_link_closed(self, event: Event) -> None: def create_connection() -> Connection: - connection = Connection("amqp://guest:guest@localhost:5672/") + connection = Connection("amqps://guest:guest@localhost:5672/") + # in case of SSL + # connection = Connection("amqps://guest:guest@localhost:5671/", ssl_context=SSlConfigurationContext(ca_cert="/Users/dpalaia/projects/rabbitmq-stream-go-client/compose/tls/tls-gen/basic/result/ca_certificate.pem")) connection.dial() return connection diff --git a/rabbitmq_amqp_python_client/__init__.py b/rabbitmq_amqp_python_client/__init__.py index 4d4c179..7af90b0 100644 --- a/rabbitmq_amqp_python_client/__init__.py +++ b/rabbitmq_amqp_python_client/__init__.py @@ -22,6 +22,7 @@ QuorumQueueSpecification, StreamSpecification, ) +from .ssl_configuration import SSlConfigurationContext try: __version__ = metadata.version(__package__) @@ -52,4 +53,5 @@ "AddressHelper", "AMQPMessagingHandler", "ArgumentOutOfRangeException", + "SSlConfigurationContext", ] diff --git a/rabbitmq_amqp_python_client/connection.py b/rabbitmq_amqp_python_client/connection.py index 7c63883..584080a 100644 --- a/rabbitmq_amqp_python_client/connection.py +++ b/rabbitmq_amqp_python_client/connection.py @@ -7,20 +7,38 @@ from .management import Management from .publisher import Publisher from .qpid.proton._handlers import MessagingHandler +from .qpid.proton._transport import SSLDomain from .qpid.proton.utils import BlockingConnection +from .ssl_configuration import SSlConfigurationContext logger = logging.getLogger(__name__) class Connection: - def __init__(self, addr: str): + def __init__( + self, addr: str, ssl_context: Optional[SSlConfigurationContext] = None + ): self._addr: str = addr self._conn: BlockingConnection self._management: Management + self._conf_ssl_context: Optional[SSlConfigurationContext] = ssl_context + self._ssl_domain = None def dial(self) -> None: logger.debug("Establishing a connection to the amqp server") - self._conn = BlockingConnection(self._addr) + if self._conf_ssl_context is not None: + logger.debug("Enabling SSL") + self._ssl_domain = SSLDomain(SSLDomain.MODE_CLIENT) + self._ssl_domain.set_trusted_ca_db(self._conf_ssl_context.ca_cert) + # for mutual authentication + if self._conf_ssl_context.client_cert is not None: + logger.debug("Enabling mutual authentication as well") + self._ssl_domain.set_credentials( + self._conf_ssl_context.client_cert.client_cert, + self._conf_ssl_context.client_cert.client_key, + self._conf_ssl_context.client_cert.password, + ) + self._conn = BlockingConnection(self._addr, ssl_domain=self._ssl_domain) self._open() logger.debug("Connection to the server established") diff --git a/rabbitmq_amqp_python_client/ssl_configuration.py b/rabbitmq_amqp_python_client/ssl_configuration.py new file mode 100644 index 0000000..435a0f1 --- /dev/null +++ b/rabbitmq_amqp_python_client/ssl_configuration.py @@ -0,0 +1,15 @@ +from dataclasses import dataclass +from typing import Optional + + +@dataclass +class ClientCert: + client_cert: str + client_key: str + password: Optional[str] = None + + +@dataclass +class SSlConfigurationContext: + ca_cert: str + client_cert: Optional[ClientCert] = None diff --git a/tests/conftest.py b/tests/conftest.py index eb266cd..ffc6cbc 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -5,6 +5,7 @@ AMQPMessagingHandler, Connection, Event, + SSlConfigurationContext, symbol, ) @@ -20,6 +21,20 @@ def connection(pytestconfig): connection.close() +@pytest.fixture() +def connection_ssl(pytestconfig): + connection = Connection( + "amqps://guest:guest@localhost:5671/", + ssl_context=SSlConfigurationContext(ca_cert="./.ci/certs/ca_certificate.pem"), + ) + connection.dial() + try: + yield connection + + finally: + connection.close() + + @pytest.fixture() def management(pytestconfig): connection = Connection("amqp://guest:guest@localhost:5672/") diff --git a/tests/test_publisher.py b/tests/test_publisher.py index 57d7196..653857f 100644 --- a/tests/test_publisher.py +++ b/tests/test_publisher.py @@ -32,6 +32,29 @@ def test_publish_queue(connection: Connection) -> None: assert raised is False +def test_publish_ssl(connection_ssl: Connection) -> None: + + queue_name = "test-queue" + management = connection_ssl.management() + + management.declare_queue(QuorumQueueSpecification(name=queue_name)) + + raised = False + + try: + publisher = connection_ssl.publisher("/queues/" + queue_name) + publisher.publish(Message(body="test")) + except Exception: + raised = True + + publisher.close() + + management.delete_queue(queue_name) + management.close() + + assert raised is False + + def test_publish_to_invalid_destination(connection: Connection) -> None: queue_name = "test-queue" From 2a5bf3d350abb6fee3cbdae42799ec68dc5ec3cd Mon Sep 17 00:00:00 2001 From: DanielePalaia Date: Wed, 22 Jan 2025 10:51:15 +0100 Subject: [PATCH 2/3] modify action/adding Dockerfile and Makefile --- .ci/conf/rabbitmq.conf | 2 - .github/workflows/build-test.yaml | 45 ++++++++++++++++++----- Dockerfile | 8 ++++ Makefile | 12 ++++++ examples/getting_started/main.py | 11 +++++- rabbitmq_amqp_python_client/connection.py | 15 +++++--- tests/conftest.py | 2 +- 7 files changed, 75 insertions(+), 20 deletions(-) create mode 100644 Dockerfile create mode 100644 Makefile diff --git a/.ci/conf/rabbitmq.conf b/.ci/conf/rabbitmq.conf index 6d1d180..ce7fd7f 100644 --- a/.ci/conf/rabbitmq.conf +++ b/.ci/conf/rabbitmq.conf @@ -5,5 +5,3 @@ ssl_options.certfile = /etc/rabbitmq/certs/server_certificate.pem ssl_options.keyfile = /etc/rabbitmq/certs/server_key.pem listeners.ssl.default = 5671 stream.listeners.ssl.default = 5551 -ssl_options.verify = verify_peer -ssl_options.fail_if_no_peer_cert = false diff --git a/.github/workflows/build-test.yaml b/.github/workflows/build-test.yaml index af2ab1a..b6b9108 100644 --- a/.github/workflows/build-test.yaml +++ b/.github/workflows/build-test.yaml @@ -17,25 +17,52 @@ jobs: python-version: [3.9] os: [ubuntu-22.04] runs-on: ${{ matrix.os }} - services: - rabbitmq-server: - image: rabbitmq:4.0.3-management - ports: - - 5672:5672 - - 15672:15672 + steps: - - uses: actions/checkout@v2 + - name: Checkout + uses: actions/checkout@v4 - uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Build and export + uses: docker/build-push-action@v6 + with: + context: . + tags: rabbitmq_tls:latest + outputs: type=docker,dest=/tmp/rabbitmq_tls.tar + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: rabbitmq_tls + path: /tmp/rabbitmq_tls.tar + - name: Download artifact + uses: actions/download-artifact@v4 + with: + name: rabbitmq_tls + path: /tmp + - name: Load image + run: | + docker load --input /tmp/rabbitmq_tls.tar + docker image ls -a + docker run -d --rm --name rabbitmq-stream-client-test \ + -p 5552:5552 -p 5672:5672 -p 5671:5671 -p 5551:5551 -p 15672:15672 \ + -e RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS="-rabbitmq_stream advertised_host localhost" \ + rabbitmq_tls + - name: wait for running + run: | + docker exec rabbitmq-stream-client-test /bin/bash -c 'ps -aux' + docker exec rabbitmq-stream-client-test /bin/bash -c 'sleep 10' + docker exec rabbitmq-stream-client-test /bin/bash -c 'rabbitmqctl status' + docker exec rabbitmq-stream-client-test /bin/bash -c 'rabbitmqctl wait --pid 1 --timeout 70' - name: Install and configure Poetry uses: snok/install-poetry@v1 with: version: 1.4.2 virtualenvs-create: true virtualenvs-in-project: false - - name: Enable RabbitMQ Plugins - run: docker exec ${{ job.services.rabbitmq-server.id }} rabbitmq-plugins enable rabbitmq_stream rabbitmq_stream_management rabbitmq_amqp1_0 + - name: poetry install run: poetry install --no-root - name: isort check-only diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..5adcbfb --- /dev/null +++ b/Dockerfile @@ -0,0 +1,8 @@ +FROM rabbitmq:4-management +#FROM pivotalrabbitmq/rabbitmq:sha-ae9fbb7bd5982aff099293adbb1edcd616ef806f + + +COPY .ci/conf/rabbitmq.conf /etc/rabbitmq/rabbitmq.conf +COPY .ci/conf/enabled_plugins /etc/rabbitmq/enabled_plugins + +COPY .ci/certs /etc/rabbitmq/certs diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..3cc9675 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ + +all: test build + +rabbitmq-server: + docker build -t rabbitmq-tls-test . + docker run -it --rm --name rabbitmq-tls-test \ + -p 5672:5672 -p 5671:5671 -p 15672:15672 \ + -e RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS="-rabbitmq_stream advertised_host localhost" \ + rabbitmq-tls-test + +help: + cat Makefile diff --git a/examples/getting_started/main.py b/examples/getting_started/main.py index 1e3b389..8859b82 100644 --- a/examples/getting_started/main.py +++ b/examples/getting_started/main.py @@ -10,6 +10,7 @@ ExchangeSpecification, Message, QuorumQueueSpecification, + SSlConfigurationContext, ) @@ -59,9 +60,15 @@ def on_link_closed(self, event: Event) -> None: def create_connection() -> Connection: - connection = Connection("amqps://guest:guest@localhost:5672/") + # connection = Connection("amqps://guest:guest@localhost:5672/") # in case of SSL - # connection = Connection("amqps://guest:guest@localhost:5671/", ssl_context=SSlConfigurationContext(ca_cert="/Users/dpalaia/projects/rabbitmq-stream-go-client/compose/tls/tls-gen/basic/result/ca_certificate.pem")) + ca_cert_file = ( + "/Users/dpalaia/projects/rabbitmq-stream-go-client/.ci/certs/ca_certificate.pem" + ) + connection = Connection( + "amqps://guest:guest@localhost:5671/", + ssl_context=SSlConfigurationContext(ca_cert=ca_cert_file), + ) connection.dial() return connection diff --git a/rabbitmq_amqp_python_client/connection.py b/rabbitmq_amqp_python_client/connection.py index 584080a..dcc1bed 100644 --- a/rabbitmq_amqp_python_client/connection.py +++ b/rabbitmq_amqp_python_client/connection.py @@ -28,16 +28,19 @@ def dial(self) -> None: logger.debug("Establishing a connection to the amqp server") if self._conf_ssl_context is not None: logger.debug("Enabling SSL") + self._ssl_domain = SSLDomain(SSLDomain.MODE_CLIENT) - self._ssl_domain.set_trusted_ca_db(self._conf_ssl_context.ca_cert) + if self._ssl_domain is not None: + self._ssl_domain.set_trusted_ca_db(self._conf_ssl_context.ca_cert) # for mutual authentication if self._conf_ssl_context.client_cert is not None: logger.debug("Enabling mutual authentication as well") - self._ssl_domain.set_credentials( - self._conf_ssl_context.client_cert.client_cert, - self._conf_ssl_context.client_cert.client_key, - self._conf_ssl_context.client_cert.password, - ) + if self._ssl_domain is not None: + self._ssl_domain.set_credentials( + self._conf_ssl_context.client_cert.client_cert, + self._conf_ssl_context.client_cert.client_key, + self._conf_ssl_context.client_cert.password, + ) self._conn = BlockingConnection(self._addr, ssl_domain=self._ssl_domain) self._open() logger.debug("Connection to the server established") diff --git a/tests/conftest.py b/tests/conftest.py index ffc6cbc..9ad1297 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -25,7 +25,7 @@ def connection(pytestconfig): def connection_ssl(pytestconfig): connection = Connection( "amqps://guest:guest@localhost:5671/", - ssl_context=SSlConfigurationContext(ca_cert="./.ci/certs/ca_certificate.pem"), + ssl_context=SSlConfigurationContext(ca_cert=".ci/certs/ca_certificate.pem"), ) connection.dial() try: From e358d5be58c5ef770eabf2e1f9b1ddfe2d29490c Mon Sep 17 00:00:00 2001 From: DanielePalaia Date: Wed, 22 Jan 2025 11:37:08 +0100 Subject: [PATCH 3/3] testing mutual authentication --- .ci/conf/rabbitmq.conf | 2 ++ examples/getting_started/main.py | 24 ++++++++++--------- rabbitmq_amqp_python_client/__init__.py | 8 +++++-- rabbitmq_amqp_python_client/connection.py | 6 ++--- .../ssl_configuration.py | 2 +- tests/conftest.py | 11 +++++++-- tests/test_connection.py | 20 +++++++++++++++- 7 files changed, 53 insertions(+), 20 deletions(-) diff --git a/.ci/conf/rabbitmq.conf b/.ci/conf/rabbitmq.conf index ce7fd7f..6d1d180 100644 --- a/.ci/conf/rabbitmq.conf +++ b/.ci/conf/rabbitmq.conf @@ -5,3 +5,5 @@ ssl_options.certfile = /etc/rabbitmq/certs/server_certificate.pem ssl_options.keyfile = /etc/rabbitmq/certs/server_key.pem listeners.ssl.default = 5671 stream.listeners.ssl.default = 5551 +ssl_options.verify = verify_peer +ssl_options.fail_if_no_peer_cert = false diff --git a/examples/getting_started/main.py b/examples/getting_started/main.py index 8859b82..7af3240 100644 --- a/examples/getting_started/main.py +++ b/examples/getting_started/main.py @@ -1,7 +1,7 @@ # type: ignore -from rabbitmq_amqp_python_client import ( # SSlConfigurationContext, +from rabbitmq_amqp_python_client import ( # SSlConfigurationContext,; SslConfigurationContext,; ClientCert, AddressHelper, AMQPMessagingHandler, BindingSpecification, @@ -10,7 +10,6 @@ ExchangeSpecification, Message, QuorumQueueSpecification, - SSlConfigurationContext, ) @@ -60,15 +59,18 @@ def on_link_closed(self, event: Event) -> None: def create_connection() -> Connection: - # connection = Connection("amqps://guest:guest@localhost:5672/") - # in case of SSL - ca_cert_file = ( - "/Users/dpalaia/projects/rabbitmq-stream-go-client/.ci/certs/ca_certificate.pem" - ) - connection = Connection( - "amqps://guest:guest@localhost:5671/", - ssl_context=SSlConfigurationContext(ca_cert=ca_cert_file), - ) + connection = Connection("amqps://guest:guest@localhost:5672/") + # in case of SSL enablement + # ca_cert_file = ".ci/certs/ca_certificate.pem" + # client_cert = ".ci/certs/client_certificate.pem" + # client_key = ".ci/certs/client_key.pem" + # connection = Connection( + # "amqps://guest:guest@localhost:5671/", + # ssl_context=SslConfigurationContext( + # ca_cert=ca_cert_file, + # client_cert=ClientCert(client_cert=client_cert, client_key=client_key), + # ), + # ) connection.dial() return connection diff --git a/rabbitmq_amqp_python_client/__init__.py b/rabbitmq_amqp_python_client/__init__.py index 7af90b0..4892c44 100644 --- a/rabbitmq_amqp_python_client/__init__.py +++ b/rabbitmq_amqp_python_client/__init__.py @@ -22,7 +22,10 @@ QuorumQueueSpecification, StreamSpecification, ) -from .ssl_configuration import SSlConfigurationContext +from .ssl_configuration import ( + ClientCert, + SslConfigurationContext, +) try: __version__ = metadata.version(__package__) @@ -53,5 +56,6 @@ "AddressHelper", "AMQPMessagingHandler", "ArgumentOutOfRangeException", - "SSlConfigurationContext", + "SslConfigurationContext", + "ClientCert", ] diff --git a/rabbitmq_amqp_python_client/connection.py b/rabbitmq_amqp_python_client/connection.py index dcc1bed..bd2a11a 100644 --- a/rabbitmq_amqp_python_client/connection.py +++ b/rabbitmq_amqp_python_client/connection.py @@ -9,19 +9,19 @@ from .qpid.proton._handlers import MessagingHandler from .qpid.proton._transport import SSLDomain from .qpid.proton.utils import BlockingConnection -from .ssl_configuration import SSlConfigurationContext +from .ssl_configuration import SslConfigurationContext logger = logging.getLogger(__name__) class Connection: def __init__( - self, addr: str, ssl_context: Optional[SSlConfigurationContext] = None + self, addr: str, ssl_context: Optional[SslConfigurationContext] = None ): self._addr: str = addr self._conn: BlockingConnection self._management: Management - self._conf_ssl_context: Optional[SSlConfigurationContext] = ssl_context + self._conf_ssl_context: Optional[SslConfigurationContext] = ssl_context self._ssl_domain = None def dial(self) -> None: diff --git a/rabbitmq_amqp_python_client/ssl_configuration.py b/rabbitmq_amqp_python_client/ssl_configuration.py index 435a0f1..e272988 100644 --- a/rabbitmq_amqp_python_client/ssl_configuration.py +++ b/rabbitmq_amqp_python_client/ssl_configuration.py @@ -10,6 +10,6 @@ class ClientCert: @dataclass -class SSlConfigurationContext: +class SslConfigurationContext: ca_cert: str client_cert: Optional[ClientCert] = None diff --git a/tests/conftest.py b/tests/conftest.py index 9ad1297..005bf6d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -3,9 +3,10 @@ from rabbitmq_amqp_python_client import ( AddressHelper, AMQPMessagingHandler, + ClientCert, Connection, Event, - SSlConfigurationContext, + SslConfigurationContext, symbol, ) @@ -23,9 +24,15 @@ def connection(pytestconfig): @pytest.fixture() def connection_ssl(pytestconfig): + ca_cert_file = ".ci/certs/ca_certificate.pem" + client_cert = ".ci/certs/client_certificate.pem" + client_key = ".ci/certs/client_key.pem" connection = Connection( "amqps://guest:guest@localhost:5671/", - ssl_context=SSlConfigurationContext(ca_cert=".ci/certs/ca_certificate.pem"), + ssl_context=SslConfigurationContext( + ca_cert=ca_cert_file, + client_cert=ClientCert(client_cert=client_cert, client_key=client_key), + ), ) connection.dial() try: diff --git a/tests/test_connection.py b/tests/test_connection.py index 1d2aa4d..b6a7676 100644 --- a/tests/test_connection.py +++ b/tests/test_connection.py @@ -1,7 +1,25 @@ -from rabbitmq_amqp_python_client import Connection +from rabbitmq_amqp_python_client import ( + ClientCert, + Connection, + SslConfigurationContext, +) def test_connection() -> None: connection = Connection("amqp://guest:guest@localhost:5672/") connection.dial() connection.close() + + +def test_connection_ssl() -> None: + ca_cert_file = ".ci/certs/ca_certificate.pem" + client_cert = ".ci/certs/client_certificate.pem" + client_key = ".ci/certs/client_key.pem" + connection = Connection( + "amqps://guest:guest@localhost:5671/", + ssl_context=SslConfigurationContext( + ca_cert=ca_cert_file, + client_cert=ClientCert(client_cert=client_cert, client_key=client_key), + ), + ) + connection.dial()