diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/irc/irc-config.c | 120 | ||||
-rw-r--r-- | src/plugins/irc/irc-server.c | 24 |
2 files changed, 84 insertions, 60 deletions
diff --git a/src/plugins/irc/irc-config.c b/src/plugins/irc/irc-config.c index 668bfea01..5d9a5b71b 100644 --- a/src/plugins/irc/irc-config.c +++ b/src/plugins/irc/irc-config.c @@ -997,7 +997,7 @@ irc_config_server_check_value_cb (const void *pointer, void *data, const char *pos_error, *proxy_name; struct t_infolist *infolist; #ifdef HAVE_GNUTLS - char **fingerprints, *str_sizes; + char *fingerprint_eval, **fingerprints, *str_sizes; int i, j, rc, algo, length; #endif /* HAVE_GNUTLS */ @@ -1053,60 +1053,77 @@ irc_config_server_check_value_cb (const void *pointer, void *data, break; case IRC_SERVER_OPTION_SSL_FINGERPRINT: #ifdef HAVE_GNUTLS - if (value && value[0]) + if (!value || !value[0]) + break; + fingerprint_eval = weechat_string_eval_expression ( + value, NULL, NULL, NULL); + if (!fingerprint_eval || !fingerprint_eval[0]) + { + weechat_printf ( + NULL, + _("%s%s: the evaluated fingerprint must not be " + "empty"), + weechat_prefix ("error"), + IRC_PLUGIN_NAME); + if (fingerprint_eval) + free (fingerprint_eval); + return 0; + } + fingerprints = weechat_string_split ( + (fingerprint_eval) ? fingerprint_eval : value, + ",", 0, 0, NULL); + if (!fingerprints) { - fingerprints = weechat_string_split (value, ",", 0, 0, - NULL); - if (fingerprints) + free (fingerprint_eval); + return 1; + } + rc = 0; + for (i = 0; fingerprints[i]; i++) + { + length = strlen (fingerprints[i]); + algo = irc_server_fingerprint_search_algo_with_size ( + length * 4); + if (algo < 0) { - rc = 0; - for (i = 0; fingerprints[i]; i++) - { - length = strlen (fingerprints[i]); - algo = irc_server_fingerprint_search_algo_with_size ( - length * 4); - if (algo < 0) - { - rc = -1; - break; - } - for (j = 0; j < length; j++) - { - if (!isxdigit ((unsigned char)fingerprints[i][j])) - { - rc = -2; - break; - } - } - if (rc < 0) - break; - } - weechat_string_free_split (fingerprints); - switch (rc) + rc = -1; + break; + } + for (j = 0; j < length; j++) + { + if (!isxdigit ((unsigned char)fingerprints[i][j])) { - case -1: /* invalid size */ - str_sizes = irc_server_fingerprint_str_sizes (); - weechat_printf ( - NULL, - _("%s%s: invalid fingerprint size, the " - "number of hexadecimal digits must be " - "one of: %s"), - weechat_prefix ("error"), - IRC_PLUGIN_NAME, - (str_sizes) ? str_sizes : "?"); - if (str_sizes) - free (str_sizes); - return 0; - case -2: /* invalid content */ - weechat_printf ( - NULL, - _("%s%s: invalid fingerprint, it must " - "contain only hexadecimal digits (0-9, " - "a-f)"), - weechat_prefix ("error"), IRC_PLUGIN_NAME); - return 0; + rc = -2; + break; } } + if (rc < 0) + break; + } + weechat_string_free_split (fingerprints); + free (fingerprint_eval); + switch (rc) + { + case -1: /* invalid size */ + str_sizes = irc_server_fingerprint_str_sizes (); + weechat_printf ( + NULL, + _("%s%s: invalid fingerprint size, the " + "number of hexadecimal digits must be " + "one of: %s"), + weechat_prefix ("error"), + IRC_PLUGIN_NAME, + (str_sizes) ? str_sizes : "?"); + if (str_sizes) + free (str_sizes); + return 0; + case -2: /* invalid content */ + weechat_printf ( + NULL, + _("%s%s: invalid fingerprint, it must " + "contain only hexadecimal digits (0-9, " + "a-f)"), + weechat_prefix ("error"), IRC_PLUGIN_NAME); + return 0; } #endif /* HAVE_GNUTLS */ break; @@ -1642,7 +1659,8 @@ irc_config_server_new_option (struct t_config_file *config_file, "20 chars for SHA-1 (insecure, not recommended); many " "fingerprints can be separated by commas; if this option " "is set, the other checks on certificates are NOT " - "performed (option \"ssl_verify\")"), + "performed (option \"ssl_verify\") " + "(note: content is evaluated, see /help eval)"), NULL, 0, 0, default_value, value, null_value_allowed, diff --git a/src/plugins/irc/irc-server.c b/src/plugins/irc/irc-server.c index 0308bf06e..1e78faba5 100644 --- a/src/plugins/irc/irc-server.c +++ b/src/plugins/irc/irc-server.c @@ -4056,8 +4056,8 @@ irc_server_gnutls_callback (const void *pointer, void *data, gnutls_datum_t filedatum; unsigned int i, cert_list_len, status; time_t cert_time; - char *cert_path0, *cert_path1, *cert_path2, *cert_str; - const char *weechat_dir, *fingerprint; + char *cert_path0, *cert_path1, *cert_path2, *cert_str, *fingerprint_eval; + const char *weechat_dir, *ptr_fingerprint; int rc, ret, fingerprint_match, hostname_match, cert_temp_init; #if LIBGNUTLS_VERSION_NUMBER >= 0x010706 /* 1.7.6 */ gnutls_datum_t cinfo; @@ -4080,6 +4080,7 @@ irc_server_gnutls_callback (const void *pointer, void *data, cert_temp_init = 0; cert_list = NULL; cert_list_len = 0; + fingerprint_eval = NULL; if (action == WEECHAT_HOOK_CONNECT_GNUTLS_CB_VERIFY_CERT) { @@ -4106,11 +4107,13 @@ irc_server_gnutls_callback (const void *pointer, void *data, cert_temp_init = 1; /* get fingerprint option in server */ - fingerprint = IRC_SERVER_OPTION_STRING (server, - IRC_SERVER_OPTION_SSL_FINGERPRINT); + ptr_fingerprint = IRC_SERVER_OPTION_STRING(server, + IRC_SERVER_OPTION_SSL_FINGERPRINT); + fingerprint_eval = weechat_string_eval_expression (ptr_fingerprint, + NULL, NULL, NULL); /* set match options */ - fingerprint_match = (fingerprint && fingerprint[0]) ? 0 : 1; + fingerprint_match = (ptr_fingerprint && ptr_fingerprint[0]) ? 0 : 1; hostname_match = 0; /* get the peer's raw certificate (chain) as sent by the peer */ @@ -4143,10 +4146,10 @@ irc_server_gnutls_callback (const void *pointer, void *data, if (i == 0) { /* check if fingerprint matches the first certificate */ - if (fingerprint && fingerprint[0]) + if (fingerprint_eval && fingerprint_eval[0]) { fingerprint_match = irc_server_check_certificate_fingerprint ( - server, cert_temp, fingerprint); + server, cert_temp, fingerprint_eval); } /* check if hostname matches in the first certificate */ if (gnutls_x509_crt_check_hostname (cert_temp, @@ -4178,7 +4181,7 @@ irc_server_gnutls_callback (const void *pointer, void *data, } #endif /* LIBGNUTLS_VERSION_NUMBER >= 0x010706 */ /* check dates, only if fingerprint is not set */ - if (!fingerprint || !fingerprint[0]) + if (!ptr_fingerprint || !ptr_fingerprint[0]) { /* check expiration date */ cert_time = gnutls_x509_crt_get_expiration_time (cert_temp); @@ -4207,7 +4210,7 @@ irc_server_gnutls_callback (const void *pointer, void *data, * if fingerprint is set, display if matches, and don't check * anything else */ - if (fingerprint && fingerprint[0]) + if (ptr_fingerprint && ptr_fingerprint[0]) { if (fingerprint_match) { @@ -4409,6 +4412,9 @@ end: if (cert_temp_init) gnutls_x509_crt_deinit (cert_temp); + if (fingerprint_eval) + free (fingerprint_eval); + return rc; } #endif /* HAVE_GNUTLS */ |