From: Daiki Ueno Date: Mon, 14 Mar 2022 15:03:07 +0000 (+0100) Subject: cli, serv: allow multiple --compress-cert options X-Git-Tag: 3.7.4~2^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4f09470377692e2dee9bbf27f72e32cb79904b8d;p=thirdparty%2Fgnutls.git cli, serv: allow multiple --compress-cert options This eliminates the need of parsing the comma separated list manually. Signed-off-by: Daiki Ueno --- diff --git a/src/cli.c b/src/cli.c index 3b28a7b839..fb7f957b48 100644 --- a/src/cli.c +++ b/src/cli.c @@ -821,7 +821,9 @@ gnutls_session_t init_tls_session(const char *host) } if (HAVE_OPT(COMPRESS_CERT) && disable_extensions == 0) { - ret = compress_cert_set_methods(session, OPT_ARG(COMPRESS_CERT)); + ret = compress_cert_set_methods(session, + OPTS_ARRAY(COMPRESS_CERT), + OPTS_COUNT(COMPRESS_CERT)); if (ret < 0) exit(1); } diff --git a/src/common.c b/src/common.c index 719106c032..d850b852f4 100644 --- a/src/common.c +++ b/src/common.c @@ -292,44 +292,38 @@ int cert_verify(gnutls_session_t session, const char *hostname, const char *purp } /* Parse input string and set certificate compression methods */ -int compress_cert_set_methods(gnutls_session_t session, const char *string) +int compress_cert_set_methods(gnutls_session_t session, + const char **strings, + size_t n_strings) { - int ret = 0, i = 0; - char *s = NULL, *t = NULL, *str = NULL; - size_t methods_len = 0; - gnutls_compression_method_t *methods = NULL; + int ret = 0; + gnutls_compression_method_t *methods; - if (!string || !*string) + if (n_strings == 0) { return 0; - - str = strdup(string); - if (!str) { - ret = GNUTLS_E_MEMORY_ERROR; - fprintf(stderr, "Could not set certificate compression methods: %s\n", - gnutls_strerror(ret)); - goto cleanup; } - methods_len = 1; - for (s = str; *s; ++s) - if (*s == ',') - ++methods_len; - - methods = gnutls_malloc(methods_len * sizeof(gnutls_compression_method_t)); +/* GCC analyzer in 11.2 mishandles reallocarray/free */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wanalyzer-mismatching-deallocation" + + methods = reallocarray(NULL, n_strings, sizeof(*methods)); if (!methods) { - ret = GNUTLS_E_MEMORY_ERROR; fprintf(stderr, "Could not set certificate compression methods: %s\n", gnutls_strerror(ret)); - goto cleanup; + return GNUTLS_E_MEMORY_ERROR; } - for (s = str, i = 0; (t = strchr(s, ',')); s = t + 1, ++i) { - *t = '\0'; - methods[i] = gnutls_compression_get_id(s); + for (size_t i = 0; i < n_strings; ++i) { + methods[i] = gnutls_compression_get_id(strings[i]); + if (methods[i] == GNUTLS_COMP_UNKNOWN) { + fprintf(stderr, "Unknown compression method: %s\n", + strings[i]); + goto cleanup; + } } - methods[i] = gnutls_compression_get_id(s); - ret = gnutls_compress_certificate_set_methods(session, methods, methods_len); + ret = gnutls_compress_certificate_set_methods(session, methods, n_strings); if (ret < 0) { fprintf(stderr, "Could not set certificate compression methods: %s\n", gnutls_strerror(ret)); @@ -337,9 +331,10 @@ int compress_cert_set_methods(gnutls_session_t session, const char *string) } cleanup: - free(str); free(methods); +#pragma GCC diagnostic pop + return ret; } diff --git a/src/common.h b/src/common.h index f93187cfee..507d0d8337 100644 --- a/src/common.h +++ b/src/common.h @@ -71,7 +71,8 @@ void print_cert_info2(gnutls_session_t, int flag, FILE *fp, int print_cert); void print_list(const char *priorities, int verbose); int cert_verify(gnutls_session_t session, const char *hostname, const char *purpose); -int compress_cert_set_methods(gnutls_session_t session, const char *string); +int compress_cert_set_methods(gnutls_session_t session, const char **strings, + size_t n_strings); const char *raw_to_string(const unsigned char *raw, size_t raw_size); const char *raw_to_hex(const unsigned char *raw, size_t raw_size); diff --git a/src/gnutls-cli-options.json b/src/gnutls-cli-options.json index 6a6eea1651..2d712ce434 100644 --- a/src/gnutls-cli-options.json +++ b/src/gnutls-cli-options.json @@ -314,8 +314,9 @@ { "long-option": "compress-cert", "description": "Compress certificate", - "detail": "This option sets a list of supported compression methods for certificate compression. Use comma delimited list of compression methods such as \"zlib,brotli,zstd\".", - "argument-type": "string" + "detail": "This option sets a supported compression method for certificate compression.", + "argument-type": "string", + "multiple": true }, { "long-option": "heartbeat", @@ -407,4 +408,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/src/gnutls-serv-options.json b/src/gnutls-serv-options.json index 342b8a8cdc..015a70d3c2 100644 --- a/src/gnutls-serv-options.json +++ b/src/gnutls-serv-options.json @@ -129,8 +129,9 @@ { "long-option": "compress-cert", "description": "Compress certificate", - "detail": "This option sets a list of supported compression methods for certificate compression. Use comma delimited list of compression methods such as \"zlib,brotli,zstd\".", - "argument-type": "string" + "detail": "This option sets a supported compression method for certificate compression.", + "argument-type": "string", + "multiple": true }, { "long-option": "heartbeat", @@ -309,4 +310,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/src/serv.c b/src/serv.c index 555406b434..3ff335d1b1 100644 --- a/src/serv.c +++ b/src/serv.c @@ -518,7 +518,9 @@ gnutls_session_t initialize_session(int dtls) } if (HAVE_OPT(COMPRESS_CERT)) { - ret = compress_cert_set_methods(session, OPT_ARG(COMPRESS_CERT)); + ret = compress_cert_set_methods(session, + OPTS_ARRAY(COMPRESS_CERT), + OPTS_COUNT(COMPRESS_CERT)); if (ret < 0) exit(1); }