1 #include    "tx_api.h"
2 #include    "nx_api.h"
3 #include    "nxd_ftp_client.h"
4 
5 extern   void  test_control_return(UINT);
6 
7 #if !defined(NX_DISABLE_IPV4) && !defined(NX_DISABLE_LOOPBACK_INTERFACE)
8 
9 #define     DEMO_STACK_SIZE         2048
10 #define     PACKET_PAYLOAD          1536
11 
12 
13 /* Define the ThreadX, NetX, and FileX object control blocks...  */
14 
15 static NX_TCP_SOCKET           server_socket;
16 static TX_THREAD               client_thread;
17 static TX_THREAD               server_thread;
18 static NX_PACKET_POOL          client_pool;
19 static NX_IP                   client_ip;
20 
21 /* Define the NetX FTP object control block.  */
22 
23 static NX_FTP_CLIENT           ftp_client;
24 
25 
26 /* Define the counters used in the demo application...  */
27 
28 static  UINT            error_counter = 0;
29 static  UINT            client_thread_done = NX_FALSE;
30 
31 
32 #define FTP_SERVER_ADDRESS  IP_ADDRESS(127,0,0,1)
33 #define FTP_CLIENT_ADDRESS  IP_ADDRESS(1,2,3,5)
34 
35 #define     SERVER_PORT                 21
36 #define     SERVER_PASSIVE_PORT1        21017
37 #define     SERVER_PASSIVE_PORT2        21018
38 
39 
40 static  void   server_thread_entry(ULONG thread_input);
41 static  void   client_thread_entry(ULONG thread_input);
42 static  UINT   nx_ftp_response_packet_send(NX_TCP_SOCKET *server_socket, ULONG packet_type, UCHAR *data, UINT data_size);
43 
44 extern   void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr);
45 
46 
47 /* There are for logging in */
48 static UCHAR welcome_220_response_1[27] = {
49 0x32, 0x32, 0x30, 0x2d, 0x4d, 0x69, 0x63, 0x72,  /* 220-Micr */
50 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x46, 0x54,  /* osoft FT */
51 0x50, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,  /* PServic  */
52 0x65, 0x0d, 0x0a                                 /* e..      */
53 };
54 
55 static UINT welcome_220_response_1_size = 27;
56 
57 static UCHAR welcome_220_response_2[21] = {
58 0x32, 0x32, 0x30, 0x20, 0x57, 0x69, 0x6e, 0x68, /* 220 Winh */
59 0x6f, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x20, /* ost.com  */
60 0x46, 0x54, 0x50, 0x0d, 0x0a                    /* FTP..    */
61 };
62 
63 static UINT welcome_220_response_2_size = 21;
64 
65 static UCHAR password_request_331[23] = {
66 0x33, 0x33, 0x31, 0x20, 0x50, 0x61, 0x73, 0x73, /* 331 Pass */
67 0x77, 0x6f, 0x72, 0x64, 0x20, 0x72, 0x65, 0x71, /* word req */
68 0x75, 0x69, 0x72, 0x65, 0x64, 0x0d, 0x0a        /* uired.. */
69 };
70 
71 static UINT password_request_331_size = 23;
72 
73 static UCHAR logged_in_230_response[21] = {
74 0x32, 0x33, 0x30, 0x20, 0x55, 0x73, 0x65, 0x72, /* 230 User */
75 0x20, 0x6c, 0x6f, 0x67, 0x67, 0x65, 0x64, 0x20, /*  logged  */
76 0x69, 0x6e, 0x2e, 0x0d, 0x0a                    /* in... */
77 };
78 
79 static UINT logged_in_230_response_size = 21;
80 
81 /* Define what the initial system looks like.  */
82 
83 #ifdef CTEST
test_application_define(void * first_unused_memory)84 VOID test_application_define(void *first_unused_memory)
85 #else
86 void    netx_ftp_client_buffer_overflow_test_application_define(void *first_unused_memory)
87 #endif
88 {
89 
90 UINT    status;
91 UCHAR   *pointer;
92 
93 
94     /* Setup the working pointer.  */
95     pointer =  (UCHAR *) first_unused_memory;
96 
97     /* Initialize NetX.  */
98     nx_system_initialize();
99 
100     /* Set up the FTP Server. */
101 
102     /* Create the main FTP server thread.  */
103     status = tx_thread_create(&server_thread, "FTP Server thread ", server_thread_entry, 0,
104                               pointer, DEMO_STACK_SIZE,
105                               6, 6, TX_NO_TIME_SLICE, TX_AUTO_START);
106 
107     pointer = pointer + DEMO_STACK_SIZE ;
108 
109     /* Check status.  */
110     if (status != NX_SUCCESS)
111     {
112         error_counter++;
113         return;
114     }
115 
116 
117     /* Set up the FTP Client. */
118 
119     /* Create the main FTP client thread.  */
120     status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0,
121                               pointer, DEMO_STACK_SIZE,
122                               6, 6, TX_NO_TIME_SLICE, TX_AUTO_START);
123 
124     pointer = pointer + DEMO_STACK_SIZE ;
125 
126     /* Check status.  */
127     if (status != NX_SUCCESS)
128     {
129         error_counter++;
130         return;
131     }
132 
133     /* Create a packet pool for the FTP client.  */
134     status =  nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", PACKET_PAYLOAD, pointer, 25*PACKET_PAYLOAD);
135 
136         /* Check status.  */
137     if (status != NX_SUCCESS)
138     {
139         error_counter++;
140         return;
141     }
142 
143     pointer =  pointer + 25*PACKET_PAYLOAD;
144 
145     /* Create an IP instance for the FTP client.  */
146     status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL,
147                           &client_pool, _nx_ram_network_driver_1024, pointer, DEMO_STACK_SIZE, 1);
148 
149         /* Check status.  */
150     if (status != NX_SUCCESS)
151     {
152         error_counter++;
153         return;
154     }
155 
156     pointer = pointer + DEMO_STACK_SIZE;
157 
158     /* Enable ARP and supply ARP cache memory for the FTP Client IP.  */
159     nx_arp_enable(&client_ip, (void *) pointer, 1024);
160 
161     pointer = pointer + 1024;
162 
163     /* Enable TCP for client IP instance.  */
164     nx_tcp_enable(&client_ip);
165     nx_icmp_enable(&client_ip);
166 
167     return;
168 
169 }
170 
171 /* Define the FTP client thread.  */
172 
client_thread_entry(ULONG thread_input)173 void    client_thread_entry(ULONG thread_input)
174 {
175 
176 UINT        status;
177 
178     /* Let the server set up. */
179     tx_thread_sleep(20);
180 
181     NX_PARAMETER_NOT_USED(thread_input);
182 
183     /* Create an FTP client.  */
184     status =  nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool);
185 
186     /* Check status.  */
187     if (status != NX_SUCCESS)
188     {
189 
190         error_counter++;
191      }
192 
193     /* Now connect with the NetX FTP (IPv4) server on the control socket. */
194     status =  nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "equenet0_alpha1", "29Pi2A792N", 500);
195 
196     /* Check status.  */
197     if (status != NX_SUCCESS)
198     {
199 
200         error_counter++;
201      }
202 
203     /* Delete the FTP client.  */
204     nx_ftp_client_disconnect(&ftp_client, 0);
205     nx_ftp_client_delete(&ftp_client);
206 
207     client_thread_done = NX_TRUE;
208 }
209 
210 
211 /* Define the helper FTP server thread.  */
server_thread_entry(ULONG thread_input)212 void    server_thread_entry(ULONG thread_input)
213 {
214 
215 UINT         status;
216 NX_PACKET   *my_packet;
217 
218     /* Print out test information banner.  */
219     printf("NetX Test:   FTP Client Buffer Overflow Test...........................");
220 
221     /* Check for earlier error. */
222     if(error_counter)
223     {
224         printf("ERROR!\n");
225         test_control_return(1);
226     }
227 
228     /* Create a TCP socket as the FTP server.  */
229     status = nx_tcp_socket_create(&client_ip, &server_socket, "Socket Server", NX_IP_NORMAL, NX_FRAGMENT_OKAY,
230                                   NX_IP_TIME_TO_LIVE, 2048, NX_NULL, NX_NULL);
231 
232     /* Check status.  */
233     if (status)
234     {
235         error_counter++;
236     }
237 
238     /* Bind the TCP socket to the FTP control port.  */
239     status =  nx_tcp_server_socket_listen(&client_ip, SERVER_PORT, &server_socket, 5, NX_NULL);
240 
241     /* Check status.  */
242     if (status)
243     {
244         error_counter++;
245     }
246 
247     /* Wait for a connection request.  */
248     status =  nx_tcp_server_socket_accept(&server_socket, 10 * NX_IP_PERIODIC_RATE);
249 
250     /* Check status.  */
251     if (status)
252     {
253         error_counter++;
254     }
255 
256     /* Send welcome response.  */
257     if (nx_ftp_response_packet_send(&server_socket, (client_pool.nx_packet_pool_payload_size - welcome_220_response_1_size) & 0xFFFFFFFC,
258                                     welcome_220_response_1, welcome_220_response_1_size))
259     {
260         error_counter++;
261     }
262 
263     if (nx_ftp_response_packet_send(&server_socket, (client_pool.nx_packet_pool_payload_size - welcome_220_response_2_size) & 0xFFFFFFFC,
264                                     welcome_220_response_2, welcome_220_response_2_size))
265     {
266         error_counter++;
267     }
268 
269     /* Receive USER request message.  */
270     status =  nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE);
271 
272     /* Check status.  */
273     if ((status) || (memcmp(my_packet ->nx_packet_prepend_ptr, "USER equenet0_alpha1", sizeof("USER equenet0_alpha1") - 1)))
274     {
275         error_counter++;
276     }
277     else
278     {
279 
280         /* Release the packet.  */
281         nx_packet_release(my_packet);
282     }
283 
284     /* Send password required message.  */
285     if (nx_ftp_response_packet_send(&server_socket, (client_pool.nx_packet_pool_payload_size - password_request_331_size) & 0xFFFFFFFC,
286                                     password_request_331, password_request_331_size))
287     {
288         error_counter++;
289     }
290 
291     /* Receive PASS request message.  */
292     status =  nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE);
293 
294     /* Check status.  */
295     if ((status) || (memcmp(my_packet ->nx_packet_prepend_ptr, "PASS 29Pi2A792N", sizeof("USER 29Pi2A792N") - 1)))
296     {
297         error_counter++;
298     }
299     else
300     {
301 
302         /* Release the packet.  */
303         nx_packet_release(my_packet);
304     }
305 
306     /* Send logged in message.  */
307     if (nx_ftp_response_packet_send(&server_socket, (client_pool.nx_packet_pool_payload_size - password_request_331_size) & 0xFFFFFFFC,
308                                     logged_in_230_response, logged_in_230_response_size))
309     {
310         error_counter++;
311     }
312 
313     /* Wait for client thread.  */
314     while (client_thread_done == NX_FALSE)
315     {
316         tx_thread_sleep(NX_IP_PERIODIC_RATE);
317     }
318 
319     nx_tcp_socket_disconnect(&server_socket, 0);
320     nx_tcp_socket_delete(&server_socket);
321 
322     /* Make sure the packet pool is not corrupted.  */
323     while (client_pool.nx_packet_pool_available)
324     {
325         if (nx_packet_allocate(&client_pool, &my_packet, 0, NX_NO_WAIT) ||
326             (my_packet -> nx_packet_pool_owner != &client_pool))
327         {
328 
329             error_counter++;
330             break;
331         }
332     }
333 
334     /* Check for error.  */
335     if (error_counter)
336     {
337 
338         printf("ERROR!\n");
339         test_control_return(1);
340     }
341     else
342     {
343 
344         printf("SUCCESS!\n");
345         test_control_return(0);
346     };
347 
348     return;
349 
350 }
351 
nx_ftp_response_packet_send(NX_TCP_SOCKET * server_socket,ULONG packet_type,UCHAR * data,UINT data_size)352 static UINT   nx_ftp_response_packet_send(NX_TCP_SOCKET *server_socket, ULONG packet_type, UCHAR *data, UINT data_size)
353 {
354 
355 UINT        status;
356 NX_PACKET   *response_packet;
357 
358 
359     /* Allocate a response packet.  */
360     status =  nx_packet_allocate(&client_pool, &response_packet, packet_type, TX_WAIT_FOREVER);
361 
362     /* Check status.  */
363     if (status)
364     {
365         error_counter++;
366     }
367 
368     /* Write the FTP response messages into the packet payload!  */
369     memcpy(response_packet -> nx_packet_prepend_ptr, data, data_size);
370 
371     /* Adjust the write pointer.  */
372     response_packet -> nx_packet_length = data_size;
373     response_packet -> nx_packet_append_ptr =  response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length;
374 
375     /* Send the TCP packet with the correct port.  */
376     status =  nx_tcp_socket_send(server_socket, response_packet, NX_IP_PERIODIC_RATE);
377 
378     /* Check the status.  */
379     if (status)
380         nx_packet_release(response_packet);
381 
382     return status;
383 }
384 #else
385 
386 #ifdef CTEST
test_application_define(void * first_unused_memory)387 VOID test_application_define(void *first_unused_memory)
388 #else
389 void    netx_ftp_client_buffer_overflow_test_application_define(void *first_unused_memory)
390 #endif
391 {
392 
393     /* Print out test information banner.  */
394     printf("NetX Test:   FTP Client Buffer Overflow Test...........................N/A\n");
395 
396     test_control_return(3);
397 }
398 #endif
399