X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=fetchmail.h;h=4560c6834c92b1fe582574750731edb1d8852e0b;hb=98cfcef26048bba06975e68a1aad05a8bac0d65d;hp=a31ddf0aba5345eef5498debfe15f0f1496a95a0;hpb=f0eb725f677dd7e152dc3b9cc40984b535048837;p=~andy%2Ffetchmail diff --git a/fetchmail.h b/fetchmail.h index a31ddf0a..4560c683 100644 --- a/fetchmail.h +++ b/fetchmail.h @@ -5,58 +5,40 @@ * For license terms, see the file COPYING in this directory. */ -/* We need this for HAVE_STDARG_H, etc */ #include "config.h" +#ifdef __NetBSD__ +#define _NETBSD_SOURCE 1 +#endif + struct addrinfo; /* We need this for size_t */ #include -/* We need this for time_t */ -#if TIME_WITH_SYS_TIME -# include -# include -#else -# if HAVE_SYS_TIME_H -# include -# else -# include -# endif -#endif +#include +#include -#ifdef HAVE_SYS_SOCKET_H #include -#endif -#ifdef HAVE_NET_SOCKET_H -#include -#endif #include #include -/* Import Trio if needed */ -#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) -# include "trio/trio.h" -#endif +#include "fm_strl.h" + +#include "uid_db.h" #ifdef HAVE_LIBPWMD #include #endif -/* We need this for strstr */ -#if !defined(HAVE_STRSTR) && !defined(strstr) -char *strstr(const char *, const char *); -#endif - -/* constants designating the various supported protocols */ -#define P_AUTO 1 -#define P_POP2 2 -#define P_POP3 3 -#define P_APOP 4 -#define P_RPOP 5 -#define P_IMAP 6 -#define P_ETRN 7 -#define P_ODMR 8 +/** constants designating the various supported protocols -- ordered */ +enum protocols { + P_AUTO = 1 /**< probe IMAP and POP3 - deprecated */, + P_POP3 /** POP3, including APOP and KPOP, RFC 1939 et al. */, + P_IMAP /** IMAP4, RFC 3501 */, + P_ETRN /** ETRN - SMTP Service Extension for Remote Message Queue Starting, "extended TURN", RFC 1985 */, + P_ODMR /** ODMR/ATRN - On-Demand Mail Relay SMTP with dynamic addresses/Authenticated TURN, RFC 2645 */ +}; #define SMTP_PORT "smtp" #define SMTP_PORT_NUM 25 @@ -74,24 +56,25 @@ char *strstr(const char *, const char *); */ #define MAILBOX_PROTOCOL(ctl) ((ctl)->server.protocol < P_ETRN) -/* authentication types */ -#define A_ANY 0 /* use the first method that works */ -#define A_PASSWORD 1 /* password authentication */ -#define A_NTLM 2 /* Microsoft NTLM protocol */ -#define A_CRAM_MD5 3 /* CRAM-MD5 shrouding (RFC2195) */ -#define A_OTP 4 /* One-time password (RFC1508) */ -#define A_KERBEROS_V4 5 /* authenticate w/ Kerberos V4 */ -#define A_KERBEROS_V5 6 /* authenticate w/ Kerberos V5 */ -#define A_GSSAPI 7 /* authenticate with GSSAPI */ -#define A_SSH 8 /* authentication at session level */ -#define A_MSN 9 /* same as NTLM with keyword MSN */ -#define A_EXTERNAL 10 /* external authentication (client cert) */ +/** authentication types */ +enum authenticators { + A_ANY = 0 /**< use the first method that works */, + A_PASSWORD /** password authentication */, + A_NTLM /** Microsoft NTLM protocol */, + A_CRAM_MD5 /** CRAM-MD5 shrouding (RFC2195) */, + A_OTP /** One-time password (RFC1508) */, + A_APOP /** POP3 APOP */, + A_KERBEROS_V5 /** authenticate w/ Kerberos V5 */, + A_GSSAPI /** authenticate with GSSAPI */, + A_SSH /** authentication at session level */, + A_MSN /** same as NTLM with keyword MSN */, + A_EXTERNAL /** external authentication (client cert) */ +}; /* some protocols or authentication types (KERBEROS, GSSAPI, SSH) don't * require a password */ #define NO_PASSWORD(ctl) \ ((ctl)->server.authenticate == A_OTP \ - || (ctl)->server.authenticate == A_KERBEROS_V4 \ || (ctl)->server.authenticate == A_KERBEROS_V5 \ || (ctl)->server.authenticate == A_GSSAPI \ || (ctl)->server.authenticate == A_SSH \ @@ -180,7 +163,7 @@ struct runctl char *logfile; /** where to write log information */ char *idfile; /** where to store UID data */ char *pidfile; /** where to record the PID of daemon mode processes */ - char *postmaster; + const char *postmaster; char *properties; #ifdef HAVE_LIBPWMD int pinentry_timeout; @@ -194,26 +177,35 @@ struct runctl flag showdots; }; +/** \name idlist */ +/** Dual-use entry of singly-linked list for storing id/status or id/id2 + * pairs. */ struct idlist { - char *id; + char *id; /**< key */ union { struct { int num; - flag mark; /* UID-index information */ -#define UID_UNSEEN 0 /* hasn't been seen */ -#define UID_SEEN 1 /* seen, but not deleted */ -#define UID_DELETED 2 /* this message has been marked deleted */ -#define UID_EXPUNGED 3 /* this message has been expunged */ + flag mark; /**< UID-index information */ } - status; - char *id2; - } val; - struct idlist *next; + status; /**< value for id/status pairs */ + char *id2; /**< value for id/id2 pairs */ + } val; /**< union to store value for key \a id */ + struct idlist *next; /**< pointer to next list element */ }; +/** List of possible values for idlist::mark */ +enum { +UID_UNSEEN= 0, /**< id hasn't been seen */ +UID_SEEN= 1, /**< id was seen, but not deleted */ +UID_DELETED= 2, /**< this message has been marked deleted */ +UID_EXPUNGED= 3 /**< this message has been expunged */ +}; +/*@}*/ + + struct query; struct method /* describe methods for protocol state machine */ @@ -252,6 +244,11 @@ struct method /* describe methods for protocol state machine */ flag retry; /* can getrange poll for new messages? */ }; +enum badheader { BHREJECT = 0, BHACCEPT }; + +/* Message retrieval error mode */ +enum retrieveerror { RE_ABORT = 0, RE_CONTINUE, RE_MARKSEEN }; + struct hostdata /* shared among all user connections to given server */ { /* rc file data */ @@ -269,7 +266,6 @@ struct hostdata /* shared among all user connections to given server */ char *qvirtual; /* prefix removed from local user id */ flag skip; /* suppress poll in implicit mode? */ flag dns; /* do DNS lookup on multidrop? */ - flag uidl; /* use RFC1725 UIDLs? */ #ifdef SDPS_ENABLE flag sdps; /* use Demon Internet SDPS *ENV */ #endif /* SDPS_ENABLE */ @@ -277,6 +273,8 @@ struct hostdata /* shared among all user connections to given server */ flag tracepolls; /* if TRUE, add poll trace info to Received */ char *principal; /* Kerberos principal for mail service */ char *esmtp_name, *esmtp_password; /* ESMTP AUTH information */ + enum badheader badheader; /* bad-header {pass|reject} */ + enum retrieveerror retrieveerror; /* retrieve-error (abort|continue|markseen) */ #if defined(linux) || defined(__FreeBSD__) #define CAN_MONITOR @@ -333,7 +331,7 @@ struct query char *smtpaddress; /* address to force in RCPT TO */ char *smtpname; /* full RCPT TO name, including domain */ struct idlist *antispam; /* list of listener's antispam response */ - char *mda; /* local MDA to pass mail to */ + const char *mda; /* local MDA to pass mail to */ char *bsmtp; /* BSMTP output file */ char listener; /* what's the listener's wire protocol? */ #define SMTP_MODE 'S' @@ -367,6 +365,7 @@ struct query char *sslcert; /* optional SSL certificate file */ char *sslproto; /** force transport protocol (ssl2|ssl3|ssl23|tls1) - if NULL, use ssl23 for SSL and opportunistic tls1 for non-SSL connections. */ + char *sslcertfile; /* Trusted certificate file for checking the server cert */ char *sslcertpath; /* Trusted certificate directory for checking the server cert */ flag sslcertck; /* Strictly check the server cert. */ char *sslcommonname; /* CommonName to expect from server */ @@ -386,24 +385,23 @@ struct query int smtp_socket; /* socket descriptor for SMTP connection */ unsigned int uid; /* UID of user to deliver to */ struct idlist *skipped; /* messages skipped on the mail server */ - struct idlist *oldsaved, *newsaved; - struct idlist **oldsavedend; + struct uid_db oldsaved, newsaved; char lastdigest[DIGESTLEN]; /* last MD5 hash seen on this connection */ char *folder; /* folder currently being polled */ /* internal use -- per-message state */ int mimemsg; /* bitmask indicating MIME body-type */ - char digest[DIGESTLEN]; /* md5 digest buffer */ + unsigned char digest[DIGESTLEN]; /* md5 digest buffer */ /* internal use -- housekeeping */ struct query *next; /* next query control block in chain */ }; -struct msgblk /* message header parsed for open_sink() */ +struct msgblk /** message header parsed for open_sink() */ { - char *headers; /* raw message headers */ - struct idlist *recipients; /* addressees */ - char return_path[HOSTLEN + USERNAMELEN + 4]; + char *headers; /**< raw message headers */ + struct idlist *recipients; /**< addressees */ + char return_path[HOSTLEN + USERNAMELEN + 4]; /**< envelope sender */ int msglen; int reallen; }; @@ -421,8 +419,8 @@ struct msgblk /* message header parsed for open_sink() */ #define NUM_ZERO(n) ((n) < 0) #define NUM_SPECIFIED(n) ((n) != 0) -#define MULTIDROP(ctl) (ctl->wildcard || \ - ((ctl)->localnames && (ctl)->localnames->next)) +#define MULTIDROP(ctl) ((ctl)->wildcard || \ + ((ctl)->localnames && (ctl)->localnames->next)) /* * Note: tags are generated with an a%04d format from a 1-origin @@ -463,7 +461,7 @@ extern char *home; /* home directory of invoking user */ extern char *fmhome; /* fetchmail home directory */ extern int pass; /* number of re-polling pass */ extern flag configdump; /* dump control blocks as Python dictionary */ -extern char *fetchmailhost; /* either "localhost" or an FQDN */ +extern const char *fetchmailhost; /* either "localhost" or an FQDN */ extern int suppress_tags; /* suppress tags in tagged protocols? */ extern char shroud[PASSWORDLEN*2+3]; /* string to shroud in debug output */ #ifdef SDPS_ENABLE @@ -473,18 +471,17 @@ extern char *sdps_envto; extern const char *iana_charset; /* IANA assigned charset name */ -/* from ucs/norm_charmap.c */ -const char *norm_charmap(const char *name); +/* from/for ucs/norm_charmap.c */ +#include "ucs/norm_charmap.h" /* prototypes for globally callable functions */ /* from /usr/include/sys/cdefs.h */ -#if !defined __GNUC__ || __GNUC__ < 2 +#if !defined __GNUC__ # define __attribute__(xyz) /* Ignore. */ #endif /* error.c: Error reporting */ -#if defined(HAVE_STDARG_H) void report_init(int foreground); /** Flush partial message, suppress program name tag for next report printout. */ void report_flush(FILE *fp); @@ -500,12 +497,6 @@ void report_complete (FILE *fp, const char *format, ...) void report_at_line (FILE *fp, int, const char *, unsigned int, const char *, ...) __attribute__ ((format (printf, 5, 6))) ; -#else -void report (); -void report_build (); -void report_complete (); -void report_at_line (); -#endif /* driver.c -- main driver loop */ void set_timeout(int); @@ -514,6 +505,16 @@ void resetidletimeout(void); int do_protocol(struct query *, const struct method *); /* transact.c: transaction support */ +/** \ingroup gen_recv_split + * Data structure to cache data between \func gen_recv_split calls, + * must be initialized before use by calling \func gen_recv_split_init. */ +struct RecvSplit +{ + char prefix[100]; /**< prefix to match/repeat when splitting lines */ + int cached; /**< flag to record if we have data cached in \a buf */ + char buf[MSGBUFSIZE]; /**< buffer for cached data */ +}; + void init_transact(const struct method *); int readheaders(int sock, long fetchlen, @@ -522,19 +523,15 @@ int readheaders(int sock, int num, flag *suppress_readbody); int readbody(int sock, struct query *ctl, flag forward, int len); -#if defined(HAVE_STDARG_H) void gen_send(int sock, const char *, ... ) __attribute__ ((format (printf, 2, 3))) ; int gen_recv(int sock, char *buf, int size); +void gen_recv_split_init(const char *prefix, struct RecvSplit *rs); +int gen_recv_split(int sock, char *buf, int size, struct RecvSplit *rs); int gen_transact(int sock, const char *, ... ) __attribute__ ((format (printf, 2, 3))) ; -#else -void gen_send(); -int gen_recv(); -int gen_transact(); -#endif extern struct msgblk msgblk; /* use these to track what was happening when the nonresponse timer fired */ @@ -575,14 +572,11 @@ int open_sink(struct query*, struct msgblk *, int*, int*); void release_sink(struct query *); int close_sink(struct query *, struct msgblk *, flag); int open_warning_by_mail(struct query *); -#if defined(HAVE_STDARG_H) void stuff_warning(const char *, struct query *, const char *, ... ) __attribute__ ((format (printf, 3, 4))) ; -#else -void stuff_warning(); -#endif void close_warning_by_mail(struct query *, struct msgblk *); +void abort_message_sink(struct query *ctl); /* rfc822.c: RFC822 header parsing */ char *reply_hack(char *, const char *, size_t *); @@ -590,29 +584,29 @@ char *nxtaddr(const char *); /* uid.c: UID support */ extern int dofastuidl; - -void initialize_saved_lists(struct query *, const char *); -struct idlist *save_str(struct idlist **, const char *, flag); -void free_str_list(struct idlist **); -struct idlist *copy_str_list(struct idlist *idl); -void save_str_pair(struct idlist **, const char *, const char *); -void free_str_pair_list(struct idlist **); -int delete_str(struct idlist **, long); -struct idlist *str_in_list(struct idlist **, const char *, const flag); -int str_nr_in_list(struct idlist **, const char *); -int str_nr_last_in_list(struct idlist **, const char *); -void str_set_mark( struct idlist **, const char *, const flag); -int count_list( struct idlist **idl ); -char *str_from_nr_list( struct idlist **idl, long number ); -char *str_find(struct idlist **, long); -struct idlist *id_find(struct idlist **idl, long); -char *idpair_find(struct idlist **, const char *); -void append_str_list(struct idlist **, struct idlist **); -void expunge_uids(struct query *); -void uid_swap_lists(struct query *); +void initialize_saved_lists(struct query *hostlist, const char *idfile); +void expunge_uids(struct query *ctl); +void uid_swap_lists(struct query *ctl); void uid_discard_new_list(struct query *ctl); void uid_reset_num(struct query *ctl); -void write_saved_lists(struct query *, const char *); +void write_saved_lists(struct query *hostlist, const char *idfile); + +/* idlist.c */ +struct idlist *save_str(struct idlist **idl, const char *str, flag status); +void free_str_list(struct idlist **idl); +void save_str_pair(struct idlist **idl, const char *str1, const char *str2); +struct idlist *str_in_list(struct idlist **idl, const char *str, const flag caseblind); +int str_nr_in_list(struct idlist **idl, const char *str); +int str_nr_last_in_list(struct idlist **idl, const char *str); +void str_set_mark(struct idlist **idl, const char *str, const flag val); +int count_list(struct idlist **idl); +char *str_from_nr_list(struct idlist **idl, long number); +char *str_find(struct idlist **idl, long number); +struct idlist *id_find(struct idlist **idl, long number); +char *idpair_find(struct idlist **idl, const char *id); +int delete_str(struct idlist **idl, long num); +struct idlist *copy_str_list(struct idlist *idl); +void append_str_list(struct idlist **idl, struct idlist **nidl); /* rcfile_y.y */ int prc_parse_file(const char *, const flag); @@ -640,17 +634,16 @@ int interface_approve(struct hostdata *, flag domonitor); #include "xmalloc.h" /* protocol driver and methods */ -int doPOP2 (struct query *); int doPOP3 (struct query *); int doIMAP (struct query *); int doETRN (struct query *); int doODMR (struct query *); /* authentication functions */ -int do_cram_md5(int sock, char *command, struct query *ctl, char *strip); -int do_rfc1731(int sock, char *command, char *truename); -int do_gssauth(int sock, char *command, char *service, char *hostname, char *username); -int do_otp(int sock, char *command, struct query *ctl); +int do_cram_md5(int sock, const char *command, struct query *ctl, const char *strip); +int check_gss_creds(const char *service, const char *hostname); +int do_gssauth(int sock, const char *command, const char *service, const char *hostname, const char *username); +int do_otp(int sock, const char *command, struct query *ctl); /* miscellanea */ @@ -658,14 +651,14 @@ int do_otp(int sock, char *command, struct query *ctl); extern char currentwd[1024], rcfiledir[1024]; struct query *hostalloc(struct query *); -int parsecmdline (int, char **, struct runctl *, struct query *); +int parsecmdline (int, char **, struct runctl *, struct query *, flag *); char *prependdir (const char *, const char *); char *MD5Digest (unsigned const char *); -void hmac_md5 (char *, size_t, char *, size_t, unsigned char *, size_t); +void hmac_md5 (const unsigned char *, size_t, const unsigned char *, size_t, unsigned char *, size_t); int POP3_auth_rpa(char *, char *, int socket); -typedef RETSIGTYPE (*SIGHANDLERTYPE) (int); +typedef void (*SIGHANDLERTYPE) (int); void deal_with_sigchld(void); -RETSIGTYPE null_signal_handler(int sig); +void null_signal_handler(int sig); SIGHANDLERTYPE set_signal_handler(int sig, SIGHANDLERTYPE handler); int daemonize(const char *); char *fm_getpassword(char *); @@ -693,34 +686,9 @@ char *rfc2047e(const char*, const char *); void yyerror(const char *); int yylex(void); -#ifdef __EMX__ -void itimerthread(void*); -/* Have to include these first to avoid errors from redefining getcwd - and chdir. They're re-include protected in EMX, so it's okay, I - guess. */ -#include -#include -/* Redefine getcwd and chdir to get drive-letter support so we can - find all of our lock files and stuff. */ -#define getcwd _getcwd2 -#define chdir _chdir2 -#endif /* _EMX_ */ - -#ifdef HAVE_STRERROR -# if !defined(strerror) && !defined(HAVE_DECL_STRERROR) /* On some systems, strerror is a macro */ -char *strerror (int); -# endif -#endif /* HAVE_STRERROR */ - #define STRING_DISABLED (char *)-1 #define STRING_DUMMY "" -#ifdef NeXT -#ifndef S_IXGRP -#define S_IXGRP 0000010 -#endif -#endif - #ifndef HAVE_STPCPY char *stpcpy(char *, const char*); #endif @@ -732,22 +700,12 @@ char *stpcpy(char *, const char*); #endif /* __CYGWIN__ */ extern int mailserver_socket_temp; -extern char *program_name; +extern const char *program_name; /* POSIX space characters, * ;;;;; */ #define POSIX_space "\t\n\v\f\r " -/* strlcpy/strlcat prototypes */ -#ifndef HAVE_STRLCAT -size_t -strlcat(char *dst, const char *src, size_t siz); -#endif -#ifndef HAVE_STRLCPY -size_t -strlcpy(char *dst, const char *src, size_t siz); -#endif - /** Resolve the a TCP service name or a string containing only a decimal * positive integer to a port number. Returns -1 for error. */ int servport(const char *service); @@ -770,6 +728,14 @@ int must_tls(struct query *ctl); /* prototype from rfc822valid.c */ int rfc822_valid_msgid(const unsigned char *); +/* prototype from x509_name_match.c */ +int name_match(const char *p1, const char *p2); + +/* prototype from ntlmsubr.c */ +#ifdef NTLM_ENABLE +int ntlm_helper(int sock, struct query *ctl, const char *protocol); +#endif + /* macro to determine if we want to spam progress to stdout */ #define want_progress() \ ((outlevel >= O_VERBOSE || (outlevel > O_SILENT && run.showdots)) \