aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2024-01-28 23:04:31 +0100
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2024-01-28 23:04:31 +0100
commitf7969b87492f612dddad4d746725962f225b5de4 (patch)
tree867664345a8e99b2870de295573b414e4b9010aa
parente981dee05ddcaf409275273c2c7ecf5460b1f927 (diff)
downloadlibmicrohttpd-f7969b87492f612dddad4d746725962f225b5de4.tar.gz
libmicrohttpd-f7969b87492f612dddad4d746725962f225b5de4.zip
digest_auth_example: updated and fixed
The example was updated to use the new digest auth API. Fixed run on W32.
-rw-r--r--src/examples/digest_auth_example.c134
1 files changed, 84 insertions, 50 deletions
diff --git a/src/examples/digest_auth_example.c b/src/examples/digest_auth_example.c
index 8d5a4041..7eaf60f1 100644
--- a/src/examples/digest_auth_example.c
+++ b/src/examples/digest_auth_example.c
@@ -1,7 +1,7 @@
1/* 1/*
2 This file is part of libmicrohttpd 2 This file is part of libmicrohttpd
3 Copyright (C) 2010 Christian Grothoff (and other contributing authors) 3 Copyright (C) 2010 Christian Grothoff (and other contributing authors)
4 Copyright (C) 2016-2022 Evgeny Grin (Karlson2k) 4 Copyright (C) 2016-2024 Evgeny Grin (Karlson2k)
5 5
6 This library is free software; you can redistribute it and/or 6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public 7 modify it under the terms of the GNU Lesser General Public
@@ -27,7 +27,12 @@
27#include "platform.h" 27#include "platform.h"
28#include <microhttpd.h> 28#include <microhttpd.h>
29#include <stdlib.h> 29#include <stdlib.h>
30#include <stdio.h>
30#include <errno.h> 31#include <errno.h>
32#if defined(_WIN32) && ! defined(__CYGWIN__)
33# include <wincrypt.h>
34#endif /* _WIN32 && ! __CYGWIN__ */
35
31 36
32#define PAGE \ 37#define PAGE \
33 "<html><head><title>libmicrohttpd demo</title></head>" \ 38 "<html><head><title>libmicrohttpd demo</title></head>" \
@@ -48,9 +53,10 @@ ahc_echo (void *cls,
48 const char *upload_data, size_t *upload_data_size, void **req_cls) 53 const char *upload_data, size_t *upload_data_size, void **req_cls)
49{ 54{
50 struct MHD_Response *response; 55 struct MHD_Response *response;
51 char *username; 56 /* Only one user has access to the page */
52 const char *password = "testpass"; 57 static const char *username = "testuser";
53 const char *realm = "test@example.com"; 58 static const char *password = "testpass";
59 static const char *realm = "test@example.com";
54 enum MHD_DigestAuthResult res_e; 60 enum MHD_DigestAuthResult res_e;
55 enum MHD_Result ret; 61 enum MHD_Result ret;
56 static int already_called_marker; 62 static int already_called_marker;
@@ -68,26 +74,17 @@ ahc_echo (void *cls,
68 return MHD_YES; 74 return MHD_YES;
69 } 75 }
70 76
71 username = MHD_digest_auth_get_username (connection); 77 /* No need to call MHD_digest_auth_get_username3() as the only
72 if (NULL == username) 78 * one user has an access. The username match is checked by
73 { 79 * MHD_digest_auth_check3() function. */
74 response = 80 res_e = MHD_digest_auth_check3 (
75 MHD_create_response_from_buffer_static (strlen (DENIED), 81 connection,
76 DENIED); 82 realm,
77 ret = MHD_queue_auth_fail_response2 (connection, realm, 83 username,
78 MY_OPAQUE_STR, 84 password,
79 response, 85 0, 0,
80 MHD_NO, 86 MHD_DIGEST_AUTH_MULT_QOP_ANY_NON_INT,
81 MHD_DIGEST_ALG_MD5); 87 MHD_DIGEST_AUTH_MULT_ALGO3_ANY_NON_SESSION);
82 MHD_destroy_response (response);
83 return ret;
84 }
85 res_e = MHD_digest_auth_check3 (connection, realm,
86 username,
87 password,
88 300, 60, MHD_DIGEST_AUTH_MULT_QOP_AUTH,
89 MHD_DIGEST_AUTH_MULT_ALGO3_MD5);
90 MHD_free (username);
91 if (res_e != MHD_DAUTH_OK) 88 if (res_e != MHD_DAUTH_OK)
92 { 89 {
93 response = 90 response =
@@ -95,12 +92,18 @@ ahc_echo (void *cls,
95 DENIED); 92 DENIED);
96 if (NULL == response) 93 if (NULL == response)
97 return MHD_NO; 94 return MHD_NO;
98 ret = MHD_queue_auth_fail_response2 (connection, realm, 95 ret = MHD_queue_auth_required_response3 (
99 MY_OPAQUE_STR, 96 connection,
100 response, 97 realm,
101 (res_e == MHD_DAUTH_NONCE_STALE) ? 98 MY_OPAQUE_STR,
102 MHD_YES : MHD_NO, 99 NULL,
103 MHD_DIGEST_ALG_MD5); 100 response,
101 (res_e == MHD_DAUTH_NONCE_STALE) ? MHD_YES : MHD_NO,
102 MHD_DIGEST_AUTH_MULT_QOP_ANY_NON_INT,
103 MHD_DIGEST_AUTH_MULT_ALGO3_ANY_NON_SESSION,
104 MHD_NO,
105 MHD_YES);
106
104 MHD_destroy_response (response); 107 MHD_destroy_response (response);
105 return ret; 108 return ret;
106 } 109 }
@@ -114,10 +117,7 @@ ahc_echo (void *cls,
114int 117int
115main (int argc, char *const *argv) 118main (int argc, char *const *argv)
116{ 119{
117 int fd;
118 char rnd[8]; 120 char rnd[8];
119 ssize_t len;
120 size_t off;
121 struct MHD_Daemon *d; 121 struct MHD_Daemon *d;
122 unsigned int port; 122 unsigned int port;
123 123
@@ -125,33 +125,67 @@ main (int argc, char *const *argv)
125 (1 != sscanf (argv[1], "%u", &port)) || 125 (1 != sscanf (argv[1], "%u", &port)) ||
126 (65535 < port) ) 126 (65535 < port) )
127 { 127 {
128 printf ("%s PORT\n", argv[0]); 128 fprintf (stderr, "%s PORT\n", argv[0]);
129 return 1; 129 return 1;
130 } 130 }
131 131
132 fd = open ("/dev/urandom", O_RDONLY); 132 if (1)
133 if (-1 == fd)
134 {
135 fprintf (stderr, "Failed to open `%s': %s\n",
136 "/dev/urandom",
137 strerror (errno));
138 return 1;
139 }
140 off = 0;
141 while (off < 8)
142 { 133 {
143 len = read (fd, rnd, 8); 134#if ! defined(_WIN32) || defined(__CYGWIN__)
144 if (0 > len) 135 int fd;
136 ssize_t len;
137 size_t off;
138
139 fd = open ("/dev/urandom", O_RDONLY);
140 if (-1 == fd)
145 { 141 {
146 fprintf (stderr, "Failed to read `%s': %s\n", 142 fprintf (stderr, "Failed to open `%s': %s\n",
147 "/dev/urandom", 143 "/dev/urandom",
148 strerror (errno)); 144 strerror (errno));
149 (void) close (fd);
150 return 1; 145 return 1;
151 } 146 }
152 off += (size_t) len; 147 for (off = 0; off < sizeof(rnd); off += (size_t) len)
148 {
149 len = read (fd, rnd, 8);
150 if (0 > len)
151 {
152 fprintf (stderr, "Failed to read `%s': %s\n",
153 "/dev/urandom",
154 strerror (errno));
155 (void) close (fd);
156 return 1;
157 }
158 }
159 (void) close (fd);
160#else /* Native W32 */
161 HCRYPTPROV cc;
162 BOOL b;
163
164 b = CryptAcquireContext (&cc,
165 NULL,
166 NULL,
167 PROV_RSA_FULL,
168 CRYPT_VERIFYCONTEXT);
169 if (FALSE == b)
170 {
171 fprintf (stderr,
172 "Failed to acquire crypto provider context: %lu\n",
173 (unsigned long) GetLastError ());
174 return 1;
175 }
176 b = CryptGenRandom (cc, sizeof(rnd), (BYTE *) rnd);
177 if (FALSE == b)
178 {
179 fprintf (stderr,
180 "Failed to generate 8 random bytes: %lu\n",
181 GetLastError ());
182 }
183 CryptReleaseContext (cc, 0);
184 if (FALSE == b)
185 return 1;
186#endif /* Native W32 */
153 } 187 }
154 (void) close (fd); 188
155 d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION 189 d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
156 | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG, 190 | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
157 (uint16_t) port, 191 (uint16_t) port,