diff --git a/contrib/epee/src/http_auth.cpp b/contrib/epee/src/http_auth.cpp index ec430c8cb..5e21d5d7b 100644 --- a/contrib/epee/src/http_auth.cpp +++ b/contrib/epee/src/http_auth.cpp @@ -64,6 +64,7 @@ #include #include #include +#include #include #include @@ -294,13 +295,21 @@ namespace std::array nc{{}}; boost::copy(out, nc.data()); + + std::array rbuf{{}}; + if (RAND_bytes(rbuf.data(), rbuf.size()) != 1) + return {}; + + const std::string cnonce = epee::string_encoding::base64_encode(rbuf.data(), rbuf.size()); const auto response = digest( - generate_a1(digest, user), u8":", user.server.nonce, u8":", nc, u8"::auth:", digest(method, u8":", uri) + generate_a1(digest, user), u8":", user.server.nonce, u8":", nc, u8":", cnonce, u8":auth:", digest(method, u8":", uri) ); + out.clear(); init_client_value(out, Digest::name, user, uri, response); add_field(out, u8"qop", ceref(u8"auth")); add_field(out, u8"nc", nc); + add_field(out, u8"cnonce", quoted_(cnonce)); return out; } @@ -590,7 +599,7 @@ namespace boost::equals((*digest).name, request.algorithm, ascii_iequal) ); if (request.qop.empty()) - value_generator = old_algorithm{*digest}; + index = boost::fusion::size(digest_algorithms); else { for (auto elem = boost::make_split_iterator(request.qop, boost::token_finder(http_list_separator)); diff --git a/tests/unit_tests/http.cpp b/tests/unit_tests/http.cpp index 947bd3c9f..4ded76c9d 100644 --- a/tests/unit_tests/http.cpp +++ b/tests/unit_tests/http.cpp @@ -614,10 +614,8 @@ TEST(HTTP_Client_Auth, BadSyntax) TEST(HTTP_Client_Auth, MD5) { - constexpr char method[] = "NOP"; constexpr char nonce[] = "some crazy nonce"; constexpr char realm[] = "the only realm"; - constexpr char uri[] = "/some_file"; const http::login user{"foo", "bar"}; http::http_client_auth auth{user}; @@ -636,42 +634,11 @@ TEST(HTTP_Client_Auth, MD5) }, }); - EXPECT_EQ(http::http_client_auth::kSuccess, auth.handle_401(response)); - const auto auth_field = auth.get_auth_field(method, uri); - ASSERT_TRUE(bool(auth_field)); - - const auto parsed = parse_fields(auth_field->second); - EXPECT_STREQ(u8"Authorization", auth_field->first.c_str()); - EXPECT_EQ(parsed.end(), parsed.find(u8"opaque")); - EXPECT_EQ(parsed.end(), parsed.find(u8"qop")); - EXPECT_EQ(parsed.end(), parsed.find(u8"nc")); - EXPECT_STREQ(u8"MD5", parsed.at(u8"algorithm").c_str()); - EXPECT_STREQ(nonce, parsed.at(u8"nonce").c_str()); - EXPECT_STREQ(uri, parsed.at(u8"uri").c_str()); - EXPECT_EQ(user.username, parsed.at(u8"username")); - EXPECT_STREQ(realm, parsed.at(u8"realm").c_str()); - - const std::string a1 = get_a1(user, parsed); - const std::string a2 = get_a2(uri); - const std::string auth_code = md5_hex( - boost::join(std::vector{md5_hex(a1), nonce, md5_hex(a2)}, u8":") - ); - EXPECT_TRUE(boost::iequals(auth_code, parsed.at(u8"response"))); - { - const auto auth_field_dup = auth.get_auth_field(method, uri); - ASSERT_TRUE(bool(auth_field_dup)); - EXPECT_EQ(*auth_field, *auth_field_dup); - } - - - EXPECT_EQ(http::http_client_auth::kBadPassword, auth.handle_401(response)); - response.m_header_info.m_etc_fields.front().second.append(u8"," + write_fields({{u8"stale", u8"TRUE"}})); - EXPECT_EQ(http::http_client_auth::kSuccess, auth.handle_401(response)); + EXPECT_EQ(http::http_client_auth::kParseFailure, auth.handle_401(response)); } TEST(HTTP_Client_Auth, MD5_auth) { - constexpr char cnonce[] = ""; constexpr char method[] = "NOP"; constexpr char nonce[] = "some crazy nonce"; constexpr char opaque[] = "this is the opaque"; @@ -723,7 +690,7 @@ TEST(HTTP_Client_Auth, MD5_auth) const std::string a1 = get_a1(user, parsed); const std::string a2 = get_a2(uri); const std::string auth_code = md5_hex( - boost::join(std::vector{md5_hex(a1), nonce, nc, cnonce, u8"auth", md5_hex(a2)}, u8":") + boost::join(std::vector{md5_hex(a1), nonce, nc, parsed.at(u8"cnonce"), u8"auth", md5_hex(a2)}, u8":") ); EXPECT_TRUE(boost::iequals(auth_code, parsed.at(u8"response"))); }