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