1 /*
2  * Copyright (c) 2011 QUALCOMM Incorporated.  All rights reserved.
3  * The file License.txt specifies the terms for use, modification,
4  * and redistribution.
5  */
6 
7 
8 /*
9  * Copyright (c) 1989 Regents of the University of California.
10  * All rights reserved.  The Berkeley software License Agreement
11  * specifies the terms and conditions for redistribution.
12  */
13 
14 
15 /*  LINTLIBRARY */
16 
17 /*
18  *  Header file for the POP programs
19  */
20 
21 #include "config.h"
22 
23 
24 #ifndef _POPPER_H
25 #  define _POPPER_H
26 
27 #include <sys/types.h>
28 #include <pwd.h>
29 #include <stdarg.h>
30 
31 #ifdef    SCRAM
32 #  include "md5.h"
33 #endif /* SCRAM */
34 
35 #define BINMAIL_IS_SETGID 1
36 
37 #ifdef HAVE_SYSLOG_H
38 #  include <syslog.h>
39 #endif /* HAVE_SYSLOG_H */
40 
41 #ifdef HAVE_SYS_SYSLOG_H
42 #  include <sys/syslog.h>
43 #endif /* HAVE_SYS_SYSLOG_H */
44 
45 #ifdef ISC
46 #  include <sys/fcntl.h>
47 #  include <net/errno.h>
48 #endif /* ISC */
49 
50 /* BSD param.h defines BSD as year and month */
51 #ifdef      HAVE_SYS_PARAM_H
52 #  include <sys/param.h>
53 #  if (defined(BSD) && (BSD >= 199103))
54 #    define     BIND43
55 #  endif /* (defined(BSD) && (BSD >= 199103)) */
56 #endif /* HAVE_SYS_PARAM_H */
57 
58 #if defined(__bsdi__)
59 #  if   _BSDI_VERSION >= 199608
60 #    include <login_cap.h>
61 #  endif /* _BSDI_VERSION >= 199608 */
62 #endif /* __bsdi__ */
63 
64 #include <sys/socket.h> /* this needs to be after system .h files */
65 
66 #ifdef BULLDB
67 #  undef    DBM     /* used by mts.c and ndbm.h */
68 #  ifdef GDBM
69 #    include <gdbm.h>
70 #  else
71 #    include <ndbm.h>
72 #  endif /* GDBM */
73 #endif /* BULLDB */
74 
75 
76 #include "version.h"
77 #include "banner.h"
78 #include "utils.h" /* for TRUE, FALSE, and BOOL */
79 
80 
81 #ifdef SCRAM
82 #  include "hmac-md5.h"
83 #  include "scram.h"
84 #endif /* SCRAM */
85 
86 
87 /*
88  * Set a maximum file name (really path) length
89  */
90 #ifdef    HAVE_LIMITS_H
91 #  include <limits.h>
92 #endif /* HAVE_LIMITS_H */
93 #ifdef    HAVE_SYS_SYSLIMITS_H
94 #  include <sys/syslimits.h>
95 #endif /* HAVE_SYS_SYSLIMITS_H */
96 #ifdef    PATH_MAX
97 #  define MAXFILENAME     PATH_MAX
98 #else
99 #  define MAXFILENAME     256
100 #endif /* PATH_MAX */
101 
102 
103 #define QPOP_NAME "Qpopper"
104 
105 
106 #define NULLCP          ((char *) 0)
107 #define SPACE           32
108 #define TAB             9
109 #define NEWLINE         '\n'
110 
111 #define MAXUSERNAMELEN  65
112 #define MAXDROPLEN      256
113 #define MAXLINELEN      1024
114 #define MAXMSGLINELEN   MAXLINELEN
115 #define MAXCMDLEN       4
116 #define MAXPARMCOUNT    5
117 #define MAXPARMLEN      10
118 #define ALLOC_MSGS      20
119 #define OUT_BUF_SIZE    512 /* Amount of output to buffer before forcing a write */
120 
121 #ifndef MAXHOSTNAMELEN
122 #  define MAXHOSTNAMELEN    64
123 #endif /* not MAXHOSTNAMELEN */
124 
125 #ifdef POPSCO
126 #  include <sys/security.h>
127 #  include <sys/audit.h>
128 #  include <prot.h>
129 #  define VOIDSTAR
130 #  ifdef SCOR5
131 #    undef  VOIDSTAR
132 #    define VOIDSTAR      (void (*)(int))
133 #  endif
134 #else /* not POPSCO */
135 #  if ( defined(AIX) || defined (HPUX) || defined(IRIX) )
136 #    define VOIDSTAR      (void (*)(int))
137 #  else
138 #    define VOIDSTAR      (void *)
139 #   endif
140 #endif /* POPSCO */
141 
142 #if defined(SCOR5) || defined(AUX) || defined(HPUX) || defined(FREEBSD)
143 #  define SIGPARAM int foo
144 #else
145 #  define SIGPARAM
146 #endif /* SCOR5 or AUX or HPUX */
147 
148 
149 typedef enum {
150     POP_PRIORITY    =   LOG_NOTICE,
151     POP_WARNING     =   LOG_WARNING,
152     POP_NOTICE      =   LOG_NOTICE,
153     POP_INFO        =   LOG_INFO,
154     POP_DEBUG       =   LOG_DEBUG
155 } log_level;
156 
157 #define POP_LOGOPTS     LOG_PID
158 
159 #ifdef POPSCO
160 #  define L_SET  0
161 #  define L_XTND 2
162 #endif /* POPSCO */
163 
164 
165 /* Make sure there is an strerror() function */
166 #ifndef HAVE_STRERROR
167 #  define STRERROR(X)  (X < sys_nerr) ? sys_errlist[X] : ""
168 #else
169 #  define STRERROR(X) strerror(X)
170 #endif /* HAVE_STRERROR */
171 
172 
173 /* Handy to have something to use in if() statements that
174  * is always defined */
175 #ifdef DEBUG
176 #  define DEBUGGING 1
177 #else /* not DEBUG */
178 #  define DEBUGGING 0
179 #endif /* DEBUG */
180 
181 
182 /*
183  * Some OSes don't have srandom, but do have srand
184  */
185 #ifndef   HAVE_SRANDOM
186 #  include <stdlib.h>
187 #  define srandom srand
188 #  define  random  rand
189 #endif /* HAVE_SRANDOM */
190 
191 /*
192  * Some OSes don't have EDQUOT defined.  If so, define it
193  * to be something unlikely to be used.
194  */
195 #include <errno.h>
196 #ifndef EDQUOT
197 #  include <limits.h>
198 #  define EDQUOT  INT_MIN /* -2147483647-1 on 32-bit systems */
199 #endif /* no EDQUOT */
200 
201 /*
202  * Some OSes don't have the newer errors defined.  If so, define
203  * to be something equivalent
204  */
205 #ifndef ECONNABORTED
206 #  define ECONNABORTED EPROTO
207 #endif /* no ECONNABORTED */
208 #ifndef EPROTO
209 #  define EPROTO ECONNABORTED
210 #endif /* no EPROTO */
211 
212 /*
213  * Some OSes (notably HPUX) use setresuid() instead of seteuid()
214  */
215 #ifdef HAVE_SETRESUID
216 #  define SETEUID(E) setresuid(-1,E,-1)
217 #else
218 #  define SETEUID(E) seteuid(E)
219 #endif /* HAVE_SETRESUID */
220 
221 /*
222  * In standalone mode we need to call _exit rather than exit
223  */
224 #ifdef STANDALONE
225 #  define EXIT _exit
226 #else
227 #  define EXIT exit
228 #endif /* STANDALONE */
229 
230 
231             /* ^A */
232 #define MMDF_SEP_CHAR   '\001'
233 
234 
235 #ifndef BULLDIR
236 #  define BULLDIR       NULL
237 #endif /* BULLDIR */
238 
239 
240 #ifndef CONTENT_LENGTH
241 #  define CONTENT_LENGTH 0
242 #endif /* CONTENT_LENGTH */
243 
244 
245 #ifndef MIN
246 #  define MIN(A,B) ( ( (A) < (B) ) ? (A) : (B) )
247 #endif /* MIN */
248 
249 #ifndef MAX
250 #  define MAX(A,B) ( ( (A) > (B) ) ? (A) : (B) )
251 #endif /* MAX */
252 
253 
254 /*
255  * Success or failure.  Such a binary world.
256  */
257 #define POP_OK          "+OK"
258 #define POP_ERR         "-ERR"
259 
260 typedef enum {
261     POP_FAILURE     =  0,
262     POP_SUCCESS     =  1
263 } pop_result;
264 
265 
266 #define POP_TERMINATE   '.'
267 #define POP_TERMINATE_S "."
268 
269 #ifndef POP_TIMEOUT
270 #  define POP_TIMEOUT 120 /* timeout connection after this many secs */
271 #endif /* POP_TIMEOUT */
272 
273 #ifndef BLOCK_UID
274 #  define BLOCK_UID   10 /* UID's <= this value are not allowed to access email */
275 #endif /* BLOCK_UID */
276 
277 #define DIG_SIZE    16
278 
279 typedef struct _pop_tls             pop_tls;            /* defined in pop_tls.h */
280 
281 #ifdef    CYRUS_SASL
282 typedef struct _pop_sasl            pop_sasl;           /* defined in pop_sasl.h */
283 #endif /* CYRUS_SASL */
284 
285 /*
286  * We often call pop_write with a literal.  Any half-decent optimizing
287  * compiler can calculate the length of a literal string much easier
288  * and more accurately than I.
289  */
290 #define POP_WRITE_LIT(P,STR)    pop_write ( P, STR, strlen(STR) )
291 
292 
293         /* Set these to the types your OS returns if they are not
294            already typedefed for you */
295 #define OFF_T       off_t
296 #define PID_T       pid_t
297 #define UID_T       uid_t
298 #define GID_T       gid_t
299 #define TIME_T      time_t
300 #define SIZE_T      size_t
301 
302 #ifdef NEXT
303 #  undef PID_T
304 #  define PID_T     int
305 #endif /* NEXT */
306 
307 #ifdef CHECK_SHELL
308 #  define WILDCARD_SHELL    "/POPPER/ANY/SHELL/"
309 #endif /* CHECK_SHELL */
310 
311 extern int              errno;
312 
313 #if !( defined(BSD) && (BSD >= 199306) ) && !defined(__USE_BSD)
314    extern int              sys_nerr;
315 #  ifndef FREEBSD
316      extern char         *   sys_errlist[];
317 #    ifndef SYS_SIGLIST_DECLARED
318 #      ifndef __linux__
319          extern char         *   sys_siglist[];
320 #      endif /* not linux */
321 #    endif /* not SYS_SIGLIST_DECLARED */
322 #  endif /* not FREEBSD */
323 #endif /* not BSD >= 199306 and not __USE_BSD */
324 
325 extern int               pop_timeout;
326 
327 extern volatile BOOL     hangup;
328 
329 
330 #define pop_command         pop_parm[0]     /*  POP command is first token */
331 #define pop_subcommand      pop_parm[1]     /*  POP XTND subcommand is the
332                                                 second token */
333 
334 typedef enum {                              /*  POP processing states */
335     auth1,                                  /*  Authentication: waiting for
336                                                 USER/APOP/AUTH  command    */
337     auth2,                                  /*  Authentication: waiting for
338                                                 PASS or RPOP or in AUTH    */
339     trans,                                  /*  Transaction                */
340     update,                                 /*  Update:  session ended,
341                                                 process maildrop changes    */
342     halt,                                   /*  (Halt):  stop processing
343                                                 and exit                    */
344     error                                   /*  (Error): something really
345                                                 bad happened                */
346 } state;
347 
348 
349 typedef enum {                              /* Authentication Method In Use: */
350     noauth,                                 /*     not established           */
351 #ifdef APOP
352     apop,                                   /*     APOP                      */
353 #endif
354 #ifdef KERBEROS
355     kerberos,                               /*     Kerberos [user/pass or
356                                                              user/rpop]      */
357 #endif
358 #ifdef SCRAM
359     scram_md5,                              /*     SCRAM-MD5                 */
360 #endif
361 #ifdef    CYRUS_SASL
362     cyrus_sasl,                             /*     The Cyrus-SASL library */
363 #endif /* CYRUS_SASL */
364     plain                                   /*     plain text [user/pass or
365                                                                user/rpop]    */
366 } auth_type;
367 
368 
369 typedef enum {                               /* Authentication Success  Substates */
370     auth=0,                                  /*  AUTH  begun                      */
371 #ifdef SCRAM
372     clchg,                                   /*  Client challenge received        */
373     clrsp,                                   /*  Client proof success             */
374     clok,                                    /*  Client likes the server's stuff  */
375 #endif
376 #ifdef APOP
377     apopcmd,                                 /*  APOP success under apop          */
378 #endif
379     user,                                    /*  USER under plain or kerberos     */
380     pass,                                    /*  PASS under plain or kerberos     */
381     rpop,                                    /*  RPOP under plain or kerberos     */
382 #ifdef    CYRUS_SASL
383     sasl,                                    /*  SASL success                     */
384 #endif /* CYRUS_SASL */
385     none                                     /*  not established or don't care    */
386 } auth_state;
387 
388 
389 /*
390  * Enumeration for chunky (pooled) network writes
391  */
392 typedef enum {                               /* Pool network writes:              */
393     ChunkyAlways = 0,                        /* - Always                          */
394     ChunkyTLS,                               /* - Only with TLS/SSL               */
395     ChunkySASL,                              /* - Only with SASL                  */
396     ChunkyNever                              /* - Never                           */
397 } chunky_type;
398 
399 
400 /*
401  * Enumeration for log-facility option
402  */
403 typedef enum {
404     PopLogMail     = LOG_MAIL,
405     PopLogLocal0   = LOG_LOCAL0,
406     PopLogLocal1   = LOG_LOCAL1,
407     PopLogLocal2   = LOG_LOCAL2,
408     PopLogLocal3   = LOG_LOCAL3,
409     PopLogLocal4   = LOG_LOCAL4,
410     PopLogLocal5   = LOG_LOCAL5,
411     PopLogLocal6   = LOG_LOCAL6,
412     PopLogLocal7   = LOG_LOCAL7
413 } log_facility_type;
414 
415 
416 /*
417  * Enumeration for clear text password handling
418  */
419 typedef enum {                               /* Clear text passwords are:         */
420     ClearTextDefault = 0,                    /* - OK if nothing better available  */
421     ClearTextNever,                          /* - never OK                        */
422     ClearTextTLS,                            /* - OK if used with TLS/SSL         */
423     ClearTextAlways,                         /* - OK even if APOP password exists */
424     ClearTextLocal                           /* - OK on 127.* (local loopback)    */
425 } clear_text_type;
426 
427 
428 /*
429  * Enumeration for how TLS/SSL is supported
430  */
431 typedef enum {
432     QPOP_TLS_NONE = 0,     /* We don't support TLS/SSL */
433     QPOP_TLS_ALT_PORT,     /* We initiate TLS immediately */
434     QPOP_TLS_STLS          /* We support the STLS command */
435 } tls_support_type;
436 
437 
438 /*
439  * Enumeration for TLS/SSL versions
440  */
441 typedef enum {
442     QPOP_TLSvDEFAULT = 0,   /* unspecified */
443     QPOP_SSLv2,             /* SSL version 2 only */
444     QPOP_SSLv3,             /* SSL version 3 only */
445     QPOP_TLSv1,             /* TLS version 1 only */
446     QPOP_SSLv23             /* TLSv1, SSLv3, and SSLv2 */
447 } tls_vers_type;
448 
449 
450 /*
451  * Enumeration for configuration option types
452  */
453 typedef enum {                               /* Config file option is:         */
454     CfgBool = 1,                             /* - boolean                      */
455     CfgInt,                                  /* - integer (positive)           */
456     CfgIntNeg,                               /* - integer, may be negative     */
457     CfgMnem,                                 /* - mnemonic                     */
458     CfgStr,                                  /* - string                       */
459     CfgBad                                   /* - INVALID VALUE                */
460 } config_opt_type;
461 
462 /*
463  * Enumeration for configuration option restrictions
464  */
465 typedef enum {                               /* Option restrictions:           */
466     CfgResNone = 1,                          /* - no restrictions              */
467     CfgResUser,                              /* - not valid under user-control */
468     CfgResInit                               /* - not valid after nw traffic   */
469 } config_restr_type;
470 
471 /*
472  * Enumeration for identifying at what stage a config file is being processed
473  */
474 typedef enum {                               /* Config file is being processed: */
475     CfgInit =1,                              /* - During our initialization     */
476     CfgConnected,                            /* - After clent traffic           */
477     CfgUser                                  /* - File is under user control    */
478 } config_call_type;
479 
480 /*
481  * Enumeration for when to call pam_*_session functions
482  */
483 typedef enum {                               /* Call pam_session_*             */
484     PamSessionDefault = 1,                   /* only if files in home dir used */
485     PamSessionNever,                         /* never                          */
486     PamSessionAlways                         /* always                         */
487 } pam_session_type;
488 
489 
490 typedef struct {                                /*  State information for
491                                                     each POP command */
492     state       ValidCurrentState;              /*  The operating state of
493                                                     the command */
494     char   *    command;                        /*  The POP command */
495     int         min_parms;                      /*  Minimum number of parms
496                                                     for the command */
497     int         max_parms;                      /*  Maximum number of parms
498                                                     for the command */
499     int         (*function) ();                 /*  The function that process
500                                                     the command */
501     state       result[2];                      /*  The resulting state after
502                                                     command processing */
503 } state_table;
504 
505 typedef struct {                                /*  Table of extensions */
506     char   *    subcommand;                     /*  The POP XTND subcommand */
507     int         min_parms;                      /*  Minimum number of parms for
508                                                     the subcommand */
509     int         max_parms;                      /*  Maximum number of parms for
510                                                     the subcommand */
511     int         (*function) ();                 /*  The function that processes
512                                                     the subcommand */
513 } xtnd_table;
514 
515 
516 typedef struct {                                /*  Table of config file settings */
517     char             *name;                     /*  The option name */
518     config_opt_type   type;                     /*  The option type */
519     config_restr_type restriction;              /*  Restrictions    */
520     int               value;                    /*  Value for switch */
521 } config_table;
522 
523 
524 typedef struct {
525     char *auth_mechanism;                       /* Name of mechanism */
526     int (*function)();                          /* Function that handles */
527 } auth_table;
528 
529 
530 typedef struct {                                /*  Message information */
531     int         number;                         /*  Message number relative to
532                                                     the beginning of list */
533     int         visible_num;                    /*  Visible message number (in
534                                                     case messages are hidden) */
535     long        length;                         /*  Length of message in
536                                                     bytes */
537     int         lines;                          /*  Number of (null-terminated)
538                                                     lines in the message */
539     int         body_lines;                     /*  Number of (null-terminated)
540                                                     lines in the body */
541     long        offset;                         /*  Offset from beginning of
542                                                     file */
543     BOOL        del_flag;                       /*  Flag indicating if message
544                                                     is marked for deletion */
545     BOOL        hide_flag;                      /*  Flag indicating if message
546                                                     is hidden but not deleted */
547     BOOL        retr_flag;                      /*  Flag indicating if message
548                                                     was retrieved */
549     BOOL        orig_retr_state;                /*  What was the state at the
550                                                     start of this session.
551                                                     Used for RSET cmd. */
552     char        uidl_str [ (DIG_SIZE * 2) + 2 ];/*  Cache of the UIDL str for
553                                                     faster access */
554 } MsgInfoList;
555 
556 typedef struct _pop POP;
557 #define QPSTACKSIZE 2                           /* Chosen for Implementation */
558 typedef void *(*FP)(POP *);
559 typedef struct CallStack {
560     FP Stack[QPSTACKSIZE];                      /* Function Pointers array */
561     int CurP;
562 } CALLSTACK;
563 
564 struct _pop {                                   /*  POP parameter block */
565     BOOL                debug;                  /*  Debugging requested */
566     BOOL                xmitting;               /*  =1 xtnd xmit started */
567     BOOL                bStats;                 /*  Stats requested */
568     BOOL                dirty;                  /*  Any mailbox changes? */
569     BOOL                bKerberos;              /*  Flag to enable kerberos
570                                                     authentication */
571     char            *   kerberos_service;       /*  Kerberos service
572                                                     being used */
573     BOOL                server_mode;            /*  Default at compile time */
574     int                 check_lock_refresh;     /*  Check for lock refresh every x msgs */
575     char            *   myname;                 /*  The name of this POP
576                                                     daemon program */
577     char            *   myhost;                 /*  The name of our host
578                                                     computer */
579     char            *   client;                 /*  Canonical name of client
580                                                     computer */
581     char            *   ipaddr;                 /*  Dotted-notation format of
582                                                     client IP address */
583     unsigned short      ipport;                 /*  Client port for privileged
584                                                     operations */
585     BOOL                bDowncase_user;         /*  TRUE to downcase user name */
586     BOOL                bTrim_domain;           /*  TRUE to trim domain from user name */
587     char                user[MAXUSERNAMELEN];   /*  Name of the POP user */
588 
589 #if     defined(__bsdi__) && _BSDI_VERSION >= 199608
590     char            *   style;                  /*  style of auth used */
591     char            *   challenge;              /*  challenge, if any */
592     login_cap_t     *   class;                  /*  user's class info */
593 #endif /* __bsdi__) && _BSDI_VERSION >= 199608 */
594 
595     clear_text_type     AllowClearText;         /*  Setting for clear text passwords */
596     state               CurrentState;           /*  The current POP operational
597                                                     state */
598     auth_type           AuthType;               /*  authentication type used */
599     auth_state          AuthState;              /*  curent authentication
600                                                     (sub) state */
601     MsgInfoList     *   mlp;                    /*  Message information list */
602     int                 msg_count;              /*  Number of messages in
603                                                     the maildrop */
604     int                 visible_msg_count;      /*  Number of visible messages */
605     int                 first_msg_hidden;       /*  =1 if the first msg is hidden */
606     int                 msgs_deleted;           /*  Number of messages flagged
607                                                     for deletion */
608     int                 last_msg;               /*  Last message touched by
609                                                     the user */
610     long                bytes_deleted;          /*  Number of maildrop bytes
611                                                     flagged for deletion */
612     char                drop_name[MAXDROPLEN];  /*  The name of the user's
613                                                     maildrop */
614     char                temp_drop[MAXDROPLEN];  /*  The name of the user's
615                                                     temporary maildrop */
616     long                drop_size;              /*  Size of the maildrop in
617                                                     bytes */
618     long                spool_end;              /*  Offset of the end of the
619                                                     mailspool */
620     FILE            *   drop;                   /*  (Temporary) mail drop */
621     int                 input_fd;               /*  Input TCP/IP communication
622                                                     file descriptor */
623     char                pcInBuf[2*MAXLINELEN];  /*  Input line buffering */
624     char            *   pcInEnd;
625     char            *   pcInStart;
626     int                 nInBufUsed;             /*  Bytes in input buffer */
627     int                 nInBufStart;            /*  Offset to 1st read byte */
628     int                 nLineLen;               /*  Length of current line */
629     FILE            *   output;                 /*  Output TCP/IP communication
630                                                     stream */
631     char                pcOutBuf[OUT_BUF_SIZE]; /*  Buffer up output so writes
632                                                     to network and TLS layer
633                                                     go in nice big chunks */
634     int                 nOutBufUsed;            /*  Number of bytes in out
635                                                     buffer */
636     FILE            *   trace;                  /*  Debugging trace file */
637     char            *   trace_name;             /*  Name of debugging trace file */
638     FILE            *   hold;                   /*  In SERVER_MODE, this value
639                                                     holds the drop FILE */
640     CALLSTACK           InProcess;              /*  Call Stack that holds the
641                                                     function to call for
642                                                     continuation */
643     char            *   inp_buffer;             /*  Input Stream */
644     char            *   pop_parm[MAXPARMCOUNT]; /*  Parse POP parameter list */
645     int                 pop_parmlen[MAXPARMCOUNT]; /*length of each parameter*/
646     int                 parm_count;             /*  Number of parameters in
647                                                     parsed list */
648     char            *   bulldir;                /*  Bulletin directory */
649     int                 nMaxBulls;              /*  Max bulletins for new users */
650 
651 #ifdef BULLDB
652 #  ifdef GDBM
653     GDBM_FILE           bull_db;
654 #  else
655     DBM            *    bull_db;                /*  Central bulletin database*/
656 #  endif
657     BOOL                bulldb_nonfatal;        /*  OK to not open bulldb ? */
658     int                 bulldb_max_tries;       /*  Max tries to open bulldb */
659 #endif
660 
661     BOOL                bNo_mime;               /*  turn all MIME into plain
662                                                     text */
663     char            *   mmdf_separator;         /*  string between messages */
664     char                md5str[BUFSIZ];         /*  String used with the shared
665                                                     secret to create the md5
666                                                     digest, i.e. APOP server
667                                                     challenge */
668     tls_support_type    tls_support;            /* TLS/SSL supported and how */
669     BOOL                tls_started;            /* handshake done */
670     struct _pop_tls *   tls_context;            /* General place to put
671                                                    TLS context */
672     char            *   tls_identity_file;      /* Single file with all certs, plus
673                                                    private key. */
674     char            *   tls_server_cert_file;   /* File with our certificate. */
675     char            *   tls_private_key_file;   /* File with our private key. */
676     char            *   tls_passphrase;         /* To decrypt private key  */
677     char            *   tls_cipher_list;        /* To restrict ciphers */
678     tls_vers_type       tls_version;            /* To restrict TLS/SSL versions */
679     int                 tls_options;            /* Desired SSL_OP_ bit flags */
680 
681 #ifdef SCRAM
682     char                cchal[ MAXLINELEN ];    /* plain text client challenge */
683     int                 cchallen;
684     char                schal[ MAXLINELEN ];    /* plain text server challenge */
685     int                 schallen;
686     SCRAM_MD5_VRFY      scram_verifiers;        /* SCRAM-MD5 verifiers & salt  */
687     SCRAM_MD5_INTEGRITY scram_mac;              /* SCRAM-MD5 MAC controls      */
688     char                authid[MAXUSERNAMELEN]; /*  Authentication ID (SASL
689                                                     only) */
690 #endif /* SCRAM */
691 
692 #ifdef    CYRUS_SASL
693     struct _pop_sasl    sasl;                   /* General place to put
694                                                    SASL items */
695 #endif /* CYRUS_SASL */
696     BOOL                sasl_complete;          /* Is SASL auth complete? */
697 
698     time_t              login_time;             /* Elapsed time to login */
699     time_t              init_time;              /* Elapsed time to init drop info */
700     time_t              clean_time;             /* Elapsed time to clean up */
701 
702 #ifdef    DRAC_AUTH
703     char            *   drac_host;              /* Host which handles drac */
704 #endif /* DRAC_AUTH */
705 
706     BOOL                bUser_opts;             /* Process ~/.qpopper-options */
707     BOOL                bSpool_opts;            /* Process .qpopper-options */
708     BOOL                bFast_update;           /* Use rename(2) instead of copying */
709     int                 login_delay;            /* Announced minimum login delay */
710     int                 expire;                 /* Announced message expiration */
711     BOOL                bDo_timing;             /* Generate timing records */
712     BOOL                bCheck_old_spool_loc;   /* Check for temp spool in spool dir despite hashed spool or home spool*/
713     BOOL                bCheck_hash_dir;        /* Check and create hash dirs */
714     BOOL                bCheck_pw_max;          /* Check for expired passwords */
715     BOOL                bUpdate_status_hdrs;    /* Update 'Status:' & 'Message-ID:' */
716     BOOL                bUpdate_on_abort;       /* Go into UPDATE on abort */
717     BOOL                bAuto_delete;           /* Delete msgs */
718     BOOL                bGroup_bulls;           /* Bulletins go to groups */
719     int                 hash_spool;             /* Using hashed spools? */
720     char               *pHome_dir_mail;         /* Home dir is spool loc */
721     BOOL                bHome_dir_misc;         /* Home dir is .cache/.pop loc */
722     BOOL                bOld_style_uid;         /* Generate pre-3.x UIDs */
723     BOOL                bUW_kluge;              /* Ignore UW status msgs */
724     BOOL                bKeep_temp_drop;        /* Keep temp drop file */
725     char               *grp_serv_mode;          /* Group for server mode */
726     char               *grp_no_serv_mode;       /* Group for no server mode */
727     char               *ext_postauth_cmd;       /* Command to exec on successful auth */
728     char               *authfile;               /* Authorization file */
729     char               *nonauthfile;            /* Non-authorization file */
730     BOOL                bShy;                   /* Hide version from non-auth users */
731     struct passwd       pw;                     /* Cached info from getpwnam (or elsewhere) */
732     gid_t               orig_group;             /* Original primary group ID */
733     char               *pMail_command;          /* Command to send mail (e.g., path to sendmail) */
734     char               *pCfg_spool_dir;         /* Spool directory */
735     char               *pCfg_temp_dir;          /* Temp spool directory */
736     char               *pCfg_temp_name;         /* Temp spool file name constant */
737     char               *pCfg_cache_dir;         /* Cache directory */
738     char               *pCfg_cache_name;        /* Cache file name constant */
739     chunky_type        chunky_writes;           /* When to pool network writes */
740     BOOL               bNo_atomic_open;         /* open() isn't automic. */
741     log_facility_type   log_facility;           /* Which log facility to use */
742     char               *pLog_login;             /* String to use when logging log-ins */
743     BOOL                bXtnd_Xmit;             /* Allow XTND XMIT */
744     BOOL                bCons_cache;            /* Be conservative when using cache */
745 #if 0 /* can't use this until we have a way to call pam_close_session with privs */
746     pam_session_type    call_pam_session;       /* When to call pam_session_* */
747 #endif
748 };
749 
750 
751 typedef enum { HANGUP,  /* SIGHUP */
752                TIMEOUT,
753                ABORT    /* Client closes connection */
754              } EXIT_REASON;
755 
756 
757 #ifdef KERBEROS
758 
759 #  if defined(KRB4) && defined(KRB5)
760 #    error you can only use one of KRB4, KRB5
761 #  endif /* KRB4 && KRB5 */
762 
763 #  if !defined(KRB4) && !defined(KRB5)
764 #    error you must use one of KRB4, KRB5
765 #  endif /* !KRB4 && !KRB5 */
766 
767 #  ifdef KRB4
768 #    ifndef KERBEROS_SERVICE
769 #      define KERBEROS_SERVICE   "rcmd"
770 #    endif
771 
772 #    ifdef SOLARIS2
773 #      include <kerberos/krb.h>
774 #    else /* not SOLARIS2 */
775 #      ifdef __bsdi__
776 #        include <kerberosIV/des.h>
777 #        include <kerberosIV/krb.h>
778 #      else /* not __bsdi__ */
779 #        include <krb.h>
780 #      endif /* __bsdi__ or not */
781 #    endif /* SOLARIS2 or not */
782 
783    extern AUTH_DAT kdata;
784 
785 #  endif /* KRB4 */
786 
787 #  ifdef KRB5
788 #    ifndef KERBEROS_SERVICE
789 #      define KERBEROS_SERVICE "pop"
790 #    endif
791 #  endif /* KRB5 */
792 
793 #endif /* KERBEROS */
794 
795 
796 int  pop_apop         (POP *p);
797 int  pop_auth         (POP *p);
798 int  pop_bull         (POP *p, struct passwd *pwp);
799 int  pop_capa         (POP *p);
800 int  pop_dele         (POP *p);
801 int  pop_dropcopy     (POP *p, struct passwd *pwp);
802 int  pop_epop         (POP *p);
803 int  pop_euidl        (POP *p);
804 int  pop_exit         (POP *p, EXIT_REASON e);
805 int  pop_init         (POP *p, int argcount, char **argmessage);
806 int  pop_last         (POP *p);
807 int  pop_list         (POP *p);
808 int  pop_mdef         (POP *p);
809 int  pop_noop         (POP *p);
810 int  pop_parse        (POP *p, char *buf);
811 pop_result pop_pass   (POP *p);
812 int  pop_quit         (POP *p);
813 int  pop_restore      (POP *p);
814 int  pop_rpop         (POP *p);
815 int  pop_rset         (POP *p);
816 int  pop_scram        (POP *p);
817 int  pop_send         (POP *p);
818 int  pop_sendline     (POP *p, char *buffer);
819 int  pop_stat         (POP *p);
820 int  pop_stls         (POP *p);
821 struct _pop_tls *pop_tls_init(POP *pPOP);
822 int  pop_uidl         (POP *p);
823 int  pop_updt         (POP *p);
824 int  pop_user         (POP *p);
825 void pop_write        (POP *p, char *buffer, int length);
826 void pop_write_flush  (POP *p);
827 void pop_write_fmt    (POP *p, const char *format, ...) ATTRIB_FMT(2,3);
828 void pop_write_line   (POP *p, char *buffer);
829 int  pop_xlst         (POP *p);
830 int  pop_xmit         (POP *p);
831 int  pop_xmit_clean   (POP *p);
832 int  pop_xmit_exec    (POP *p);
833 int  pop_xmit_recv    (POP *p, char *buffer);
834 int  pop_xtnd         (POP *p);
835 
836 pop_result pop_config (POP *p, char *config_file, config_call_type CallTime);
837 pop_result delete_msg (POP *p, MsgInfoList *mp);
838 pop_result undelete_msg(POP *p, MsgInfoList *mp);
839 pop_result set_option (POP *p, char *opt_name, char *opt_value);
840 
841 int  decode64(char *instr, int instrlen, char *outstr, int *outstrlen);
842 int  encode64(char *instr, int instrlen, char *outstr, int *outstrlen);
843 
844 int pop_log (POP *p, log_level  loglev, const char  *fn, size_t ln, const char *format, ... ) ATTRIB_FMT(5,6);  /* parameters for format string */
845 int pop_msg (POP *p, pop_result status, const char  *fn, size_t ln, const char *format, ... ) ATTRIB_FMT(5,6);
846 int pop_logv(POP *p, log_level  loglev, const char  *fn, size_t ln, const char *format, va_list ap ) ATTRIB_FMT(5,0); /* parameters for format string */
847 
848 int  cache_write   (POP *p, int spool_fd, MsgInfoList *mp);
849 int  cache_read    (POP *p, FILE* spool_fd, MsgInfoList **mp);
850 void cache_unlink  (POP *p);
851 
852 pop_tls *pop_tls_init(POP *pPOP);
853 int      pop_tls_handshake(pop_tls *);
854 int      pop_tls_write(pop_tls *, char *, int);
855 int      pop_tls_flush(pop_tls *);
856 int      pop_tls_read(pop_tls *, char *, int);
857 void     pop_tls_shutdown(POP *pPOP);
858 
859 void     pop_sasl_mechs(POP *p);
860 int      pop_sasl_write(POP *, char *, int);
861 int      pop_sasl_read(POP *, char *, int);
862 int      pop_sasl_flush(POP *);
863 void     pop_sasl_done(POP *p);
864 
865 int  mkstemp       (char *path);
866 void pop_lower     (char *buf);
867 
868 int   check_group        (POP *p, struct passwd *pwd, const char *group_name);
869 int   isfromline         (char *cp);
870 void  downcase_uname     (POP *p, char *q);
871 void  trim_domain        (POP *p, char *q);
872 char *get_state_name     (state curState );
873 void  check_config_files (POP *p, struct passwd *pwp );
874 int   checkauthfile      (POP *p);
875 int   checknonauthfile   (POP *p);
876 void  do_log_login       (POP *p);
877 
878 int  qpopper ( int argc, char *argv[] );
879 
880 extern char *pwerrmsg;
881 
882 #define pop_auth_fail   pop_msg
883 
884 
885 int          Push        (CALLSTACK *, FP);
886 FP           Pop         (CALLSTACK *);
887 int          StackSize   (CALLSTACK *);
888 CALLSTACK   *StackInit   (CALLSTACK *);
889 FP           GetTop      (CALLSTACK *, int *);
890 FP           GetNext     (CALLSTACK *, int *);
891 
892 
893 char *get_time();
894 extern char *ZONE;
895 
896 struct topper {
897   int    lines_to_output;
898   void **out_state;
899   char   last_char;
900   char   in_header;
901   char   is_top;
902   unsigned long    body_lines;
903 } ;
904 extern struct topper topper_global;
905 #define MSG_LINES (topper_global.body_lines)
906 
907 typedef struct {
908     char *mdef_macro;
909     char *mdef_value;
910 }MDEFRecordType;              /* To maintain MDEF Array defined
911                                  in pop_extend.c. Used by pop_parse
912                                  for expansion. */
913 enum { MAX_MDEF_INDEX = 10 };
914 enum { MAX_MDEF_LENGTH = 100 };
915 
916 
917 MsgInfoList *msg_ptr ( POP *p, int msg_num );
918 
919 
920 #define HERE    __FILE__,        __LINE__
921 #define WHENCE  const char * fn, size_t ln
922 
923 #ifdef DEBUG
924 
925 #  define DEBUG_LOG0(a,b) do {                                      \
926         if ( (a)->debug )                                           \
927             pop_log ( a, POP_DEBUG, HERE, b);                       \
928     } while ( 0 );
929 #  define DEBUG_LOG1(a,b,a1) do {                                   \
930         if ( (a)->debug )                                           \
931             pop_log ( a, POP_DEBUG, HERE, b, a1);                   \
932     } while ( 0 );
933 #  define DEBUG_LOG2(a,b,a1,a2) do {                                \
934         if ( (a)->debug )                                           \
935             pop_log ( a, POP_DEBUG, HERE, b, a1, a2);               \
936     } while ( 0 );
937 #  define DEBUG_LOG3(a,b,a1,a2,a3) do {                             \
938         if ( (a)->debug )                                           \
939             pop_log ( a, POP_DEBUG, HERE, b, a1, a2, a3);           \
940     }while(0);
941 #  define DEBUG_LOG4(a,b,a1,a2,a3,a4) do {                          \
942         if ( (a)->debug )                                           \
943             pop_log ( a, POP_DEBUG, HERE, b, a1, a2, a3, a4);       \
944     } while ( 0 );
945 #  define DEBUG_LOG5(a,b,a1,a2,a3,a4,a5) do {                       \
946         if ( (a)->debug )                                           \
947             pop_log ( a, POP_DEBUG, HERE, b, a1, a2, a3, a4, a5);   \
948     } while ( 0 );
949 #  define DEBUG_LOG6(a,b,a1,a2,a3,a4,a5,a6) do {                    \
950         if ( (a)->debug )                                           \
951             pop_log ( a, POP_DEBUG, HERE, b, a1, a2, a3, a4, a5,    \
952                       a6);                                          \
953     } while ( 0 );
954 #  define DEBUG_LOG7(a,b,a1,a2,a3,a4,a5,a6,a7) do {                 \
955         if ( (a)->debug )                                           \
956             pop_log ( a, POP_DEBUG, HERE, b, a1, a2, a3, a4, a5,    \
957                       a6, a7);                                      \
958     } while ( 0 );
959 #  define DEBUG_LOG8(a,b,a1,a2,a3,a4,a5,a6,a7,a8) do {              \
960         if ( (a)->debug )                                           \
961             pop_log ( a, POP_DEBUG, HERE, b, a1, a2, a3, a4, a5,    \
962                       a6, a7, a8);                                  \
963     } while ( 0 );
964 #  define DEBUG_LOG9(a,b,a1,a2,a3,a4,a5,a6,a7,a8,a9) do {           \
965         if ( (a)->debug )                                           \
966             pop_log ( a, POP_DEBUG, HERE, b, a1, a2, a3, a4, a5,    \
967                       a6, a7, a8, a9);                              \
968     } while ( 0 );
969 
970 #else
971 
972 #  define DEBUG_LOG0(a,b)
973 #  define DEBUG_LOG1(a,b,a1)
974 #  define DEBUG_LOG2(a,b,a1,a2)
975 #  define DEBUG_LOG3(a,b,a1,a2,a3)
976 #  define DEBUG_LOG4(a,b,a1,a2,a3,a4)
977 #  define DEBUG_LOG5(a,b,a1,a2,a3,a4,a5)
978 #  define DEBUG_LOG6(a,b,a1,a2,a3,a4,a5,a6)
979 #  define DEBUG_LOG7(a,b,a1,a2,a3,a4,a5,a6,a7)
980 #  define DEBUG_LOG8(a,b,a1,a2,a3,a4,a5,a6,a7,a8)
981 #  define DEBUG_LOG9(a,b,a1,a2,a3,a4,a5,a6,a7,a8,a9)
982 #endif
983 
984 #ifdef    _DEBUG
985 #  define _DEBUG_LOG0 DEBUG_LOG0
986 #  define _DEBUG_LOG1 DEBUG_LOG1
987 #  define _DEBUG_LOG2 DEBUG_LOG2
988 #  define _DEBUG_LOG3 DEBUG_LOG3
989 #  define _DEBUG_LOG4 DEBUG_LOG4
990 #  define _DEBUG_LOG5 DEBUG_LOG5
991 #  define _DEBUG_LOG6 DEBUG_LOG6
992 #  define _DEBUG_LOG7 DEBUG_LOG7
993 #  define _DEBUG_LOG8 DEBUG_LOG8
994 #  define _DEBUG_LOG9 DEBUG_LOG9
995 #else
996 #  define _DEBUG_LOG0(a,b)
997 #  define _DEBUG_LOG1(a,b,a1)
998 #  define _DEBUG_LOG2(a,b,a1,a2)
999 #  define _DEBUG_LOG3(a,b,a1,a2,a3)
1000 #  define _DEBUG_LOG4(a,b,a1,a2,a3,a4)
1001 #  define _DEBUG_LOG5(a,b,a1,a2,a3,a4,a5)
1002 #  define _DEBUG_LOG6(a,b,a1,a2,a3,a4,a5,a6)
1003 #  define _DEBUG_LOG7(a,b,a1,a2,a3,a4,a5,a6,a7)
1004 #  define _DEBUG_LOG8(a,b,a1,a2,a3,a4,a5,a6,a7,a8)
1005 #  define _DEBUG_LOG9(a,b,a1,a2,a3,a4,a5,a6,a7,a8,a9)
1006 #endif /* _DEBUG */
1007 
1008 
1009 #endif /* _POPPER_H */
1010