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