mirror of
https://git.gnunet.org/libmicrohttpd.git
synced 2026-09-25 04:09:31 +03:00
add test for RFC 7616 and document new API
This commit is contained in:
@@ -1,3 +1,6 @@
|
||||
Sat Dec 8 22:53:56 CET 2018
|
||||
Added test for RFC 7616 and documented new API. -CG
|
||||
|
||||
Sat Dec 8 17:34:58 CET 2018
|
||||
Adding support for RFC 7616, experimental, needs
|
||||
testing and documentation still! -CG
|
||||
|
||||
+112
-16
@@ -2440,13 +2440,34 @@ client with a 401 HTTP status.
|
||||
@node microhttpd-dauth digest
|
||||
@section Using Digest Authentication
|
||||
|
||||
MHD supports MD5 (deprecated by IETF) and SHA-256 hash algorithms
|
||||
for digest authentication. The @code{MHD_DigestAuthAlgorithm} enumeration
|
||||
is used to specify which algorithm should be used.
|
||||
|
||||
@deftp {Enumeration} MHD_DigestAuthAlgorithm
|
||||
Which digest algorithm should be used. Must be used consistently.
|
||||
|
||||
@table @code
|
||||
@item MHD_DIGEST_ALG_AUTO
|
||||
Have MHD pick an algorithm currently considered secure. For now defaults to SHA-256.
|
||||
|
||||
@item MHD_DIGEST_ALG_MD5
|
||||
Force use of (deprecated, ancient, insecure) MD5.
|
||||
|
||||
@item MHD_DIGEST_ALG_SHA256
|
||||
Force use of SHA-256.
|
||||
|
||||
@end table
|
||||
@end deftp
|
||||
|
||||
|
||||
@deftypefun {char *} MHD_digest_auth_get_username (struct MHD_Connection *connection)
|
||||
Find and return a pointer to the username value from the request header.
|
||||
Return @code{NULL} if the value is not found or header does not exist.
|
||||
If returned value is not @code{NULL}, the value must be @code{MHD_free()}'ed.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun int MHD_digest_auth_check (struct MHD_Connection *connection, const char *realm, const char *username, const char *password, unsigned int nonce_timeout)
|
||||
@deftypefun int MHD_digest_auth_check2 (struct MHD_Connection *connection, const char *realm, const char *username, const char *password, unsigned int nonce_timeout, enum MHD_DigestAuthAlgorithm algo)
|
||||
Checks if the provided values in the WWW-Authenticate header are valid
|
||||
and sound according to RFC2716. If valid return @code{MHD_YES}, otherwise return @code{MHD_NO}.
|
||||
|
||||
@@ -2460,11 +2481,52 @@ most probably it will be the result of a lookup of the username against a local
|
||||
|
||||
@var{nonce_timeout} is the amount of time in seconds for a nonce to be invalid.
|
||||
Most of the time it is sound to specify 300 seconds as its values.
|
||||
|
||||
@var{algo} which digest algorithm should we use.
|
||||
@end deftypefun
|
||||
|
||||
|
||||
@deftypefun int MHD_digest_auth_check (struct MHD_Connection *connection, const char *realm, const char *username, const char *password, unsigned int nonce_timeout)
|
||||
Checks if the provided values in the WWW-Authenticate header are valid
|
||||
and sound according to RFC2716. If valid return @code{MHD_YES}, otherwise return @code{MHD_NO}.
|
||||
Deprecated, use @code{MHD_digest_auth_check2} instead.
|
||||
|
||||
|
||||
@var{realm} must reference to a zero-terminated string representing the realm.
|
||||
|
||||
@var{username} must reference to a zero-terminated string representing the username,
|
||||
it is usually the returned value from MHD_digest_auth_get_username.
|
||||
|
||||
@var{password} must reference to a zero-terminated string representing the password,
|
||||
most probably it will be the result of a lookup of the username against a local database.
|
||||
|
||||
@var{nonce_timeout} is the amount of time in seconds for a nonce to be invalid.
|
||||
Most of the time it is sound to specify 300 seconds as its values.
|
||||
@end deftypefun
|
||||
|
||||
|
||||
|
||||
@deftypefun int MHD_digest_auth_check_digest2 (struct MHD_Connection *connection, const char *realm, const char *username, const uint8_t *digest, unsigned int nonce_timeout, enum MHD_DigestAuthAlgorithm algo)
|
||||
Checks if the provided values in the WWW-Authenticate header are valid
|
||||
and sound according to RFC2716. If valid return @code{MHD_YES}, otherwise return @code{MHD_NO}.
|
||||
|
||||
@var{realm} must reference to a zero-terminated string representing the realm.
|
||||
|
||||
@var{username} must reference to a zero-terminated string representing the username,
|
||||
it is usually the returned value from MHD_digest_auth_get_username.
|
||||
|
||||
@var{digest} pointer to the binary MD5 sum for the precalculated hash value ``userame:realm:password''. The size must match the selected @var{algo}!
|
||||
|
||||
@var{nonce_timeout} is the amount of time in seconds for a nonce to be invalid.
|
||||
Most of the time it is sound to specify 300 seconds as its values.
|
||||
|
||||
@var{algo} digest authentication algorithm to use.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun int MHD_digest_auth_check_digest (struct MHD_Connection *connection, const char *realm, const char *username, const unsigned char digest[MHD_MD5_DIGEST_SIZE], unsigned int nonce_timeout)
|
||||
Checks if the provided values in the WWW-Authenticate header are valid
|
||||
and sound according to RFC2716. If valid return @code{MHD_YES}, otherwise return @code{MHD_NO}.
|
||||
Deprecated, use @code{MHD_digest_auth_check_digest2} instead.
|
||||
|
||||
@var{realm} must reference to a zero-terminated string representing the realm.
|
||||
|
||||
@@ -2477,6 +2539,31 @@ it is usually the returned value from MHD_digest_auth_get_username.
|
||||
Most of the time it is sound to specify 300 seconds as its values.
|
||||
@end deftypefun
|
||||
|
||||
|
||||
@deftypefun int MHD_queue_auth_fail_response2 (struct MHD_Connection *connection, const char *realm, const char *opaque, struct MHD_Response *response, int signal_stale, enum MHD_DigestAuthAlgorithm algo)
|
||||
Queues a response to request authentication from the client,
|
||||
return @code{MHD_YES} if successful, otherwise @code{MHD_NO}.
|
||||
|
||||
@var{realm} must reference to a zero-terminated string representing the realm.
|
||||
|
||||
@var{opaque} must reference to a zero-terminated string representing a value
|
||||
that gets passed to the client and expected to be passed again to the server
|
||||
as-is. This value can be a hexadecimal or base64 string.
|
||||
|
||||
@var{response} a response structure to specify what shall be presented to the
|
||||
client with a 401 HTTP status.
|
||||
|
||||
@var{signal_stale} a value that signals "stale=true" in the response header to
|
||||
indicate the invalidity of the nonce and no need to ask for authentication
|
||||
parameters and only a new nonce gets generated. @code{MHD_YES} to generate a new
|
||||
nonce, @code{MHD_NO} to ask for authentication parameters.
|
||||
|
||||
@var{algo} which digest algorithm should we use. The same algorithm
|
||||
must then be selected when checking digests received from clients!
|
||||
|
||||
@end deftypefun
|
||||
|
||||
|
||||
@deftypefun int MHD_queue_auth_fail_response (struct MHD_Connection *connection, const char *realm, const char *opaque, struct MHD_Response *response, int signal_stale)
|
||||
Queues a response to request authentication from the client,
|
||||
return @code{MHD_YES} if successful, otherwise @code{MHD_NO}.
|
||||
@@ -2517,23 +2604,27 @@ ahc_echo (void *cls,
|
||||
const char *realm = "test@@example.com";
|
||||
int ret;
|
||||
|
||||
username = MHD_digest_auth_get_username(connection);
|
||||
username = MHD_digest_auth_get_username (connection);
|
||||
if (username == NULL)
|
||||
@{
|
||||
response = MHD_create_response_from_buffer(strlen (DENIED),
|
||||
DENIED,
|
||||
MHD_RESPMEM_PERSISTENT);
|
||||
ret = MHD_queue_auth_fail_response(connection, realm,
|
||||
OPAQUE,
|
||||
response,
|
||||
MHD_NO);
|
||||
ret = MHD_queue_auth_fail_response2 (connection,
|
||||
realm,
|
||||
OPAQUE,
|
||||
response,
|
||||
MHD_NO,
|
||||
MHD_DIGEST_ALG_SHA256);
|
||||
MHD_destroy_response(response);
|
||||
return ret;
|
||||
@}
|
||||
ret = MHD_digest_auth_check(connection, realm,
|
||||
username,
|
||||
password,
|
||||
300);
|
||||
ret = MHD_digest_auth_check2 (connection,
|
||||
realm,
|
||||
username,
|
||||
password,
|
||||
300,
|
||||
MHD_DIGEST_ALG_SHA256);
|
||||
free(username);
|
||||
if ( (ret == MHD_INVALID_NONCE) ||
|
||||
(ret == MHD_NO) )
|
||||
@@ -2543,16 +2634,21 @@ ahc_echo (void *cls,
|
||||
MHD_RESPMEM_PERSISTENT);
|
||||
if (NULL == response)
|
||||
return MHD_NO;
|
||||
ret = MHD_queue_auth_fail_response(connection, realm,
|
||||
OPAQUE,
|
||||
response,
|
||||
(ret == MHD_INVALID_NONCE) ? MHD_YES : MHD_NO);
|
||||
ret = MHD_queue_auth_fail_response2 (connection,
|
||||
realm,
|
||||
OPAQUE,
|
||||
response,
|
||||
(ret == MHD_INVALID_NONCE) ? MHD_YES : MHD_NO,
|
||||
MHD_DIGEST_ALG_SHA256);
|
||||
MHD_destroy_response(response);
|
||||
return ret;
|
||||
@}
|
||||
response = MHD_create_response_from_buffer (strlen(PAGE), PAGE,
|
||||
response = MHD_create_response_from_buffer (strlen(PAGE),
|
||||
PAGE,
|
||||
MHD_RESPMEM_PERSISTENT);
|
||||
ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
|
||||
ret = MHD_queue_response (connection,
|
||||
MHD_HTTP_OK,
|
||||
response);
|
||||
MHD_destroy_response(response);
|
||||
return ret;
|
||||
@}
|
||||
|
||||
@@ -3331,7 +3331,7 @@ MHD_digest_auth_check_digest (struct MHD_Connection *connection,
|
||||
* @return #MHD_YES on success, #MHD_NO otherwise
|
||||
* @ingroup authentication
|
||||
*/
|
||||
int
|
||||
_MHD_EXTERN int
|
||||
MHD_queue_auth_fail_response2 (struct MHD_Connection *connection,
|
||||
const char *realm,
|
||||
const char *opaque,
|
||||
|
||||
@@ -104,4 +104,4 @@
|
||||
*.exe
|
||||
test_quiesce_stream
|
||||
test_large_put_inc11
|
||||
/test_delete
|
||||
/test_deletetest_digestauth_sha256
|
||||
|
||||
@@ -23,7 +23,7 @@ THREAD_ONLY_TESTS = \
|
||||
test_long_header11 \
|
||||
test_iplimit11 \
|
||||
test_termination \
|
||||
test_timeout
|
||||
test_timeout
|
||||
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ endif
|
||||
if ENABLE_DAUTH
|
||||
THREAD_ONLY_TESTS += \
|
||||
test_digestauth \
|
||||
test_digestauth_sha256 \
|
||||
test_digestauth_with_arguments
|
||||
endif
|
||||
|
||||
@@ -156,6 +157,12 @@ test_digestauth_LDADD = \
|
||||
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
|
||||
@LIBGCRYPT_LIBS@ @LIBCURL@
|
||||
|
||||
test_digestauth_sha256_SOURCES = \
|
||||
test_digestauth_sha256.c
|
||||
test_digestauth_sha256_LDADD = \
|
||||
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
|
||||
@LIBGCRYPT_LIBS@ @LIBCURL@
|
||||
|
||||
test_digestauth_with_arguments_SOURCES = \
|
||||
test_digestauth_with_arguments.c
|
||||
test_digestauth_with_arguments_LDADD = \
|
||||
|
||||
@@ -0,0 +1,314 @@
|
||||
/*
|
||||
This file is part of libmicrohttpd
|
||||
Copyright (C) 2010, 2018 Christian Grothoff
|
||||
|
||||
libmicrohttpd is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published
|
||||
by the Free Software Foundation; either version 2, or (at your
|
||||
option) any later version.
|
||||
|
||||
libmicrohttpd is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with libmicrohttpd; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file daemontest_digestauth_sha256.c
|
||||
* @brief Testcase for libmicrohttpd Digest Auth with SHA256
|
||||
* @author Amr Ali
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
|
||||
#include "MHD_config.h"
|
||||
#include "platform.h"
|
||||
#include <curl/curl.h>
|
||||
#include <microhttpd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#ifdef MHD_HTTPS_REQUIRE_GRYPT
|
||||
#ifdef HAVE_GCRYPT_H
|
||||
#include <gcrypt.h>
|
||||
#endif
|
||||
#endif /* MHD_HTTPS_REQUIRE_GRYPT */
|
||||
|
||||
#ifndef WINDOWS
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#include <wincrypt.h>
|
||||
#endif
|
||||
|
||||
#define PAGE "<html><head><title>libmicrohttpd demo</title></head><body>Access granted</body></html>"
|
||||
|
||||
#define DENIED "<html><head><title>libmicrohttpd demo</title></head><body>Access denied</body></html>"
|
||||
|
||||
#define MY_OPAQUE "11733b200778ce33060f31c9af70a870ba96ddd4"
|
||||
|
||||
struct CBC
|
||||
{
|
||||
char *buf;
|
||||
size_t pos;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
|
||||
static size_t
|
||||
copyBuffer (void *ptr,
|
||||
size_t size,
|
||||
size_t nmemb,
|
||||
void *ctx)
|
||||
{
|
||||
struct CBC *cbc = ctx;
|
||||
|
||||
if (cbc->pos + size * nmemb > cbc->size)
|
||||
return 0; /* overflow */
|
||||
memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
|
||||
cbc->pos += size * nmemb;
|
||||
return size * nmemb;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ahc_echo (void *cls,
|
||||
struct MHD_Connection *connection,
|
||||
const char *url,
|
||||
const char *method,
|
||||
const char *version,
|
||||
const char *upload_data,
|
||||
size_t *upload_data_size,
|
||||
void **unused)
|
||||
{
|
||||
struct MHD_Response *response;
|
||||
char *username;
|
||||
const char *password = "testpass";
|
||||
const char *realm = "test@example.com";
|
||||
int ret;
|
||||
(void)cls;(void)url; /* Unused. Silent compiler warning. */
|
||||
(void)method;(void)version;(void)upload_data; /* Unused. Silent compiler warning. */
|
||||
(void)upload_data_size;(void)unused; /* Unused. Silent compiler warning. */
|
||||
|
||||
username = MHD_digest_auth_get_username (connection);
|
||||
if ( (username == NULL) ||
|
||||
(0 != strcmp (username, "testuser")) )
|
||||
{
|
||||
response = MHD_create_response_from_buffer (strlen (DENIED),
|
||||
DENIED,
|
||||
MHD_RESPMEM_PERSISTENT);
|
||||
ret = MHD_queue_auth_fail_response2 (connection,
|
||||
realm,
|
||||
MY_OPAQUE,
|
||||
response,
|
||||
MHD_NO,
|
||||
MHD_DIGEST_ALG_SHA256);
|
||||
MHD_destroy_response(response);
|
||||
return ret;
|
||||
}
|
||||
ret = MHD_digest_auth_check2 (connection,
|
||||
realm,
|
||||
username,
|
||||
password,
|
||||
300,
|
||||
MHD_DIGEST_ALG_SHA256);
|
||||
free (username);
|
||||
if ( (ret == MHD_INVALID_NONCE) ||
|
||||
(ret == MHD_NO) )
|
||||
{
|
||||
response = MHD_create_response_from_buffer (strlen (DENIED),
|
||||
DENIED,
|
||||
MHD_RESPMEM_PERSISTENT);
|
||||
if (NULL == response)
|
||||
return MHD_NO;
|
||||
ret = MHD_queue_auth_fail_response2 (connection,
|
||||
realm,
|
||||
MY_OPAQUE,
|
||||
response,
|
||||
(MHD_INVALID_NONCE == ret) ? MHD_YES : MHD_NO,
|
||||
MHD_DIGEST_ALG_SHA256);
|
||||
MHD_destroy_response(response);
|
||||
return ret;
|
||||
}
|
||||
response = MHD_create_response_from_buffer (strlen(PAGE),
|
||||
PAGE,
|
||||
MHD_RESPMEM_PERSISTENT);
|
||||
ret = MHD_queue_response (connection,
|
||||
MHD_HTTP_OK,
|
||||
response);
|
||||
MHD_destroy_response (response);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
testDigestAuth ()
|
||||
{
|
||||
CURL *c;
|
||||
CURLcode errornum;
|
||||
struct MHD_Daemon *d;
|
||||
struct CBC cbc;
|
||||
char buf[2048];
|
||||
char rnd[8];
|
||||
int port;
|
||||
char url[128];
|
||||
#ifndef WINDOWS
|
||||
int fd;
|
||||
size_t len;
|
||||
size_t off = 0;
|
||||
#endif /* ! WINDOWS */
|
||||
|
||||
if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
|
||||
port = 0;
|
||||
else
|
||||
port = 1165;
|
||||
|
||||
cbc.buf = buf;
|
||||
cbc.size = 2048;
|
||||
cbc.pos = 0;
|
||||
#ifndef WINDOWS
|
||||
fd = open ("/dev/urandom",
|
||||
O_RDONLY);
|
||||
if (-1 == fd)
|
||||
{
|
||||
fprintf (stderr,
|
||||
"Failed to open `%s': %s\n",
|
||||
"/dev/urandom",
|
||||
strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
while (off < 8)
|
||||
{
|
||||
len = read (fd,
|
||||
rnd,
|
||||
8);
|
||||
if (len == (size_t)-1)
|
||||
{
|
||||
fprintf (stderr,
|
||||
"Failed to read `%s': %s\n",
|
||||
"/dev/urandom",
|
||||
strerror(errno));
|
||||
(void) close(fd);
|
||||
return 1;
|
||||
}
|
||||
off += len;
|
||||
}
|
||||
(void) close(fd);
|
||||
#else
|
||||
{
|
||||
HCRYPTPROV cc;
|
||||
BOOL b;
|
||||
|
||||
b = CryptAcquireContext (&cc,
|
||||
NULL,
|
||||
NULL,
|
||||
PROV_RSA_FULL,
|
||||
CRYPT_VERIFYCONTEXT);
|
||||
if (b == 0)
|
||||
{
|
||||
fprintf (stderr,
|
||||
"Failed to acquire crypto provider context: %lu\n",
|
||||
GetLastError ());
|
||||
return 1;
|
||||
}
|
||||
b = CryptGenRandom (cc, 8, (BYTE*)rnd);
|
||||
if (b == 0)
|
||||
{
|
||||
fprintf (stderr,
|
||||
"Failed to generate 8 random bytes: %lu\n",
|
||||
GetLastError ());
|
||||
}
|
||||
CryptReleaseContext (cc, 0);
|
||||
if (b == 0)
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
|
||||
port, NULL, NULL,
|
||||
&ahc_echo, PAGE,
|
||||
MHD_OPTION_DIGEST_AUTH_RANDOM, sizeof (rnd), rnd,
|
||||
MHD_OPTION_NONCE_NC_SIZE, 300,
|
||||
MHD_OPTION_END);
|
||||
if (d == NULL)
|
||||
return 1;
|
||||
if (0 == port)
|
||||
{
|
||||
const union MHD_DaemonInfo *dinfo;
|
||||
|
||||
dinfo = MHD_get_daemon_info (d,
|
||||
MHD_DAEMON_INFO_BIND_PORT);
|
||||
if ( (NULL == dinfo) ||
|
||||
(0 == dinfo->port) )
|
||||
{
|
||||
MHD_stop_daemon (d);
|
||||
return 32;
|
||||
}
|
||||
port = (int)dinfo->port;
|
||||
}
|
||||
snprintf (url,
|
||||
sizeof (url),
|
||||
"http://127.0.0.1:%d/bar%%20foo%%3Fkey%%3Dvalue",
|
||||
port);
|
||||
c = curl_easy_init ();
|
||||
curl_easy_setopt (c, CURLOPT_URL, url);
|
||||
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
|
||||
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
|
||||
curl_easy_setopt (c, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
|
||||
curl_easy_setopt (c, CURLOPT_USERPWD, "testuser:testpass");
|
||||
curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
|
||||
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
|
||||
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
|
||||
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
|
||||
/* NOTE: use of CONNECTTIMEOUT without also
|
||||
setting NOSIGNAL results in really weird
|
||||
crashes on my system!*/
|
||||
curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
|
||||
if (CURLE_OK != (errornum = curl_easy_perform (c)))
|
||||
{
|
||||
fprintf (stderr,
|
||||
"curl_easy_perform failed: `%s'\n",
|
||||
curl_easy_strerror (errornum));
|
||||
curl_easy_cleanup (c);
|
||||
MHD_stop_daemon (d);
|
||||
return 2;
|
||||
}
|
||||
curl_easy_cleanup (c);
|
||||
MHD_stop_daemon (d);
|
||||
if (cbc.pos != strlen (PAGE))
|
||||
return 4;
|
||||
if (0 != strncmp (PAGE, cbc.buf, strlen (PAGE)))
|
||||
return 8;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char *const *argv)
|
||||
{
|
||||
unsigned int errorCount = 0;
|
||||
curl_version_info_data *d = curl_version_info (CURLVERSION_NOW);
|
||||
(void)argc; (void)argv; /* Unused. Silent compiler warning. */
|
||||
|
||||
/* curl added SHA256 support in 7.57 = 7.0x39 */
|
||||
if (d->version_num < 0x073900)
|
||||
return 77; /* skip test, curl is too old */
|
||||
#ifdef MHD_HTTPS_REQUIRE_GRYPT
|
||||
#ifdef HAVE_GCRYPT_H
|
||||
gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
|
||||
#ifdef GCRYCTL_INITIALIZATION_FINISHED
|
||||
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
|
||||
#endif
|
||||
#endif
|
||||
#endif /* MHD_HTTPS_REQUIRE_GRYPT */
|
||||
if (0 != curl_global_init (CURL_GLOBAL_WIN32))
|
||||
return 2;
|
||||
errorCount += testDigestAuth ();
|
||||
if (errorCount != 0)
|
||||
fprintf (stderr, "Error (code: %u)\n", errorCount);
|
||||
curl_global_cleanup ();
|
||||
return errorCount != 0; /* 0 == pass */
|
||||
}
|
||||
Reference in New Issue
Block a user