aboutsummaryrefslogtreecommitdiffstats
Commit message (Expand)AuthorAgeFilesLines
...
* | Fix useless GCC8 warning, strncpy->memcpy for fixed string.Matthias Andree2018-04-141-1/+1
* | Fix GCC8 ?: operator type promotion warning.Matthias Andree2018-04-141-2/+2
* | Fix indentation to silence GCC 8 warnings.Matthias Andree2018-04-142-8/+8
* | In-depth fix for to64frombits() BASE64 encoder buffer sizing.Matthias Andree2018-04-147-14/+20
* | ISO C90 ("C89") compatibility fix.Matthias Andree2018-04-141-1/+1
* | Abort GSSAPI authentication properly in more situations.Matthias Andree2018-04-141-3/+3
* | Prevent buffer overruns in do_gssauth() with long user names.Matthias Andree2018-04-142-1/+14
* | GSSAPI: Do not add gratuitious NUL byte to username.Matthias Andree2018-04-142-1/+4
|/
* Merge branch 'bluhm/fetchmail-plugin-length' into legacy_64Matthias Andree2017-08-111-1/+3
|\
| * Add a FIXME comment.Matthias Andree2017-08-111-0/+2
| * Do not overrun plugin string when copying it.Alexander Bluhm2017-08-101-1/+1
|/
* Call AM_PROG_AR to simplify LTO use.Matthias Andree2017-04-231-1/+2
* Cast argument to quiet -Wformat warning in C89 mode.Matthias Andree2017-04-231-1/+1
* Remove last traces of gethostbyname().Matthias Andree2017-04-227-415/+3
* Update copyright.Matthias Andree2017-04-224-1040/+1255
* Avoid deprecated regexps in manServer.plMatthias Andree2017-04-221-3/+3
* Update.Matthias Andree2017-02-201-0/+3
* Update.Matthias Andree2017-02-201-1/+2
* Reinstate --sslcertfile documentation.Matthias Andree2017-02-201-0/+1
* Quiet linker warnings around yywrap() fix when using a C++ compiler.Matthias Andree2017-02-111-0/+3
* Work around GNU flex madness around yywrap().Matthias Andree2017-02-111-3/+5
* Mention tls1.3 and + option in NEWS.Matthias Andree2017-02-111-2/+3
* Reformat.Matthias Andree2017-02-111-2/+2
* TLS: set hostname for SNI.Matthias Andree2017-02-111-0/+14
* Initial TLSv1.3 support code.Matthias Andree2017-02-111-1/+27
* Add one comment to pop3_fastuidl().Matthias Andree2017-02-111-0/+2
* Bump version to beta3.Matthias Andree2017-02-111-1/+1
* Cease creating .tar.bz2 tarballs. (Keep .tar.xz)Matthias Andree2016-12-121-1/+1
* Fixup protocol version handling in OpenSSL 1.0.X.Matthias Andree2016-12-121-0/+4
* Drop unused variable.Matthias Andree2016-12-121-1/+0
* Merge branch 'uidl-speedup-n-log-n-64' into legacy_64Matthias Andree2016-12-1211-144/+967
|\
| * Mention import of P-Tree O(n log n) code for UIDL.Matthias Andree2016-12-111-0/+8
| * Avoid compiling unused function.Matthias Andree2016-12-111-0/+2
| * Fix portability to C90 and C++.Matthias Andree2016-12-115-12/+17
| * Report UIDs from databases one-per-line, with one leading blank space.Matthias Andree2016-12-111-9/+9
| * #define __EXTENSIONS__ to have Solaris expose ffs() from strings.hMatthias Andree2016-12-111-1/+4
| * Fixup last patch from Thomas, return void rather than NULL.Matthias Andree2016-12-111-1/+1
| * Protect against possible NULL pointerThomas Jarosch2016-12-111-0/+2
| * Fix crash on --flush.Rainer Weikusat2016-12-111-2/+5
| * #include <strings.h> for ffs() prototype.Matthias Andree2016-12-111-0/+1
| * Fix uninitialized variable.Matthias Andree2016-12-111-2/+2
| * C++ compat: cast types explicitly.Matthias Andree2016-12-112-8/+8
| * UIDL database speedup with Patricia trees.Matthias Andree2016-12-117-128/+927
* | Update German translation.Matthias Andree2016-12-121-331/+376
* | Support for Debian/Ubuntu mutilated SSLv3 support.Matthias Andree2016-12-121-0/+4
* | OpenSSL 1.1.0 API support.Matthias Andree2016-12-121-4/+76
* | Refactor OpenSSL protocol version selection logic.Matthias Andree2016-12-121-44/+54
* | Fail build early if socket.o cannot be generated.Matthias Andree2016-12-121-1/+4
|/
* Bump OpenSSL requirement to v1.0.2.Matthias Andree2016-12-113-4/+4
* Fix missing fileno() declaration.Matthias Andree2016-09-242-6/+8
>options = "" self.capabilities = "" self.recognition = "" self.comment = "" if line: (self.host, self.mailaddr, self.username, self.password, \ self.protocol, self.ssl, self.options, self.capabilities, \ self.recognition, self.comment) = \ line.strip().split(":") if not self.mailaddr: self.mailaddr = self.username # Test results self.status = None self.output = None def allattrs(self): "Return a tuple consisting of all this site's attributes." return (self.host, self.mailaddr, self.username, self.password, \ self.protocol, self.ssl, self.options, self.capabilities, \ self.recognition, self.comment) def __repr__(self): "Return the external representation of this site's data." return ":".join(self.allattrs()) def prettyprint(self): "Prettyprint a site entry in human-readable form." return "Host: %s\n" \ "Mail To: %s\n" \ "Username: %s\n" \ "Password: %s\n" \ "Protocol: %s\n" \ "SSL: %s\n" \ "Options: %s\n" \ "Capabilities: %s\n" \ "Recognition: %s\n" \ "Comment: %s\n" \ % self.allattrs() def entryprint(self): "Print a .fetchmailrc entry corresponding to a site entry." rep = "poll %s-%s via %s with proto %s %s\n" \ " user %s there with password '%s' is %s here" \ % (self.host,self.protocol,self.host,self.protocol,self.options,self.username,self.password,localuser) if self.ssl and self.ssl != 'False': rep += " options ssl" rep += "\n\n" return rep def tableprint(self): "Print an HTML server-type table entry." return "<tr><td>%s: %s</td><td>%s</td>\n" \ % (self.protocol, self.comment, self.capabilities) def id(self): "Identify this site." rep = "%s %s at %s" % (self.protocol, self.recognition, self.host) if self.capabilities: rep += " (" + self.capabilities + ")" if self.options: rep += " using " + self.options return rep def testmail(self, n=None): "Send test mail to the site." server = smtplib.SMTP(smtpserver) if self.mailaddr.find("@") > -1: toaddr = self.mailaddr else: toaddr = "%s@%s" % (self.mailaddr, self.host) msg = ("From: %s\r\nTo: %s\r\n\r\n" % (fromaddr, toaddr)) if n != None: msg += `n` + ": " msg += "Test mail collected from %s.\n" % (self.id(),) server.sendmail(fromaddr, toaddr, msg) server.quit() def fetch(self, logfile=False): "Run a mail fetch on this site." try: ofp = open(TestSite.temp, "w") if logfile: mda = "(echo \'From torturetest\' `date`;cat -;echo) >>TEST.LOG" else: mda = 'cat' ofp.write('defaults mda "%s"\n' % mda) ofp.write(self.entryprint()) ofp.close() (self.status, self.output) = commands.getstatusoutput("fetchmail -d0 -v -f - <%s"%TestSite.temp) if self.status: os.system("cat " + TestSite.temp) finally: os.remove(TestSite.temp) def failed(self): "Did we have a test failure here?" return os.WIFEXITED(self.status) and os.WEXITSTATUS(self.status) > 1 def explain(self): "Explain the status of the last test." if not os.WIFEXITED(self.status): return self.id() + ": abnormal termination\n" elif os.WEXITSTATUS(self.status) > 1: return self.id() + ": %d\n" % os.WEXITSTATUS(self.status) + self.output else: return self.id() + ": succeeded\n" class TortureGUI: "Torturetest editing GUI," # All site parameters except protocol field_map = ('host', 'mailaddr', 'username', 'password', \ 'options', 'capabilities', 'recognition', 'comment') def __init__(self): # Build the widget tree from the glade XML file. self.wtree = gtk.glade.XML("torturetest.glade") # File in initial values self.combo = self.wtree.get_widget("combo1") self.combo.set_popdown_strings(map(lambda x: x.comment, sitelist)) self.sslcheck = self.wtree.get_widget("ssl_checkbox") self.site = sitelist[0] self.display(self.site) # Provide handlers for the widget tree's events mydict = {} for key in ('on_torturetest_destroy', 'on_updatebutton_clicked', 'on_newbutton_clicked', 'on_testbutton_clicked', 'on_quitbutton_clicked', 'on_dumpbutton_clicked', 'on_combo_entry1_activate'): mydict[key] = getattr(self, key) self.wtree.signal_autoconnect(mydict) gtk.mainloop() print `self.site` def get_widget(self, widget): "Get the value of a widget's contents." if type(widget) == type(""): widget = self.wtree.get_widget(widget) if type(widget) == gtk.Entry: return widget.get_text() #elif type(widget) == gtk.SpinButton: # return widget.get_value() #elif type(widget) == gtk.TextView: # return widget.get_buffer().get_text() def set_widget(self, name, exp): "Set the value of a widget by name." widget = self.wtree.get_widget(name) if type(widget) == gtk.Entry: widget.set_text(exp) elif type(widget) == gtk.SpinButton: widget.set_value(exp) elif type(widget) == gtk.TextView: if not widget.get_buffer(): widget.set_buffer(gtk.TextBuffer()) widget.get_buffer().set_text(exp) def display(self, site): for member in TortureGUI.field_map: self.set_widget(member + "_entry", getattr(site, member)) for proto in protocols: self.wtree.get_widget(proto + "_radiobutton").set_active(site.protocol == proto) self.sslcheck.set_active(int(site.ssl != '' and site.ssl != 'False')) self.combo.entry.set_text(site.comment) def update(self, site): for member in TortureGUI.field_map: setattr(site, member, self.get_widget(member + "_entry")) for proto in protocols: if self.wtree.get_widget(proto + "_radiobutton").get_active(): site.protocol = proto if self.wtree.get_widget("ssl_checkbox").get_active(): site.ssl = "True" else: site.ssl = "False" # Housekeeping def on_torturetest_destroy(self, obj): gtk.mainquit() def on_updatebutton_clicked(self, obj): self.update(self.site) print self.site if self.site.comment: self.combo.entry.set_text(self.site.comment) else: self.combo.entry.set_text(self.site.host) def on_newbutton_clicked(self, obj): global sitelist sitelist = [TestSite()] + sitelist self.site = sitelist[0] self.display(self.site) self.combo.entry.set_text("") def on_testbutton_clicked(self, obj): self.site.fetch(False) print self.site.output def on_quitbutton_clicked(self, obj): gtk.mainquit() def on_dumpbutton_clicked(self, obj): print `self.site` def on_combo_entry1_activate(self, obj): key = self.combo.entry.get_text() for site in sitelist: if site.comment.find(key) > -1: self.site = site self.display(self.site) break if __name__ == "__main__": # Start by reading in the sitelist ifp = open("testsites") sitelist = [] linect = 0 while 1: linect += 1 line = ifp.readline() if not line: break elif line[0] in ("#", "\n"): continue else: try: sitelist.append(TestSite(line)) except: print "Error on line %d" % linect sys.exit(0) (options, arguments) = getopt.getopt(sys.argv[1:], "dfp:tigvse") verbose = 0 for (switch, value) in options: if switch == "-d": # Prettprint the sitelist map(lambda x: sys.stdout.write(x.prettyprint() + "%%\n"), sitelist) sys.exit(0) elif switch == "-f": # Dump the sitelist as a .fetchmailrc file map(lambda x: sys.stdout.write(x.entryprint()), sitelist) sys.exit(0) elif switch == "-p": # Probe a single site selected = [] for site in sitelist: if `site`.find(value) > -1: selected.append(site) sitelist = selected # Fall through elif switch == "-t": # Dump the sitelist in HTML table form map(lambda x: sys.stdout.write(x.tableprint()), sitelist) sys.exit(0) elif switch == "-i": # Dump the ids of the sitelist map(lambda x: sys.stdout.write(x.id() + "\n"), sitelist) sys.exit(0) elif switch == "-g": i = 1 for site in sitelist: print "Sending test mail to " + site.id() site.testmail(i) i+= 1 # Send test mail to each site print "Delaying to give the test mail time to land..." time.sleep(delay) print "Here we go:" # Fall through elif switch == "-v": # Display the test output verbose = 1 elif switch == "-s": # Dump recognition strings of all tested servers as a Python tuple print "(" + ",\n".join(map(lambda x: repr(x.recognition), filter(lambda x: x.recognition, sitelist))) + ")" sys.exit(0) elif switch == "-e": TortureGUI() sys.exit(0) # If no options, run the torture test try: failures = successes = 0 os.system("fetchmail -q") for site in sitelist: print "Testing " + site.id() site.fetch(True) if verbose: print site.output if site.failed(): failures += 1 else: successes += 1 # OK, summarize results print "\n%d successes and %d failures out of %d tests" \ % (successes, failures, len(sitelist)) if failures: print "Bad status was returned on the following sites:" for site in sitelist: if site.failed(): sys.stdout.write(site.explain() + "\n") except KeyboardInterrupt: print "Interrupted." # end