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