Skip to content

Commit

Permalink
pythongh-103142: Upgrade binary builds and CI to OpenSSL 1.1.1u (pyth…
Browse files Browse the repository at this point in the history
…on#105174)

Upgrade builds to OpenSSL 1.1.1u.

This OpenSSL version addresses a pile if less-urgent CVEs since 1.1.1t.

The Mac/BuildScript/build-installer.py was already updated.

Also updates _ssl_data_111.h from OpenSSL 1.1.1u, _ssl_data_300.h from 3.0.9, and adds a new _ssl_data_31.h file from 3.1.1 along with the ssl.c code to use it.

Manual edits to the _ssl_data_300.h file prevent it from removing any existing definitions in case those exist in some peoples builds and were important (avoiding regressions during backporting).

backports of this prior to 3.12 will not include the openssl 3.1 header.

(cherry picked from commit ede89af)
  • Loading branch information
gpshead authored and glebfm committed Jul 30, 2023
1 parent a2e3d79 commit fa7bccb
Show file tree
Hide file tree
Showing 5 changed files with 8,778 additions and 5 deletions.
4 changes: 3 additions & 1 deletion Modules/_ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,9 @@ struct py_ssl_library_code {
};

/* Include generated data (error codes) */
#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
#if (OPENSSL_VERSION_NUMBER >= 0x30100000L)
#include "_ssl_data_31.h"
#elif (OPENSSL_VERSION_NUMBER >= 0x30000000L)
#include "_ssl_data_300.h"
#elif (OPENSSL_VERSION_NUMBER >= 0x10101000L) && !defined(LIBRESSL_VERSION_NUMBER)
#include "_ssl_data_111.h"
Expand Down
17 changes: 16 additions & 1 deletion Modules/_ssl_data_111.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* File generated by Tools/ssl/make_ssl_data.py *//* Generated on 2021-04-09T09:36:21.493286 */
/* File generated by Tools/ssl/make_ssl_data.py *//* Generated on 2023-06-01T02:58:04.081473 */
static struct py_ssl_library_code library_codes[] = {
#ifdef ERR_LIB_ASN1
{"ASN1", ERR_LIB_ASN1},
Expand Down Expand Up @@ -1375,6 +1375,11 @@ static struct py_ssl_error_code error_codes[] = {
#else
{"UNSUPPORTED_COMPRESSION_ALGORITHM", 46, 151},
#endif
#ifdef CMS_R_UNSUPPORTED_CONTENT_ENCRYPTION_ALGORITHM
{"UNSUPPORTED_CONTENT_ENCRYPTION_ALGORITHM", ERR_LIB_CMS, CMS_R_UNSUPPORTED_CONTENT_ENCRYPTION_ALGORITHM},
#else
{"UNSUPPORTED_CONTENT_ENCRYPTION_ALGORITHM", 46, 194},
#endif
#ifdef CMS_R_UNSUPPORTED_CONTENT_TYPE
{"UNSUPPORTED_CONTENT_TYPE", ERR_LIB_CMS, CMS_R_UNSUPPORTED_CONTENT_TYPE},
#else
Expand Down Expand Up @@ -4860,6 +4865,11 @@ static struct py_ssl_error_code error_codes[] = {
#else
{"MISSING_PARAMETERS", 20, 290},
#endif
#ifdef SSL_R_MISSING_PSK_KEX_MODES_EXTENSION
{"MISSING_PSK_KEX_MODES_EXTENSION", ERR_LIB_SSL, SSL_R_MISSING_PSK_KEX_MODES_EXTENSION},
#else
{"MISSING_PSK_KEX_MODES_EXTENSION", 20, 310},
#endif
#ifdef SSL_R_MISSING_RSA_CERTIFICATE
{"MISSING_RSA_CERTIFICATE", ERR_LIB_SSL, SSL_R_MISSING_RSA_CERTIFICATE},
#else
Expand Down Expand Up @@ -5065,6 +5075,11 @@ static struct py_ssl_error_code error_codes[] = {
#else
{"NULL_SSL_METHOD_PASSED", 20, 196},
#endif
#ifdef SSL_R_OCSP_CALLBACK_FAILURE
{"OCSP_CALLBACK_FAILURE", ERR_LIB_SSL, SSL_R_OCSP_CALLBACK_FAILURE},
#else
{"OCSP_CALLBACK_FAILURE", 20, 294},
#endif
#ifdef SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED
{"OLD_SESSION_CIPHER_NOT_RETURNED", ERR_LIB_SSL, SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED},
#else
Expand Down
152 changes: 151 additions & 1 deletion Modules/_ssl_data_300.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* File generated by Tools/ssl/make_ssl_data.py *//* Generated on 2021-04-09T09:44:43.288448 */
/* File generated by Tools/ssl/make_ssl_data.py *//* Generated on 2023-06-01T03:03:52.163218 */
static struct py_ssl_library_code library_codes[] = {
#ifdef ERR_LIB_ASN1
{"ASN1", ERR_LIB_ASN1},
Expand Down Expand Up @@ -1035,6 +1035,11 @@ static struct py_ssl_error_code error_codes[] = {
#else
{"NO_INVERSE", 3, 108},
#endif
#ifdef BN_R_NO_PRIME_CANDIDATE
{"NO_PRIME_CANDIDATE", ERR_LIB_BN, BN_R_NO_PRIME_CANDIDATE},
#else
{"NO_PRIME_CANDIDATE", 3, 121},
#endif
#ifdef BN_R_NO_SOLUTION
{"NO_SOLUTION", ERR_LIB_BN, BN_R_NO_SOLUTION},
#else
Expand Down Expand Up @@ -1255,6 +1260,11 @@ static struct py_ssl_error_code error_codes[] = {
#else
{"INVALID_OPTION", 58, 174},
#endif
#ifdef CMP_R_MISSING_CERTID
{"MISSING_CERTID", ERR_LIB_CMP, CMP_R_MISSING_CERTID},
#else
{"MISSING_CERTID", 58, 165},
#endif
#ifdef CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION
{"MISSING_KEY_INPUT_FOR_CREATING_PROTECTION", ERR_LIB_CMP, CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION},
#else
Expand All @@ -1280,21 +1290,41 @@ static struct py_ssl_error_code error_codes[] = {
#else
{"MISSING_PRIVATE_KEY", 58, 131},
#endif
#ifdef CMP_R_MISSING_PRIVATE_KEY_FOR_POPO
{"MISSING_PRIVATE_KEY_FOR_POPO", ERR_LIB_CMP, CMP_R_MISSING_PRIVATE_KEY_FOR_POPO},
#else
{"MISSING_PRIVATE_KEY_FOR_POPO", 58, 190},
#endif
#ifdef CMP_R_MISSING_PROTECTION
{"MISSING_PROTECTION", ERR_LIB_CMP, CMP_R_MISSING_PROTECTION},
#else
{"MISSING_PROTECTION", 58, 143},
#endif
#ifdef CMP_R_MISSING_PUBLIC_KEY
{"MISSING_PUBLIC_KEY", ERR_LIB_CMP, CMP_R_MISSING_PUBLIC_KEY},
#else
{"MISSING_PUBLIC_KEY", 58, 183},
#endif
#ifdef CMP_R_MISSING_REFERENCE_CERT
{"MISSING_REFERENCE_CERT", ERR_LIB_CMP, CMP_R_MISSING_REFERENCE_CERT},
#else
{"MISSING_REFERENCE_CERT", 58, 168},
#endif
#ifdef CMP_R_MISSING_SECRET
{"MISSING_SECRET", ERR_LIB_CMP, CMP_R_MISSING_SECRET},
#else
{"MISSING_SECRET", 58, 178},
#endif
#ifdef CMP_R_MISSING_SENDER_IDENTIFICATION
{"MISSING_SENDER_IDENTIFICATION", ERR_LIB_CMP, CMP_R_MISSING_SENDER_IDENTIFICATION},
#else
{"MISSING_SENDER_IDENTIFICATION", 58, 111},
#endif
#ifdef CMP_R_MISSING_TRUST_ANCHOR
{"MISSING_TRUST_ANCHOR", ERR_LIB_CMP, CMP_R_MISSING_TRUST_ANCHOR},
#else
{"MISSING_TRUST_ANCHOR", 58, 179},
#endif
#ifdef CMP_R_MISSING_TRUST_STORE
{"MISSING_TRUST_STORE", ERR_LIB_CMP, CMP_R_MISSING_TRUST_STORE},
#else
Expand Down Expand Up @@ -1455,6 +1485,11 @@ static struct py_ssl_error_code error_codes[] = {
#else
{"WRONG_ALGORITHM_OID", 58, 138},
#endif
#ifdef CMP_R_WRONG_CERTID
{"WRONG_CERTID", ERR_LIB_CMP, CMP_R_WRONG_CERTID},
#else
{"WRONG_CERTID", 58, 189},
#endif
#ifdef CMP_R_WRONG_CERTID_IN_RP
{"WRONG_CERTID_IN_RP", ERR_LIB_CMP, CMP_R_WRONG_CERTID_IN_RP},
#else
Expand Down Expand Up @@ -1885,6 +1920,11 @@ static struct py_ssl_error_code error_codes[] = {
#else
{"UNSUPPORTED_COMPRESSION_ALGORITHM", 46, 151},
#endif
#ifdef CMS_R_UNSUPPORTED_CONTENT_ENCRYPTION_ALGORITHM
{"UNSUPPORTED_CONTENT_ENCRYPTION_ALGORITHM", ERR_LIB_CMS, CMS_R_UNSUPPORTED_CONTENT_ENCRYPTION_ALGORITHM},
#else
{"UNSUPPORTED_CONTENT_ENCRYPTION_ALGORITHM", 46, 194},
#endif
#ifdef CMS_R_UNSUPPORTED_CONTENT_TYPE
{"UNSUPPORTED_CONTENT_TYPE", ERR_LIB_CMS, CMS_R_UNSUPPORTED_CONTENT_TYPE},
#else
Expand Down Expand Up @@ -2045,6 +2085,11 @@ static struct py_ssl_error_code error_codes[] = {
#else
{"RECURSIVE_DIRECTORY_INCLUDE", 14, 111},
#endif
#ifdef CONF_R_RELATIVE_PATH
{"RELATIVE_PATH", ERR_LIB_CONF, CONF_R_RELATIVE_PATH},
#else
{"RELATIVE_PATH", 14, 125},
#endif
#ifdef CONF_R_SSL_COMMAND_SECTION_EMPTY
{"SSL_COMMAND_SECTION_EMPTY", ERR_LIB_CONF, CONF_R_SSL_COMMAND_SECTION_EMPTY},
#else
Expand Down Expand Up @@ -2235,6 +2280,11 @@ static struct py_ssl_error_code error_codes[] = {
#else
{"INSUFFICIENT_SECURE_DATA_SPACE", 15, 108},
#endif
#ifdef CRYPTO_R_INVALID_NEGATIVE_VALUE
{"INVALID_NEGATIVE_VALUE", ERR_LIB_CRYPTO, CRYPTO_R_INVALID_NEGATIVE_VALUE},
#else
{"INVALID_NEGATIVE_VALUE", 15, 122},
#endif
#ifdef CRYPTO_R_INVALID_NULL_ARGUMENT
{"INVALID_NULL_ARGUMENT", ERR_LIB_CRYPTO, CRYPTO_R_INVALID_NULL_ARGUMENT},
#else
Expand Down Expand Up @@ -2605,6 +2655,11 @@ static struct py_ssl_error_code error_codes[] = {
#else
{"SEED_LEN_SMALL", 10, 110},
#endif
#ifdef DSA_R_TOO_MANY_RETRIES
{"TOO_MANY_RETRIES", ERR_LIB_DSA, DSA_R_TOO_MANY_RETRIES},
#else
{"TOO_MANY_RETRIES", 10, 116},
#endif
#ifdef DSO_R_CTRL_FAILED
{"CTRL_FAILED", ERR_LIB_DSO, DSO_R_CTRL_FAILED},
#else
Expand Down Expand Up @@ -2745,6 +2800,11 @@ static struct py_ssl_error_code error_codes[] = {
#else
{"EC_GROUP_NEW_BY_NAME_FAILURE", 16, 119},
#endif
#ifdef EC_R_EXPLICIT_PARAMS_NOT_SUPPORTED
{"EXPLICIT_PARAMS_NOT_SUPPORTED", ERR_LIB_EC, EC_R_EXPLICIT_PARAMS_NOT_SUPPORTED},
#else
{"EXPLICIT_PARAMS_NOT_SUPPORTED", 16, 127},
#endif
#ifdef EC_R_FAILED_MAKING_PUBLIC_KEY
{"FAILED_MAKING_PUBLIC_KEY", ERR_LIB_EC, EC_R_FAILED_MAKING_PUBLIC_KEY},
#else
Expand Down Expand Up @@ -2850,6 +2910,11 @@ static struct py_ssl_error_code error_codes[] = {
#else
{"INVALID_KEY", 16, 116},
#endif
#ifdef EC_R_INVALID_LENGTH
{"INVALID_LENGTH", ERR_LIB_EC, EC_R_INVALID_LENGTH},
#else
{"INVALID_LENGTH", 16, 117},
#endif
#ifdef EC_R_INVALID_NAMED_GROUP_CONVERSION
{"INVALID_NAMED_GROUP_CONVERSION", ERR_LIB_EC, EC_R_INVALID_NAMED_GROUP_CONVERSION},
#else
Expand Down Expand Up @@ -3010,6 +3075,11 @@ static struct py_ssl_error_code error_codes[] = {
#else
{"SLOT_FULL", 16, 108},
#endif
#ifdef EC_R_TOO_MANY_RETRIES
{"TOO_MANY_RETRIES", ERR_LIB_EC, EC_R_TOO_MANY_RETRIES},
#else
{"TOO_MANY_RETRIES", 16, 176},
#endif
#ifdef EC_R_UNDEFINED_GENERATOR
{"UNDEFINED_GENERATOR", ERR_LIB_EC, EC_R_UNDEFINED_GENERATOR},
#else
Expand Down Expand Up @@ -3690,6 +3760,11 @@ static struct py_ssl_error_code error_codes[] = {
#else
{"PUBLIC_KEY_NOT_RSA", 6, 106},
#endif
#ifdef EVP_R_SETTING_XOF_FAILED
{"SETTING_XOF_FAILED", ERR_LIB_EVP, EVP_R_SETTING_XOF_FAILED},
#else
{"SETTING_XOF_FAILED", 6, 227},
#endif
#ifdef EVP_R_SET_DEFAULT_PROPERTY_FAILURE
{"SET_DEFAULT_PROPERTY_FAILURE", ERR_LIB_EVP, EVP_R_SET_DEFAULT_PROPERTY_FAILURE},
#else
Expand Down Expand Up @@ -3865,6 +3940,11 @@ static struct py_ssl_error_code error_codes[] = {
#else
{"FAILED_READING_DATA", 61, 128},
#endif
#ifdef HTTP_R_HEADER_PARSE_ERROR
{"HEADER_PARSE_ERROR", ERR_LIB_HTTP, HTTP_R_HEADER_PARSE_ERROR},
#else
{"HEADER_PARSE_ERROR", 61, 126},
#endif
#ifdef HTTP_R_INCONSISTENT_CONTENT_LENGTH
{"INCONSISTENT_CONTENT_LENGTH", ERR_LIB_HTTP, HTTP_R_INCONSISTENT_CONTENT_LENGTH},
#else
Expand Down Expand Up @@ -3935,6 +4015,16 @@ static struct py_ssl_error_code error_codes[] = {
#else
{"RESPONSE_PARSE_ERROR", 61, 104},
#endif
#ifdef HTTP_R_RETRY_TIMEOUT
{"RETRY_TIMEOUT", ERR_LIB_HTTP, HTTP_R_RETRY_TIMEOUT},
#else
{"RETRY_TIMEOUT", 61, 129},
#endif
#ifdef HTTP_R_SERVER_CANCELED_CONNECTION
{"SERVER_CANCELED_CONNECTION", ERR_LIB_HTTP, HTTP_R_SERVER_CANCELED_CONNECTION},
#else
{"SERVER_CANCELED_CONNECTION", 61, 127},
#endif
#ifdef HTTP_R_SOCK_NOT_SUPPORTED
{"SOCK_NOT_SUPPORTED", ERR_LIB_HTTP, HTTP_R_SOCK_NOT_SUPPORTED},
#else
Expand Down Expand Up @@ -4100,6 +4190,16 @@ static struct py_ssl_error_code error_codes[] = {
#else
{"UNSUPPORTED_REQUESTORNAME_TYPE", 39, 129},
#endif
#ifdef OSSL_DECODER_R_COULD_NOT_DECODE_OBJECT
{"COULD_NOT_DECODE_OBJECT", ERR_LIB_OSSL_DECODER, OSSL_DECODER_R_COULD_NOT_DECODE_OBJECT},
#else
{"COULD_NOT_DECODE_OBJECT", 60, 101},
#endif
#ifdef OSSL_DECODER_R_DECODER_NOT_FOUND
{"DECODER_NOT_FOUND", ERR_LIB_OSSL_DECODER, OSSL_DECODER_R_DECODER_NOT_FOUND},
#else
{"DECODER_NOT_FOUND", 60, 102},
#endif
#ifdef OSSL_DECODER_R_MISSING_GET_PARAMS
{"MISSING_GET_PARAMS", ERR_LIB_OSSL_DECODER, OSSL_DECODER_R_MISSING_GET_PARAMS},
#else
Expand Down Expand Up @@ -4190,6 +4290,11 @@ static struct py_ssl_error_code error_codes[] = {
#else
{"NOT_PARAMETERS", 44, 104},
#endif
#ifdef OSSL_STORE_R_NO_LOADERS_FOUND
{"NO_LOADERS_FOUND", ERR_LIB_OSSL_STORE, OSSL_STORE_R_NO_LOADERS_FOUND},
#else
{"NO_LOADERS_FOUND", 44, 123},
#endif
#ifdef OSSL_STORE_R_PASSPHRASE_CALLBACK_ERROR
{"PASSPHRASE_CALLBACK_ERROR", ERR_LIB_OSSL_STORE, OSSL_STORE_R_PASSPHRASE_CALLBACK_ERROR},
#else
Expand Down Expand Up @@ -4935,6 +5040,11 @@ static struct py_ssl_error_code error_codes[] = {
#else
{"INVALID_DIGEST_SIZE", 57, 218},
#endif
#ifdef PROV_R_INVALID_INPUT_LENGTH
{"INVALID_INPUT_LENGTH", ERR_LIB_PROV, PROV_R_INVALID_INPUT_LENGTH},
#else
{"INVALID_INPUT_LENGTH", 57, 230},
#endif
#ifdef PROV_R_INVALID_ITERATION_COUNT
{"INVALID_ITERATION_COUNT", ERR_LIB_PROV, PROV_R_INVALID_ITERATION_COUNT},
#else
Expand Down Expand Up @@ -4970,6 +5080,11 @@ static struct py_ssl_error_code error_codes[] = {
#else
{"INVALID_MODE", 57, 125},
#endif
#ifdef PROV_R_INVALID_OUTPUT_LENGTH
{"INVALID_OUTPUT_LENGTH", ERR_LIB_PROV, PROV_R_INVALID_OUTPUT_LENGTH},
#else
{"INVALID_OUTPUT_LENGTH", 57, 217},
#endif
#ifdef PROV_R_INVALID_PADDING_MODE
{"INVALID_PADDING_MODE", ERR_LIB_PROV, PROV_R_INVALID_PADDING_MODE},
#else
Expand Down Expand Up @@ -5035,6 +5150,16 @@ static struct py_ssl_error_code error_codes[] = {
#else
{"KEY_SIZE_TOO_SMALL", 57, 171},
#endif
#ifdef PROV_R_LENGTH_TOO_LARGE
{"LENGTH_TOO_LARGE", ERR_LIB_PROV, PROV_R_LENGTH_TOO_LARGE},
#else
{"LENGTH_TOO_LARGE", 57, 202},
#endif
#ifdef PROV_R_MISMATCHING_DOMAIN_PARAMETERS
{"MISMATCHING_DOMAIN_PARAMETERS", ERR_LIB_PROV, PROV_R_MISMATCHING_DOMAIN_PARAMETERS},
#else
{"MISMATCHING_DOMAIN_PARAMETERS", 57, 203},
#endif
#ifdef PROV_R_MISSING_CEK_ALG
{"MISSING_CEK_ALG", ERR_LIB_PROV, PROV_R_MISSING_CEK_ALG},
#else
Expand Down Expand Up @@ -5695,6 +5820,11 @@ static struct py_ssl_error_code error_codes[] = {
#else
{"INVALID_LABEL", 4, 160},
#endif
#ifdef RSA_R_INVALID_LENGTH
{"INVALID_LENGTH", ERR_LIB_RSA, RSA_R_INVALID_LENGTH},
#else
{"INVALID_LENGTH", 4, 181},
#endif
#ifdef RSA_R_INVALID_MESSAGE_LENGTH
{"INVALID_MESSAGE_LENGTH", ERR_LIB_RSA, RSA_R_INVALID_MESSAGE_LENGTH},
#else
Expand Down Expand Up @@ -5880,6 +6010,11 @@ static struct py_ssl_error_code error_codes[] = {
#else
{"Q_NOT_PRIME", 4, 129},
#endif
#ifdef RSA_R_RANDOMNESS_SOURCE_STRENGTH_INSUFFICIENT
{"RANDOMNESS_SOURCE_STRENGTH_INSUFFICIENT", ERR_LIB_RSA, RSA_R_RANDOMNESS_SOURCE_STRENGTH_INSUFFICIENT},
#else
{"RANDOMNESS_SOURCE_STRENGTH_INSUFFICIENT", 4, 180},
#endif
#ifdef RSA_R_RSA_OPERATIONS_NOT_SUPPORTED
{"RSA_OPERATIONS_NOT_SUPPORTED", ERR_LIB_RSA, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED},
#else
Expand Down Expand Up @@ -6680,6 +6815,11 @@ static struct py_ssl_error_code error_codes[] = {
#else
{"INVALID_TICKET_KEYS_LENGTH", 20, 325},
#endif
#ifdef SSL_R_LEGACY_SIGALG_DISALLOWED_OR_UNSUPPORTED
{"LEGACY_SIGALG_DISALLOWED_OR_UNSUPPORTED", ERR_LIB_SSL, SSL_R_LEGACY_SIGALG_DISALLOWED_OR_UNSUPPORTED},
#else
{"LEGACY_SIGALG_DISALLOWED_OR_UNSUPPORTED", 20, 333},
#endif
#ifdef SSL_R_LENGTH_MISMATCH
{"LENGTH_MISMATCH", ERR_LIB_SSL, SSL_R_LENGTH_MISMATCH},
#else
Expand Down Expand Up @@ -6725,6 +6865,11 @@ static struct py_ssl_error_code error_codes[] = {
#else
{"MISSING_PARAMETERS", 20, 290},
#endif
#ifdef SSL_R_MISSING_PSK_KEX_MODES_EXTENSION
{"MISSING_PSK_KEX_MODES_EXTENSION", ERR_LIB_SSL, SSL_R_MISSING_PSK_KEX_MODES_EXTENSION},
#else
{"MISSING_PSK_KEX_MODES_EXTENSION", 20, 310},
#endif
#ifdef SSL_R_MISSING_RSA_CERTIFICATE
{"MISSING_RSA_CERTIFICATE", ERR_LIB_SSL, SSL_R_MISSING_RSA_CERTIFICATE},
#else
Expand Down Expand Up @@ -6940,6 +7085,11 @@ static struct py_ssl_error_code error_codes[] = {
#else
{"NULL_SSL_METHOD_PASSED", 20, 196},
#endif
#ifdef SSL_R_OCSP_CALLBACK_FAILURE
{"OCSP_CALLBACK_FAILURE", ERR_LIB_SSL, SSL_R_OCSP_CALLBACK_FAILURE},
#else
{"OCSP_CALLBACK_FAILURE", 20, 305},
#endif
#ifdef SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED
{"OLD_SESSION_CIPHER_NOT_RETURNED", ERR_LIB_SSL, SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED},
#else
Expand Down
Loading

0 comments on commit fa7bccb

Please sign in to comment.