1 /**************************************************************************/
2 /* */
3 /* Copyright (c) Microsoft Corporation. All rights reserved. */
4 /* */
5 /* This software is licensed under the Microsoft Software License */
6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */
7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
8 /* and in the root directory of this software. */
9 /* */
10 /**************************************************************************/
11
12 /**************************************************************************/
13 /**************************************************************************/
14 /** */
15 /** NetX POP3 Client Component */
16 /** */
17 /** Post Office Protocol Version 3 (POP3) */
18 /** */
19 /**************************************************************************/
20 /**************************************************************************/
21
22 /**************************************************************************/
23 /* */
24 /* APPLICATION INTERFACE DEFINITION RELEASE */
25 /* */
26 /* nxd_pop3_client.c PORTABLE C */
27 /* 6.1 */
28 /* AUTHOR */
29 /* */
30 /* Yuxin Zhou, Microsoft Corporation */
31 /* */
32 /* DESCRIPTION */
33 /* */
34 /* This file defines the NetX Post Office Protocol (POP3) */
35 /* Client component, including all data types and external references. */
36 /* It is assumed that tx_api.h, tx_port.h, nx_api.h, and nx_port.h, */
37 /* have already been included. */
38 /* */
39 /* RELEASE HISTORY */
40 /* */
41 /* DATE NAME DESCRIPTION */
42 /* */
43 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
44 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
45 /* resulting in version 6.1 */
46 /* */
47 /**************************************************************************/
48
49 #define NX_POP3_CLIENT_SOURCE_CODE
50
51 /* Force error checking to be disabled in this module */
52
53 #ifndef NX_DISABLE_ERROR_CHECKING
54 #define NX_DISABLE_ERROR_CHECKING
55 #endif
56
57
58 #include "nx_api.h"
59 #include "nx_md5.h"
60 #include "nx_ip.h"
61 #include "nxd_pop3_client.h"
62 #include "nx_ipv6.h"
63 #include <ctype.h>
64
65 /* The following array of state handlers is indexed by the state. */
66
67 /**************************************************************************/
68 /* */
69 /* FUNCTION RELEASE */
70 /* */
71 /* _nxe_pop3_client_create PORTABLE C */
72 /* 6.1 */
73 /* AUTHOR */
74 /* */
75 /* Yuxin Zhou, Microsoft Corporation */
76 /* */
77 /* DESCRIPTION */
78 /* */
79 /* This function performs error checking on the create POP3 client */
80 /* service (IPv4 only). */
81 /* */
82 /* Note: The string lengths of client_name and client_password are */
83 /* limited by internal buffer size. */
84 /* */
85 /* INPUT */
86 /* */
87 /* client_ptr Pointer to client struct */
88 /* APOP_authentication 1=enable APOP; 0=disable APOP */
89 /* ip_ptr Pointer to client IP instance */
90 /* packet_pool_ptr Pointer to client packet pool */
91 /* server_ip_address POP3 server IP address */
92 /* server_port POP3 server port */
93 /* client_name Client POP3 user name */
94 /* client_password Client POP3 password */
95 /* */
96 /* OUTPUT */
97 /* */
98 /* NX_PTR_ERROR Invalid pointer parameter */
99 /* status Actual completion status */
100 /* */
101 /* CALLS */
102 /* */
103 /* _nx_pop3_client_create Creates the POP3 client */
104 /* */
105 /* CALLED BY */
106 /* */
107 /* Application Code */
108 /* */
109 /* RELEASE HISTORY */
110 /* */
111 /* DATE NAME DESCRIPTION */
112 /* */
113 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
114 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
115 /* resulting in version 6.1 */
116 /* */
117 /**************************************************************************/
_nxe_pop3_client_create(NX_POP3_CLIENT * client_ptr,UINT APOP_authentication,NX_IP * ip_ptr,NX_PACKET_POOL * packet_pool_ptr,ULONG server_ip_address,ULONG server_port,CHAR * client_name,CHAR * client_password)118 UINT _nxe_pop3_client_create(NX_POP3_CLIENT *client_ptr, UINT APOP_authentication, NX_IP *ip_ptr,
119 NX_PACKET_POOL *packet_pool_ptr, ULONG server_ip_address, ULONG server_port, CHAR *client_name,
120 CHAR *client_password)
121 {
122
123 #ifndef NX_DISABLE_IPV4
124 UINT status;
125
126
127 /* Check for valid input pointers. */
128 if ((ip_ptr == NX_NULL) || (client_ptr == NX_NULL) || (packet_pool_ptr == NX_NULL) || (client_name == NX_NULL) ||
129 (client_password == NX_NULL))
130 {
131
132 /* Return pointer error. */
133 return(NX_PTR_ERROR);
134 }
135
136 if ((ip_ptr -> nx_ip_id != NX_IP_ID) || (server_ip_address == 0) || (server_port == 0))
137 {
138
139 return NX_POP3_PARAM_ERROR;
140 }
141
142 /* Call the actual client create service. */
143 status = _nx_pop3_client_create(client_ptr,
144 APOP_authentication,
145 ip_ptr, packet_pool_ptr,
146 server_ip_address, server_port, client_name,
147 client_password);
148
149 /* Return completion status. */
150 return(status);
151 #else
152 NX_PARAMETER_NOT_USED(client_ptr);
153 NX_PARAMETER_NOT_USED(APOP_authentication);
154 NX_PARAMETER_NOT_USED(ip_ptr);
155 NX_PARAMETER_NOT_USED(packet_pool_ptr);
156 NX_PARAMETER_NOT_USED(server_ip_address);
157 NX_PARAMETER_NOT_USED(server_port);
158 NX_PARAMETER_NOT_USED(client_name);
159 NX_PARAMETER_NOT_USED(client_password);
160
161 return(NX_NOT_SUPPORTED);
162 #endif /* NX_DISABLE_IPV4 */
163 }
164
165
166 /**************************************************************************/
167 /* */
168 /* FUNCTION RELEASE */
169 /* */
170 /* _nx_pop3_client_create PORTABLE C */
171 /* 6.1 */
172 /* AUTHOR */
173 /* */
174 /* Yuxin Zhou, Microsoft Corporation */
175 /* */
176 /* DESCRIPTION */
177 /* */
178 /* This function creates a POP3 Client on the specified IP instance. */
179 /* */
180 /* Note: The string lengths of client_name and client_password are */
181 /* limited by internal buffer size. */
182 /* */
183 /* INPUT */
184 /* */
185 /* client_ptr Pointer to client struct */
186 /* APOP_authentication 1=enable APOP; 0=disable APOP */
187 /* ip_ptr Pointer to client IP instance */
188 /* packet_pool_ptr Pointer to client packet pool */
189 /* server_ip_address POP3 server IP address */
190 /* server_port POP3 server port */
191 /* client_name Client POP3 user name */
192 /* client_password Client POP3 password */
193 /* */
194 /* OUTPUT */
195 /* */
196 /* NX_SUCCESS Successful completion status */
197 /* */
198 /* CALLED BY */
199 /* */
200 /* Application Code */
201 /* */
202 /* CALLS */
203 /* */
204 /* _nxd_pop3_client_create Duo Client POP3 create service */
205 /* */
206 /* RELEASE HISTORY */
207 /* */
208 /* DATE NAME DESCRIPTION */
209 /* */
210 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
211 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
212 /* resulting in version 6.1 */
213 /* */
214 /**************************************************************************/
_nx_pop3_client_create(NX_POP3_CLIENT * client_ptr,UINT APOP_authentication,NX_IP * ip_ptr,NX_PACKET_POOL * packet_pool_ptr,ULONG server_ip_address,ULONG server_port,CHAR * client_name,CHAR * client_password)215 UINT _nx_pop3_client_create(NX_POP3_CLIENT *client_ptr, UINT APOP_authentication, NX_IP *ip_ptr,
216 NX_PACKET_POOL *packet_pool_ptr, ULONG server_ip_address, ULONG server_port, CHAR *client_name,
217 CHAR *client_password)
218 {
219
220 #ifndef NX_DISABLE_IPV4
221 UINT status;
222 NXD_ADDRESS server_address;
223
224 server_address.nxd_ip_address.v4 = server_ip_address;
225 server_address.nxd_ip_version = NX_IP_VERSION_V4;
226
227 status = _nxd_pop3_client_create(client_ptr,
228 APOP_authentication,
229 ip_ptr, packet_pool_ptr,
230 &server_address, server_port, client_name,
231 client_password);
232
233 return status;
234 #else
235 NX_PARAMETER_NOT_USED(client_ptr);
236 NX_PARAMETER_NOT_USED(APOP_authentication);
237 NX_PARAMETER_NOT_USED(ip_ptr);
238 NX_PARAMETER_NOT_USED(packet_pool_ptr);
239 NX_PARAMETER_NOT_USED(server_ip_address);
240 NX_PARAMETER_NOT_USED(server_port);
241 NX_PARAMETER_NOT_USED(client_name);
242 NX_PARAMETER_NOT_USED(client_password);
243
244 return(NX_NOT_SUPPORTED);
245 #endif /* NX_DISABLE_IPV4 */
246 }
247
248
249 /**************************************************************************/
250 /* */
251 /* FUNCTION RELEASE */
252 /* */
253 /* _nxde_pop3_client_create PORTABLE C */
254 /* 6.1 */
255 /* AUTHOR */
256 /* */
257 /* Yuxin Zhou, Microsoft Corporation */
258 /* */
259 /* DESCRIPTION */
260 /* */
261 /* This function performs error checking on the create POP3 client */
262 /* service (supports IPv6 and IPv4). */
263 /* */
264 /* Note: The string lengths of client_name and client_password are */
265 /* limited by internal buffer size. */
266 /* */
267 /* INPUT */
268 /* */
269 /* client_ptr Pointer to client struct */
270 /* APOP_authentication 1=enable APOP; 0=disable APOP */
271 /* ip_ptr Pointer to client IP instance */
272 /* packet_pool_ptr Pointer to client packet pool */
273 /* server_duo_address POP3 server IPv6/IPv4 address */
274 /* server_port POP3 server port */
275 /* client_name Client POP3 user name */
276 /* client_password Client POP3 password */
277 /* */
278 /* OUTPUT */
279 /* */
280 /* NX_PTR_ERROR Invalid pointer parameter */
281 /* status Actual completion status */
282 /* */
283 /* CALLS */
284 /* */
285 /* _nxd_pop3_client_create Creates the POP3 client */
286 /* */
287 /* CALLED BY */
288 /* */
289 /* Application Code */
290 /* */
291 /* RELEASE HISTORY */
292 /* */
293 /* DATE NAME DESCRIPTION */
294 /* */
295 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
296 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
297 /* resulting in version 6.1 */
298 /* */
299 /**************************************************************************/
_nxde_pop3_client_create(NX_POP3_CLIENT * client_ptr,UINT APOP_authentication,NX_IP * ip_ptr,NX_PACKET_POOL * packet_pool_ptr,NXD_ADDRESS * server_ip_address,ULONG server_port,CHAR * client_name,CHAR * client_password)300 UINT _nxde_pop3_client_create(NX_POP3_CLIENT *client_ptr, UINT APOP_authentication, NX_IP *ip_ptr,
301 NX_PACKET_POOL *packet_pool_ptr, NXD_ADDRESS *server_ip_address, ULONG server_port, CHAR *client_name,
302 CHAR *client_password)
303 {
304
305 UINT status;
306
307
308 /* Check for valid input pointers. */
309 if ((ip_ptr == NX_NULL) || (client_ptr == NX_NULL) || (packet_pool_ptr == NX_NULL) || (server_ip_address == NX_NULL) ||
310 (client_name == NX_NULL) || (client_password == NX_NULL))
311 {
312
313 /* Return pointer error. */
314 return(NX_PTR_ERROR);
315 }
316
317 if ((ip_ptr -> nx_ip_id != NX_IP_ID) || (server_port == 0))
318 {
319
320 return NX_POP3_PARAM_ERROR;
321 }
322
323 /* Call the actual client create service. */
324 status = _nxd_pop3_client_create(client_ptr,
325 APOP_authentication,
326 ip_ptr, packet_pool_ptr,
327 server_ip_address, server_port, client_name,
328 client_password);
329
330 /* Return completion status. */
331 return(status);
332
333 }
334
335
336 /**************************************************************************/
337 /* */
338 /* FUNCTION RELEASE */
339 /* */
340 /* _nxd_pop3_client_create PORTABLE C */
341 /* 6.1 */
342 /* AUTHOR */
343 /* */
344 /* Yuxin Zhou, Microsoft Corporation */
345 /* */
346 /* DESCRIPTION */
347 /* */
348 /* This function creates a POP3 Client on the specified IP instance. */
349 /* This supports both IPv6 and IPv4 POP3 server connections. */
350 /* */
351 /* Note: The string lengths of client_name and client_password are */
352 /* limited by internal buffer size. */
353 /* */
354 /* INPUT */
355 /* */
356 /* client_ptr Pointer to client struct */
357 /* APOP_authentication 1=enable APOP; 0=disable APOP */
358 /* ip_ptr Pointer to client IP instance */
359 /* packet_pool_ptr Pointer to client packet pool */
360 /* server_ip_address POP3 server IP address */
361 /* server_port POP3 server port */
362 /* client_name Client POP3 user name */
363 /* client_password Client POP3 password */
364 /* */
365 /* OUTPUT */
366 /* */
367 /* NX_SUCCESS Successful completion status */
368 /* */
369 /* CALLED BY */
370 /* */
371 /* Application Code */
372 /* */
373 /* CALLS */
374 /* */
375 /* nx_tcp_socket_create NetX TCP socket create service */
376 /* _nxd_pop3_client_connect Connect POP3 Client to Server */
377 /* */
378 /* RELEASE HISTORY */
379 /* */
380 /* DATE NAME DESCRIPTION */
381 /* */
382 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
383 /* 09-30-2020 Yuxin Zhou Modified comment(s), and */
384 /* verified memcpy use cases, */
385 /* resulting in version 6.1 */
386 /* */
387 /**************************************************************************/
_nxd_pop3_client_create(NX_POP3_CLIENT * client_ptr,UINT APOP_authentication,NX_IP * ip_ptr,NX_PACKET_POOL * packet_pool_ptr,NXD_ADDRESS * server_ip_address,ULONG server_port,CHAR * client_name,CHAR * client_password)388 UINT _nxd_pop3_client_create(NX_POP3_CLIENT *client_ptr, UINT APOP_authentication, NX_IP *ip_ptr,
389 NX_PACKET_POOL *packet_pool_ptr, NXD_ADDRESS *server_ip_address, ULONG server_port, CHAR *client_name,
390 CHAR *client_password)
391
392 {
393
394 UINT status;
395 UINT client_name_length;
396 UINT client_password_length;
397
398
399 client_ptr -> nx_pop3_client_ready_to_download = NX_FALSE;
400
401 if (_nx_utility_string_length_check(client_name, &client_name_length, NX_POP3_MAX_USERNAME) ||
402 _nx_utility_string_length_check(client_password, &client_password_length, NX_POP3_MAX_PASSWORD))
403 {
404
405 return NX_POP3_PARAM_ERROR;
406 }
407
408 /* Null the members of NX_POP3_CLIENT. */
409 memset(client_ptr, 0, sizeof(NX_POP3_CLIENT));
410
411 /* Configure Client identification. */
412 memset(client_ptr -> nx_pop3_client_name, 0, NX_POP3_MAX_USERNAME);
413 memcpy(client_ptr -> nx_pop3_client_name, client_name, client_name_length); /* Use case of memcpy is verified. */
414 memset(client_ptr -> nx_pop3_client_password, 0, NX_POP3_MAX_PASSWORD);
415 memcpy(client_ptr -> nx_pop3_client_password, client_password, client_password_length); /* Use case of memcpy is verified. */
416
417 /* Configure Client POP3 authentication options. */
418 client_ptr -> nx_pop3_client_enable_APOP_authentication = APOP_authentication;
419
420 /* Create a tcp socket to send/receive POP3 data. */
421 status = nx_tcp_socket_create(ip_ptr, &client_ptr -> nx_pop3_client_tcp_socket, "POP3 Client socket",
422 NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE,
423 NX_POP3_CLIENT_TCP_WINDOW_SIZE,
424 NX_NULL, NX_NULL);
425
426 /* Check for error. */
427 if (status != NX_SUCCESS)
428 {
429
430 /* Return error status. */
431 return(status);
432 }
433
434 /* Configure Client NetX and TCP/IP options. */
435 client_ptr -> nx_pop3_client_packet_pool_ptr = packet_pool_ptr;
436
437 status = _nxd_pop3_client_connect(client_ptr, server_ip_address, server_port);
438
439 /* Return successful completion status. */
440 return(status);
441 }
442
443
444
445 /**************************************************************************/
446 /* */
447 /* FUNCTION RELEASE */
448 /* */
449 /* _nxe_pop3_client_delete PORTABLE C */
450 /* 6.1 */
451 /* AUTHOR */
452 /* */
453 /* Yuxin Zhou, Microsoft Corporation */
454 /* */
455 /* DESCRIPTION */
456 /* */
457 /* This function performs error checking on the POP3 Client delete */
458 /* service. */
459 /* */
460 /* INPUT */
461 /* */
462 /* client_ptr Pointer to client struct */
463 /* */
464 /* OUTPUT */
465 /* */
466 /* NX_PTR_ERROR Invalid pointer input */
467 /* status Actual completion status */
468 /* */
469 /* CALLED BY */
470 /* */
471 /* Application Code */
472 /* */
473 /* CALLS */
474 /* */
475 /* _nx_pop3_client_delete Actual Client delete service */
476 /* */
477 /* RELEASE HISTORY */
478 /* */
479 /* DATE NAME DESCRIPTION */
480 /* */
481 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
482 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
483 /* resulting in version 6.1 */
484 /* */
485 /**************************************************************************/
_nxe_pop3_client_delete(NX_POP3_CLIENT * client_ptr)486 UINT _nxe_pop3_client_delete(NX_POP3_CLIENT *client_ptr)
487 {
488
489 UINT status;
490
491
492 /* Check for valid input parameter. */
493 if (client_ptr == NX_NULL)
494 {
495
496 /* Return error status. */
497 return(NX_PTR_ERROR);
498 }
499
500 /* Call client create function. */
501 status = _nx_pop3_client_delete(client_ptr);
502
503 /* Return completion status. */
504 return(status);
505 }
506
507
508 /**************************************************************************/
509 /* */
510 /* FUNCTION RELEASE */
511 /* */
512 /* _nx_pop3_client_delete PORTABLE C */
513 /* 6.1 */
514 /* AUTHOR */
515 /* */
516 /* Yuxin Zhou, Microsoft Corporation */
517 /* */
518 /* DESCRIPTION */
519 /* */
520 /* This function deletes the specified POP3 Client. */
521 /* */
522 /* INPUT */
523 /* */
524 /* client_ptr Pointer to client struct */
525 /* */
526 /* OUTPUT */
527 /* */
528 /* NX_SUCCESS Successful completion status */
529 /* status Actual completion status */
530 /* */
531 /* CALLED BY */
532 /* */
533 /* Application Code */
534 /* */
535 /* CALLS */
536 /* */
537 /* nx_tcp_socket_disconnect Closes the TCP connection */
538 /* nx_tcp_client_socket_unbind Releases (unbinds) the TCP port */
539 /* nx_tcp_socket_delete Deletes unbound TCP socket */
540 /* */
541 /* RELEASE HISTORY */
542 /* */
543 /* DATE NAME DESCRIPTION */
544 /* */
545 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
546 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
547 /* resulting in version 6.1 */
548 /* */
549 /**************************************************************************/
_nx_pop3_client_delete(NX_POP3_CLIENT * client_ptr)550 UINT _nx_pop3_client_delete(NX_POP3_CLIENT *client_ptr)
551 {
552
553 if (client_ptr -> nx_pop3_client_message_ptr)
554 {
555 nx_packet_release(client_ptr -> nx_pop3_client_message_ptr);
556 }
557
558 /* Yes, so disconnect client socket from server. */
559 nx_tcp_socket_disconnect(&client_ptr -> nx_pop3_client_tcp_socket, NX_POP3_CLIENT_DISCONNECT_TIMEOUT);
560
561 /* Unbind the port from client socket. */
562 nx_tcp_client_socket_unbind(&client_ptr -> nx_pop3_client_tcp_socket);
563
564 /* Release client socket. */
565 nx_tcp_socket_delete(&client_ptr -> nx_pop3_client_tcp_socket);
566
567 /* Clear the members of NX_POP3_CLIENT. */
568 memset(client_ptr, 0, sizeof(NX_POP3_CLIENT));
569
570 /* Return completion status. */
571 return(NX_SUCCESS);
572 }
573
574
575 /**************************************************************************/
576 /* */
577 /* FUNCTION RELEASE */
578 /* */
579 /* _nxe_pop3_client_mail_items_get PORTABLE C */
580 /* 6.1 */
581 /* AUTHOR */
582 /* */
583 /* Yuxin Zhou, Microsoft Corporation */
584 /* */
585 /* DESCRIPTION */
586 /* */
587 /* This function performs error checking for the get mail items in */
588 /* client mailbox service. */
589 /* */
590 /* INPUT */
591 /* */
592 /* client_ptr Pointer to client struct */
593 /* number_mail_items Pointer to items in mailbox */
594 /* maildrop_total_size Pointer to total mailbox size */
595 /* */
596 /* OUTPUT */
597 /* */
598 /* NX_PTR_ERROR Invalid pointer parameter */
599 /* status Actual completion status */
600 /* */
601 /* CALLS */
602 /* */
603 /* _nxe_pop3_client_mail_items_get Actual get mail items service */
604 /* */
605 /* CALLED BY */
606 /* */
607 /* Application Code */
608 /* */
609 /* RELEASE HISTORY */
610 /* */
611 /* DATE NAME DESCRIPTION */
612 /* */
613 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
614 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
615 /* resulting in version 6.1 */
616 /* */
617 /**************************************************************************/
_nxe_pop3_client_mail_items_get(NX_POP3_CLIENT * client_ptr,UINT * number_mail_items,ULONG * maildrop_total_size)618 UINT _nxe_pop3_client_mail_items_get(NX_POP3_CLIENT *client_ptr, UINT *number_mail_items, ULONG *maildrop_total_size)
619 {
620
621 UINT status;
622
623
624 /* Check for invalid pointer inpu. */
625 if ((client_ptr == NX_NULL) || (number_mail_items == NX_NULL) || (maildrop_total_size == NX_NULL))
626 {
627
628 return NX_PTR_ERROR;
629 }
630
631 status = _nx_pop3_client_mail_items_get(client_ptr, number_mail_items, maildrop_total_size);
632
633 return status;
634 }
635
636
637 /**************************************************************************/
638 /* */
639 /* FUNCTION RELEASE */
640 /* */
641 /* _nx_pop3_client_mail_items_get PORTABLE C */
642 /* 6.1 */
643 /* AUTHOR */
644 /* */
645 /* Yuxin Zhou, Microsoft Corporation */
646 /* */
647 /* DESCRIPTION */
648 /* */
649 /* This function retrieves the number of items and total size in bytes */
650 /* of mail data in the Client's mailbox. */
651 /* */
652 /* INPUT */
653 /* */
654 /* client_ptr Pointer to client struct */
655 /* number_mail_items Pointer to items in mailbox */
656 /* maildrop_total_size Pointer to total mailbox size */
657 /* */
658 /* OUTPUT */
659 /* */
660 /* NX_PTR_ERROR Invalid pointer parameter */
661 /* NX_POP3_INSUFFICIENT_PACKET_PAYLOAD */
662 /* Packet too small for command */
663 /* status Actual completion status */
664 /* */
665 /* CALLS */
666 /* */
667 /* nx_packet_allocate Allocate packet from packet pool */
668 /* nx_packet_release Release packet back to pool */
669 /* nx_tcp_socket_send Send packet out TCP socket */
670 /* nx_tcp_socket_receive Retrieve packet from TCP socket */
671 /* _nx_pop3_parse_response Extract word from server response */
672 /* */
673 /* CALLED BY */
674 /* */
675 /* Application Code */
676 /* */
677 /* RELEASE HISTORY */
678 /* */
679 /* DATE NAME DESCRIPTION */
680 /* */
681 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
682 /* 09-30-2020 Yuxin Zhou Modified comment(s), and */
683 /* verified memcpy use cases, */
684 /* resulting in version 6.1 */
685 /* */
686 /**************************************************************************/
_nx_pop3_client_mail_items_get(NX_POP3_CLIENT * client_ptr,UINT * number_mail_items,ULONG * maildrop_total_size)687 UINT _nx_pop3_client_mail_items_get(NX_POP3_CLIENT *client_ptr, UINT *number_mail_items, ULONG *maildrop_total_size)
688 {
689
690 UINT status;
691 NX_PACKET *packet_ptr, *recv_packet_ptr;
692 CHAR *buffer;
693 CHAR argument[10];
694 UINT packet_type;
695
696 /* Determine type of packet to allocate. */
697 if (client_ptr -> nx_pop3_client_tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_version == NX_IP_VERSION_V6)
698 packet_type = NX_IPv6_TCP_PACKET;
699 else
700 packet_type = NX_IPv4_TCP_PACKET;
701
702 /* Allocate a packet. */
703 status = nx_packet_allocate(client_ptr -> nx_pop3_client_packet_pool_ptr,
704 &packet_ptr, packet_type, NX_POP3_CLIENT_PACKET_TIMEOUT);
705
706 /* Check for error. */
707 if (status != NX_SUCCESS)
708 {
709
710 /* Return the error condition. */
711 return(status);
712 }
713
714 /* Check for sufficient packet buffer size for command. */
715 if ((packet_ptr -> nx_packet_prepend_ptr + (sizeof(NX_POP3_COMMAND_STAT) - 1) + (sizeof(NX_POP3_COMMAND_TERMINATION) - 1)) >= packet_ptr -> nx_packet_data_end)
716 {
717
718 /* Release the packet. */
719 nx_packet_release(packet_ptr);
720
721 return NX_POP3_INSUFFICIENT_PACKET_PAYLOAD;
722 }
723
724 /* Send the STAT command. */
725 buffer = (CHAR *)(packet_ptr -> nx_packet_prepend_ptr);
726
727 memcpy(buffer, NX_POP3_COMMAND_STAT, (sizeof(NX_POP3_COMMAND_STAT) - 1)); /* Use case of memcpy is verified. */
728 packet_ptr -> nx_packet_length = (sizeof(NX_POP3_COMMAND_STAT) - 1);
729 packet_ptr -> nx_packet_append_ptr += (sizeof(NX_POP3_COMMAND_STAT) - 1);
730 buffer += (sizeof(NX_POP3_COMMAND_STAT) - 1);
731
732 memcpy(buffer, NX_POP3_COMMAND_TERMINATION, (sizeof(NX_POP3_COMMAND_TERMINATION) - 1)); /* Use case of memcpy is verified. */
733 packet_ptr -> nx_packet_length += (sizeof(NX_POP3_COMMAND_TERMINATION) - 1);
734 packet_ptr -> nx_packet_append_ptr += (sizeof(NX_POP3_COMMAND_TERMINATION) - 1);
735 buffer += (sizeof(NX_POP3_COMMAND_TERMINATION) - 1);
736
737 /* Send the packet out. */
738 status = nx_tcp_socket_send(&client_ptr -> nx_pop3_client_tcp_socket, packet_ptr, NX_POP3_TCP_SOCKET_SEND_WAIT);
739
740 /* Check for error. */
741 if (status != NX_SUCCESS)
742 {
743
744 /* Release the packet. */
745 nx_packet_release(packet_ptr);
746
747 /* Return the error condition. */
748 return(status);
749 }
750
751 /* Clear existing Client maildrop data. */
752 client_ptr -> nx_pop3_client_total_message_size = 0;
753 client_ptr -> nx_pop3_client_maildrop_items = 0;
754
755 /* Receive server reply. */
756 status = nx_tcp_socket_receive(&(client_ptr -> nx_pop3_client_tcp_socket), &recv_packet_ptr, NX_POP3_SERVER_REPLY_TIMEOUT);
757
758 /* Check for error. */
759 if (status != NX_SUCCESS)
760 {
761
762 /* Return error condition. */
763 return(status);
764 }
765
766 #ifndef NX_DISABLE_PACKET_CHAIN
767 if (recv_packet_ptr -> nx_packet_next)
768 {
769
770 /* Chained packet is not supported. */
771 nx_packet_release(recv_packet_ptr);
772 return(NX_INVALID_PACKET);
773 }
774 #endif /* NX_DISABLE_PACKET_CHAIN */
775
776 /* Set a pointer to the packet data. */
777 buffer = (CHAR *)(recv_packet_ptr -> nx_packet_prepend_ptr);
778
779 /* Parse the first argument of the server reply. */
780 _nx_pop3_parse_response(buffer, 1, recv_packet_ptr -> nx_packet_length, (CHAR *)&argument, 10, NX_FALSE, NX_FALSE);
781
782 /* Initialize status to server error received. */
783 status = NX_POP3_SERVER_ERROR_STATUS;
784
785 /* Did the server accept the Client command? */
786 if (memcmp(argument, NX_POP3_POSITIVE_STATUS, (sizeof(NX_POP3_POSITIVE_STATUS) - 1)) == 0x0)
787 {
788
789 /* Yes. Clear memory for parsing the mail item count. */
790 memset(argument, 0, 5);
791
792 /* Get the number of messages. */
793 _nx_pop3_parse_response(buffer, 2, recv_packet_ptr -> nx_packet_length, (CHAR *)&argument, 10, NX_FALSE, NX_FALSE);
794
795 /* Check if argument parsed successfully. */
796 if ((argument[0] >= 0x30) && (argument[0] <= 0x39))
797 {
798
799 /* It was; update session maildrop items. */
800 client_ptr -> nx_pop3_client_maildrop_items = strtoul(argument, NULL, 10);
801
802 /* Get total mail message data next. */
803 memset(argument, 0, 5);
804
805 /* Get the size in bytes of message data. */
806 _nx_pop3_parse_response(buffer, 3, recv_packet_ptr -> nx_packet_length, (CHAR *)&argument, 10, NX_FALSE, NX_FALSE);
807
808 /* Check if argument parsed successfully. */
809 if ((argument[0] >= 0x30) && (argument[0] <= 0x39))
810 {
811
812 /* It was; update total message data. */
813 client_ptr -> nx_pop3_client_total_message_size = strtoul(argument, NULL, 10);
814
815 status = NX_SUCCESS;
816 }
817 }
818 }
819
820 *maildrop_total_size = client_ptr -> nx_pop3_client_total_message_size;
821 *number_mail_items = client_ptr -> nx_pop3_client_maildrop_items;
822
823 nx_packet_release(recv_packet_ptr);
824
825 /* Return completion status. */
826 return status;
827 }
828
829
830 /**************************************************************************/
831 /* */
832 /* FUNCTION RELEASE */
833 /* */
834 /* _nxe_pop3_client_get_mail_item PORTABLE C */
835 /* 6.1 */
836 /* AUTHOR */
837 /* */
838 /* Yuxin Zhou, Microsoft Corporation */
839 /* */
840 /* DESCRIPTION */
841 /* */
842 /* This function performs error checking for the get mail item size */
843 /* service. */
844 /* */
845 /* INPUT */
846 /* */
847 /* client_ptr Pointer to client struct */
848 /* mail_item Index into POP3 mailbox */
849 /* item_size Pointer to mail size */
850 /* */
851 /* OUTPUT */
852 /* */
853 /* NX_PTR_ERROR Invalid pointer parameter */
854 /* NX_POP3_INVALID_MAIL_ITEM Invalid mail index input */
855 /* status Actual completion status */
856 /* */
857 /* CALLS */
858 /* */
859 /* _nx_pop3_client_get_mail_size Actual get mail size service */
860 /* */
861 /* CALLED BY */
862 /* */
863 /* Application Code */
864 /* */
865 /* RELEASE HISTORY */
866 /* */
867 /* DATE NAME DESCRIPTION */
868 /* */
869 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
870 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
871 /* resulting in version 6.1 */
872 /* */
873 /**************************************************************************/
_nxe_pop3_client_mail_item_size_get(NX_POP3_CLIENT * client_ptr,UINT mail_item,ULONG * size)874 UINT _nxe_pop3_client_mail_item_size_get(NX_POP3_CLIENT *client_ptr, UINT mail_item, ULONG *size)
875 {
876
877 UINT status;
878
879
880 /* Check for invalid pointer input. */
881 if ((client_ptr == NX_NULL) || (size == NX_NULL))
882 {
883
884 return NX_PTR_ERROR;
885 }
886
887 /* Check for an invalid index. */
888 if (mail_item == 0)
889 {
890 return NX_POP3_CLIENT_INVALID_INDEX;
891 }
892
893 status = _nx_pop3_client_mail_item_size_get(client_ptr, mail_item, size);
894
895 return status;
896 }
897
898
899 /**************************************************************************/
900 /* */
901 /* FUNCTION RELEASE */
902 /* */
903 /* _nx_pop3_client_mail_item_size_get PORTABLE C */
904 /* 6.1 */
905 /* AUTHOR */
906 /* */
907 /* Yuxin Zhou, Microsoft Corporation */
908 /* */
909 /* DESCRIPTION */
910 /* */
911 /* This function sends a LIST command for the specified mail item and */
912 /* processes the server response for size of the requested item. Note */
913 /* that there is considerable discrepancy between reported size and */
914 /* actual size, with the reported size usually 15% or more larger than */
915 /* actual. */
916 /* */
917 /* INPUT */
918 /* */
919 /* client_ptr Pointer to client struct */
920 /* mail_item Index into POP3 mailbox */
921 /* size Pointer to mail item size */
922 /* */
923 /* OUTPUT */
924 /* */
925 /* NX_PTR_ERROR Invalid pointer parameter */
926 /* NX_POP3_INVALID_MAIL_ITEM Invalid mail index input */
927 /* NX_POP3_INSUFFICIENT_PACKET_PAYLOAD */
928 /* Packet too small for command */
929 /* status Actual completion status */
930 /* */
931 /* CALLS */
932 /* */
933 /* nx_packet_allocate Allocate packet from packet pool */
934 /* nx_packet_release Release packet back to pool */
935 /* nx_tcp_socket_send Send packet out TCP socket */
936 /* nx_tcp_socket_receive Retrieve packet from TCP socket */
937 /* _nx_pop3_parse_response Extract word from server response */
938 /* _nx_pop3_server_number_convert Convert integer to ascii */
939 /* */
940 /* CALLED BY */
941 /* */
942 /* Application Code */
943 /* */
944 /* RELEASE HISTORY */
945 /* */
946 /* DATE NAME DESCRIPTION */
947 /* */
948 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
949 /* 09-30-2020 Yuxin Zhou Modified comment(s), and */
950 /* verified memcpy use cases, */
951 /* resulting in version 6.1 */
952 /* */
953 /**************************************************************************/
_nx_pop3_client_mail_item_size_get(NX_POP3_CLIENT * client_ptr,UINT mail_item,ULONG * size)954 UINT _nx_pop3_client_mail_item_size_get(NX_POP3_CLIENT *client_ptr, UINT mail_item, ULONG *size)
955 {
956
957 NX_PACKET *packet_ptr, *recv_packet_ptr;
958 CHAR *buffer_ptr;
959 UINT num_size;
960 UINT status;
961 CHAR argument[10];
962 UINT packet_type;
963
964
965 /* Initialize mail box to having zero items. */
966 *size = 0;
967
968 /* Verify mail_item is valid index (less than total number items in mailbox. */
969 if (mail_item > client_ptr -> nx_pop3_client_maildrop_items)
970 {
971 return NX_POP3_INVALID_MAIL_ITEM;
972 }
973
974 /* Determine which packet type to allocate. */
975 if (client_ptr -> nx_pop3_client_tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_version == NX_IP_VERSION_V6)
976 packet_type = NX_IPv6_TCP_PACKET;
977 else
978 packet_type = NX_IPv4_TCP_PACKET;
979
980 /* Allocate a packet. */
981 status = nx_packet_allocate(client_ptr -> nx_pop3_client_packet_pool_ptr,
982 &packet_ptr, packet_type, NX_POP3_CLIENT_PACKET_TIMEOUT);
983
984 /* Check for error. */
985 if (status != NX_SUCCESS)
986 {
987
988 /* Return the error condition. */
989 return(status);
990 }
991
992 num_size = _nx_pop3_server_number_convert(mail_item, &argument[0]);
993
994 /* Determine if the packet payload is large enough for LIST command. */
995 if ((packet_ptr -> nx_packet_prepend_ptr + (sizeof(NX_POP3_COMMAND_LIST) - 1) + 1 +
996 num_size + (sizeof(NX_POP3_COMMAND_TERMINATION) - 1)) >= packet_ptr -> nx_packet_data_end)
997 {
998
999 /* Release the packet. */
1000 nx_packet_release(packet_ptr);
1001
1002 return NX_POP3_INSUFFICIENT_PACKET_PAYLOAD;
1003 }
1004
1005 buffer_ptr = (CHAR *)packet_ptr -> nx_packet_prepend_ptr;
1006
1007 /* Send LIST mail_item query to server */
1008 memcpy(buffer_ptr, NX_POP3_COMMAND_LIST, (sizeof(NX_POP3_COMMAND_LIST) - 1)); /* Use case of memcpy is verified. */
1009 packet_ptr -> nx_packet_length = (sizeof(NX_POP3_COMMAND_LIST) - 1);
1010 packet_ptr -> nx_packet_append_ptr += (sizeof(NX_POP3_COMMAND_LIST) - 1);
1011 buffer_ptr += (sizeof(NX_POP3_COMMAND_LIST) - 1);
1012
1013 memcpy(buffer_ptr, " ", 1); /* Use case of memcpy is verified. */
1014 packet_ptr -> nx_packet_length++;
1015 packet_ptr -> nx_packet_append_ptr++;
1016 buffer_ptr++;
1017
1018 memcpy(buffer_ptr, &argument[0], num_size); /* Use case of memcpy is verified. */
1019 packet_ptr -> nx_packet_length += num_size;
1020 packet_ptr -> nx_packet_append_ptr += num_size;
1021 buffer_ptr += num_size;
1022
1023 memcpy(buffer_ptr, NX_POP3_COMMAND_TERMINATION, (sizeof(NX_POP3_COMMAND_TERMINATION) - 1)); /* Use case of memcpy is verified. */
1024 packet_ptr -> nx_packet_length += (sizeof(NX_POP3_COMMAND_TERMINATION) - 1);
1025 packet_ptr -> nx_packet_append_ptr += (sizeof(NX_POP3_COMMAND_TERMINATION) - 1);
1026 buffer_ptr += (sizeof(NX_POP3_COMMAND_TERMINATION) - 1);
1027
1028 /* Send the packet out. */
1029 status = nx_tcp_socket_send(&client_ptr -> nx_pop3_client_tcp_socket, packet_ptr, NX_POP3_TCP_SOCKET_SEND_WAIT);
1030
1031 /* Check for error. */
1032 if (status != NX_SUCCESS)
1033 {
1034
1035 /* Release the packet. */
1036 nx_packet_release(packet_ptr);
1037
1038 /* Return the error condition. */
1039 return(status);
1040 }
1041
1042 /* Receive server reply over session socket. */
1043 status = nx_tcp_socket_receive(&(client_ptr -> nx_pop3_client_tcp_socket), &recv_packet_ptr, NX_POP3_SERVER_REPLY_TIMEOUT);
1044
1045 /* Check for error. */
1046 if (status != NX_SUCCESS)
1047 {
1048
1049 /* Return error condition. */
1050 return(status);
1051 }
1052
1053 #ifndef NX_DISABLE_PACKET_CHAIN
1054 if (recv_packet_ptr -> nx_packet_next)
1055 {
1056
1057 /* Chained packet is not supported. */
1058 nx_packet_release(recv_packet_ptr);
1059 return(NX_INVALID_PACKET);
1060 }
1061 #endif /* NX_DISABLE_PACKET_CHAIN */
1062
1063 /* Set a pointer to the packet data. */
1064 buffer_ptr = (CHAR *)(recv_packet_ptr -> nx_packet_prepend_ptr);
1065
1066 /* Initialize status to bad reply error condition. */
1067 status = NX_POP3_SERVER_ERROR_STATUS;
1068
1069 /* Parse the first argument of the server reply. */
1070 _nx_pop3_parse_response(buffer_ptr, 1, recv_packet_ptr -> nx_packet_length, (CHAR *)&argument, 10, NX_FALSE, NX_FALSE);
1071
1072 /* Did the server accept the Client command? */
1073 if (memcmp(argument, NX_POP3_POSITIVE_STATUS, (sizeof(NX_POP3_POSITIVE_STATUS) - 1)) == 0x0)
1074 {
1075
1076 /* Clear memory for parsing the mail item count. */
1077 memset(argument, 0, 5);
1078
1079 /* Extact the message size. */
1080 _nx_pop3_parse_response(buffer_ptr, 2, recv_packet_ptr -> nx_packet_length, (CHAR *)&argument, 10, NX_FALSE, NX_FALSE);
1081
1082 /* Check if argument parsed successfully. */
1083 if ((argument[0] >= 0x30) && (argument[0] <= 0x39))
1084 {
1085
1086 /* It was; verify it matches the input mail index. */
1087 UINT server_maildrop_items = strtoul(argument, NULL, 10);
1088
1089 if (mail_item == server_maildrop_items)
1090 {
1091
1092 /* It does. Parse the message size. */
1093 _nx_pop3_parse_response(buffer_ptr, 3, recv_packet_ptr -> nx_packet_length,
1094 (CHAR *)&argument, 10, NX_FALSE, NX_FALSE);
1095
1096 if ((argument[0] >= 0x30) && (argument[0] <= 0x39))
1097 {
1098
1099 *size = strtoul(argument, NULL, 10);
1100
1101 status = NX_SUCCESS;
1102 }
1103 }
1104 }
1105 }
1106
1107 /* Done with the server response, delete the packet. */
1108 nx_packet_release(recv_packet_ptr);
1109
1110 return status;
1111 }
1112
1113 /**************************************************************************/
1114 /* */
1115 /* FUNCTION RELEASE */
1116 /* */
1117 /* _nxe_pop3_client_mail_item_get PORTABLE C */
1118 /* 6.1 */
1119 /* AUTHOR */
1120 /* */
1121 /* Yuxin Zhou, Microsoft Corporation */
1122 /* */
1123 /* DESCRIPTION */
1124 /* */
1125 /* This function performs error checking for the get mail item */
1126 /* service. */
1127 /* */
1128 /* INPUT */
1129 /* */
1130 /* client_ptr Pointer to client struct */
1131 /* mail_item Index into POP3 mailbox */
1132 /* item_size Pointer to mail size */
1133 /* */
1134 /* OUTPUT */
1135 /* */
1136 /* NX_PTR_ERROR Invalid pointer parameter */
1137 /* status Actual completion status */
1138 /* */
1139 /* CALLS */
1140 /* */
1141 /* _nx_pop3_client_mail_item_get Actual get mail service */
1142 /* */
1143 /* CALLED BY */
1144 /* */
1145 /* Application Code */
1146 /* */
1147 /* RELEASE HISTORY */
1148 /* */
1149 /* DATE NAME DESCRIPTION */
1150 /* */
1151 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
1152 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
1153 /* resulting in version 6.1 */
1154 /* */
1155 /**************************************************************************/
_nxe_pop3_client_mail_item_get(NX_POP3_CLIENT * client_ptr,UINT mail_item,ULONG * item_size)1156 UINT _nxe_pop3_client_mail_item_get(NX_POP3_CLIENT *client_ptr, UINT mail_item, ULONG *item_size)
1157 {
1158
1159 UINT status;
1160
1161 /* Check for invalid pointer input. */
1162 if ((client_ptr == NX_NULL) || (item_size == NX_NULL))
1163 {
1164
1165 return NX_PTR_ERROR;
1166 }
1167
1168 /* Check for an invalid index. */
1169 if (mail_item == 0)
1170 {
1171 return NX_POP3_CLIENT_INVALID_INDEX;
1172 }
1173
1174 status = _nx_pop3_client_mail_item_get(client_ptr, mail_item, item_size);
1175
1176 return status;
1177 }
1178
1179 /**************************************************************************/
1180 /* */
1181 /* FUNCTION RELEASE */
1182 /* */
1183 /* _nx_pop3_client_mail_item_get PORTABLE C */
1184 /* 6.1 */
1185 /* AUTHOR */
1186 /* */
1187 /* Yuxin Zhou, Microsoft Corporation */
1188 /* */
1189 /* DESCRIPTION */
1190 /* */
1191 /* This function sends the RETR command to the server for the specified*/
1192 /* mail item, and returns the server response. If accepted, it will */
1193 /* parse the mail item size as well. */
1194 /* */
1195 /* INPUT */
1196 /* */
1197 /* client_ptr Pointer to client struct */
1198 /* mail_item Index into POP3 mailbox */
1199 /* item_size Pointer to mail size */
1200 /* */
1201 /* OUTPUT */
1202 /* */
1203 /* NX_PTR_ERROR Invalid pointer parameter */
1204 /* NX_POP3_INVALID_MAIL_ITEM Invalid mail index input */
1205 /* NX_POP3_INSUFFICIENT_PACKET_PAYLOAD */
1206 /* Packet too small for command */
1207 /* status Actual completion status */
1208 /* */
1209 /* CALLS */
1210 /* */
1211 /* nx_packet_allocate Allocate packet from packet pool */
1212 /* nx_packet_release Release packet back to pool */
1213 /* nx_tcp_socket_send Send packet out TCP socket */
1214 /* nx_tcp_socket_receive Retrieve packet from TCP socket */
1215 /* _nx_pop3_parse_response Extract word from server response */
1216 /* _nx_pop3_server_number_convert Convert integer to ascii */
1217 /* */
1218 /* CALLED BY */
1219 /* */
1220 /* Application Code */
1221 /* */
1222 /* RELEASE HISTORY */
1223 /* */
1224 /* DATE NAME DESCRIPTION */
1225 /* */
1226 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
1227 /* 09-30-2020 Yuxin Zhou Modified comment(s), and */
1228 /* verified memcpy use cases, */
1229 /* resulting in version 6.1 */
1230 /* */
1231 /**************************************************************************/
_nx_pop3_client_mail_item_get(NX_POP3_CLIENT * client_ptr,UINT mail_item,ULONG * item_size)1232 UINT _nx_pop3_client_mail_item_get(NX_POP3_CLIENT *client_ptr, UINT mail_item, ULONG *item_size)
1233 {
1234
1235 UINT status;
1236 UINT size;
1237 NX_PACKET *packet_ptr, *recv_packet_ptr;
1238 CHAR *buffer;
1239 CHAR argument[10];
1240 UINT packet_type;
1241
1242
1243 client_ptr -> nx_pop3_client_ready_to_download = NX_FALSE;
1244
1245 /* Verify mail_item is valid index (less than total number items in mailbox. */
1246 if (mail_item > client_ptr -> nx_pop3_client_maildrop_items)
1247 {
1248 return NX_POP3_INVALID_MAIL_ITEM;
1249 }
1250
1251 /* Allocate a packet. */
1252 if (client_ptr -> nx_pop3_client_tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_version == NX_IP_VERSION_V6)
1253 packet_type = NX_IPv6_TCP_PACKET;
1254 else
1255 packet_type = NX_IPv4_TCP_PACKET;
1256
1257 /* Allocate a packet. */
1258 status = nx_packet_allocate(client_ptr -> nx_pop3_client_packet_pool_ptr,
1259 &packet_ptr, packet_type, NX_POP3_CLIENT_PACKET_TIMEOUT);
1260
1261 /* Check for error. */
1262 if (status != NX_SUCCESS)
1263 {
1264
1265 /* Return the error condition. */
1266 return(status);
1267 }
1268
1269 /* Check packet payload can hold the Client message. . */
1270 if ((packet_ptr -> nx_packet_prepend_ptr + (sizeof(NX_POP3_COMMAND_RETR) - 1) + 1) >= packet_ptr -> nx_packet_data_end)
1271 {
1272
1273 /* Release the packet. */
1274 nx_packet_release(packet_ptr);
1275
1276 return NX_POP3_INSUFFICIENT_PACKET_PAYLOAD;
1277 }
1278
1279 buffer = (CHAR *)(packet_ptr -> nx_packet_prepend_ptr);
1280
1281 /* Send a RETR command to the server. */
1282 memcpy(packet_ptr -> nx_packet_prepend_ptr, NX_POP3_COMMAND_RETR, (sizeof(NX_POP3_COMMAND_RETR) - 1)); /* Use case of memcpy is verified. */
1283 packet_ptr -> nx_packet_length += (sizeof(NX_POP3_COMMAND_RETR) - 1);
1284 packet_ptr -> nx_packet_append_ptr += (sizeof(NX_POP3_COMMAND_RETR) - 1);
1285 buffer += (sizeof(NX_POP3_COMMAND_RETR) - 1);
1286
1287 memcpy(buffer, " ", 1); /* Use case of memcpy is verified. */
1288 packet_ptr -> nx_packet_length++;
1289 packet_ptr -> nx_packet_append_ptr++;
1290 buffer++;
1291
1292 /* Convert the mail item index to ascii. */
1293 size = _nx_pop3_server_number_convert(mail_item, &argument[0]);
1294 if ((buffer + size + (sizeof(NX_POP3_COMMAND_TERMINATION) - 1)) >= (CHAR *)packet_ptr -> nx_packet_data_end)
1295 {
1296
1297 /* Release the packet. */
1298 nx_packet_release(packet_ptr);
1299
1300 return NX_POP3_INSUFFICIENT_PACKET_PAYLOAD;
1301 }
1302
1303 memcpy(buffer, &argument[0], size); /* Use case of memcpy is verified. */
1304 packet_ptr -> nx_packet_length += size;
1305 packet_ptr -> nx_packet_append_ptr += size;
1306 buffer += size;
1307
1308 memcpy(buffer, NX_POP3_COMMAND_TERMINATION, (sizeof(NX_POP3_COMMAND_TERMINATION) - 1)); /* Use case of memcpy is verified. */
1309 packet_ptr -> nx_packet_length += (sizeof(NX_POP3_COMMAND_TERMINATION) - 1);
1310 packet_ptr -> nx_packet_append_ptr += (sizeof(NX_POP3_COMMAND_TERMINATION) - 1);
1311 buffer += (sizeof(NX_POP3_COMMAND_TERMINATION) - 1);
1312
1313 /* Send the packet out. */
1314 status = nx_tcp_socket_send(&client_ptr -> nx_pop3_client_tcp_socket, packet_ptr, NX_POP3_TCP_SOCKET_SEND_WAIT);
1315
1316 /* Check for error. */
1317 if (status != NX_SUCCESS)
1318 {
1319
1320 /* Release the packet. */
1321 nx_packet_release(packet_ptr);
1322
1323 /* Return the error condition. */
1324 return(status);
1325 }
1326
1327 /* Receive server reply over Client socket. */
1328 status = nx_tcp_socket_receive(&(client_ptr -> nx_pop3_client_tcp_socket), &recv_packet_ptr, NX_POP3_SERVER_REPLY_TIMEOUT);
1329
1330 /* Check for error. */
1331 if (status != NX_SUCCESS)
1332 {
1333
1334 /* Return error condition. */
1335 return(status);
1336 }
1337
1338 #ifndef NX_DISABLE_PACKET_CHAIN
1339 if (recv_packet_ptr -> nx_packet_next)
1340 {
1341
1342 /* Chained packet is not supported. */
1343 nx_packet_release(recv_packet_ptr);
1344 return(NX_INVALID_PACKET);
1345 }
1346 #endif /* NX_DISABLE_PACKET_CHAIN */
1347
1348 /* Set a pointer to the packet data. */
1349 buffer = (CHAR *)(recv_packet_ptr -> nx_packet_prepend_ptr);
1350
1351 /* Parse the first argument of the server reply. */
1352 _nx_pop3_parse_response(buffer, 1, recv_packet_ptr -> nx_packet_length, (CHAR *)&argument,
1353 sizeof(argument), NX_FALSE, NX_FALSE);
1354
1355 /* Did the server accept the Client command? */
1356 if (memcmp(argument, NX_POP3_POSITIVE_STATUS, (sizeof(NX_POP3_POSITIVE_STATUS) - 1)) == 0x0)
1357 {
1358
1359 client_ptr -> nx_pop3_client_ready_to_download = NX_TRUE;
1360 *item_size = 0;
1361
1362 /* Yes. Clear memory for parsing the mail item size. */
1363 memset(argument, 0, sizeof(argument));
1364
1365 /* Get the number of szie of the message. . */
1366 _nx_pop3_parse_response(buffer, 2, recv_packet_ptr -> nx_packet_length, (CHAR *)&argument,
1367 sizeof(argument) - 1, NX_FALSE, NX_FALSE);
1368
1369 /* Check if argument parsed successfully. */
1370 if ((argument[0] >= 0x30) && (argument[0] <= 0x39))
1371 {
1372
1373 /* It was; set the size of th e mail item. */
1374 *item_size = strtoul(argument, NULL, 10);
1375 }
1376
1377 while (((ULONG)buffer < ((ULONG)recv_packet_ptr -> nx_packet_append_ptr - 1)) &&
1378 ((*buffer != 0x0D) || (*(buffer + 1) != 0x0A)))
1379 {
1380 buffer++;
1381 }
1382
1383 buffer += 2;
1384
1385 if ((UCHAR *)buffer == recv_packet_ptr -> nx_packet_append_ptr)
1386 {
1387 nx_packet_release(recv_packet_ptr);
1388 }
1389 else
1390 {
1391 client_ptr -> nx_pop3_client_message_ptr = recv_packet_ptr;
1392 recv_packet_ptr -> nx_packet_length -=
1393 (ULONG)buffer - (ULONG)recv_packet_ptr -> nx_packet_prepend_ptr;
1394 recv_packet_ptr -> nx_packet_prepend_ptr = (UCHAR *)buffer;
1395 }
1396
1397 return NX_SUCCESS;
1398 }
1399 else
1400 {
1401 nx_packet_release(recv_packet_ptr);
1402 return NX_POP3_SERVER_ERROR_STATUS;
1403 }
1404
1405 }
1406
1407
1408 /**************************************************************************/
1409 /* */
1410 /* FUNCTION RELEASE */
1411 /* */
1412 /* _nxe_pop3_client_mail_item_message_get PORTABLE C */
1413 /* 6.1 */
1414 /* AUTHOR */
1415 /* */
1416 /* Yuxin Zhou, Microsoft Corporation */
1417 /* */
1418 /* DESCRIPTION */
1419 /* */
1420 /* This function performs error checking for the get message data */
1421 /* service. */
1422 /* */
1423 /* INPUT */
1424 /* */
1425 /* client_ptr Pointer to client struct */
1426 /* recv_packet_ptr Pointer to received PP3 packet */
1427 /* bytes_retrieved Size of message data in packet */
1428 /* final_packet Indicates if last packet */
1429 /* NX_FALSE = not the last packet */
1430 /* NX_TRUE = is the last packet */
1431 /* */
1432 /* OUTPUT */
1433 /* */
1434 /* NX_PTR_ERROR Invalid pointer parameter */
1435 /* status Actual completion status */
1436 /* */
1437 /* CALLS */
1438 /* */
1439 /* _nx_pop3_client_mail_item_message_data_get */
1440 /* Actual get message data service */
1441 /* */
1442 /* CALLED BY */
1443 /* */
1444 /* Application Code */
1445 /* */
1446 /* RELEASE HISTORY */
1447 /* */
1448 /* DATE NAME DESCRIPTION */
1449 /* */
1450 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
1451 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
1452 /* resulting in version 6.1 */
1453 /* */
1454 /**************************************************************************/
_nxe_pop3_client_mail_item_message_get(NX_POP3_CLIENT * client_ptr,NX_PACKET ** recv_packet_ptr,ULONG * bytes_retrieved,UINT * final_packet)1455 UINT _nxe_pop3_client_mail_item_message_get(NX_POP3_CLIENT *client_ptr, NX_PACKET **recv_packet_ptr, ULONG *bytes_retrieved, UINT *final_packet)
1456 {
1457
1458 UINT status;
1459
1460
1461 if ((client_ptr == NX_NULL) || (recv_packet_ptr == NX_NULL) || (bytes_retrieved == NX_NULL) || (final_packet == NX_NULL))
1462 {
1463
1464 return NX_PTR_ERROR;
1465 }
1466
1467 status = _nx_pop3_client_mail_item_message_get(client_ptr, recv_packet_ptr, bytes_retrieved, final_packet);
1468
1469 return status;
1470 }
1471
1472
1473 /**************************************************************************/
1474 /* */
1475 /* FUNCTION RELEASE */
1476 /* */
1477 /* _nx_pop3_client_mail_item_message_get PORTABLE C */
1478 /* 6.1 */
1479 /* AUTHOR */
1480 /* */
1481 /* Yuxin Zhou, Microsoft Corporation */
1482 /* */
1483 /* DESCRIPTION */
1484 /* */
1485 /* This function retrieves message packets from the POP3 Client TCP */
1486 /* socket and returns them to the caller without further processing. */
1487 /* It is up to the caller to strip off the trailing end of message tag */
1488 /* \r\n.\r\n if one is appended to the message. Note the end of */
1489 /* message is included in the packet length. */
1490 /* */
1491 /* When packets are received with only the end of message tag (EOM), */
1492 /* this function returns zero bytes retrieved and sets final_packet to */
1493 /* true. */
1494 /* */
1495 /* If the status return is NX_SUCCESS, the caller MUST release the */
1496 /* packet, even if there bytes_retrieved is set to zero. */
1497 /* */
1498 /* INPUT */
1499 /* */
1500 /* client_ptr Pointer to client struct */
1501 /* recv_packet_ptr Pointer to received packet */
1502 /* bytes_retrieved Received packet length */
1503 /* final_packet If last packet of message */
1504 /* */
1505 /* OUTPUT */
1506 /* */
1507 /* NX_PTR_ERROR Invalid pointer parameter */
1508 /* status Actual completion status */
1509 /* */
1510 /* CALLS */
1511 /* */
1512 /* None */
1513 /* */
1514 /* CALLED BY */
1515 /* */
1516 /* Application Code */
1517 /* */
1518 /* RELEASE HISTORY */
1519 /* */
1520 /* DATE NAME DESCRIPTION */
1521 /* */
1522 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
1523 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
1524 /* resulting in version 6.1 */
1525 /* */
1526 /**************************************************************************/
_nx_pop3_client_mail_item_message_get(NX_POP3_CLIENT * client_ptr,NX_PACKET ** recv_packet_ptr,ULONG * bytes_retrieved,UINT * final_packet)1527 UINT _nx_pop3_client_mail_item_message_get(NX_POP3_CLIENT *client_ptr, NX_PACKET **recv_packet_ptr, ULONG *bytes_retrieved, UINT *final_packet)
1528 {
1529 UINT status;
1530 UINT index;
1531 CHAR *buffer_ptr;
1532
1533 /* Initialize results to no data retrieved, or if the received packet is the last in the message. */
1534 *final_packet = NX_FALSE;
1535 *bytes_retrieved = 0;
1536
1537 /* Verify client is ready to download mail messages. */
1538 if (client_ptr -> nx_pop3_client_ready_to_download == NX_FALSE)
1539 {
1540
1541 return NX_POP3_CLIENT_INVALID_STATE;
1542 }
1543
1544 if (client_ptr -> nx_pop3_client_message_ptr)
1545 {
1546 status = NX_SUCCESS;
1547 *recv_packet_ptr = client_ptr -> nx_pop3_client_message_ptr;
1548 client_ptr -> nx_pop3_client_message_ptr = NX_NULL;
1549 }
1550 else
1551 {
1552
1553 /* Retrieve the next data packet. */
1554 status = nx_tcp_socket_receive(&client_ptr -> nx_pop3_client_tcp_socket, recv_packet_ptr, NX_POP3_SERVER_REPLY_TIMEOUT);
1555 }
1556
1557 if (status == NX_SUCCESS)
1558 {
1559
1560 /* Update the bytes_retrieved with amount of data in the packet. */
1561 *bytes_retrieved = (*recv_packet_ptr) -> nx_packet_length;
1562
1563 /* Check for end of message tag in this packet. */
1564 if (*bytes_retrieved > (sizeof(NX_POP3_END_OF_MESSAGE) - 1))
1565 {
1566 buffer_ptr = (CHAR *)(*recv_packet_ptr) -> nx_packet_prepend_ptr;
1567
1568 index = *bytes_retrieved - (sizeof(NX_POP3_END_OF_MESSAGE) - 1);
1569
1570 /* Determine if the end of the data contains the terminating \r\n.\r\n marker. */
1571 if (memcmp((buffer_ptr + index), NX_POP3_END_OF_MESSAGE, (sizeof(NX_POP3_END_OF_MESSAGE) - 1)) == 0)
1572 {
1573
1574 /* It does; indicate this is the end of the mail download. */
1575 *final_packet = NX_TRUE;
1576
1577 /* Client cannot download any data for this particular mail item. */
1578 client_ptr -> nx_pop3_client_ready_to_download = NX_FALSE;
1579 }
1580 }
1581 else
1582 {
1583
1584 if (
1585 (memcmp((*recv_packet_ptr) -> nx_packet_prepend_ptr, NX_POP3_END_OF_MESSAGE, (sizeof(NX_POP3_END_OF_MESSAGE) - 1))== 0) ||
1586 (memcmp((*recv_packet_ptr) -> nx_packet_prepend_ptr, NX_POP3_END_OF_MESSAGE_TAG, (sizeof(NX_POP3_END_OF_MESSAGE_TAG) - 1))== 0)
1587 )
1588 {
1589
1590 /* Yes, but this is not considered part of the message. Indicate this with the bytes retrieved. */
1591 *bytes_retrieved = 0;
1592
1593 /* It does; indicate this is the end of the mail download. */
1594 *final_packet = NX_TRUE;
1595
1596 /* Client cannot download any data for this particular mail item. */
1597 client_ptr -> nx_pop3_client_ready_to_download = NX_FALSE;
1598 }
1599 }
1600 }
1601
1602 return status;
1603
1604 }
1605
1606 /**************************************************************************/
1607 /* */
1608 /* FUNCTION RELEASE */
1609 /* */
1610 /* _nxe_pop3_client_mail_item_delete PORTABLE C */
1611 /* 6.1 */
1612 /* AUTHOR */
1613 /* */
1614 /* Yuxin Zhou, Microsoft Corporation */
1615 /* */
1616 /* DESCRIPTION */
1617 /* */
1618 /* This function performs error checking for the delete mail item */
1619 /* service. */
1620 /* */
1621 /* INPUT */
1622 /* */
1623 /* client_ptr Pointer to client struct */
1624 /* mail_index Index of mail item to delete */
1625 /* */
1626 /* OUTPUT */
1627 /* */
1628 /* NX_PTR_ERROR Invalid pointer parameter */
1629 /* NX_POP3_INVALID_MAIL_ITEM Invalid mail index input */
1630 /* status Actual completion status */
1631 /* */
1632 /* CALLS */
1633 /* */
1634 /* _nx_pop3_client_mail_item_delete Actual delete mail service */
1635 /* */
1636 /* CALLED BY */
1637 /* */
1638 /* Application Code */
1639 /* */
1640 /* RELEASE HISTORY */
1641 /* */
1642 /* DATE NAME DESCRIPTION */
1643 /* */
1644 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
1645 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
1646 /* resulting in version 6.1 */
1647 /* */
1648 /**************************************************************************/
_nxe_pop3_client_mail_item_delete(NX_POP3_CLIENT * client_ptr,UINT mail_index)1649 UINT _nxe_pop3_client_mail_item_delete(NX_POP3_CLIENT *client_ptr, UINT mail_index)
1650 {
1651
1652 UINT status;
1653
1654
1655 /* Check for invalid pointer input. */
1656 if (client_ptr == NX_NULL)
1657 {
1658 return NX_PTR_ERROR;
1659 }
1660
1661 /* Check for invalid mail item input. */
1662 if (mail_index == 0)
1663 {
1664
1665 return NX_POP3_CLIENT_INVALID_INDEX;
1666 }
1667
1668 status = _nx_pop3_client_mail_item_delete(client_ptr, mail_index);
1669
1670 return status;
1671 }
1672
1673
1674 /**************************************************************************/
1675 /* */
1676 /* FUNCTION RELEASE */
1677 /* */
1678 /* _nx_pop3_client_mail_item_delete PORTABLE C */
1679 /* 6.1 */
1680 /* AUTHOR */
1681 /* */
1682 /* Yuxin Zhou, Microsoft Corporation */
1683 /* */
1684 /* DESCRIPTION */
1685 /* */
1686 /* This function sends the DELE command for the specified mail item */
1687 /* and verifies the server will delete the item. Note that for some */
1688 /* servers, items marked for deletion are not deleted immediately, in */
1689 /* some cases only if they receive the QUIT command. */
1690 /* */
1691 /* INPUT */
1692 /* */
1693 /* client_ptr Pointer to client struct */
1694 /* mail_item Index into POP3 mailbox */
1695 /* */
1696 /* OUTPUT */
1697 /* */
1698 /* NX_PTR_ERROR Invalid pointer parameter */
1699 /* NX_POP3_INVALID_MAIL_ITEM Invalid mail index input */
1700 /* NX_POP3_INSUFFICIENT_PACKET_PAYLOAD */
1701 /* Packet too small for command */
1702 /* status Actual completion status */
1703 /* */
1704 /* CALLS */
1705 /* */
1706 /* nx_packet_allocate Allocate packet from packet pool */
1707 /* nx_packet_release Release packet back to pool */
1708 /* nx_tcp_socket_send Send packet out TCP socket */
1709 /* nx_tcp_socket_receive Retrieve packet from TCP socket */
1710 /* _nx_pop3_parse_response Extract word from server response */
1711 /* _nx_pop3_server_number_convert Convert integer to ascii */
1712 /* */
1713 /* CALLED BY */
1714 /* */
1715 /* Application Code */
1716 /* */
1717 /* RELEASE HISTORY */
1718 /* */
1719 /* DATE NAME DESCRIPTION */
1720 /* */
1721 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
1722 /* 09-30-2020 Yuxin Zhou Modified comment(s), and */
1723 /* verified memcpy use cases, */
1724 /* resulting in version 6.1 */
1725 /* */
1726 /**************************************************************************/
_nx_pop3_client_mail_item_delete(NX_POP3_CLIENT * client_ptr,UINT mail_index)1727 UINT _nx_pop3_client_mail_item_delete(NX_POP3_CLIENT *client_ptr, UINT mail_index)
1728 {
1729
1730 UINT status;
1731 UINT size;
1732 NX_PACKET *packet_ptr, *recv_packet_ptr;
1733 CHAR *buffer_ptr;
1734 CHAR argument[10];
1735 UINT packet_type;
1736
1737
1738 /* Allocate a packet. */
1739 if (client_ptr -> nx_pop3_client_tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_version == NX_IP_VERSION_V6)
1740 packet_type = NX_IPv6_TCP_PACKET;
1741 else
1742 packet_type = NX_IPv4_TCP_PACKET;
1743
1744 /* Allocate a packet. */
1745 status = nx_packet_allocate(client_ptr -> nx_pop3_client_packet_pool_ptr,
1746 &packet_ptr, packet_type, NX_POP3_CLIENT_PACKET_TIMEOUT);
1747
1748 /* Check for error. */
1749 if (status != NX_SUCCESS)
1750 {
1751
1752 /* Return the error condition. */
1753 return(status);
1754 }
1755
1756 buffer_ptr = (CHAR *)packet_ptr -> nx_packet_prepend_ptr;
1757
1758 /* Convert the ascii word to a number. */
1759 size = _nx_pop3_server_number_convert(mail_index, &argument[0]);
1760
1761 /* Check packet payload is large enough for DEL request. */
1762 if ((packet_ptr -> nx_packet_prepend_ptr + (sizeof(NX_POP3_COMMAND_DELE) - 1) + 1 + size +
1763 (sizeof(NX_POP3_COMMAND_TERMINATION) - 1)) >= packet_ptr -> nx_packet_data_end)
1764 {
1765
1766 /* Release the packet. */
1767 nx_packet_release(packet_ptr);
1768
1769 return NX_POP3_INSUFFICIENT_PACKET_PAYLOAD;
1770 }
1771
1772 /* Send the DELE command. */
1773 memcpy(buffer_ptr, NX_POP3_COMMAND_DELE, (sizeof(NX_POP3_COMMAND_DELE) - 1)); /* Use case of memcpy is verified. */
1774 packet_ptr -> nx_packet_length += (sizeof(NX_POP3_COMMAND_DELE) - 1);
1775 packet_ptr -> nx_packet_append_ptr += (sizeof(NX_POP3_COMMAND_DELE) - 1);
1776 buffer_ptr += (sizeof(NX_POP3_COMMAND_DELE) - 1);
1777
1778
1779 memcpy(buffer_ptr, " ", 1); /* Use case of memcpy is verified. */
1780 packet_ptr -> nx_packet_length++;
1781 packet_ptr -> nx_packet_append_ptr++;
1782 buffer_ptr++;
1783
1784 memcpy(buffer_ptr, &argument[0], size); /* Use case of memcpy is verified. */
1785 packet_ptr -> nx_packet_length += size;
1786 packet_ptr -> nx_packet_append_ptr += size;
1787 buffer_ptr += size;
1788
1789 memcpy(buffer_ptr, NX_POP3_COMMAND_TERMINATION, (sizeof(NX_POP3_COMMAND_TERMINATION) - 1)); /* Use case of memcpy is verified. */
1790 packet_ptr -> nx_packet_length += (sizeof(NX_POP3_COMMAND_TERMINATION) - 1);
1791 packet_ptr -> nx_packet_append_ptr += (sizeof(NX_POP3_COMMAND_TERMINATION) - 1);
1792 buffer_ptr += (sizeof(NX_POP3_COMMAND_TERMINATION) - 1);
1793
1794 /* Send the DELE command out. */
1795 status = nx_tcp_socket_send(&client_ptr -> nx_pop3_client_tcp_socket, packet_ptr, NX_POP3_TCP_SOCKET_SEND_WAIT);
1796
1797 /* Check for error. */
1798 if (status != NX_SUCCESS)
1799 {
1800
1801 /* Release the packet. */
1802 nx_packet_release(packet_ptr);
1803
1804 /* Return the error condition. */
1805 return(status);
1806 }
1807
1808 /* Receive server reply to DELE command. */
1809 status = nx_tcp_socket_receive(&(client_ptr -> nx_pop3_client_tcp_socket), &recv_packet_ptr, NX_POP3_SERVER_REPLY_TIMEOUT);
1810
1811 /* Check for error. */
1812 if (status != NX_SUCCESS)
1813 {
1814
1815 /* Return error condition. */
1816 return(status);
1817 }
1818
1819 #ifndef NX_DISABLE_PACKET_CHAIN
1820 if (recv_packet_ptr -> nx_packet_next)
1821 {
1822
1823 /* Chained packet is not supported. */
1824 nx_packet_release(recv_packet_ptr);
1825 return(NX_INVALID_PACKET);
1826 }
1827 #endif /* NX_DISABLE_PACKET_CHAIN */
1828
1829 /* Set a pointer to the packet data. */
1830 buffer_ptr = (CHAR *)(recv_packet_ptr -> nx_packet_prepend_ptr);
1831
1832 /* Parse the first argument of the server reply. */
1833 _nx_pop3_parse_response(buffer_ptr, 1, recv_packet_ptr -> nx_packet_length, (CHAR *)&argument, 10, NX_FALSE, NX_FALSE);
1834
1835 /* Initialize status to server error status received. */
1836 status = NX_POP3_SERVER_ERROR_STATUS;
1837
1838 /* Did the server accept the Client command? */
1839 if (memcmp(argument, NX_POP3_POSITIVE_STATUS, (sizeof(NX_POP3_POSITIVE_STATUS) - 1)) == 0x0)
1840 {
1841
1842 /* Yes, set status to successful completion. */
1843 status = NX_SUCCESS;
1844 }
1845
1846 nx_packet_release(recv_packet_ptr);
1847
1848 return status;
1849 }
1850
1851 /**************************************************************************/
1852 /* */
1853 /* FUNCTION RELEASE */
1854 /* */
1855 /* _nxe_pop3_client_quit PORTABLE C */
1856 /* 6.1 */
1857 /* AUTHOR */
1858 /* */
1859 /* Yuxin Zhou, Microsoft Corporation */
1860 /* */
1861 /* DESCRIPTION */
1862 /* */
1863 /* The service performs error checking for the send QUIT service. */
1864 /* */
1865 /* INPUT */
1866 /* */
1867 /* client_ptr Pointer to POP3 Client */
1868 /* */
1869 /* OUTPUT */
1870 /* */
1871 /* NX_SUCCESS Successful completion status */
1872 /* NX_PTR_ERROR Invalid pointer input */
1873 /* status Actual completion status */
1874 /* */
1875 /* CALLED BY */
1876 /* */
1877 /* Application thread */
1878 /* */
1879 /* CALLS */
1880 /* */
1881 /* _nx_pop3_client_quit Actual send QUIT command service */
1882 /* */
1883 /* RELEASE HISTORY */
1884 /* */
1885 /* DATE NAME DESCRIPTION */
1886 /* */
1887 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
1888 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
1889 /* resulting in version 6.1 */
1890 /* */
1891 /**************************************************************************/
_nxe_pop3_client_quit(NX_POP3_CLIENT * client_ptr)1892 UINT _nxe_pop3_client_quit(NX_POP3_CLIENT *client_ptr)
1893 {
1894
1895 UINT status;
1896
1897 if (client_ptr == NX_NULL)
1898 {
1899 return NX_PTR_ERROR;
1900 }
1901
1902 status = _nx_pop3_client_quit(client_ptr);
1903
1904 return status;
1905 }
1906
1907
1908 /**************************************************************************/
1909 /* */
1910 /* FUNCTION RELEASE */
1911 /* */
1912 /* _nx_pop3_client_quit PORTABLE C */
1913 /* 6.1 */
1914 /* AUTHOR */
1915 /* */
1916 /* Yuxin Zhou, Microsoft Corporation */
1917 /* */
1918 /* DESCRIPTION */
1919 /* */
1920 /* The service sends a QUIT command to the Client POP3 server. The */
1921 /* QUIT command takes no arguments and can be called at any time during*/
1922 /* the Client session. */
1923 /* */
1924 /* INPUT */
1925 /* */
1926 /* client_ptr Pointer to POP3 Client */
1927 /* */
1928 /* OUTPUT */
1929 /* */
1930 /* NX_SUCCESS Successful completion status */
1931 /* NX_POP3_INSUFFICIENT_PACKET_PAYLOAD */
1932 /* Packet too small for command */
1933 /* status Actual completion status */
1934 /* */
1935 /* CALLED BY */
1936 /* */
1937 /* Application thread */
1938 /* */
1939 /* CALLS */
1940 /* */
1941 /* None */
1942 /* */
1943 /* RELEASE HISTORY */
1944 /* */
1945 /* DATE NAME DESCRIPTION */
1946 /* */
1947 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
1948 /* 09-30-2020 Yuxin Zhou Modified comment(s), and */
1949 /* verified memcpy use cases, */
1950 /* resulting in version 6.1 */
1951 /* */
1952 /**************************************************************************/
_nx_pop3_client_quit(NX_POP3_CLIENT * client_ptr)1953 UINT _nx_pop3_client_quit(NX_POP3_CLIENT *client_ptr)
1954 {
1955
1956 UINT status;
1957 NX_PACKET *packet_ptr, *recv_packet_ptr;
1958 CHAR *buffer_ptr;
1959 CHAR argument[10];
1960 UINT packet_type;
1961
1962
1963 /* Allocate a packet. */
1964 if (client_ptr -> nx_pop3_client_tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_version == NX_IP_VERSION_V6)
1965 packet_type = NX_IPv6_TCP_PACKET;
1966 else
1967 packet_type = NX_IPv4_TCP_PACKET;
1968
1969 /* Allocate a packet. */
1970 status = nx_packet_allocate(client_ptr -> nx_pop3_client_packet_pool_ptr,
1971 &packet_ptr, packet_type, NX_POP3_CLIENT_PACKET_TIMEOUT);
1972
1973 /* Check for error. */
1974 if (status != NX_SUCCESS)
1975 {
1976
1977 /* Return the error condition. */
1978 return(status);
1979 }
1980
1981 buffer_ptr = (CHAR *)packet_ptr -> nx_packet_prepend_ptr;
1982
1983 /* Check packet payload will hold the QUIT request. */
1984 if ((packet_ptr -> nx_packet_prepend_ptr + (sizeof(NX_POP3_COMMAND_QUIT) - 1) + 1 +
1985 (sizeof(NX_POP3_COMMAND_TERMINATION) - 1)) >= packet_ptr -> nx_packet_data_end)
1986 {
1987
1988 /* Release the packet. */
1989 nx_packet_release(packet_ptr);
1990
1991 return NX_POP3_INSUFFICIENT_PACKET_PAYLOAD;
1992 }
1993
1994 memcpy(buffer_ptr, NX_POP3_COMMAND_QUIT, (sizeof(NX_POP3_COMMAND_QUIT) - 1)); /* Use case of memcpy is verified. */
1995 packet_ptr -> nx_packet_length += (sizeof(NX_POP3_COMMAND_QUIT) - 1);
1996 packet_ptr -> nx_packet_append_ptr += (sizeof(NX_POP3_COMMAND_QUIT) - 1);
1997 buffer_ptr += (sizeof(NX_POP3_COMMAND_QUIT) - 1);
1998
1999 memcpy(buffer_ptr, NX_POP3_COMMAND_TERMINATION, (sizeof(NX_POP3_COMMAND_TERMINATION) - 1)); /* Use case of memcpy is verified. */
2000 packet_ptr -> nx_packet_length += (sizeof(NX_POP3_COMMAND_TERMINATION) - 1);
2001 packet_ptr -> nx_packet_append_ptr += (sizeof(NX_POP3_COMMAND_TERMINATION) - 1);
2002 buffer_ptr += (sizeof(NX_POP3_COMMAND_TERMINATION) - 1);
2003
2004 /* Send the packet out. */
2005 status = nx_tcp_socket_send(&client_ptr -> nx_pop3_client_tcp_socket, packet_ptr, NX_POP3_TCP_SOCKET_SEND_WAIT);
2006
2007 /* Check for error. */
2008 if (status != NX_SUCCESS)
2009 {
2010
2011 /* Release the packet. */
2012 nx_packet_release(packet_ptr);
2013
2014 /* Return the error condition. */
2015 return(status);
2016 }
2017
2018 /* Receive server reply over session socket. */
2019 status = nx_tcp_socket_receive(&(client_ptr -> nx_pop3_client_tcp_socket), &recv_packet_ptr, NX_POP3_SERVER_REPLY_TIMEOUT);
2020
2021 /* Check for error. */
2022 if (status != NX_SUCCESS)
2023 {
2024
2025 /* Return error condition. */
2026 return(status);
2027 }
2028
2029 #ifndef NX_DISABLE_PACKET_CHAIN
2030 if (recv_packet_ptr -> nx_packet_next)
2031 {
2032
2033 /* Chained packet is not supported. */
2034 nx_packet_release(recv_packet_ptr);
2035 return(NX_INVALID_PACKET);
2036 }
2037 #endif /* NX_DISABLE_PACKET_CHAIN */
2038
2039 /* Set a pointer to the packet data. */
2040 buffer_ptr = (CHAR *)(recv_packet_ptr -> nx_packet_prepend_ptr);
2041
2042 /* Parse the first argument of the server reply. */
2043 _nx_pop3_parse_response(buffer_ptr, 1, recv_packet_ptr -> nx_packet_length, (CHAR *)&argument, 10, NX_FALSE, NX_FALSE);
2044
2045 /* Initialize status to bad reply error condition. */
2046 status = NX_POP3_SERVER_ERROR_STATUS;
2047
2048 /* Did the server accept the Client command? */
2049 if (memcmp(argument, NX_POP3_POSITIVE_STATUS, (sizeof(NX_POP3_POSITIVE_STATUS) - 1)) == 0x0)
2050 {
2051
2052 /* Yes, set status to successful completion. */
2053 status = NX_SUCCESS;
2054 }
2055
2056 nx_packet_release(recv_packet_ptr);
2057
2058 return status;
2059 }
2060
2061
2062 /**************************************************************************/
2063 /* */
2064 /* FUNCTION RELEASE */
2065 /* */
2066 /* _nx_pop3_digest_authenticate PORTABLE C */
2067 /* 6.1 */
2068 /* AUTHOR */
2069 /* */
2070 /* Yuxin Zhou, Microsoft Corporation */
2071 /* */
2072 /* DESCRIPTION */
2073 /* */
2074 /* This function creates an MD5 digest based on input string which per */
2075 /* POP3 protocol is the process ID and secret (e.g. Client password). */
2076 /* This digest is used in APOP commands for the Client to authenticate */
2077 /* itself without clear texting it's password. */
2078 /* */
2079 /* INPUT */
2080 /* */
2081 /* client_ptr POP3 Client pointer */
2082 /* process_ID_ptr Pointer to process_ID string */
2083 /* process_ID_length Process ID string length */
2084 /* result Pointer to MD5 digest */
2085 /* */
2086 /* OUTPUT */
2087 /* */
2088 /* NX_SUCCESS Successful completion status */
2089 /* */
2090 /* CALLS */
2091 /* */
2092 /* _nx_md5_initialize Initialize MD5 algorithm */
2093 /* _nx_md5_update Update MD5 digest */
2094 /* _nx_md5_digest_calculate Complete the MD5 algorithm */
2095 /* _nx_pop3_hex_ascii_convert Convert digest to ascii */
2096 /* */
2097 /* CALLED BY */
2098 /* */
2099 /* _nx_pop3_client_apop Send APOP cmd to Server */
2100 /* */
2101 /* RELEASE HISTORY */
2102 /* */
2103 /* DATE NAME DESCRIPTION */
2104 /* */
2105 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
2106 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
2107 /* resulting in version 6.1 */
2108 /* */
2109 /**************************************************************************/
_nx_pop3_digest_authenticate(NX_POP3_CLIENT * client_ptr,CHAR * process_ID_ptr,UINT process_ID_length,CHAR * result)2110 UINT _nx_pop3_digest_authenticate(NX_POP3_CLIENT *client_ptr, CHAR *process_ID_ptr, UINT process_ID_length, CHAR *result)
2111 {
2112
2113 CHAR md5_binary[NX_POP3_MAX_BINARY_MD5];
2114
2115 /* Initialize the Client session MD5 data. */
2116 _nx_md5_initialize(&client_ptr -> nx_pop3_client_md5data);
2117
2118
2119 _nx_md5_update(&client_ptr -> nx_pop3_client_md5data, (unsigned char *)process_ID_ptr, process_ID_length);
2120
2121 /* Finish calculation of the MD5 digest. */
2122 _nx_md5_digest_calculate(&client_ptr -> nx_pop3_client_md5data, (unsigned char *)&md5_binary[0]);
2123
2124 /* Convert digest to ASCII Hex representation. */
2125 _nx_pop3_hex_ascii_convert(&md5_binary[0], NX_POP3_MAX_BINARY_MD5, result);
2126
2127 /* Return successful completion */
2128 return NX_SUCCESS;
2129 }
2130
2131 /**************************************************************************/
2132 /* */
2133 /* FUNCTION RELEASE */
2134 /* */
2135 /* _nx_pop3_parse_process_id PORTABLE C */
2136 /* 6.1 */
2137 /* AUTHOR */
2138 /* */
2139 /* Yuxin Zhou, Microsoft Corporation */
2140 /* */
2141 /* DESCRIPTION */
2142 /* */
2143 /* This function extracts the process ID in the greeting from server. */
2144 /* If found the Server is indicating we may use APOP to secure (open) */
2145 /* the mailbox. The process ID is saved to the POP3 Client instance. If*/
2146 /* no process ID is found, this field is set to NULL. */
2147 /* */
2148 /* INPUT */
2149 /* */
2150 /* client_ptr Pointer to Client */
2151 /* buffer Pointer to server reply buffer */
2152 /* buffer_length Size of server reply buffer */
2153 /* */
2154 /* OUTPUT */
2155 /* */
2156 /* status Actual completion status */
2157 /* */
2158 /* CALLED BY */
2159 /* */
2160 /* _nxd_pop3_client_connect Connect and authenticate with server*/
2161 /* */
2162 /* CALLS */
2163 /* */
2164 /* None */
2165 /* */
2166 /* RELEASE HISTORY */
2167 /* */
2168 /* DATE NAME DESCRIPTION */
2169 /* */
2170 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
2171 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
2172 /* resulting in version 6.1 */
2173 /* */
2174 /**************************************************************************/
_nx_pop3_parse_process_id(NX_POP3_CLIENT * client_ptr,CHAR * buffer,UINT buffer_length)2175 VOID _nx_pop3_parse_process_id(NX_POP3_CLIENT *client_ptr, CHAR *buffer, UINT buffer_length)
2176 {
2177
2178 CHAR c;
2179 UINT index;
2180 UINT pid_index;
2181
2182
2183 /* Set a pointer to the start of the buffer to search. */
2184 index = 0;
2185
2186 /* Clear memory for parsing the server process ID. */
2187 memset(&client_ptr -> nx_pop3_server_process_id[0], 0, NX_POP3_SERVER_PROCESS_ID_SIZE);
2188
2189 while(index < buffer_length)
2190 {
2191 c = *buffer;
2192 if (c == '<')
2193 {
2194
2195 /* Found the start of the process ID. Now save it to the session instance including the angle brackets. */
2196 pid_index = 0;
2197
2198 /* Check that we don't go over the size of the process ID buffer or off the end of the packet data. */
2199 while ((pid_index < NX_POP3_SERVER_PROCESS_ID_SIZE) && (index < buffer_length))
2200 {
2201
2202 /* Copy the next character and advance the counters and buffer pointer. */
2203 client_ptr -> nx_pop3_server_process_id[pid_index] = *buffer;
2204
2205 /* Check if this is the end of the time stamp which is included in the process id string. . */
2206 if (*buffer == '>')
2207 {
2208
2209 /* This is the enclosing bracket. We're done. */
2210 return;
2211 }
2212
2213 index++;
2214 pid_index++;
2215 buffer++;
2216 }
2217
2218 }
2219 index++;
2220 buffer++;
2221 }
2222
2223 /* If we got here, we did not find any process IDs. */
2224 return;
2225 }
2226
2227 /**************************************************************************/
2228 /* */
2229 /* FUNCTION RELEASE */
2230 /* */
2231 /* _nx_pop3_parse_response PORTABLE C */
2232 /* 6.1.4 */
2233 /* AUTHOR */
2234 /* */
2235 /* Yuxin Zhou, Microsoft Corporation */
2236 /* */
2237 /* DESCRIPTION */
2238 /* */
2239 /* This service parses the specified argument from the input buffer */
2240 /* and returns a pointer to the argument if found, else the a NULL */
2241 /* pointer. Dashes are handled as word separators. */
2242 /* */
2243 /* crlf_are_word_breaks indicates if CR LF's should be handled as word */
2244 /* separators. convert_to_uppercase indicates if the argument should be*/
2245 /* converted to uppercase. */
2246 /* */
2247 /* This service removes CR LF's at the end of the message. It does not*/
2248 /* allocate or clear argument memory, but does. */
2249 /* */
2250 /* INPUT */
2251 /* */
2252 /* buffer Pointer to buffer to parse */
2253 /* argument_index Index of argument to parse */
2254 /* buffer_length Buffer size */
2255 /* argument Pointer to argument parsed */
2256 /* argument_length Argument buffer size */
2257 /* convert_to_uppercase Convert argument to uppercase */
2258 /* crlf_are_word_breaks Handle CR LF's as word breaks */
2259 /* */
2260 /* OUTPUT */
2261 /* */
2262 /* None */
2263 /* */
2264 /* CALLS */
2265 /* */
2266 /* None */
2267 /* */
2268 /* CALLED BY */
2269 /* */
2270 /* */
2271 /* RELEASE HISTORY */
2272 /* */
2273 /* DATE NAME DESCRIPTION */
2274 /* */
2275 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
2276 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
2277 /* resulting in version 6.1 */
2278 /* 02-02-2021 Yuxin Zhou Modified comment(s), improved */
2279 /* buffer length verification, */
2280 /* resulting in version 6.1.4 */
2281 /* */
2282 /**************************************************************************/
_nx_pop3_parse_response(CHAR * buffer,UINT argument_index,UINT buffer_length,CHAR * argument,UINT argument_length,UINT convert_to_uppercase,UINT crlf_are_word_breaks)2283 void _nx_pop3_parse_response(CHAR *buffer, UINT argument_index, UINT buffer_length, CHAR *argument, UINT argument_length,
2284 UINT convert_to_uppercase, UINT crlf_are_word_breaks)
2285 {
2286
2287 UINT i = 0;
2288 UINT j = 0;
2289 UINT argument_char_count;
2290
2291
2292 /* Check for invalid input. */
2293 if ((buffer == NX_NULL)|| (buffer[0] == 0x0) || (argument == NX_NULL) || (buffer_length == 0) ||
2294 (argument_length == 0) || (argument_index == 0))
2295 {
2296
2297 /* Return with argument not found status. */
2298 return;
2299 }
2300
2301 /* Initialize the argument to not found with NULL character. */
2302 *argument = (CHAR)0x0;
2303 argument_char_count = 0;
2304
2305 /* Is this the first argument? */
2306 if (argument_index == 1)
2307 {
2308
2309 /* Yes, search each character up to the end of the buffer for the first separator. */
2310 while (i < buffer_length)
2311 {
2312
2313 /* Did we find it? */
2314 if (*buffer == ' ')
2315 {
2316
2317 /* Yes, we're done with this loop! */
2318 break;
2319 }
2320
2321 /* Treat a hyphen as word breaks if it is between words, not if it is the first char. */
2322 if (*buffer == '-' && i > 0)
2323 {
2324
2325 /* Yes, we're done with this loop! */
2326 break;
2327 }
2328
2329 /* Did we go past the argument size limit? */
2330 if (argument_char_count >= argument_length)
2331 {
2332
2333 /* Yes, no argument found. */
2334 break;
2335 }
2336
2337 /* Copy the next character into the argument, converting
2338 to uppercase if the caller requested this. */
2339 *argument++ = convert_to_uppercase ? (CHAR)toupper((INT)(*buffer)) : *buffer;
2340
2341 argument_char_count++;
2342
2343 /* Move to the next character. */
2344 i++;
2345 buffer++;
2346 }
2347
2348 /* Are we at the end of the buffer? */
2349 if ((i == buffer_length) && (buffer_length >= 2))
2350 {
2351
2352 /* Yes, is there a line terminator? */
2353 if (*(argument - 2) == 0x0D && *(argument - 1) == 0x0A)
2354 {
2355
2356 /* Yes, remove it with a null character */
2357 *(argument - 2) = (CHAR) 0x0;
2358 }
2359 }
2360 }
2361 else
2362 {
2363 /* No, we're not parsing the first argument. */
2364
2365 /* Mark the start of the argument at the separator after the end of the previous argument. */
2366 while (j < argument_index && i < buffer_length)
2367 {
2368
2369 /* Keep track of the number of separators in the buffer */
2370
2371 /* Did we hit a line terminator? */
2372 if ((*buffer == 0x0D) && (*(buffer + 1) == 0x0A))
2373 {
2374
2375 /* Yes, Update the count of separators. */
2376 j++;
2377
2378 /* Are line terminators as word breaks? */
2379 if (!crlf_are_word_breaks)
2380 {
2381
2382 /* No, treat as the end of the search string buffer. */
2383 break;
2384 }
2385
2386 buffer++;
2387 }
2388
2389 /* Did we hit a space or a dash in the first argument? */
2390 else if (*buffer == ' ' ||
2391 (*buffer == '-' && j == 0))
2392 {
2393
2394 /* These are counted as separators (note that
2395 dashes found in arguments after the first arg
2396 are NOT considered separators */
2397 j++;
2398 }
2399 else
2400 {
2401
2402 if (j == argument_index - 1)
2403 {
2404
2405 /* Have we exceeded the limit on the argument size? */
2406 if (argument_char_count < argument_length)
2407 {
2408
2409 /* No, copy the next character into the argument. */
2410 argument_char_count++;
2411
2412 /* Convert to uppercase if the caller requests. */
2413 *argument++ = convert_to_uppercase ? (CHAR)toupper((INT)*buffer) : *buffer;
2414 }
2415 }
2416 }
2417
2418 /* Get the next character */
2419 i++;
2420 buffer++;
2421 }
2422 }
2423
2424 return;
2425 }
2426
2427 /**************************************************************************/
2428 /* */
2429 /* FUNCTION RELEASE */
2430 /* */
2431 /* _nx_pop3_hex_ascii_convert PORTABLE C */
2432 /* 6.1 */
2433 /* AUTHOR */
2434 /* */
2435 /* Yuxin Zhou, Microsoft Corporation */
2436 /* */
2437 /* DESCRIPTION */
2438 /* */
2439 /* This function converts hexadecimal characters into an ASCII string. */
2440 /* */
2441 /* INPUT */
2442 /* */
2443 /* source Source hex string */
2444 /* source_length Length of source string */
2445 /* destination Pointer to destination string */
2446 /* */
2447 /* OUTPUT */
2448 /* */
2449 /* None */
2450 /* */
2451 /* CALLS */
2452 /* */
2453 /* None */
2454 /* */
2455 /* CALLED BY */
2456 /* */
2457 /* _nx_pop3_utility_digest_authenticate Create digest for */
2458 /* authentication */
2459 /* */
2460 /* RELEASE HISTORY */
2461 /* */
2462 /* DATE NAME DESCRIPTION */
2463 /* */
2464 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
2465 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
2466 /* resulting in version 6.1 */
2467 /* */
2468 /**************************************************************************/
_nx_pop3_hex_ascii_convert(CHAR * source,UINT source_length,CHAR * destination)2469 VOID _nx_pop3_hex_ascii_convert(CHAR *source, UINT source_length, CHAR *destination)
2470 {
2471
2472 UINT i,j;
2473 CHAR digit;
2474
2475
2476 /* Setup destination index. */
2477 j = 0;
2478
2479 /* Loop to process the entire source string. */
2480 for (i = 0; i < source_length; i++)
2481 {
2482
2483 /* Pickup the first nibble. */
2484 digit = (source[i] >> 4) & 0xF;
2485
2486 /* Convert to ASCII and store. */
2487 if (digit <= 9)
2488 destination[j++] = (CHAR)(digit + '0');
2489 else
2490 destination[j++] = (CHAR)(digit + 'a' - 10);
2491
2492 /* Pickup the second nibble. */
2493 digit = source[i] & 0xF;
2494
2495 /* Convert to ASCII and store. */
2496 if (digit <= 9)
2497 destination[j++] = (CHAR)(digit + '0');
2498 else
2499 destination[j++] = (CHAR)(digit + 'a' - 10);
2500 }
2501
2502 /* Place a NULL in the destination string. */
2503 destination[j] = (CHAR) NX_NULL;
2504
2505 return;
2506 }
2507
2508
2509 /**************************************************************************/
2510 /* */
2511 /* FUNCTION RELEASE */
2512 /* */
2513 /* _nx_pop3_server_number_convert PORTABLE C */
2514 /* 6.1 */
2515 /* AUTHOR */
2516 /* */
2517 /* Yuxin Zhou, Microsoft Corporation */
2518 /* */
2519 /* DESCRIPTION */
2520 /* */
2521 /* This function converts a number into an ASCII string and returns the*/
2522 /* size of the string holding the number. */
2523 /* */
2524 /* INPUT */
2525 /* */
2526 /* number Unsigned integer number */
2527 /* string_to_convert Destination string */
2528 /* */
2529 /* OUTPUT */
2530 /* */
2531 /* Size Number of bytes in string */
2532 /* (0 implies an error) */
2533 /* */
2534 /* CALLS */
2535 /* */
2536 /* _nx_pop3_client_mail_item_get Get mail item size */
2537 /* _nx_pop3_client_mail_item_delete Delete mail item */
2538 /* */
2539 /* CALLED BY */
2540 /* */
2541 /* */
2542 /* RELEASE HISTORY */
2543 /* */
2544 /* DATE NAME DESCRIPTION */
2545 /* */
2546 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
2547 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
2548 /* resulting in version 6.1 */
2549 /* */
2550 /**************************************************************************/
_nx_pop3_server_number_convert(UINT number,CHAR * string_to_convert)2551 UINT _nx_pop3_server_number_convert(UINT number, CHAR *string_to_convert)
2552 {
2553
2554 UINT j;
2555 UINT digit;
2556 UINT size;
2557
2558
2559 /* Initialize counters. */
2560 size = 0;
2561
2562 /* Loop to convert the number to ASCII. */
2563 while (size < 9)
2564 {
2565
2566 /* Shift the current digits over one. */
2567 for (j = size; j != 0; j--)
2568 {
2569
2570 /* Move each digit over one place. */
2571 string_to_convert[j] = string_to_convert[j - 1];
2572 }
2573
2574 /* Compute the next decimal digit. */
2575 digit = number % 10;
2576
2577 /* Update the input number. */
2578 number = number / 10;
2579
2580 /* Store the new digit in ASCII form. */
2581 string_to_convert[0] = (CHAR) (digit + 0x30);
2582
2583 /* Increment the size. */
2584 size++;
2585
2586 /* Determine if the number is now zero. */
2587 if (number == 0)
2588 break;
2589 }
2590
2591 /* Make the string NULL terminated. */
2592 string_to_convert[size] = (CHAR) NX_NULL;
2593
2594 /* Determine if there is an overflow error. */
2595 if (number)
2596 {
2597
2598 /* Error, return bad values to user. */
2599 size = 0;
2600 string_to_convert[0] = '0';
2601 }
2602
2603 /* Return size to caller. */
2604 return(size);
2605 }
2606
2607
2608 /**************************************************************************/
2609 /* */
2610 /* FUNCTION RELEASE */
2611 /* */
2612 /* _nxd_pop3_client_connect PORTABLE C */
2613 /* 6.1.6 */
2614 /* AUTHOR */
2615 /* */
2616 /* Yuxin Zhou, Microsoft Corporation */
2617 /* */
2618 /* DESCRIPTION */
2619 /* */
2620 /* This function binds the Client socket to the POP3 port and connects */
2621 /* to the POP3 server. If the connection is made, this function */
2622 /* processes the server greeting, and initiates the APOP/USER */
2623 /* authentication with the sever. */
2624 /* */
2625 /* This supports both IPv6 and IPv4 POP3 server connections. */
2626 /* */
2627 /* INPUT */
2628 /* */
2629 /* client_ptr Pointer to client struct */
2630 /* server_ip_address Pointer to POP3 server IP address */
2631 /* server_port POP3 server port */
2632 /* */
2633 /* OUTPUT */
2634 /* */
2635 /* NX_SUCCESS Successful completion status */
2636 /* NX_POP3_PARAM_ERROR Invalid Client user or password */
2637 /* NX_POP3_CANNOT_PARSE_REPLY Unable to parse server reply */
2638 /* status TCP service completion status */
2639 /* */
2640 /* CALLED BY */
2641 /* */
2642 /* _nxd_pop3_client_create Create POP3 Client and socket */
2643 /* */
2644 /* CALLS */
2645 /* */
2646 /* nx_tcp_client_socket_bind NetX TCP socket bind service */
2647 /* nxd_tcp_client_socket_connect NetX TCP socket connect service */
2648 /* nx_tcp_socket_receive NetX TCP socket receive service */
2649 /* _nx_pop3_parse_response Parse Server reply code */
2650 /* _nx_pop3_parse_process_id Parse server ID for APOP digest */
2651 /* _nx_pop3_client_apop Send Authenticated user/pass */
2652 /* _nx_pop3_client_user_pass Send User Pass in clear text */
2653 /* */
2654 /* RELEASE HISTORY */
2655 /* */
2656 /* DATE NAME DESCRIPTION */
2657 /* */
2658 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
2659 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
2660 /* resulting in version 6.1 */
2661 /* 04-02-2021 Yuxin Zhou Modified comment(s), and */
2662 /* corrected the client port, */
2663 /* resulting in version 6.1.6 */
2664 /* */
2665 /**************************************************************************/
_nxd_pop3_client_connect(NX_POP3_CLIENT * client_ptr,NXD_ADDRESS * server_ip_address,ULONG server_port)2666 UINT _nxd_pop3_client_connect(NX_POP3_CLIENT *client_ptr, NXD_ADDRESS *server_ip_address, ULONG server_port)
2667 {
2668
2669 UINT status;
2670 NX_PACKET *recv_packet_ptr;
2671 CHAR *buffer_ptr;
2672 CHAR argument[10];
2673
2674
2675 /* Check for client name/password/shared secret too long for allotted buffer. */
2676 if ((_nx_utility_string_length_check(&client_ptr -> nx_pop3_client_name[0], NX_NULL, NX_POP3_MAX_USERNAME)) ||
2677 (_nx_utility_string_length_check(&client_ptr -> nx_pop3_client_password[0], NX_NULL, NX_POP3_MAX_PASSWORD)))
2678 {
2679
2680 return NX_POP3_PARAM_ERROR;
2681 }
2682
2683 status = nx_tcp_client_socket_bind(&client_ptr -> nx_pop3_client_tcp_socket, NX_ANY_PORT, NX_IP_PERIODIC_RATE);
2684
2685 /* Check for error. */
2686 if (status != NX_SUCCESS)
2687 {
2688 return status;
2689 }
2690
2691 status = nxd_tcp_client_socket_connect(&client_ptr -> nx_pop3_client_tcp_socket,
2692 server_ip_address,
2693 server_port,
2694 NX_POP3_CLIENT_CONNECTION_TIMEOUT);
2695
2696 if (status != NX_SUCCESS)
2697 {
2698 return status;
2699 }
2700
2701 /* Receive server reply over session socket. */
2702 status = nx_tcp_socket_receive(&(client_ptr -> nx_pop3_client_tcp_socket), &recv_packet_ptr, NX_POP3_SERVER_REPLY_TIMEOUT);
2703
2704 /* Check for error. */
2705 if (status != NX_SUCCESS)
2706 {
2707
2708 /* Return error condition. */
2709 return(status);
2710 }
2711
2712 #ifndef NX_DISABLE_PACKET_CHAIN
2713 if (recv_packet_ptr -> nx_packet_next)
2714 {
2715
2716 /* Chained packet is not supported. */
2717 nx_packet_release(recv_packet_ptr);
2718 return(NX_INVALID_PACKET);
2719 }
2720 #endif /* NX_DISABLE_PACKET_CHAIN */
2721
2722 /* Set a pointer to the packet data. */
2723 buffer_ptr = (CHAR *)(recv_packet_ptr -> nx_packet_prepend_ptr);
2724
2725 /* Parse the first argument of the server reply. */
2726 _nx_pop3_parse_response(buffer_ptr, 1, recv_packet_ptr -> nx_packet_length, (CHAR *)&argument, 10, NX_FALSE, NX_FALSE);
2727
2728 /* Initialize status to bad reply error condition. */
2729 status = NX_POP3_SERVER_ERROR_STATUS;
2730
2731 /* Did the server accept the Client command? */
2732 if (memcmp(argument, NX_POP3_POSITIVE_STATUS, (sizeof(NX_POP3_POSITIVE_STATUS) - 1)) == 0x0)
2733 {
2734
2735 if (client_ptr -> nx_pop3_client_enable_APOP_authentication)
2736 {
2737
2738 /* Attempt to extract the server process ID in the greeting. */
2739 _nx_pop3_parse_process_id(client_ptr, buffer_ptr, recv_packet_ptr -> nx_packet_length);
2740
2741 /* Did we find a process ID? */
2742 if (client_ptr -> nx_pop3_server_process_id[0] != 0)
2743 {
2744
2745 /* Do APOP authentication. */
2746 status = _nx_pop3_client_apop(client_ptr);
2747
2748 if (status == NX_SUCCESS)
2749 {
2750 return status;
2751 }
2752 else if (status != NX_POP3_SERVER_ERROR_STATUS)
2753 {
2754
2755 /* Another error encountered (packet pool depletion, broken connection, etc*/
2756 return status;
2757 }
2758 }
2759 else
2760 {
2761 /* Possibly the server doesn't like APOP. Try User Pass */
2762 client_ptr -> nx_pop3_client_enable_APOP_authentication = NX_FALSE;
2763 }
2764 }
2765
2766 /* Try USER PASS authentication. */
2767 status = _nx_pop3_client_user_pass(client_ptr);
2768 }
2769
2770 nx_packet_release(recv_packet_ptr);
2771
2772 return status;
2773 }
2774
2775 /**************************************************************************/
2776 /* */
2777 /* FUNCTION RELEASE */
2778 /* */
2779 /* _nx_pop3_client_apop PORTABLE C */
2780 /* 6.1 */
2781 /* AUTHOR */
2782 /* */
2783 /* Yuxin Zhou, Microsoft Corporation */
2784 /* */
2785 /* DESCRIPTION */
2786 /* */
2787 /* This function attempts to authenticate the POP3 client with the POP3*/
2788 /* server. If successful returns NX_SUCCESS. */
2789 /* */
2790 /* INPUT */
2791 /* */
2792 /* client_ptr Pointer to client struct */
2793 /* */
2794 /* OUTPUT */
2795 /* */
2796 /* NX_SUCCESS Authentication accepted by server */
2797 /* NX_POP3_APOP_FAILED_MD5_DIGEST Error creating digest */
2798 /* NX_POP3_INSUFFICIENT_PACKET_PAYLOAD */
2799 /* Packet too small for command */
2800 /* status Actual completion status */
2801 /* */
2802 /* CALLS */
2803 /* */
2804 /* nx_packet_allocate Allocate packet from packet pool */
2805 /* nx_packet_release Release packet back to pool */
2806 /* nx_tcp_socket_send Send packet out TCP socket */
2807 /* nx_tcp_socket_receive Retrieve packet from TCP socket */
2808 /* _nx_pop3_parse_response Extract word from server response */
2809 /* _nx_pop3_digest_authenticate Create authentication string */
2810 /* */
2811 /* CALLED BY */
2812 /* */
2813 /* nxd_pop3_client_connect Connect with POP3 server */
2814 /* */
2815 /* RELEASE HISTORY */
2816 /* */
2817 /* DATE NAME DESCRIPTION */
2818 /* */
2819 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
2820 /* 09-30-2020 Yuxin Zhou Modified comment(s), and */
2821 /* verified memcpy use cases, */
2822 /* resulting in version 6.1 */
2823 /* */
2824 /**************************************************************************/
_nx_pop3_client_apop(NX_POP3_CLIENT * client_ptr)2825 UINT _nx_pop3_client_apop(NX_POP3_CLIENT *client_ptr)
2826 {
2827
2828 UINT status;
2829 NX_PACKET *packet_ptr, *recv_packet_ptr;
2830 CHAR *buffer;
2831 CHAR argument[10];
2832 CHAR md5_digest_buffer[NX_POP3_MAX_ASCII_MD5 + 1];
2833 UINT packet_type;
2834 UINT index;
2835 CHAR userid_buffer[100];
2836 UINT server_process_id_length;
2837 UINT client_password_length;
2838 UINT client_name_length;
2839 UINT md5_digest_buffer_length;
2840
2841
2842 if (client_ptr -> nx_pop3_client_tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_version == NX_IP_VERSION_V6)
2843 packet_type = NX_IPv6_TCP_PACKET;
2844 else
2845 packet_type = NX_IPv4_TCP_PACKET;
2846
2847 /* Allocate a packet. */
2848 status = nx_packet_allocate(client_ptr -> nx_pop3_client_packet_pool_ptr,
2849 &packet_ptr, packet_type, NX_POP3_CLIENT_PACKET_TIMEOUT);
2850
2851 /* Check for error. */
2852 if (status != NX_SUCCESS)
2853 {
2854
2855 /* Return the error condition. */
2856 return(status);
2857 }
2858
2859 /* Create the APOP digest. */
2860 memset(&userid_buffer[0],0,sizeof(userid_buffer));
2861
2862 /* Validate copy size. */
2863 if (_nx_utility_string_length_check(client_ptr -> nx_pop3_server_process_id, &server_process_id_length, NX_POP3_SERVER_PROCESS_ID_SIZE) ||
2864 _nx_utility_string_length_check(client_ptr -> nx_pop3_client_password, &client_password_length, NX_POP3_MAX_PASSWORD))
2865 {
2866 nx_packet_release(packet_ptr);
2867 return(NX_POP3_INSUFFICIENT_PACKET_PAYLOAD);
2868 }
2869 if((server_process_id_length + client_password_length) > sizeof(userid_buffer))
2870 {
2871 nx_packet_release(packet_ptr);
2872 return(NX_POP3_INSUFFICIENT_PACKET_PAYLOAD);
2873 }
2874
2875 memcpy(&userid_buffer[0], &client_ptr -> nx_pop3_server_process_id[0], server_process_id_length); /* Use case of memcpy is verified. */
2876 index = server_process_id_length;
2877 memcpy(&userid_buffer[index], &client_ptr -> nx_pop3_client_password[0], client_password_length); /* Use case of memcpy is verified. */
2878 status = _nx_pop3_digest_authenticate(client_ptr, &userid_buffer[0], (server_process_id_length + client_password_length), &md5_digest_buffer[0]);
2879
2880 /* Check for error. */
2881 if (status != NX_SUCCESS)
2882 {
2883
2884 nx_packet_release(packet_ptr);
2885
2886 /* Return failed APOP attempt error condition. */
2887 return NX_POP3_APOP_FAILED_MD5_DIGEST;
2888 }
2889
2890 /* Verify the packet payload will hold the APOP command. */
2891 if (_nx_utility_string_length_check(client_ptr -> nx_pop3_client_name, &client_name_length, NX_POP3_MAX_USERNAME) ||
2892 _nx_utility_string_length_check(md5_digest_buffer, &md5_digest_buffer_length, NX_POP3_MAX_ASCII_MD5))
2893 {
2894
2895 /* Release the packet. */
2896 nx_packet_release(packet_ptr);
2897
2898 return NX_POP3_INSUFFICIENT_PACKET_PAYLOAD;
2899 }
2900
2901 if ((packet_ptr -> nx_packet_prepend_ptr + (sizeof(NX_POP3_COMMAND_APOP) - 1)
2902 + (sizeof(NX_POP3_COMMAND_TERMINATION) - 1) + 2
2903 + client_name_length
2904 + md5_digest_buffer_length) >= packet_ptr -> nx_packet_data_end)
2905 {
2906
2907 /* Release the packet. */
2908 nx_packet_release(packet_ptr);
2909
2910 return NX_POP3_INSUFFICIENT_PACKET_PAYLOAD;
2911 }
2912
2913 buffer = (CHAR *)packet_ptr -> nx_packet_prepend_ptr;
2914
2915 /* Create the APOP command. */
2916 memcpy(buffer, NX_POP3_COMMAND_APOP, (sizeof(NX_POP3_COMMAND_APOP) - 1)); /* Use case of memcpy is verified. */
2917 buffer += (sizeof(NX_POP3_COMMAND_APOP) - 1);
2918 packet_ptr -> nx_packet_length += (sizeof(NX_POP3_COMMAND_APOP) - 1);
2919 packet_ptr -> nx_packet_append_ptr += (sizeof(NX_POP3_COMMAND_APOP) - 1);
2920
2921 memcpy(buffer, " ", 1); /* Use case of memcpy is verified. */
2922 buffer++;
2923 packet_ptr -> nx_packet_append_ptr++;
2924 packet_ptr -> nx_packet_length++;
2925
2926 memcpy(buffer, client_ptr -> nx_pop3_client_name, client_name_length); /* Use case of memcpy is verified. */
2927 buffer += client_name_length;
2928 packet_ptr -> nx_packet_length += client_name_length;
2929 packet_ptr -> nx_packet_append_ptr += client_name_length;
2930
2931 memcpy(buffer, " ", 1); /* Use case of memcpy is verified. */
2932 buffer++;
2933 packet_ptr -> nx_packet_append_ptr++;
2934 packet_ptr -> nx_packet_length++;
2935
2936 memcpy(buffer, &md5_digest_buffer[0], md5_digest_buffer_length); /* Use case of memcpy is verified. */
2937 buffer += md5_digest_buffer_length;
2938 packet_ptr -> nx_packet_length += md5_digest_buffer_length;
2939 packet_ptr -> nx_packet_append_ptr += md5_digest_buffer_length;
2940
2941 memcpy(buffer, NX_POP3_COMMAND_TERMINATION, (sizeof(NX_POP3_COMMAND_TERMINATION) - 1)); /* Use case of memcpy is verified. */
2942 packet_ptr -> nx_packet_length += (sizeof(NX_POP3_COMMAND_TERMINATION) - 1);
2943 packet_ptr -> nx_packet_append_ptr += (sizeof(NX_POP3_COMMAND_TERMINATION) - 1);
2944
2945 /* Send the packet out. */
2946 status = nx_tcp_socket_send(&client_ptr -> nx_pop3_client_tcp_socket, packet_ptr, NX_POP3_TCP_SOCKET_SEND_WAIT);
2947
2948 /* Check for error. */
2949 if (status != NX_SUCCESS)
2950 {
2951
2952 /* Release the packet. */
2953 nx_packet_release(packet_ptr);
2954
2955 /* Return the error condition. */
2956 return(status);
2957 }
2958
2959 /* Receive server reply over session socket. */
2960 status = nx_tcp_socket_receive(&(client_ptr -> nx_pop3_client_tcp_socket), &recv_packet_ptr, NX_POP3_SERVER_REPLY_TIMEOUT);
2961
2962 /* Check for error. */
2963 if (status != NX_SUCCESS)
2964 {
2965
2966 /* Return error condition. */
2967 return(status);
2968 }
2969
2970 #ifndef NX_DISABLE_PACKET_CHAIN
2971 if (recv_packet_ptr -> nx_packet_next)
2972 {
2973
2974 /* Chained packet is not supported. */
2975 nx_packet_release(recv_packet_ptr);
2976 return(NX_INVALID_PACKET);
2977 }
2978 #endif /* NX_DISABLE_PACKET_CHAIN */
2979
2980 /* Set a pointer to the packet data. */
2981 buffer = (CHAR *)(recv_packet_ptr -> nx_packet_prepend_ptr);
2982
2983 /* Parse the first argument of the server reply. */
2984 _nx_pop3_parse_response(buffer, 1, recv_packet_ptr -> nx_packet_length, (CHAR *)&argument, 10, NX_FALSE, NX_FALSE);
2985
2986 /* Initialize status to bad reply error condition. */
2987 status = NX_POP3_SERVER_ERROR_STATUS;
2988
2989 /* Did the server accept the Client command? */
2990 if (memcmp(argument, NX_POP3_POSITIVE_STATUS, (sizeof(NX_POP3_POSITIVE_STATUS) - 1)) == 0x0)
2991 {
2992
2993 /* APOP command accepted. */
2994 status = NX_SUCCESS;
2995 }
2996
2997 nx_packet_release(recv_packet_ptr);
2998
2999 return status;
3000 }
3001
3002
3003 /**************************************************************************/
3004 /* */
3005 /* FUNCTION RELEASE */
3006 /* */
3007 /* _nx_pop3_client_user_pass PORTABLE C */
3008 /* 6.1 */
3009 /* AUTHOR */
3010 /* */
3011 /* Yuxin Zhou, Microsoft Corporation */
3012 /* */
3013 /* DESCRIPTION */
3014 /* */
3015 /* This function attempts to login using client sername and password */
3016 /* with the POP3 server. If successful returns NX_SUCCESS. */
3017 /* */
3018 /* INPUT */
3019 /* */
3020 /* client_ptr Pointer to client struct */
3021 /* */
3022 /* OUTPUT */
3023 /* */
3024 /* NX_SUCCESS Login accepted by server */
3025 /* NX_POP3_INSUFFICIENT_PACKET_PAYLOAD */
3026 /* Packet too small for command */
3027 /* status Actual completion status */
3028 /* */
3029 /* CALLS */
3030 /* */
3031 /* nx_packet_allocate Allocate packet from packet pool */
3032 /* nx_packet_release Release packet back to pool */
3033 /* nx_tcp_socket_send Send packet out TCP socket */
3034 /* nx_tcp_socket_receive Retrieve packet from TCP socket */
3035 /* _nx_pop3_parse_response Extract word from server response */
3036 /* _nx_pop3_digest_authenticate Create authentication string */
3037 /* */
3038 /* CALLED BY */
3039 /* */
3040 /* nxd_pop3_client_connect Connect with POP3 server */
3041 /* */
3042 /* RELEASE HISTORY */
3043 /* */
3044 /* DATE NAME DESCRIPTION */
3045 /* */
3046 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
3047 /* 09-30-2020 Yuxin Zhou Modified comment(s), and */
3048 /* verified memcpy use cases, */
3049 /* resulting in version 6.1 */
3050 /* */
3051 /**************************************************************************/
_nx_pop3_client_user_pass(NX_POP3_CLIENT * client_ptr)3052 UINT _nx_pop3_client_user_pass(NX_POP3_CLIENT *client_ptr)
3053 {
3054
3055 UINT status;
3056 NX_PACKET *packet_ptr, *recv_packet_ptr, *next_recv_packet_ptr;
3057 CHAR *buffer;
3058 CHAR argument[10];
3059 UINT packet_type;
3060 UINT client_name_length;
3061 UINT client_password_length;
3062
3063
3064 if (client_ptr -> nx_pop3_client_tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_version == NX_IP_VERSION_V6)
3065 packet_type = NX_IPv6_TCP_PACKET;
3066 else
3067 packet_type = NX_IPv4_TCP_PACKET;
3068
3069 /* Allocate a packet. */
3070 status = nx_packet_allocate(client_ptr -> nx_pop3_client_packet_pool_ptr,
3071 &packet_ptr, packet_type, NX_POP3_CLIENT_PACKET_TIMEOUT);
3072
3073 /* Check for error. */
3074 if (status != NX_SUCCESS)
3075 {
3076
3077 /* Return the error condition. */
3078 return(status);
3079 }
3080
3081 /* Verify the packet payload will hold the user command message. */
3082 if (_nx_utility_string_length_check(client_ptr -> nx_pop3_client_name, &client_name_length, NX_POP3_MAX_USERNAME))
3083 {
3084
3085 /* Release the packet. */
3086 nx_packet_release(packet_ptr);
3087
3088 return NX_POP3_INSUFFICIENT_PACKET_PAYLOAD;
3089 }
3090
3091 if ((packet_ptr -> nx_packet_prepend_ptr + (sizeof(NX_POP3_COMMAND_USER) - 1) +
3092 1 + client_name_length + (sizeof(NX_POP3_COMMAND_TERMINATION) - 1))
3093 >= packet_ptr -> nx_packet_data_end)
3094 {
3095
3096 /* Release the packet. */
3097 nx_packet_release(packet_ptr);
3098
3099 return NX_POP3_INSUFFICIENT_PACKET_PAYLOAD;
3100 }
3101
3102 buffer = (CHAR *)(packet_ptr -> nx_packet_prepend_ptr);
3103
3104
3105 memcpy(buffer, NX_POP3_COMMAND_USER, (sizeof(NX_POP3_COMMAND_USER) - 1)); /* Use case of memcpy is verified. */
3106 packet_ptr -> nx_packet_length = (sizeof(NX_POP3_COMMAND_USER) - 1);
3107 packet_ptr -> nx_packet_append_ptr += (sizeof(NX_POP3_COMMAND_USER) - 1);
3108 buffer += (sizeof(NX_POP3_COMMAND_USER) - 1);
3109
3110 memcpy(buffer, " ", 1); /* Use case of memcpy is verified. */
3111 packet_ptr -> nx_packet_length++;
3112 packet_ptr -> nx_packet_append_ptr++;
3113 buffer++;
3114
3115 memcpy(buffer, client_ptr -> nx_pop3_client_name, client_name_length); /* Use case of memcpy is verified. */
3116 packet_ptr -> nx_packet_length += client_name_length;
3117 packet_ptr -> nx_packet_append_ptr += client_name_length;
3118 buffer += client_name_length;
3119
3120 memcpy(buffer, NX_POP3_COMMAND_TERMINATION, (sizeof(NX_POP3_COMMAND_TERMINATION) - 1)); /* Use case of memcpy is verified. */
3121 packet_ptr -> nx_packet_length += (sizeof(NX_POP3_COMMAND_TERMINATION) - 1);
3122 packet_ptr -> nx_packet_append_ptr += (sizeof(NX_POP3_COMMAND_TERMINATION) - 1);
3123 buffer += (sizeof(NX_POP3_COMMAND_TERMINATION) - 1);
3124
3125 /* Send the packet out. */
3126 status = nx_tcp_socket_send(&client_ptr -> nx_pop3_client_tcp_socket, packet_ptr, NX_POP3_TCP_SOCKET_SEND_WAIT);
3127
3128 /* Check for error. */
3129 if (status != NX_SUCCESS)
3130 {
3131
3132 /* Release the packet. */
3133 nx_packet_release(packet_ptr);
3134
3135 /* Return the error condition. */
3136 return(status);
3137 }
3138
3139 /* Receive server reply to Client username over session socket. */
3140 status = nx_tcp_socket_receive(&(client_ptr -> nx_pop3_client_tcp_socket), &recv_packet_ptr, NX_POP3_SERVER_REPLY_TIMEOUT);
3141
3142 /* Check for error. */
3143 if (status != NX_SUCCESS)
3144 {
3145
3146 /* Return error condition. */
3147 return(status);
3148 }
3149
3150 #ifndef NX_DISABLE_PACKET_CHAIN
3151 if (recv_packet_ptr -> nx_packet_next)
3152 {
3153
3154 /* Chained packet is not supported. */
3155 nx_packet_release(recv_packet_ptr);
3156 return(NX_INVALID_PACKET);
3157 }
3158 #endif /* NX_DISABLE_PACKET_CHAIN */
3159
3160 /* Set a pointer to the packet data. */
3161 buffer = (CHAR *)(recv_packet_ptr -> nx_packet_prepend_ptr);
3162
3163 /* Parse the first argument of the server reply. */
3164 _nx_pop3_parse_response(buffer, 1, recv_packet_ptr -> nx_packet_length, (CHAR *)&argument, 10, NX_FALSE, NX_FALSE);
3165
3166 /* Initialize status to bad reply error condition. */
3167 status = NX_POP3_SERVER_ERROR_STATUS;
3168
3169 /* Did the server accept the Client command? */
3170 if (memcmp(argument, NX_POP3_POSITIVE_STATUS, (sizeof(NX_POP3_POSITIVE_STATUS) - 1)) == 0x0)
3171 {
3172
3173 /* We are done with this packet. */
3174 nx_packet_release(recv_packet_ptr);
3175
3176 if (client_ptr -> nx_pop3_client_tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_version == NX_IP_VERSION_V6)
3177 packet_type = NX_IPv6_TCP_PACKET;
3178 else
3179 packet_type = NX_IPv4_TCP_PACKET;
3180
3181 /* Allocate another packet. */
3182 status = nx_packet_allocate(client_ptr -> nx_pop3_client_packet_pool_ptr,
3183 &packet_ptr, packet_type, NX_POP3_CLIENT_PACKET_TIMEOUT);
3184
3185 /* Check for error. */
3186 if (status != NX_SUCCESS)
3187 {
3188
3189 /* Return the error condition. */
3190 return(status);
3191 }
3192
3193 /* Verify the packet payload will hold the password request. */
3194 if (_nx_utility_string_length_check(client_ptr -> nx_pop3_client_password, &client_password_length, NX_POP3_MAX_PASSWORD))
3195 {
3196
3197 /* Release the packet. */
3198 nx_packet_release(packet_ptr);
3199
3200 return NX_POP3_INSUFFICIENT_PACKET_PAYLOAD;
3201 }
3202
3203 if ((packet_ptr -> nx_packet_prepend_ptr + (sizeof(NX_POP3_COMMAND_PASS) - 1) +
3204 1 + client_password_length + (sizeof(NX_POP3_COMMAND_TERMINATION) - 1))
3205 >= packet_ptr -> nx_packet_data_end)
3206 {
3207
3208 /* Release the packet. */
3209 nx_packet_release(packet_ptr);
3210
3211 return NX_POP3_INSUFFICIENT_PACKET_PAYLOAD;
3212 }
3213
3214 buffer = (CHAR *)packet_ptr -> nx_packet_prepend_ptr;
3215 memcpy(buffer, NX_POP3_COMMAND_PASS, (sizeof(NX_POP3_COMMAND_PASS) - 1)); /* Use case of memcpy is verified. */
3216 buffer += (sizeof(NX_POP3_COMMAND_PASS) - 1);
3217 packet_ptr -> nx_packet_length += (sizeof(NX_POP3_COMMAND_PASS) - 1);
3218 packet_ptr -> nx_packet_append_ptr += (sizeof(NX_POP3_COMMAND_PASS) - 1);
3219
3220 memcpy(buffer, " ", 1); /* Use case of memcpy is verified. */
3221 buffer++;
3222 packet_ptr -> nx_packet_length++;
3223 packet_ptr -> nx_packet_append_ptr++;
3224
3225 memcpy(buffer, client_ptr -> nx_pop3_client_password, client_password_length); /* Use case of memcpy is verified. */
3226 buffer += client_password_length;
3227 packet_ptr -> nx_packet_length += client_password_length;
3228 packet_ptr -> nx_packet_append_ptr += client_password_length;
3229
3230 memcpy(buffer, NX_POP3_COMMAND_TERMINATION, (sizeof(NX_POP3_COMMAND_TERMINATION) - 1)); /* Use case of memcpy is verified. */
3231 buffer += (sizeof(NX_POP3_COMMAND_TERMINATION) - 1);
3232 packet_ptr -> nx_packet_length += (sizeof(NX_POP3_COMMAND_TERMINATION) - 1);
3233 packet_ptr -> nx_packet_append_ptr += (sizeof(NX_POP3_COMMAND_TERMINATION) - 1);
3234
3235 /* Send the next Client message out. */
3236 status = nx_tcp_socket_send(&client_ptr -> nx_pop3_client_tcp_socket, packet_ptr, NX_POP3_TCP_SOCKET_SEND_WAIT);
3237
3238 /* Check for error. */
3239 if (status != NX_SUCCESS)
3240 {
3241
3242 /* Release the packet. */
3243 nx_packet_release(packet_ptr);
3244
3245 /* Return the error condition. */
3246 return(status);
3247 }
3248
3249 /* Receive server reply to Client password over session socket. */
3250 status = nx_tcp_socket_receive(&(client_ptr -> nx_pop3_client_tcp_socket), &next_recv_packet_ptr, NX_POP3_SERVER_REPLY_TIMEOUT);
3251
3252 /* Check for error. */
3253 if (status != NX_SUCCESS)
3254 {
3255
3256 /* Return error condition. */
3257 return(status);
3258 }
3259
3260 #ifndef NX_DISABLE_PACKET_CHAIN
3261 if (next_recv_packet_ptr -> nx_packet_next)
3262 {
3263
3264 /* Chained packet is not supported. */
3265 nx_packet_release(next_recv_packet_ptr);
3266 return(NX_INVALID_PACKET);
3267 }
3268 #endif /* NX_DISABLE_PACKET_CHAIN */
3269
3270 /* Set a pointer to the packet data. */
3271 buffer = (CHAR *)(next_recv_packet_ptr -> nx_packet_prepend_ptr);
3272
3273 /* Parse the first argument of the server reply. */
3274 _nx_pop3_parse_response(buffer, 1, next_recv_packet_ptr -> nx_packet_length, (CHAR *)&argument, 10, NX_FALSE, NX_FALSE);
3275
3276 /* Did the server accept the Client command? */
3277 if (memcmp(argument, NX_POP3_POSITIVE_STATUS, (sizeof(NX_POP3_POSITIVE_STATUS) - 1)) == 0x0)
3278 {
3279
3280 status = NX_SUCCESS;
3281 }
3282
3283 /* We are done with this packet. */
3284 nx_packet_release(next_recv_packet_ptr);
3285 }
3286 else
3287 {
3288
3289 /* Server rejected the Client message. */
3290 nx_packet_release(recv_packet_ptr);
3291 }
3292
3293 return status;
3294 }
3295
3296