diff options
Diffstat (limited to 'fetchmail.py')
-rwxr-xr-x | fetchmail.py | 367 |
1 files changed, 348 insertions, 19 deletions
diff --git a/fetchmail.py b/fetchmail.py index ef3c5212..889f59ab 100755 --- a/fetchmail.py +++ b/fetchmail.py @@ -49,17 +49,6 @@ KPOP_PORT = 1109 SIMAP_PORT = 993 SPOP3_PORT = 995 -# authentication types -A_ANY = 0 # use the first method that works -A_PASSWORD = 1 # password authentication -A_NTLM = 2 # Microsoft NTLM protocol -A_CRAM_MD5 = 3 # CRAM-MD5 shrouding (RFC2195) -A_OTP = 4 # One-time password (RFC1508) -A_KERBEROS_V4 = 5 # authenticate w/ Kerberos V4 -A_KERBEROS_V5 = 6 # authenticate w/ Kerberos V5 -A_GSSAPI = 7 # authenticate with GSSAPI -A_SSH = 8 # authentication at session level - def DOTLINE(s): return (s[0] == '.' and (s[1]=='\r' or s[1]=='\n' or s[1]=='\0')) @@ -174,11 +163,10 @@ class hostdata: akalist = [] # server name first, then akas localdomains = [] # list of pass-through domains protocol = None # protocol type - service = None # IPv6 service name netsec = None # IPv6 security request - port = 0 # TCP/IP service port number + port = None # TCP/IP service port number (name in IPV6) interval = 0 # cycles to skip between polls - authenticate = 'A_PASSWD' # authentication mode to try + authenticate = 'password' # authentication mode to try timeout = 300 # inactivity timout in seconds envelope = None # envelope address list header envskip = 0 # skip to numbered envelope header @@ -210,6 +198,12 @@ class hostdata: lead_server = None # ptr to lead query for this server esmtp_options = [] # ESMTP option list + def is_mailbox_protocol(self): + # We need to distinguish between mailbox and mailbag protocols. + # Under a mailbox protocol we're pulling mail for a speecific user. + # Under a mailbag protocol we're fetching mail for an entire domain. + return self.protocol != proto_etrn + class query: "All the parameters of a fetchmail query." # mailserver connection controls @@ -283,11 +277,346 @@ class query: mimemsg = 0 # bitmask indicating MIME body-type digest = None - def mailbox_protocol(self): - # We need to distinguish between mailbox and mailbag protocols. - # Under a mailbox protocol we're pulling mail for a speecific user. - # Under a mailbag protocol we're fetching mail for an entire domain. - return self.server.protocol != proto_etrn + def dump(self): + print "Options for retrieving from %s@%s:" \ + % (self.remotename, self.server.pollname) + if self.server.via and self.server.server.is_mailbox_protocol(): + print " Mail will be retrieved via %s" % self.server.via + if self.server.interval: + print " Poll of this server will occur every %d intervals." \ + % self.server.interval; + if self.server.truename: + print " True name of server is %s." % self.server.truename + if self.server.skip || outlevel >= O_VERBOSE: + if self.server.skip: + print " Will not be queried when no host is specified." + else: + print " Will not be queried when no host is specified." + if self.server.authenticate not in ('KERBEROS', 'GSSAPI', 'SSH'): + if not self.password: + print " Password will be prompted for." + else if outlevel >= O_VERBOSE: + if self.server.protocol == proto_apop: + print " APOP secret = \"%s\"." % self.password + elif self.server.protocol == proto_rpop: + print " RPOP id = \"%s\"." % self.password + else + print " Password = \"%s\"." % self.password + + if self.server.protocol == proto_pop3 \ + and self.server.port == KPOP_PORT \ + and self.server.authenticate.startswith("Kerberos"): + sys.stdout.write(" Protocol is KPOP with %s authentication" \ + % self.server.authenticate) + else + sys.stdout.write(" Protocol is %s" % self.server.protocol.name) + if ipv6: + if self.server.port: + sys.stdout.write(" (using service %s)" % self.server.port) + if (self.server.netsec) + sys.stdout.write(" (using network security options %s)" % self.server.netsec) + else: + if self.server.port: + sys.stdout.write(" (using port %d)" % self.server.port) + else if outlevel >= O_VERBOSE: + sys.stdout.write(" (using default port)") + if self.server.uidl and self.server.is_mailbox.protocol()) + sys.stdout.write(" (forcing UIDL use)") + sys.stdout.write("\n") + print { + None : " All available authentication methods will be tried.", + 'password' : " Password authentication will be forced.", + 'NTLM' : " NTLM authentication will be forced.", + 'OTP' : " OTP authentication will be forced.", + 'CRAM-MD5' " CRAM-MD5 authentication will be forced.", + 'GSSAPI' : " GSSAPI authentication will be forced.", + 'Kerberos V4' : " Kerberos V4 authentication will be forced.", + 'Kerberos V5' : " Kerberos V5 authentication will be forced.", + 'ssh' : " End-to-end encryption will be assumed.", + }[self.server.authenticate] + + if self.server.principal: + print " Mail service principal is: %s" % self.server.principal + if self.use_ssl: + print " SSL encrypted sessions enabled." + if self.sslproto: + print " SSL protocol: %s." % self.sslproto; + if self.sslcertck: + print " SSL server certificate checking enabled." + if self.sslcertpath: + print " SSL trusted certificate directory: %s" % self.sslcertpath; + if self.sslfingerprint: + print " SSL key fingerprint (checked against the server key): %s" % self.sslfingerprint; + if self.server.timeout > 0: + print " Server nonresponse timeout is %d seconds" % self.server.timeout; + if self.server.is_mailbox_protocol(): + if not self.mailboxes.id: + print " Default mailbox selected." + else + print " Selected mailboxes are: ", ", ".join(self.mailboxes) + flagarray = ( + ('fetchall', + "%s messages will be retrieved (--all %s)." + "All", "Only new") + ('keep', + " Fetched messages %s be kept on the server (--keep %s)." + "will", "will not") + ('flush', + " Old messages %s be flushed before message retrieval (--flush %s).", + "will", "will not") + ('rewrite', + " Rewrite of server-local addresses is %s (norewrite %s).", + "enabled", "disabled") + ('stripcr', + " Carriage-return stripping is %s (stripcr %s).", + "enabled", "disabled") + ('forcecr', + " Carriage-return forcing is %s (forcecr %s).", + "enabled", "disabled") + ('pass8bits', + " Interpretation of Content-Transfer-Encoding is %s (pass8bits %s).", + "enabled", "disabled") + ('mimedecode', + " MIME decoding is %s (mimedecode %s).", + "enabled", "disabled") + ('idle', + " Idle after poll is %s (idle %s).", + "enabled", "disabled") + ('dropstatus', + " Nonempty Status lines will be %s (dropstatus %s)", + "discarded", "kept") + ('dropdelivered', + " Delivered-To lines will be %s (dropdelivered %s)", + "discarded", "kept") + ) + for (attr, template, on, off) in flagarray: + flag = getattr(self, att) + if flag: + onoff1 = on + onoff2 = "on" + else: + onoff1 = off + onoff2 = "off" + print template % (onoff1, onoff2) + if self.limit: + { + if NUM_NONZERO(self.limit): + print " Message size limit is %d octets (--limit %d)." % + self.limit, self.limit); + else if outlevel >= O_VERBOSE: + print " No message size limit (--limit 0)." + if run.poll_interval > 0: + print " Message size warning interval is %d seconds (--warnings %d)." % + self.warnings, self.warnings); + else if outlevel >= O_VERBOSE: + print " Size warnings on every poll (--warnings 0)." + } + if NUM_NONZERO(self.fetchlimit): + print " Received-message limit is %d (--fetchlimit %d)."), + self.fetchlimit, self.fetchlimit); + else if outlevel >= O_VERBOSE: + print " No received-message limit (--fetchlimit 0)." + if NUM_NONZERO(self.batchlimit): + print " SMTP message batch limit is %d." % self.batchlimit); + else if outlevel >= O_VERBOSE: + print " No SMTP message batch limit (--batchlimit 0)." + if MAILBOX_PROTOCOL(ctl): + { + if NUM_NONZERO(self.expunge): + print " Deletion interval between expunges forced to %d (--expunge %d)." % self.expunge, self.expunge); + else if outlevel >= O_VERBOSE: + print " No forced expunges (--expunge 0)." + } + } + else /* ODMR or ETRN */ + { + struct idlist *idp; + + print " Domains for which mail will be fetched are:" + for (idp = self.domainlist; idp; idp = idp.next: + { + printf(" %s", idp.id); + if not idp.val.status.mark: + print " (default)" + } + printf(""); + } + if self.bsmtp: + print " Messages will be appended to %s as BSMTP" % visbuf(self.bsmtp + else if self.mda and MAILBOX_PROTOCOL(ctl): + print " Messages will be delivered with \"%s\"." % visbuf(self.mda + else + { + struct idlist *idp; + + if self.smtphunt: + { + print " Messages will be %cMTP-forwarded to:" % + self.listener); + for (idp = self.smtphunt; idp; idp = idp.next: + { + printf(" %s", idp.id); + if not idp.val.status.mark: + print " (default)" + } + printf(""); + } + if self.smtpaddress: + print " Host part of MAIL FROM line will be %s"), + self.smtpaddress); + if self.smtpname: + print " Address to be put in RCPT TO lines shipped to SMTP will be %s"), + self.smtpname); + } + if MAILBOX_PROTOCOL(ctl): + { + if self.antispam != (struct idlist *)NULL: + { + struct idlist *idp; + + print " Recognized listener spam block responses are:" + for (idp = self.antispam; idp; idp = idp.next: + printf(" %d", idp.val.status.num); + printf(""); + } + else if outlevel >= O_VERBOSE: + print " Spam-blocking disabled" + } + if self.preconnect: + print " Server connection will be brought up with \"%s\"."), + visbuf(self.preconnect + else if outlevel >= O_VERBOSE: + print " No pre-connection command." + if self.postconnect: + print " Server connection will be taken down with \"%s\"."), + visbuf(self.postconnect + else if outlevel >= O_VERBOSE: + print " No post-connection command." + if MAILBOX_PROTOCOL(ctl)) { + if !self.localnames: + print " No localnames declared for this host." + else + { + struct idlist *idp; + int count = 0; + + for (idp = self.localnames; idp; idp = idp.next: + ++count; + + if count > 1 || self.wildcard: + print " Multi-drop mode: " + else + print " Single-drop mode: " + + print "%d local name(s) recognized." % count); + if outlevel >= O_VERBOSE: + { + for (idp = self.localnames; idp; idp = idp.next: + if idp.val.id2: + printf("\t%s . %s", idp.id, idp.val.id2); + else + printf("\t%s", idp.id); + if self.wildcard: + fputs("\t*", stdout); + } + + if count > 1 || self.wildcard: + { + print " DNS lookup for multidrop addresses is %s."), + self.server.dns ? GT_("enabled") : GT_("disabled" + if self.server.dns: + { + print " Server aliases will be compared with multidrop addresses by " + if self.server.checkalias: + print "IP address." + else + print "name." + } + if self.server.envelope == STRING_DISABLED: + print " Envelope-address routing is disabled" + else + { + print " Envelope header is assumed to be: %s"), + self.server.envelope ? self.server.envelope:GT_("Received" + if self.server.envskip > 1 || outlevel >= O_VERBOSE: + print " Number of envelope header to be parsed: %d"), + self.server.envskip); + if self.server.qvirtual: + print " Prefix %s will be removed from user id"), + self.server.qvirtual); + else if outlevel >= O_VERBOSE) + print " No prefix stripping" + } + + if self.server.akalist: + { + struct idlist *idp; + + print " Predeclared mailserver aliases:" + for (idp = self.server.akalist; idp; idp = idp.next: + printf(" %s", idp.id); + putchar(''); + } + if self.server.localdomains: + { + struct idlist *idp; + + print " Local domains:" + for (idp = self.server.localdomains; idp; idp = idp.next: + printf(" %s", idp.id); + putchar(''); + } + } + } + } +#if defined(linux) || defined(__FreeBSD__: + if self.server.interface: + print " Connection must be through interface %s." % self.server.interface); + else if outlevel >= O_VERBOSE: + print " No interface requirement specified." + if self.server.monitor: + print " Polling loop will monitor %s." % self.server.monitor); + else if outlevel >= O_VERBOSE: + print " No monitor interface specified." +#endif + + if self.server.plugin: + print " Server connections will be made via plugin %s (--plugin %s)." % self.server.plugin, self.server.plugin); + else if outlevel >= O_VERBOSE: + print " No plugin command specified." + if self.server.plugout: + print " Listener connections will be made via plugout %s (--plugout %s)." % self.server.plugout, self.server.plugout); + else if outlevel >= O_VERBOSE: + print " No plugout command specified." + + if self.server.protocol > P_POP2 and MAILBOX_PROTOCOL(ctl): + { + if !self.oldsaved: + print " No UIDs saved from this host." + else + { + struct idlist *idp; + int count = 0; + + for (idp = self.oldsaved; idp; idp = idp.next: + ++count; + + print " %d UIDs saved." % count); + if outlevel >= O_VERBOSE: + for (idp = self.oldsaved; idp; idp = idp.next: + printf("\t%s", idp.id); + } + } + + if self.tracepolls: + print " Poll trace information will be added to the Received header." + else if outlevel >= O_VERBOSE: + print " No poll trace information will be added to the Received header.." + + if self.properties: + print " Pass-through properties \"%s\"." % self.properties + + if __name__ == '__main__': # C version queried FETCHMAILUSER, then USER, then LOGNAME. |