1 /* This case tests digest authentication.
2  HA1 = MD5("name:NetX Duo HTTP demo:password")
3      = 01bb2595c9221423951ee86f3573b465
4  HA2 = MD5("GET:/index.htm")
5      = d4b1da8c7955d2e98bc56ffc93003b44
6  Response = MD5("01bb2595c9221423951ee86f3573b465:
7                  nonce:
8                  00000001:0a4f113b:auth:
9                  d4b1da8c7955d2e98bc56ffc93003b44")
10  */
11 #include    "tx_api.h"
12 #include    "nx_api.h"
13 #include    "fx_api.h"
14 #include    "nx_web_http_client.h"
15 #include    "nx_web_http_server.h"
16 
17 extern void test_control_return(UINT);
18 
19 #if !defined(NX_DISABLE_IPV4) && defined(NX_WEB_HTTP_DIGEST_ENABLE) && !defined(NX_WEB_HTTP_KEEPALIVE_DISABLE)
20 
21 #include "http_digest_authentication.c"
22 
23 #include "test_device_cert.c"
24 #include "test_ca_cert.c"
25 #define ca_cert_der test_ca_cert_der
26 #define ca_cert_der_len test_ca_cert_der_len
27 
28 #define     DEMO_STACK_SIZE         4096
29 
30 /* Set up FileX and file memory resources. */
31 static CHAR             ram_disk_memory[4096];
32 static FX_MEDIA         ram_disk;
33 static UCHAR            media_memory[4096];
34 
35 static UCHAR            server_stack[16000];
36 
37 /* Define device drivers.  */
38 extern void _fx_ram_driver(FX_MEDIA *media_ptr);
39 extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr);
40 
41 /* Set up the HTTP client global variables. */
42 
43 #define         CLIENT_PACKET_SIZE  (NX_WEB_HTTP_CLIENT_MIN_PACKET_SIZE * 2)
44 
45 static TX_THREAD           client_thread;
46 static NX_PACKET_POOL      client_pool;
47 static NX_WEB_HTTP_CLIENT  my_client;
48 static NX_IP               client_ip;
49 static UINT                error_counter;
50 
51 /* Set up the HTTP server global variables */
52 
53 #define         SERVER_PACKET_SIZE  (NX_WEB_HTTP_SERVER_MIN_PACKET_SIZE * 2)
54 
55 static NX_WEB_HTTP_SERVER  my_server;
56 static NX_PACKET_POOL      server_pool;
57 static TX_THREAD           server_thread;
58 static NX_IP               server_ip;
59 static NXD_ADDRESS         server_ip_address;
60 static UINT                http_server_start = 0;
61 static UINT                http_client_stop = 0;
62 
63 static void thread_client_entry(ULONG thread_input);
64 static void thread_server_entry(ULONG thread_input);
65 
66 #define HTTP_SERVER_ADDRESS  IP_ADDRESS(1,2,3,4)
67 #define HTTP_CLIENT_ADDRESS  IP_ADDRESS(1,2,3,5)
68 
69 #ifdef NX_WEB_HTTPS_ENABLE
70 static UINT                https_server_start = 0;
71 static UINT                https_client_stop = 0;
72 static UINT loop = 2;
73 extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers;
74 static CHAR crypto_metadata_server[20000 * NX_WEB_HTTP_SERVER_SESSION_MAX];
75 static CHAR crypto_metadata_client[20000 * NX_WEB_HTTP_SERVER_SESSION_MAX];
76 static UCHAR tls_packet_buffer[18500];
77 static NX_SECURE_X509_CERT certificate;
78 static NX_SECURE_X509_CERT trusted_certificate;
79 static NX_SECURE_X509_CERT remote_certificate, remote_issuer;
80 static UCHAR remote_cert_buffer[2000];
81 static UCHAR remote_issuer_buffer[2000];
82 static UINT tls_setup_callback(NX_WEB_HTTP_CLIENT *client_ptr, NX_SECURE_TLS_SESSION *tls_session);
83 #else
84 static UINT loop = 1;
85 #endif /* NX_WEB_HTTPS_ENABLE  */
86 
87 
88 static UINT  authentication_check(NX_WEB_HTTP_SERVER *server_ptr, UINT request_type,
89                                   CHAR *resource, CHAR **name, CHAR **password, CHAR **realm);
90 extern UINT _nx_web_http_client_receive(NX_WEB_HTTP_CLIENT *client_ptr, NX_PACKET **packet_ptr, ULONG wait_option);
91 
92 static CHAR nonce_buffer[NX_WEB_HTTP_SERVER_NONCE_SIZE + 1];
93 static CHAR response_buffer[32 + 1];
94 static NX_MD5 client_md5data;
95 
96 static char pkt[] = {
97 0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x20, /* GET /index.htm  */
98 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, /* HTTP/1.1.. */
99 };
100 
101 #ifdef CTEST
test_application_define(void * first_unused_memory)102 VOID test_application_define(void *first_unused_memory)
103 #else
104 void    netx_web_digest_authenticate_test_application_define(void *first_unused_memory)
105 #endif
106 {
107 CHAR    *pointer;
108 UINT    status;
109 
110 
111     error_counter = 0;
112 
113     /* Setup the working pointer.  */
114     pointer =  (CHAR *) first_unused_memory;
115 
116     /* Create a helper thread for the server. */
117     tx_thread_create(&server_thread, "HTTP Server thread", thread_server_entry, 0,
118                      pointer, DEMO_STACK_SIZE,
119                      NX_WEB_HTTP_SERVER_PRIORITY, NX_WEB_HTTP_SERVER_PRIORITY, TX_NO_TIME_SLICE, TX_AUTO_START);
120 
121     pointer =  pointer + DEMO_STACK_SIZE;
122 
123     /* Initialize the NetX system.  */
124     nx_system_initialize();
125 
126     /* Create the server packet pool.  */
127     status =  nx_packet_pool_create(&server_pool, "HTTP Server Packet Pool", SERVER_PACKET_SIZE,
128                                     pointer, SERVER_PACKET_SIZE*8);
129     pointer = pointer + SERVER_PACKET_SIZE * 8;
130     if (status)
131         error_counter++;
132 
133     /* Create an IP instance.  */
134     status = nx_ip_create(&server_ip, "HTTP Server IP", HTTP_SERVER_ADDRESS,
135                           0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024,
136                           pointer, 4096, 1);
137     pointer =  pointer + 4096;
138     if (status)
139         error_counter++;
140 
141     /* Enable ARP and supply ARP cache memory for the server IP instance.  */
142     status = nx_arp_enable(&server_ip, (void *) pointer, 1024);
143     pointer = pointer + 1024;
144     if (status)
145         error_counter++;
146 
147 
148      /* Enable TCP traffic.  */
149     status = nx_tcp_enable(&server_ip);
150     if (status)
151         error_counter++;
152 
153     /* Create the HTTP Client thread. */
154     status = tx_thread_create(&client_thread, "HTTP Client", thread_client_entry, 0,
155                               pointer, DEMO_STACK_SIZE,
156                               NX_WEB_HTTP_SERVER_PRIORITY + 2, NX_WEB_HTTP_SERVER_PRIORITY + 2, TX_NO_TIME_SLICE, TX_AUTO_START);
157     pointer =  pointer + DEMO_STACK_SIZE;
158     if (status)
159         error_counter++;
160 
161     /* Create the Client packet pool.  */
162     status =  nx_packet_pool_create(&client_pool, "HTTP Client Packet Pool", CLIENT_PACKET_SIZE,
163                                     pointer, CLIENT_PACKET_SIZE*8);
164     pointer = pointer + CLIENT_PACKET_SIZE * 8;
165     if (status)
166         error_counter++;
167 
168     /* Create an IP instance.  */
169     status = nx_ip_create(&client_ip, "HTTP Client IP", HTTP_CLIENT_ADDRESS,
170                           0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024,
171                           pointer, 2048, 1);
172     pointer =  pointer + 2048;
173     if (status)
174         error_counter++;
175 
176     status  = nx_arp_enable(&client_ip, (void *) pointer, 1024);
177     pointer =  pointer + 2048;
178     if (status)
179         error_counter++;
180 
181      /* Enable TCP traffic.  */
182     status = nx_tcp_enable(&client_ip);
183     if (status)
184         error_counter++;
185 }
186 
187 #ifdef NX_WEB_HTTPS_ENABLE
188 /* Define the TLS setup callback function.  */
tls_setup_callback(NX_WEB_HTTP_CLIENT * client_ptr,NX_SECURE_TLS_SESSION * tls_session)189 static UINT tls_setup_callback(NX_WEB_HTTP_CLIENT *client_ptr, NX_SECURE_TLS_SESSION *tls_session)
190 {
191 UINT status;
192 
193 
194     /* Initialize and create TLS session.  */
195     status = nx_secure_tls_session_create(tls_session, &nx_crypto_tls_ciphers, crypto_metadata_client, sizeof(crypto_metadata_client));
196 
197     /* Check status.  */
198     if (status)
199     {
200         return(status);
201     }
202 
203     /* Allocate space for packet reassembly.  */
204     status = nx_secure_tls_session_packet_buffer_set(&(client_ptr -> nx_web_http_client_tls_session), tls_packet_buffer, sizeof(tls_packet_buffer));
205 
206     /* Check status.  */
207     if (status)
208     {
209         return(status);
210     }
211 
212     /* Add a CA Certificate to our trusted store for verifying incoming server certificates.  */
213     nx_secure_x509_certificate_initialize(&trusted_certificate, ca_cert_der, ca_cert_der_len, NX_NULL, 0, NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE);
214     nx_secure_tls_trusted_certificate_add(&(client_ptr -> nx_web_http_client_tls_session), &trusted_certificate);
215 
216     /* Need to allocate space for the certificate coming in from the remote host.  */
217     nx_secure_tls_remote_certificate_allocate(&(client_ptr -> nx_web_http_client_tls_session), &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer));
218     nx_secure_tls_remote_certificate_allocate(&(client_ptr -> nx_web_http_client_tls_session), &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer));
219 
220     return(NX_SUCCESS);
221 }
222 #endif /* NX_WEB_HTTPS_ENABLE  */
223 
thread_client_entry(ULONG thread_input)224 void thread_client_entry(ULONG thread_input)
225 {
226 UINT            i;
227 UINT            status;
228 NX_PACKET       *recv_packet;
229 CHAR            *buffer_ptr;
230 
231 
232     /* Give IP task and driver a chance to initialize the system.  */
233     tx_thread_sleep(NX_IP_PERIODIC_RATE);
234 
235     /* Set server IP address.  */
236     server_ip_address.nxd_ip_address.v4 = HTTP_SERVER_ADDRESS;
237     server_ip_address.nxd_ip_version = NX_IP_VERSION_V4;
238 
239     /* First loop test HTTP, second loop test HTTPS.  */
240     for (i = 0; i < loop ; i++)
241     {
242         if (i == 0)
243         {
244 
245             /* Wait HTTP server started.  */
246             while(!http_server_start)
247             {
248                 tx_thread_sleep(NX_IP_PERIODIC_RATE);
249             }
250         }
251 #ifdef NX_WEB_HTTPS_ENABLE
252         else
253         {
254 
255             /* Wait HTTPS server started.  */
256             while(!https_server_start)
257             {
258                 tx_thread_sleep(NX_IP_PERIODIC_RATE);
259             }
260         }
261 #endif /* NX_WEB_HTTPS_ENABLE  */
262 
263         /* Create an HTTP client instance.  */
264         status = nx_web_http_client_create(&my_client, "HTTP Client", &client_ip, &client_pool, 1536);
265 
266         /* Check status.  */
267         if (status)
268             error_counter++;
269 
270         /* Connect to server.  */
271         if (i == 0)
272         {
273             status = nx_web_http_client_connect(&my_client, &server_ip_address, NX_WEB_HTTP_SERVER_PORT, NX_WAIT_FOREVER);
274 
275             /* Check status.  */
276             if (status)
277                 error_counter++;
278         }
279 #ifdef NX_WEB_HTTPS_ENABLE
280         else
281         {
282             status = nx_web_http_client_secure_connect(&my_client, &server_ip_address, NX_WEB_HTTPS_SERVER_PORT,
283                                                        tls_setup_callback, NX_WAIT_FOREVER);
284 
285             /* Check status.  */
286             if (status)
287                 error_counter++;
288         }
289 #endif /* NX_WEB_HTTPS_ENABLE  */
290 
291         /* Initialize the request.  */
292         status = nx_web_http_client_request_initialize(&my_client, NX_WEB_HTTP_METHOD_GET, "/index.htm", "1.2.3.4",
293                                                        0, NX_FALSE, NX_NULL, NX_NULL, NX_WAIT_FOREVER);
294 
295         /* Check status.  */
296         if (status)
297             error_counter++;
298 
299         /* Initialize the buffer.  */
300         memset(nonce_buffer, 0, sizeof(nonce_buffer));
301         memset(response_buffer, 0, sizeof(response_buffer));
302 
303         /* Send the request.  */
304         status = nx_web_http_client_request_send(&my_client, NX_WAIT_FOREVER);
305 
306         /* Check status.  */
307         if (status)
308             error_counter++;
309 
310         /* Pickup the response from the Server.  */
311         if (i == 0)
312         {
313             status = nx_tcp_socket_receive(&my_client.nx_web_http_client_socket, &recv_packet, NX_WAIT_FOREVER);
314         }
315         else
316         {
317             status = nx_secure_tls_session_receive(&my_client.nx_web_http_client_tls_session, &recv_packet, NX_WAIT_FOREVER);
318         }
319 
320         /* Check status.  */
321         if (status)
322             error_counter++;
323         else
324         {
325             status = http_nonce_retrieve(recv_packet, nonce_buffer);
326             if (status)
327                 error_counter++;
328             nx_packet_release(recv_packet);
329         }
330 
331         http_digest_response_calculate(&client_md5data, "name", "NetX Duo HTTP demo", "password", nonce_buffer, "GET",
332                                        "/index.htm", "00000001", "0a4f113b", response_buffer);
333 
334         /* Initialize the request.  */
335         status = nx_web_http_client_request_initialize(&my_client, NX_WEB_HTTP_METHOD_GET, "/index.htm", "1.2.3.4",
336                                                        0, NX_FALSE, NX_NULL, NX_NULL, NX_WAIT_FOREVER);
337 
338         /* Check status.  */
339         if (status)
340             error_counter++;
341 
342         /* Build the Authorization header.  */
343         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, "Authorization: Digest", 21, &client_pool, NX_WAIT_FOREVER);
344         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, " username=\"name\",", 17, &client_pool, NX_WAIT_FOREVER);
345         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, " realm=\"NetX Duo HTTP demo\",", 28, &client_pool, NX_WAIT_FOREVER);
346         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, " nonce=\"", 8, &client_pool, NX_WAIT_FOREVER);
347         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, nonce_buffer, NX_WEB_HTTP_SERVER_NONCE_SIZE, &client_pool, NX_WAIT_FOREVER);
348         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, "\",", 2, &client_pool, NX_WAIT_FOREVER);
349         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, " uri=\"/index.htm\",", 17, &client_pool, NX_WAIT_FOREVER);
350         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, " qop=auth,", 10, &client_pool, NX_WAIT_FOREVER);
351         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, " nc=00000001,", 13, &client_pool, NX_WAIT_FOREVER);
352         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, " cnonce=\"0a4f113b\",", 19, &client_pool, NX_WAIT_FOREVER);
353         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, " response=\"", 11, &client_pool, NX_WAIT_FOREVER);
354         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, response_buffer, 32, &client_pool, NX_WAIT_FOREVER);
355         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, "\",", 2, &client_pool, NX_WAIT_FOREVER);
356         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, " opaque=\"5ccc069c403ebaf9f0171e9517f40e41\"\r\n", 44, &client_pool, NX_WAIT_FOREVER);
357 
358         /* Send the request.  */
359         status = nx_web_http_client_request_send(&my_client, NX_WAIT_FOREVER);
360 
361         /* Check status.  */
362         if (status)
363             error_counter++;
364 
365         /* Receive the response from http server.  */
366         status = nx_web_http_client_response_body_get(&my_client, &recv_packet, 1 * NX_IP_PERIODIC_RATE);
367         if(status != NX_WEB_HTTP_GET_DONE)
368             error_counter++;
369         else
370             nx_packet_release(recv_packet);
371 
372         /* Connect to server.  */
373         if (i == 0)
374         {
375             status = nx_web_http_client_connect(&my_client, &server_ip_address, NX_WEB_HTTP_SERVER_PORT, NX_WAIT_FOREVER);
376 
377             /* Check status.  */
378             if (status)
379                 error_counter++;
380         }
381 #ifdef NX_WEB_HTTPS_ENABLE
382         else
383         {
384             status = nx_web_http_client_secure_connect(&my_client, &server_ip_address, NX_WEB_HTTPS_SERVER_PORT,
385                                                        tls_setup_callback, NX_WAIT_FOREVER);
386 
387             /* Check status.  */
388             if (status)
389                 error_counter++;
390         }
391 #endif /* NX_WEB_HTTPS_ENABLE  */
392 
393         memset(response_buffer, 0, sizeof(response_buffer));
394         http_digest_response_calculate(&client_md5data, "name", "NetX Duo HTTP demo", "password", nonce_buffer, "DELETE",
395                                        "/index.htm", "00000001", "0a4f113b", response_buffer);
396 
397         /* Initialize the request for delete.  */
398         status = nx_web_http_client_request_initialize(&my_client, NX_WEB_HTTP_METHOD_DELETE, "/index.htm", "1.2.3.4",
399                                                        0, NX_FALSE, "name", "password", NX_WAIT_FOREVER);
400 
401         /* Check status.  */
402         if (status)
403             error_counter++;
404 
405         /* Build the Authorization header.  */
406         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, "Authorization: Digest", 21, &client_pool, NX_WAIT_FOREVER);
407         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, " username=\"name\",", 17, &client_pool, NX_WAIT_FOREVER);
408         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, " realm=\"NetX Duo HTTP demo\",", 28, &client_pool, NX_WAIT_FOREVER);
409         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, " nonce=\"", 8, &client_pool, NX_WAIT_FOREVER);
410         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, nonce_buffer, NX_WEB_HTTP_SERVER_NONCE_SIZE, &client_pool, NX_WAIT_FOREVER);
411         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, "\",", 2, &client_pool, NX_WAIT_FOREVER);
412         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, " uri=\"/index.htm\",", 17, &client_pool, NX_WAIT_FOREVER);
413         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, " qop=auth,", 10, &client_pool, NX_WAIT_FOREVER);
414         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, " nc=00000001,", 13, &client_pool, NX_WAIT_FOREVER);
415         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, " cnonce=\"0a4f113b\",", 19, &client_pool, NX_WAIT_FOREVER);
416         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, " response=\"", 11, &client_pool, NX_WAIT_FOREVER);
417         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, response_buffer, 32, &client_pool, NX_WAIT_FOREVER);
418         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, "\",", 2, &client_pool, NX_WAIT_FOREVER);
419         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, " opaque=\"5ccc069c403ebaf9f0171e9517f40e41\"\r\n", 44, &client_pool, NX_WAIT_FOREVER);
420 
421         /* Send the request.  */
422         status = nx_web_http_client_request_send(&my_client, NX_WAIT_FOREVER);
423 
424         /* Check status.  */
425         if (status)
426             error_counter++;
427 
428         /* Receive the response from http server.  */
429         status = nx_web_http_client_response_body_get(&my_client, &recv_packet, 1 * NX_IP_PERIODIC_RATE);
430         if(status != NX_WEB_HTTP_GET_DONE)
431             error_counter++;
432         else
433             nx_packet_release(recv_packet);
434 
435 
436         /* Connect to server.  */
437         if (i == 0)
438         {
439             status = nx_web_http_client_connect(&my_client, &server_ip_address, NX_WEB_HTTP_SERVER_PORT, NX_WAIT_FOREVER);
440 
441             /* Check status.  */
442             if (status)
443                 error_counter++;
444         }
445 #ifdef NX_WEB_HTTPS_ENABLE
446         else
447         {
448             status = nx_web_http_client_secure_connect(&my_client, &server_ip_address, NX_WEB_HTTPS_SERVER_PORT,
449                                                        tls_setup_callback, NX_WAIT_FOREVER);
450 
451             /* Check status.  */
452             if (status)
453                 error_counter++;
454         }
455 #endif /* NX_WEB_HTTPS_ENABLE  */
456 
457         /* Initialize the request.  */
458         status = nx_web_http_client_request_initialize(&my_client, NX_WEB_HTTP_METHOD_GET, "/index.htm", "1.2.3.4",
459                                                        0, NX_FALSE, NX_NULL, NX_NULL, NX_WAIT_FOREVER);
460 
461         /* Check status.  */
462         if (status)
463             error_counter++;
464 
465         /* Initialize the buffer.  */
466         memset(nonce_buffer, 0, sizeof(nonce_buffer));
467         memset(response_buffer, 0, sizeof(response_buffer));
468 
469         /* Send the request.  */
470         status = nx_web_http_client_request_send(&my_client, NX_WAIT_FOREVER);
471 
472         /* Check status.  */
473         if (status)
474             error_counter++;
475 
476         /* Pickup the response from the Server.  */
477         if (i == 0)
478         {
479             status = nx_tcp_socket_receive(&my_client.nx_web_http_client_socket, &recv_packet, NX_WAIT_FOREVER);
480         }
481         else
482         {
483             status = nx_secure_tls_session_receive(&my_client.nx_web_http_client_tls_session, &recv_packet, NX_WAIT_FOREVER);
484         }
485 
486         /* Check status.  */
487         if (status)
488             error_counter++;
489         else
490         {
491             status = http_nonce_retrieve(recv_packet, nonce_buffer);
492             if (status)
493                 error_counter++;
494             nx_packet_release(recv_packet);
495         }
496 
497         /* Use error password to generate "response".  */
498         http_digest_response_calculate(&client_md5data, "name", "NetX Duo HTTP demo", "pass", nonce_buffer, "GET",
499                                        "/index.htm", "00000001", "0a4f113b", response_buffer);
500 
501         /* Initialize the request.  */
502         status = nx_web_http_client_request_initialize(&my_client, NX_WEB_HTTP_METHOD_GET, "/index.htm", "1.2.3.4",
503                                                        0, NX_FALSE, NX_NULL, NX_NULL, NX_WAIT_FOREVER);
504 
505         /* Check status.  */
506         if (status)
507             error_counter++;
508 
509         /* Build the Authorization header.  */
510         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, "Authorization: Digest", 21, &client_pool, NX_WAIT_FOREVER);
511         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, " username=\"name\",", 17, &client_pool, NX_WAIT_FOREVER);
512         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, " realm=\"NetX Duo HTTP demo\",", 28, &client_pool, NX_WAIT_FOREVER);
513         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, " nonce=\"", 8, &client_pool, NX_WAIT_FOREVER);
514         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, nonce_buffer, NX_WEB_HTTP_SERVER_NONCE_SIZE, &client_pool, NX_WAIT_FOREVER);
515         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, "\",", 2, &client_pool, NX_WAIT_FOREVER);
516         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, " uri=\"/index.htm\",", 17, &client_pool, NX_WAIT_FOREVER);
517         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, " qop=auth,", 10, &client_pool, NX_WAIT_FOREVER);
518         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, " nc=00000001,", 13, &client_pool, NX_WAIT_FOREVER);
519         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, " cnonce=\"0a4f113b\",", 19, &client_pool, NX_WAIT_FOREVER);
520         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, " response=\"", 11, &client_pool, NX_WAIT_FOREVER);
521         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, response_buffer, 32, &client_pool, NX_WAIT_FOREVER);
522         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, "\",", 2, &client_pool, NX_WAIT_FOREVER);
523         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, " opaque=\"5ccc069c403ebaf9f0171e9517f40e41\"\r\n", 44, &client_pool, NX_WAIT_FOREVER);
524 
525         /* Send the request.  */
526         status = nx_web_http_client_request_send(&my_client, NX_WAIT_FOREVER);
527 
528         /* Check status.  */
529         if (status)
530             error_counter++;
531 
532         /* Receive the response from http server.  */
533         status = _nx_web_http_client_receive(&my_client, &recv_packet, 1 * NX_IP_PERIODIC_RATE);
534         if(status)
535             error_counter++;
536         else
537         {
538             buffer_ptr = (CHAR *)recv_packet -> nx_packet_prepend_ptr;
539 
540             /* Check the status, If authentication failed , it should be 401. */
541             if((buffer_ptr[9] != '4') || (buffer_ptr[10] != '0') || (buffer_ptr[11] != '1'))
542                 error_counter++;
543 
544             nx_packet_release(recv_packet);
545         }
546 
547         status = nx_web_http_client_delete(&my_client);
548         if (status)
549             error_counter++;
550 
551         /* Set the flag.  */
552         if (i == 0)
553         {
554             http_client_stop = 1;
555         }
556 #ifdef NX_WEB_HTTPS_ENABLE
557         else
558         {
559             https_client_stop = 1;
560         }
561 #endif /* NX_WEB_HTTPS_ENABLE  */
562     }
563 }
564 
565 /* Define the helper HTTP server thread.  */
thread_server_entry(ULONG thread_input)566 void    thread_server_entry(ULONG thread_input)
567 {
568 UINT            i;
569 UINT            status;
570 FX_FILE         my_file;
571 UINT            server_port = NX_WEB_HTTP_SERVER_PORT;
572 
573 
574     /* Print out test information banner.  */
575     printf("NetX Test:   Web Digest Authenticate Test..............................");
576 
577     /* Check for earlier error.  */
578     if(error_counter)
579     {
580         printf("ERROR!\n");
581         test_control_return(1);
582     }
583 
584     fx_media_format(&ram_disk,
585                     _fx_ram_driver,               // Driver entry
586                     ram_disk_memory,              // RAM disk memory pointer
587                     media_memory,                 // Media buffer pointer
588                     sizeof(media_memory),         // Media buffer size
589                     "MY_RAM_DISK",                // Volume Name
590                     1,                            // Number of FATs
591                     32,                           // Directory Entries
592                     0,                            // Hidden sectors
593                     256,                          // Total sectors
594                     512,                          // Sector size
595                     8,                            // Sectors per cluster
596                     1,                            // Heads
597                     1);                           // Sectors per track
598 
599     /* Open the RAM disk.  */
600     status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, media_memory, sizeof(media_memory)) ;
601     if(status)
602         error_counter++;
603 
604     /* Give NetX a chance to initialize the system.  */
605     tx_thread_sleep(NX_IP_PERIODIC_RATE);
606 
607     /* First loop test HTTP, second loop test HTTPS.  */
608     for (i = 0; i < loop; i++)
609     {
610         status = fx_file_create(&ram_disk, "index.htm");
611         status += fx_file_open(&ram_disk, &my_file, "index.htm", FX_OPEN_FOR_WRITE);
612         status += fx_file_write(&my_file, "https server", 12);
613         status += fx_file_close(&my_file);
614         if(status)
615             error_counter++;
616 
617         if (i == 1)
618         {
619             server_port = NX_WEB_HTTPS_SERVER_PORT;
620         }
621 
622         /* Create the HTTP Server. */
623         status = nx_web_http_server_create(&my_server, "My HTTP Server", &server_ip, server_port, &ram_disk,
624                                            &server_stack, sizeof(server_stack), &server_pool,
625                                            authentication_check, NX_NULL);
626         if (status)
627             error_counter++;
628 
629 #ifdef NX_WEB_HTTPS_ENABLE
630         /* Set TLS for HTTPS.  */
631         if (i == 1)
632         {
633             /* Initialize device certificate (used for all sessions in HTTPS server).  */
634             memset(&certificate, 0, sizeof(certificate));
635             nx_secure_x509_certificate_initialize(&certificate, test_device_cert_der, test_device_cert_der_len, NX_NULL, 0, test_device_cert_key_der, test_device_cert_key_der_len, NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER);
636 
637             /* Setup TLS session data for the TCP server.  */
638             status = nx_web_http_server_secure_configure(&my_server, &nx_crypto_tls_ciphers,
639                                                          crypto_metadata_server, sizeof(crypto_metadata_server), tls_packet_buffer, sizeof(tls_packet_buffer),
640                                                          &certificate, NX_NULL, 0, NX_NULL, 0, NX_NULL, 0);
641             if (status)
642                 error_counter++;
643         }
644 #endif /* NX_WEB_HTTPS_ENABLE  */
645 
646         /* OK to start the HTTP Server.  */
647         status = nx_web_http_server_start(&my_server);
648         if (status)
649             error_counter++;
650 
651         /* Set the flag.  */
652         if (i == 0)
653         {
654             http_server_start = 1;
655 
656             /* Wait HTTP test finished.  */
657             while(!http_client_stop)
658             {
659                 tx_thread_sleep(NX_IP_PERIODIC_RATE);
660             }
661         }
662 #ifdef NX_WEB_HTTPS_ENABLE
663         else
664         {
665             https_server_start = 1;
666 
667             /* Wait HTTPS test finished.  */
668             while(!https_client_stop)
669             {
670                 tx_thread_sleep(NX_IP_PERIODIC_RATE);
671             }
672         }
673 #endif /* NX_WEB_HTTPS_ENABLE  */
674 
675         status = nx_web_http_server_delete(&my_server);
676         if (status)
677             error_counter++;
678     }
679 
680     /* Check packet pool.  */
681     if (server_pool.nx_packet_pool_available != server_pool.nx_packet_pool_total)
682     {
683         error_counter++;
684     }
685 
686     if (client_pool.nx_packet_pool_available != client_pool.nx_packet_pool_total)
687     {
688         error_counter++;
689     }
690 
691     if(error_counter)
692     {
693         printf("ERROR!\n");
694         test_control_return(1);
695     }
696     else
697     {
698         printf("SUCCESS!\n");
699         test_control_return(0);
700     }
701 }
702 
703 /* Define the application's authentication check.  This is called by
704    the HTTP server whenever a new request is received.  */
authentication_check(NX_WEB_HTTP_SERVER * server_ptr,UINT request_type,CHAR * resource,CHAR ** name,CHAR ** password,CHAR ** realm)705 static UINT  authentication_check(NX_WEB_HTTP_SERVER *server_ptr, UINT request_type,
706                                   CHAR *resource, CHAR **name, CHAR **password, CHAR **realm)
707 {
708 
709     /* Just use a simple name, password, and realm for all
710        requests and resources.  */
711     *name =     "name";
712     *password = "password";
713     *realm =    "NetX Duo HTTP demo";
714 
715     /* Request basic authentication.  */
716     return(NX_WEB_HTTP_DIGEST_AUTHENTICATE);
717 }
718 #else
719 
720 #ifdef CTEST
test_application_define(void * first_unused_memory)721 VOID test_application_define(void *first_unused_memory)
722 #else
723 void    netx_web_digest_authenticate_test_application_define(void *first_unused_memory)
724 #endif
725 {
726 
727     /* Print out test information banner.  */
728     printf("NetX Test:   Web Digest Authenticate Test..............................N/A\n");
729 
730     test_control_return(3);
731 }
732 #endif
733 
734