diff --git a/src/plugins/relay/relay-http.c b/src/plugins/relay/relay-http.c index 9c24e032b..1c948bd05 100644 --- a/src/plugins/relay/relay-http.c +++ b/src/plugins/relay/relay-http.c @@ -599,9 +599,15 @@ relay_http_get_auth_status (struct t_relay_client *client) user_pass = NULL; use_base64url = 0; + /* check TOTP */ client_totp = weechat_hashtable_get (client->http_req->headers, "x-weechat-totp"); - if (client_totp && client_totp[0]) + if (client_totp) { + if (!client_totp[0]) + { + rc = -4; + goto end; + } number = strtol (client_totp, &error, 10); if (!error || error[0] || (number < 0) || (number > 999999)) { @@ -609,7 +615,47 @@ relay_http_get_auth_status (struct t_relay_client *client) goto end; } } + totp_secret = weechat_string_eval_expression ( + weechat_config_string (relay_config_network_totp_secret), + NULL, NULL, NULL); + if (totp_secret && totp_secret[0]) + { + if (!client_totp || !client_totp[0]) + { + rc = -3; + goto end; + } + /* validate the TOTP received from the client */ + if (weechat_asprintf ( + &info_totp_args, + "%s,%s,0,%d", + totp_secret, /* the shared secret */ + client_totp, /* the TOTP from client */ + weechat_config_integer (relay_config_network_totp_window)) >= 0) + { + info_totp = weechat_info_get ("totp_validate", info_totp_args); + totp_ok = (info_totp && (strcmp (info_totp, "1") == 0)) ? + 1 : 0; + free (info_totp); + free (info_totp_args); + if (!totp_ok) + { + rc = -4; + goto end; + } + } + } + else + { + /* error if TOTP received without TOTP configuration */ + if (client_totp && client_totp[0]) + { + rc = -4; + goto end; + } + } + /* check password */ relay_password = weechat_string_eval_expression ( weechat_config_string (relay_config_network_password), NULL, NULL, NULL); @@ -731,37 +777,6 @@ relay_http_get_auth_status (struct t_relay_client *client) } } - totp_secret = weechat_string_eval_expression ( - weechat_config_string (relay_config_network_totp_secret), - NULL, NULL, NULL); - if (totp_secret && totp_secret[0]) - { - if (!client_totp || !client_totp[0]) - { - rc = -3; - goto end; - } - /* validate the TOTP received from the client */ - if (weechat_asprintf ( - &info_totp_args, - "%s,%s,0,%d", - totp_secret, /* the shared secret */ - client_totp, /* the TOTP from client */ - weechat_config_integer (relay_config_network_totp_window)) >= 0) - { - info_totp = weechat_info_get ("totp_validate", info_totp_args); - totp_ok = (info_totp && (strcmp (info_totp, "1") == 0)) ? - 1 : 0; - free (info_totp); - free (info_totp_args); - if (!totp_ok) - { - rc = -4; - goto end; - } - } - } - end: weechat_string_free_split (protocol_array); free (relay_password); diff --git a/tests/unit/plugins/relay/test-relay-http.cpp b/tests/unit/plugins/relay/test-relay-http.cpp index 843255e00..2ca2fec3c 100644 --- a/tests/unit/plugins/relay/test-relay-http.cpp +++ b/tests/unit/plugins/relay/test-relay-http.cpp @@ -713,13 +713,6 @@ TEST(RelayHttp, GetAuthStatus) hashtable_set (client->http_req->headers, "authorization", "Basic \u26c4"); LONGS_EQUAL(-2, relay_http_get_auth_status (client)); - /* test invalid TOTP */ - hashtable_set (client->http_req->headers, "x-weechat-totp", "abcdef"); - LONGS_EQUAL(-4, relay_http_get_auth_status (client)); - hashtable_set (client->http_req->headers, "x-weechat-totp", "1234567"); - LONGS_EQUAL(-4, relay_http_get_auth_status (client)); - hashtable_remove (client->http_req->headers, "x-weechat-totp"); - /* test invalid plain-text password ("test") */ hashtable_set (client->http_req->headers, "authorization", "Basic cGxhaW46dGVzdA=="); LONGS_EQUAL(-2, relay_http_get_auth_status (client)); @@ -898,6 +891,20 @@ TEST(RelayHttp, GetAuthStatus) hashtable_set (client->http_req->headers, "authorization", auth_header); LONGS_EQUAL(0, relay_http_get_auth_status (client)); + /* test invalid TOTP */ + hashtable_set (client->http_req->headers, "x-weechat-totp", ""); + LONGS_EQUAL(-4, relay_http_get_auth_status (client)); + hashtable_set (client->http_req->headers, "x-weechat-totp", "abcdef"); + LONGS_EQUAL(-4, relay_http_get_auth_status (client)); + hashtable_set (client->http_req->headers, "x-weechat-totp", "1234567"); + LONGS_EQUAL(-4, relay_http_get_auth_status (client)); + hashtable_remove (client->http_req->headers, "x-weechat-totp"); + + /* test valid TOTP without TOTP configuration */ + hashtable_set (client->http_req->headers, "x-weechat-totp", "123456"); + LONGS_EQUAL(-4, relay_http_get_auth_status (client)); + hashtable_remove (client->http_req->headers, "x-weechat-totp"); + /* test missing/invalid TOTP */ config_file_option_set (relay_config_network_totp_secret, "secretbase32", 1); config_file_option_set (relay_config_network_totp_window, "1", 1);