1 /* This case tests abnormal cases. */
2 #include    "tx_api.h"
3 #include    "nx_api.h"
4 #include    "fx_api.h"
5 #include    "nx_web_http_client.h"
6 #include    "nx_web_http_server.h"
7 
8 extern void test_control_return(UINT);
9 
10 #if !defined(NX_DISABLE_IPV4)
11 
12 #ifdef NX_WEB_HTTPS_ENABLE
13 #include "test_device_cert.c"
14 #include "test_ca_cert.c"
15 #define ca_cert_der test_ca_cert_der
16 #define ca_cert_der_len test_ca_cert_der_len
17 #endif /* NX_WEB_HTTPS_ENABLE  */
18 
19 #define     DEMO_STACK_SIZE         4096
20 
21 /* Set up FileX and file memory resources. */
22 static CHAR             ram_disk_memory[4096];
23 static FX_MEDIA         ram_disk;
24 static UCHAR            media_memory[4096];
25 
26 static UCHAR            server_stack[16000];
27 
28 /* Define device drivers.  */
29 extern void _fx_ram_driver(FX_MEDIA *media_ptr);
30 extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr);
31 
32 /* Set up the HTTP client global variables. */
33 
34 #define         CLIENT_PACKET_SIZE  (NX_WEB_HTTP_CLIENT_MIN_PACKET_SIZE * 2)
35 
36 static TX_THREAD           client_thread;
37 static NX_PACKET_POOL      client_pool;
38 static NX_WEB_HTTP_CLIENT  my_client;
39 static NX_IP               client_ip;
40 static UINT                error_counter;
41 
42 /* Set up the HTTP server global variables */
43 
44 #define         SERVER_PACKET_SIZE  (NX_WEB_HTTP_SERVER_MIN_PACKET_SIZE * 2)
45 
46 static NX_WEB_HTTP_SERVER  my_server;
47 static NX_PACKET_POOL      server_pool;
48 static TX_THREAD           server_thread;
49 static NX_IP               server_ip;
50 static NXD_ADDRESS         server_ip_address;
51 static UINT                http_server_start = 0;
52 static UINT                http_client_stop = 0;
53 
54 static void thread_client_entry(ULONG thread_input);
55 static void thread_server_entry(ULONG thread_input);
56 
57 #define HTTP_SERVER_ADDRESS  IP_ADDRESS(1,2,3,4)
58 #define HTTP_CLIENT_ADDRESS  IP_ADDRESS(1,2,3,5)
59 
60 #ifdef NX_WEB_HTTPS_ENABLE
61 static UINT https_server_start = 0;
62 static UINT https_client_stop = 0;
63 static UINT loop = 2;
64 extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers;
65 static CHAR crypto_metadata_server[20000 * NX_WEB_HTTP_SERVER_SESSION_MAX];
66 static CHAR crypto_metadata_client[20000 * NX_WEB_HTTP_SERVER_SESSION_MAX];
67 static UCHAR tls_packet_buffer[18500];
68 static NX_SECURE_X509_CERT certificate;
69 static NX_SECURE_X509_CERT trusted_certificate;
70 static NX_SECURE_X509_CERT remote_certificate, remote_issuer;
71 static UCHAR remote_cert_buffer[2000];
72 static UCHAR remote_issuer_buffer[2000];
73 
74 static UINT tls_setup_callback(NX_WEB_HTTP_CLIENT *client_ptr, NX_SECURE_TLS_SESSION *tls_session);
75 #else
76 static UINT loop = 1;
77 #endif /* NX_WEB_HTTPS_ENABLE  */
78 
79 #ifdef CTEST
test_application_define(void * first_unused_memory)80 VOID test_application_define(void *first_unused_memory)
81 #else
82 void    netx_web_abnormal_test_application_define(void *first_unused_memory)
83 #endif
84 {
85 CHAR    *pointer;
86 UINT    status;
87 
88 
89     error_counter = 0;
90 
91     /* Setup the working pointer.  */
92     pointer =  (CHAR *) first_unused_memory;
93 
94     /* Create a helper thread for the server. */
95     tx_thread_create(&server_thread, "HTTP Server thread", thread_server_entry, 0,
96                      pointer, DEMO_STACK_SIZE,
97                      NX_WEB_HTTP_SERVER_PRIORITY, NX_WEB_HTTP_SERVER_PRIORITY, TX_NO_TIME_SLICE, TX_AUTO_START);
98 
99     pointer =  pointer + DEMO_STACK_SIZE;
100 
101     /* Initialize the NetX system.  */
102     nx_system_initialize();
103 
104     /* Create the server packet pool.  */
105     status =  nx_packet_pool_create(&server_pool, "HTTP Server Packet Pool", SERVER_PACKET_SIZE,
106                                     pointer, SERVER_PACKET_SIZE*8);
107     pointer = pointer + SERVER_PACKET_SIZE * 8;
108     if (status)
109         error_counter++;
110 
111     /* Create an IP instance.  */
112     status = nx_ip_create(&server_ip, "HTTP Server IP", HTTP_SERVER_ADDRESS,
113                           0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024,
114                           pointer, 4096, 1);
115     pointer =  pointer + 4096;
116     if (status)
117         error_counter++;
118 
119     /* Enable ARP and supply ARP cache memory for the server IP instance.  */
120     status = nx_arp_enable(&server_ip, (void *) pointer, 1024);
121     pointer = pointer + 1024;
122     if (status)
123         error_counter++;
124 
125 
126      /* Enable TCP traffic.  */
127     status = nx_tcp_enable(&server_ip);
128     if (status)
129         error_counter++;
130 
131     /* Create the HTTP Client thread. */
132     status = tx_thread_create(&client_thread, "HTTP Client", thread_client_entry, 0,
133                               pointer, DEMO_STACK_SIZE,
134                               NX_WEB_HTTP_SERVER_PRIORITY + 2, NX_WEB_HTTP_SERVER_PRIORITY + 2, TX_NO_TIME_SLICE, TX_AUTO_START);
135     pointer =  pointer + DEMO_STACK_SIZE;
136     if (status)
137         error_counter++;
138 
139     /* Create the Client packet pool.  */
140     status =  nx_packet_pool_create(&client_pool, "HTTP Client Packet Pool", CLIENT_PACKET_SIZE,
141                                     pointer, CLIENT_PACKET_SIZE*8);
142     pointer = pointer + CLIENT_PACKET_SIZE * 8;
143     if (status)
144         error_counter++;
145 
146     /* Create an IP instance.  */
147     status = nx_ip_create(&client_ip, "HTTP Client IP", HTTP_CLIENT_ADDRESS,
148                           0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024,
149                           pointer, 2048, 1);
150     pointer =  pointer + 2048;
151     if (status)
152         error_counter++;
153 
154     status  = nx_arp_enable(&client_ip, (void *) pointer, 1024);
155     pointer =  pointer + 2048;
156     if (status)
157         error_counter++;
158 
159      /* Enable TCP traffic.  */
160     status = nx_tcp_enable(&client_ip);
161     if (status)
162         error_counter++;
163 }
164 
165 #ifdef NX_WEB_HTTPS_ENABLE
166 /* Define the TLS setup callback function.  */
tls_setup_callback(NX_WEB_HTTP_CLIENT * client_ptr,NX_SECURE_TLS_SESSION * tls_session)167 static UINT tls_setup_callback(NX_WEB_HTTP_CLIENT *client_ptr, NX_SECURE_TLS_SESSION *tls_session)
168 {
169 UINT status;
170 
171 
172     /* Initialize and create TLS session.  */
173     status = nx_secure_tls_session_create(tls_session, &nx_crypto_tls_ciphers, crypto_metadata_client, sizeof(crypto_metadata_client));
174 
175     /* Check status.  */
176     if (status)
177     {
178         return(status);
179     }
180 
181     /* Allocate space for packet reassembly.  */
182     status = nx_secure_tls_session_packet_buffer_set(&(client_ptr -> nx_web_http_client_tls_session), tls_packet_buffer, sizeof(tls_packet_buffer));
183 
184     /* Check status.  */
185     if (status)
186     {
187         return(status);
188     }
189 
190     /* Add a CA Certificate to our trusted store for verifying incoming server certificates.  */
191     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);
192     nx_secure_tls_trusted_certificate_add(&(client_ptr -> nx_web_http_client_tls_session), &trusted_certificate);
193 
194     /* Need to allocate space for the certificate coming in from the remote host.  */
195     nx_secure_tls_remote_certificate_allocate(&(client_ptr -> nx_web_http_client_tls_session), &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer));
196     nx_secure_tls_remote_certificate_allocate(&(client_ptr -> nx_web_http_client_tls_session), &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer));
197 
198     return(NX_SUCCESS);
199 }
200 #endif /* NX_WEB_HTTPS_ENABLE  */
201 
thread_client_entry(ULONG thread_input)202 void thread_client_entry(ULONG thread_input)
203 {
204 UINT            i;
205 UINT            status;
206 NX_PACKET       *recv_packet;
207 
208 
209     /* Give IP task and driver a chance to initialize the system.  */
210     tx_thread_sleep(NX_IP_PERIODIC_RATE);
211 
212     /* Set server IP address.  */
213     server_ip_address.nxd_ip_address.v4 = HTTP_SERVER_ADDRESS;
214     server_ip_address.nxd_ip_version = NX_IP_VERSION_V4;
215 
216     /* First loop test HTTP, second loop test HTTPS.  */
217     for (i = 0; i < loop ; i++)
218     {
219         if (i == 0)
220         {
221 
222             /* Wait HTTP server started.  */
223             while(!http_server_start)
224             {
225                 tx_thread_sleep(NX_IP_PERIODIC_RATE);
226             }
227         }
228 #ifdef NX_WEB_HTTPS_ENABLE
229         else
230         {
231 
232             /* Wait HTTPS server started.  */
233             while(!https_server_start)
234             {
235                 tx_thread_sleep(NX_IP_PERIODIC_RATE);
236             }
237         }
238 #endif
239 
240         /* Create an HTTP client instance.  */
241         status = nx_web_http_client_create(&my_client, "HTTP Client", &client_ip, &client_pool, 1536);
242 
243         /* Check status.  */
244         if (status)
245             error_counter++;
246 
247         /* Connect to server.  */
248         if (i == 0)
249         {
250             status = nx_web_http_client_connect(&my_client, &server_ip_address, NX_WEB_HTTP_SERVER_PORT, NX_WAIT_FOREVER);
251         }
252 #ifdef NX_WEB_HTTPS_ENABLE
253         else
254         {
255             status = nx_web_http_client_secure_connect(&my_client, &server_ip_address, NX_WEB_HTTPS_SERVER_PORT,
256                                                        tls_setup_callback, NX_WAIT_FOREVER);
257         }
258 #endif /* NX_WEB_HTTPS_ENABLE  */
259 
260         /* Check status.  */
261         if (status)
262             error_counter++;
263 
264         /* Abnormal case: Request packet is NULL, should return error.  */
265         status = nx_web_http_client_request_header_add(&my_client, "", 0, "", 0, NX_NO_WAIT);
266         if (status != NX_WEB_HTTP_ERROR)
267             error_counter++;
268 
269         /* Abnormal case: Request packet is NULL, should return error.  */
270         status = nx_web_http_client_request_send(&my_client, NX_NO_WAIT);
271         if (status != NX_WEB_HTTP_ERROR)
272             error_counter++;
273 
274         /* Abnormal case: Request packet isn't sent, should return error.  */
275         status = nx_web_http_client_response_body_get(&my_client, &recv_packet, NX_NO_WAIT);
276         if (status != NX_WEB_HTTP_ERROR)
277             error_counter++;
278 
279         /* Initialize the request.  */
280         status = nx_web_http_client_request_initialize(&my_client, NX_WEB_HTTP_METHOD_GET, "/test.txt", "1.2.3.4",
281                                                        0, NX_FALSE, "", "", NX_WAIT_FOREVER);
282 
283         /* Check status.  */
284         if (status)
285             error_counter++;
286 
287         /* Abnorml case: Duplicate initialize, the old request packet should be released.  */
288         status = nx_web_http_client_request_initialize(&my_client, NX_WEB_HTTP_METHOD_GET, "/test.txt", "1.2.3.4",
289                                                        0, NX_FALSE, "", "", NX_WAIT_FOREVER);
290 
291         /* Check status.  */
292         if (status)
293             error_counter++;
294 
295         /* Send the request.  */
296         status = nx_web_http_client_request_send(&my_client, NX_WAIT_FOREVER);
297 
298         /* Check status.  */
299         if (status)
300             error_counter++;
301 
302        /* Get response from server.  */
303         while(1)
304         {
305             status = nx_web_http_client_response_body_get(&my_client, &recv_packet, 1 * NX_IP_PERIODIC_RATE);
306 
307             if (status)
308                 break;
309             else
310                 nx_packet_release(recv_packet);
311         }
312 
313         /* Check status.  */
314         if (status != NX_WEB_HTTP_GET_DONE)
315             error_counter++;
316         else
317             nx_packet_release(recv_packet);
318 
319         /* Abnorml case: Error basic authorization field.  */
320         status = nx_web_http_client_request_initialize(&my_client, NX_WEB_HTTP_METHOD_GET, "/test.txt", "1.2.3.4",
321                                                        0, NX_FALSE, NX_NULL, NX_NULL, NX_WAIT_FOREVER);
322 
323         /* Check status.  */
324         if (status)
325             error_counter++;
326 
327         /* Add error basic authorization field. The correct string should be "Basic Og==".  */
328         status = nx_web_http_client_request_header_add(&my_client, "Authorization", 13, "Bassc OgOg", 10, NX_NO_WAIT);
329         if (status)
330             error_counter++;
331 
332         /* Send the request.  */
333         status = nx_web_http_client_request_send(&my_client, NX_WAIT_FOREVER);
334 
335         /* Check status.  */
336         if (status)
337             error_counter++;
338 
339        /* Get response from server.  */
340         while(1)
341         {
342             status = nx_web_http_client_response_body_get(&my_client, &recv_packet, 1 * NX_IP_PERIODIC_RATE);
343 
344             if (status)
345                 break;
346             else
347                 nx_packet_release(recv_packet);
348         }
349 
350         /* Check status.  */
351         if (status != NX_WEB_HTTP_STATUS_CODE_UNAUTHORIZED)
352             error_counter++;
353 
354         if (recv_packet)
355             nx_packet_release(recv_packet);
356 
357         status = nx_web_http_client_delete(&my_client);
358         if (status)
359             error_counter++;
360 
361         /* Set the flag.  */
362         if (i == 0)
363         {
364             http_client_stop = 1;
365         }
366 #ifdef NX_WEB_HTTPS_ENABLE
367         else
368         {
369             https_client_stop = 1;
370         }
371 #endif /* NX_WEB_HTTPS_ENABLE  */
372     }
373 }
374 
375 /* Define the application's authentication check.  This is called by
376    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)377 static UINT  authentication_check(NX_WEB_HTTP_SERVER *server_ptr, UINT request_type,
378                                   CHAR *resource, CHAR **name, CHAR **password, CHAR **realm)
379 {
380 
381     /* Just use a simple name, password, and realm for all
382        requests and resources.  */
383     *name =     "";
384     *password = "";
385     *realm =    "NetX Duo HTTP demo";
386 
387     /* Request basic authentication.  */
388     return(NX_WEB_HTTP_BASIC_AUTHENTICATE);
389 }
390 
391 /* Define the helper HTTP server thread.  */
thread_server_entry(ULONG thread_input)392 void    thread_server_entry(ULONG thread_input)
393 {
394 UINT            i;
395 UINT            status;
396 FX_FILE         my_file;
397 UINT            server_port = NX_WEB_HTTP_SERVER_PORT;
398 
399 
400     /* Print out test information banner.  */
401     printf("NetX Test:   Web Abnormal Test.........................................");
402 
403     /* Check for earlier error.  */
404     if(error_counter)
405     {
406         printf("ERROR!\n");
407         test_control_return(1);
408     }
409 
410     fx_media_format(&ram_disk,
411                     _fx_ram_driver,               // Driver entry
412                     ram_disk_memory,              // RAM disk memory pointer
413                     media_memory,                 // Media buffer pointer
414                     sizeof(media_memory),         // Media buffer size
415                     "MY_RAM_DISK",                // Volume Name
416                     1,                            // Number of FATs
417                     32,                           // Directory Entries
418                     0,                            // Hidden sectors
419                     256,                          // Total sectors
420                     512,                          // Sector size
421                     8,                            // Sectors per cluster
422                     1,                            // Heads
423                     1);                           // Sectors per track
424 
425     /* Open the RAM disk.  */
426     status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, media_memory, sizeof(media_memory)) ;
427     status += fx_file_create(&ram_disk, "TEST.TXT");
428     status += fx_file_open(&ram_disk, &my_file, "TEST.TXT", FX_OPEN_FOR_WRITE);
429     status += fx_file_write(&my_file, "https server", 12);
430     status += fx_file_close(&my_file);
431     if(status)
432         error_counter++;
433 
434     /* Give NetX a chance to initialize the system.  */
435     tx_thread_sleep(NX_IP_PERIODIC_RATE);
436 
437     /* First loop test HTTP, second loop test HTTPS.  */
438     for (i = 0; i < loop; i++)
439     {
440 
441         if (i == 1)
442         {
443             server_port = NX_WEB_HTTPS_SERVER_PORT;
444         }
445 
446         /* Create the HTTP Server. */
447         status = nx_web_http_server_create(&my_server, "My HTTP Server", &server_ip, server_port, &ram_disk,
448                                            &server_stack, sizeof(server_stack), &server_pool,
449                                            authentication_check, NX_NULL);
450         if (status)
451             error_counter++;
452 
453 #ifdef NX_WEB_HTTPS_ENABLE
454         /* Set TLS for HTTPS.  */
455         if (i == 1)
456         {
457             /* Initialize device certificate (used for all sessions in HTTPS server).  */
458             memset(&certificate, 0, sizeof(certificate));
459             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);
460 
461             /* Setup TLS session data for the TCP server.  */
462             status = nx_web_http_server_secure_configure(&my_server, &nx_crypto_tls_ciphers,
463                                                          crypto_metadata_server, sizeof(crypto_metadata_server), tls_packet_buffer, sizeof(tls_packet_buffer),
464                                                          &certificate, NX_NULL, 0, NX_NULL, 0, NX_NULL, 0);
465             if (status)
466                 error_counter++;
467         }
468 #endif /* NX_WEB_HTTPS_ENABLE  */
469 
470         /* OK to start the HTTP Server.  */
471         status = nx_web_http_server_start(&my_server);
472         if (status)
473             error_counter++;
474 
475         /* Set the flag.  */
476         if (i == 0)
477         {
478             http_server_start = 1;
479 
480             /* Wait HTTP test finished.  */
481             while(!http_client_stop)
482             {
483                 tx_thread_sleep(NX_IP_PERIODIC_RATE);
484             }
485         }
486 #ifdef NX_WEB_HTTPS_ENABLE
487         else
488         {
489             https_server_start = 1;
490 
491             /* Wait HTTPS test finished.  */
492             while(!https_client_stop)
493             {
494                 tx_thread_sleep(NX_IP_PERIODIC_RATE);
495             }
496         }
497 #endif /* NX_WEB_HTTPS_ENABLE  */
498 
499         status = nx_web_http_server_delete(&my_server);
500         if (status)
501             error_counter++;
502     }
503 
504     /* Check packet pool.  */
505     if (server_pool.nx_packet_pool_available != server_pool.nx_packet_pool_total)
506     {
507         error_counter++;
508     }
509 
510     if (client_pool.nx_packet_pool_available != client_pool.nx_packet_pool_total)
511     {
512         error_counter++;
513     }
514 
515     if(error_counter)
516     {
517         printf("ERROR!\n");
518         test_control_return(1);
519     }
520     else
521     {
522         printf("SUCCESS!\n");
523         test_control_return(0);
524     }
525 }
526 #else
527 
528 #ifdef CTEST
test_application_define(void * first_unused_memory)529 VOID test_application_define(void *first_unused_memory)
530 #else
531 void    netx_web_abnormal_test_application_define(void *first_unused_memory)
532 #endif
533 {
534 
535     /* Print out test information banner.  */
536     printf("NetX Test:   Web Abnormal Test.........................................N/A\n");
537 
538     test_control_return(3);
539 }
540 #endif
541 
542