Skip to content

Commit 6e85f70

Browse files
committed
Test authentication
1 parent b7487b5 commit 6e85f70

File tree

3 files changed

+180
-1
lines changed

3 files changed

+180
-1
lines changed

src/webserver.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,7 +749,9 @@ void webserver::end_request_construction(
749749
user = MHD_basic_auth_get_username_password(connection, &pass);
750750
}
751751
if(digest_auth_enabled)
752+
{
752753
digested_user = MHD_digest_auth_get_username(connection);
754+
}
753755
mr->dhr->set_version(version);
754756
const MHD_ConnectionInfo * conninfo = MHD_get_connection_info(
755757
connection,

test/Makefile.am

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,15 @@
1919
LDADD = $(top_builddir)/src/libhttpserver.la
2020
AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/httpserver/
2121
METASOURCES = AUTO
22-
check_PROGRAMS = basic http_utils threaded string_utilities http_endpoint ban_system ws_start_stop
22+
check_PROGRAMS = basic http_utils threaded string_utilities http_endpoint ban_system ws_start_stop authentication
2323

2424
MOSTLYCLEANFILES = *.gcda *.gcno *.gcov
2525

2626
basic_SOURCES = integ/basic.cpp
2727
threaded_SOURCES = integ/threaded.cpp
2828
ban_system_SOURCES = integ/ban_system.cpp
2929
ws_start_stop_SOURCES = integ/ws_start_stop.cpp
30+
authentication_SOURCES = integ/authentication.cpp
3031
http_utils_SOURCES = unit/http_utils_test.cpp
3132
string_utilities_SOURCES = unit/string_utilities_test.cpp
3233
http_endpoint_SOURCES = unit/http_endpoint_test.cpp

test/integ/authentication.cpp

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
/*
2+
This file is part of libhttpserver
3+
Copyright (C) 2011-2019 Sebastiano Merlino
4+
5+
This library is free software; you can redistribute it and/or
6+
modify it under the terms of the GNU Lesser General Public
7+
License as published by the Free Software Foundation; either
8+
version 2.1 of the License, or (at your option) any later version.
9+
10+
This library is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
Lesser General Public License for more details.
14+
15+
You should have received a copy of the GNU Lesser General Public
16+
License along with this library; if not, write to the Free Software
17+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
18+
USA
19+
*/
20+
21+
#if defined(__MINGW32__) || defined(__CYGWIN32__)
22+
#define _WINDOWS
23+
#undef _WIN32_WINNT
24+
#define _WIN32_WINNT 0x600
25+
#include <winsock2.h>
26+
#include <ws2tcpip.h>
27+
#else
28+
#include <arpa/inet.h>
29+
#endif
30+
31+
#include "littletest.hpp"
32+
#include <curl/curl.h>
33+
#include <netinet/in.h>
34+
#include <sys/socket.h>
35+
#include "httpserver.hpp"
36+
37+
#define MY_OPAQUE "11733b200778ce33060f31c9af70a870ba96ddd4"
38+
39+
using namespace std;
40+
using namespace httpserver;
41+
42+
size_t writefunc(void *ptr, size_t size, size_t nmemb, std::string *s)
43+
{
44+
s->append((char*) ptr, size*nmemb);
45+
return size*nmemb;
46+
}
47+
48+
class user_pass_resource : public httpserver::http_resource
49+
{
50+
public:
51+
const httpserver::http_response render_GET(const httpserver::http_request& req)
52+
{
53+
return httpserver::http_response_builder(req.get_user() + " " + req.get_pass(), 200, "text/plain").string_response();
54+
}
55+
};
56+
57+
class digest_resource : public httpserver::http_resource
58+
{
59+
public:
60+
const httpserver::http_response render_GET(const httpserver::http_request& req)
61+
{
62+
if (req.get_digested_user() == "") {
63+
return httpserver::http_response_builder("FAIL").digest_auth_fail_response("test@example.com", MY_OPAQUE, true);
64+
}
65+
else
66+
{
67+
bool reload_nonce = false;;
68+
if(!req.check_digest_auth("test@example.com", "mypass", 300, reload_nonce))
69+
{
70+
return httpserver::http_response_builder("FAIL").digest_auth_fail_response("test@example.com", MY_OPAQUE, reload_nonce);
71+
}
72+
}
73+
return httpserver::http_response_builder("SUCCESS", 200, "text/plain").string_response();
74+
}
75+
};
76+
77+
LT_BEGIN_SUITE(authentication_suite)
78+
void set_up()
79+
{
80+
}
81+
82+
void tear_down()
83+
{
84+
}
85+
LT_END_SUITE(authentication_suite)
86+
87+
LT_BEGIN_AUTO_TEST(authentication_suite, base_auth)
88+
webserver ws = create_webserver(8080);
89+
90+
user_pass_resource* user_pass = new user_pass_resource();
91+
ws.register_resource("base", user_pass);
92+
ws.start(false);
93+
94+
curl_global_init(CURL_GLOBAL_ALL);
95+
std::string s;
96+
CURL *curl = curl_easy_init();
97+
CURLcode res;
98+
curl_easy_setopt(curl, CURLOPT_USERNAME, "myuser");
99+
curl_easy_setopt(curl, CURLOPT_PASSWORD, "mypass");
100+
curl_easy_setopt(curl, CURLOPT_URL, "localhost:8080/base");
101+
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
102+
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc);
103+
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s);
104+
res = curl_easy_perform(curl);
105+
LT_ASSERT_EQ(res, 0);
106+
LT_CHECK_EQ(s, "myuser mypass");
107+
curl_easy_cleanup(curl);
108+
109+
ws.stop();
110+
LT_END_AUTO_TEST(base_auth)
111+
112+
LT_BEGIN_AUTO_TEST(authentication_suite, digest_auth)
113+
webserver ws = create_webserver(8080)
114+
.digest_auth_random("myrandom")
115+
.nonce_nc_size(300);
116+
117+
digest_resource* digest = new digest_resource();
118+
ws.register_resource("base", digest);
119+
ws.start(false);
120+
121+
curl_global_init(CURL_GLOBAL_ALL);
122+
std::string s;
123+
CURL *curl = curl_easy_init();
124+
CURLcode res;
125+
curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
126+
curl_easy_setopt(curl, CURLOPT_USERPWD, "myuser:mypass");
127+
curl_easy_setopt(curl, CURLOPT_URL, "localhost:8080/base");
128+
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
129+
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc);
130+
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s);
131+
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 150L);
132+
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 150L);
133+
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
134+
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
135+
res = curl_easy_perform(curl);
136+
LT_ASSERT_EQ(res, 0);
137+
LT_CHECK_EQ(s, "SUCCESS");
138+
curl_easy_cleanup(curl);
139+
140+
ws.stop();
141+
LT_END_AUTO_TEST(digest_auth)
142+
143+
LT_BEGIN_AUTO_TEST(authentication_suite, digest_auth_wrong_pass)
144+
webserver ws = create_webserver(8080)
145+
.digest_auth_random("myrandom")
146+
.nonce_nc_size(300);
147+
148+
digest_resource* digest = new digest_resource();
149+
ws.register_resource("base", digest);
150+
ws.start(false);
151+
152+
curl_global_init(CURL_GLOBAL_ALL);
153+
std::string s;
154+
CURL *curl = curl_easy_init();
155+
CURLcode res;
156+
curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
157+
curl_easy_setopt(curl, CURLOPT_USERPWD, "myuser:wrongpass");
158+
curl_easy_setopt(curl, CURLOPT_URL, "localhost:8080/base");
159+
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
160+
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc);
161+
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s);
162+
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 150L);
163+
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 150L);
164+
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
165+
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
166+
res = curl_easy_perform(curl);
167+
LT_ASSERT_EQ(res, 0);
168+
LT_CHECK_EQ(s, "FAIL");
169+
curl_easy_cleanup(curl);
170+
171+
ws.stop();
172+
LT_END_AUTO_TEST(digest_auth_wrong_pass)
173+
174+
LT_BEGIN_AUTO_TEST_ENV()
175+
AUTORUN_TESTS()
176+
LT_END_AUTO_TEST_ENV()

0 commit comments

Comments
 (0)