Hello community, here is the log from the commit of package offlineimap for openSUSE:Factory checked in at 2018-07-07 22:01:56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/offlineimap (Old) and /work/SRC/openSUSE:Factory/.offlineimap.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "offlineimap" Sat Jul 7 22:01:56 2018 rev:46 rq:621308 version:7.2.1 Changes: -------- --- /work/SRC/openSUSE:Factory/offlineimap/offlineimap.changes 2018-06-29 22:26:58.574457493 +0200 +++ /work/SRC/openSUSE:Factory/.offlineimap.new/offlineimap.changes 2018-07-07 22:02:01.547041957 +0200 @@ -1,0 +2,14 @@ +Fri Jul 6 09:41:44 UTC 2018 - mimi...@gmail.com + +- update tp 7.2.1 + * Added support for sha512, sha384, sha256, sha224 hashing algorithms + to calculate server certificate fingerprints + * Pass username through in GSSAPI connections + * Gmail: allow parenthesis in labels. + * Correct typographical errors in offlineimap.conf + * Create filenames with no path separators in them. + * Removed uneccessary call of list() on zip() object + * Make CTRL-C message more clear. + * setup: add long_description. + +------------------------------------------------------------------- Old: ---- offlineimap-7.2.0.tar.gz New: ---- offlineimap-7.2.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ offlineimap.spec ++++++ --- /var/tmp/diff_new_pack.ZwJzfb/_old 2018-07-07 22:02:02.155041188 +0200 +++ /var/tmp/diff_new_pack.ZwJzfb/_new 2018-07-07 22:02:02.155041188 +0200 @@ -17,7 +17,7 @@ Name: offlineimap -Version: 7.2.0 +Version: 7.2.1 Release: 0 Summary: IMAP/Maildir Synchronization Tool License: GPL-2.0-or-later ++++++ offlineimap-7.2.0.tar.gz -> offlineimap-7.2.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.2.0/Changelog.md new/offlineimap-7.2.1/Changelog.md --- old/offlineimap-7.2.0/Changelog.md 2018-04-07 20:17:52.000000000 +0200 +++ new/offlineimap-7.2.1/Changelog.md 2018-06-16 15:08:07.000000000 +0200 @@ -15,6 +15,78 @@ * The following excerpt is only usefull when rendered in the website. {:toc} +### OfflineIMAP v7.2.1 (2018-06-16) + +#### Notes + +This new version introduces interesting features. The fingerprints now accepts +hashes in sha224, sha256, sha384 and sha512 to improve the compatibility with +IMAP servers. + +There's a new script in ./contrib to store passwords with GPG. + +The new GSSAPI library for kerberos gets a fix about authentication. Gmail +labels can now have parenthesis and the hostname can have path separators in +theirs names. + +There's a lot of other minors improvements to make offlineimap better +(in the documentation, UI, configuration file and the code). + +This release was tested by: + +- Nicolas Sebrecht + +Thanks to all the contributors. A lot of patches are first time contributions to +this project. This is very pleasant. + +Special thanks to Ilias Tsitsimpis, Eygene Ryabinkin, Chris Coleman our long +time contributors involved in this release and Sebastian Spaeth who is still +paying for the domain name! + + +#### Authors + +- Nicolas Sebrecht (9) +- velleto (6) +- Chris Coleman (1) +- Edgar HIPP (1) +- Eygene Ryabinkin (1) +- Lorenzo (1) +- Michael Billington (1) +- Robbie Harwood (1) + + +#### Features + +- Script to store passwords in a file with GPG or using OSX's secure keychain. [Lorenzo] +- Added support for sha512, sha384, sha256, sha224 hashing algorithms to calculate server certificate fingerprints.. [velleto] + +#### Fixes + +- Pass username through in GSSAPI connections. [Robbie Harwood] +- Gmail: allow parenthesis in labels. [Nicolas Sebrecht] +- Correct typographical errors in offlineimap.conf. [Michael Billington] +- Create filenames with no path separators in them. [Eygene Ryabinkin] + +#### Changes + +- imapserver: fix copyright line. [Nicolas Sebrecht] +- Available hashes added to documentation.. [velleto] +- Documented the now allowed use of colon separated fingerprints with examples.. [velleto] +- Allow users to keep colons between each hex pair of server certificate fingerprint in configuration file.. [velleto] +- Removed uneccessary call of list() on zip() object.. [velleto] +- Changed the 'exception raised' message, to be more understandable.. [velleto] +- Make CTRL-C message more clear. [Edgar HIPP] +- setup: add long_description. [Nicolas Sebrecht] +- offlineimap.conf: fix comment about gssapi. [Nicolas Sebrecht] +- Add self to maintainers. Update email address.. [Chris Coleman] +- Makefile: targz: don't set the abbrev in the archive directory name. [Nicolas Sebrecht] +- contrib: learn to build website/_uploads. [Nicolas Sebrecht] +- docs/website-doc.sh: limit the number of exported versions in _data/announces.yml. [Nicolas Sebrecht] +- Makefile: targz: update files. [Nicolas Sebrecht] +- Makefile: clean: remove __pycache__ directories. [Nicolas Sebrecht] + + ### OfflineIMAP v7.2.0 (2018-04-07) #### Notes diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.2.0/MAINTAINERS.rst new/offlineimap-7.2.1/MAINTAINERS.rst --- old/offlineimap-7.2.0/MAINTAINERS.rst 2018-04-07 20:17:52.000000000 +0200 +++ new/offlineimap-7.2.1/MAINTAINERS.rst 2018-06-16 15:08:07.000000000 +0200 @@ -16,7 +16,7 @@ - github: benutzer193 - Chris Coleman - - email: christocoleman at yahoo.com + - email: chris at espacenetworks.com - github: chris001 - Darshit Shah @@ -83,6 +83,7 @@ - Eygene Ryabinkin - Sebastian Spaeth - Nicolas Sebrecht +- Chris Coleman Github diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.2.0/Makefile new/offlineimap-7.2.1/Makefile --- old/offlineimap-7.2.0/Makefile 2018-04-07 20:17:52.000000000 +0200 +++ new/offlineimap-7.2.1/Makefile 2018-06-16 15:08:07.000000000 +0200 @@ -1,5 +1,4 @@ -# Copyright (C) 2002 - 2006 John Goerzen -# <jgoer...@complete.org> +# Copyright (C) 2002 - 2018 John Goerzen & contributors. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -15,9 +14,10 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# Warning: VERSION, ABBREV and TARGZ are used in docs/build-uploads.sh. VERSION=$(shell ./offlineimap.py --version) ABBREV=$(shell git log --format='%h' HEAD~1..) -TARGZ=offlineimap-$(VERSION)-$(ABBREV) +TARGZ=offlineimap-v$(VERSION)-$(ABBREV) SHELL=/bin/bash RST2HTML=`type rst2html >/dev/null 2>&1 && echo rst2html || echo rst2html.py` @@ -36,6 +36,7 @@ -find . -name '*.pygc' -exec rm -f {} \; -find . -name '*.class' -exec rm -f {} \; -find . -name '.cache*' -exec rm -f {} \; + -find . -type d -name '__pycache__' -exec rm -rf {} \; -rm -f manpage.links manpage.refs 2>/dev/null -find . -name auth -exec rm -vf {}/password {}/username \; -$(MAKE) -C docs clean @@ -49,7 +50,7 @@ targz: ../$(TARGZ) ../$(TARGZ): - cd .. && tar -zhcv --transform s,^offlineimap,$(TARGZ), -f $(TARGZ).tar.gz --exclude '*.pyc' offlineimap/{bin,Changelog.md,contrib,CONTRIBUTING.rst,COPYING,docs,MAINTAINERS.rst,MANIFEST.in,offlineimap,offlineimap.conf,offlineimap.conf.minimal,offlineimap.py,README.md,scripts,setup.py,test,TODO.rst} + cd .. && tar -zhcv --transform s,^offlineimap,offlineimap-v$(VERSION), -f $(TARGZ).tar.gz --exclude '.*.swp' --exclude '.*.swo' --exclude '*.pyc' --exclude '__pycache__' offlineimap/{bin,Changelog.md,Changelog.maint.md,contrib,CONTRIBUTING.rst,COPYING,docs,MAINTAINERS.rst,Makefile,MANIFEST.in,offlineimap,offlineimap.conf,offlineimap.conf.minimal,offlineimap.py,README.md,requirements.txt,scripts,setup.cfg,setup.py,snapcraft.yaml,test,tests,TODO.rst} rpm: targz cd .. && sudo rpmbuild -ta $(TARGZ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.2.0/contrib/release.py new/offlineimap-7.2.1/contrib/release.py --- old/offlineimap-7.2.0/contrib/release.py 2018-04-07 20:17:52.000000000 +0200 +++ new/offlineimap-7.2.1/contrib/release.py 2018-06-16 15:08:07.000000000 +0200 @@ -26,7 +26,7 @@ ) -__VERSION__ = "0.1" +__VERSION__ = "0.2" SPHINXBUILD = 'sphinx-build' DOCSDIR = 'docs' @@ -260,6 +260,15 @@ class Website(object): + def updateUploads(self): + req = ("update uploads/ of the website? " + "(warning: checksums will change if they already exist)") + if User.yesNo(req, defaultToYes=True) is False: + return False + if check_call(shlex.split("./docs/build-uploads.sh")) != 0: + return exit(5) + return True + def updateAPI(self): req = "update API of the website? (requires {})".format(SPHINXBUILD) if User.yesNo(req, defaultToYes=True) is False: @@ -292,9 +301,7 @@ with open(WEBSITE_LATEST, 'w') as fd: fd.write(WEBSITE_LATEST_SKEL.format(stable=version)) - def exportDocs(self, version): - branchName = "import-v{}".format(version) - + def exportDocs(self): if not goTo(DOCSDIR): User.pause() return @@ -303,6 +310,9 @@ print("error while calling 'make websitedoc'") exit(3) + def createImportBranch(self, version): + branchName = "import-v{}".format(version) + Git.chdirToRepositoryTopLevel() if not goTo("website"): User.pause() @@ -410,8 +420,12 @@ self.state.saveWebsite() website = Website() website.buildLatest(newVersion) - if website.updateAPI(): - self.websiteBranch = website.exportDocs(newVersion) + res_upload = website.updateUploads() + res_api = website.updateAPI() + if res_api: + res_export = website.exportDocs() + if True in [res_upload, res_api, res_export]: + self.websiteBranch = website.createImportBranch(newVersion) def getWebsiteBranch(self): return self.websiteBranch diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.2.0/contrib/store-pw-with-gpg/README.md new/offlineimap-7.2.1/contrib/store-pw-with-gpg/README.md --- old/offlineimap-7.2.0/contrib/store-pw-with-gpg/README.md 1970-01-01 01:00:00.000000000 +0100 +++ new/offlineimap-7.2.1/contrib/store-pw-with-gpg/README.md 2018-06-16 15:08:07.000000000 +0200 @@ -0,0 +1,37 @@ +# gpg-offlineimap + +Python bindings for offlineimap to use gpg instead of storing cleartext passwords + +Author: Lorenzo G. +[GitHub](https://github.com/lorenzog/gpg-offlineimap) + +## Quickstart + +Requirements: a working GPG set-up. Ideally with gpg-agent. Should work +out of the box on most modern Linux desktop environments. + + 1. Enable IMAP in gmail (if you have two factor authentication, you + need to create an app-specific password) + + 2. Create a directory `~/Mail` + + 3. In `~/Mail`, create a password file `passwords-gmail.txt`. Format: + `acco...@gmail.com password`. Look at the example file in this + directory. + + 4. **ENCRYPT** the file: `gpg -e passwords-gmail.txt`. It should create + a file `passwords-gmail.txt.gpg`. Check you can decrypt it: `gpg -d + passwords-gmail.txt.gpg`: it will ask you for your GPG password and + show it to you. + + 5. Use the file `offlineimaprc.sample` as a sample for your own + `.offlineimaprc`; edit it by following the comments. Minimal items + to configure: the `remoteuser` field and the `pythonfile` parameter + pointing at the `offlineimap.py` file in this directory. + + 6. Run it: `offlineimap`. It should ask you for your GPG passphrase to + decrypt the password file. + + 7. If all works well, delete the cleartext password file. + + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.2.0/contrib/store-pw-with-gpg/gpg-pw.py new/offlineimap-7.2.1/contrib/store-pw-with-gpg/gpg-pw.py --- old/offlineimap-7.2.0/contrib/store-pw-with-gpg/gpg-pw.py 1970-01-01 01:00:00.000000000 +0100 +++ new/offlineimap-7.2.1/contrib/store-pw-with-gpg/gpg-pw.py 2018-06-16 15:08:07.000000000 +0200 @@ -0,0 +1,99 @@ +#!/usr/bin/python +# Originally taken from: http://stevelosh.com/blog/2012/10/the-homely-mutt/ +# by Steve Losh +# Modified by Lorenzo Grespan on Jan, 2014 + +import re +import subprocess +from sys import argv +import logging +from os.path import expanduser +import unittest +import os +import sys + +logging.basicConfig(level=logging.INFO) + + +DEFAULT_PASSWORDS_FILE = os.path.join( + os.path.expanduser('~/Mail'), + 'passwords.gpg') + + +def get_keychain_pass(account=None, server=None): + '''Mac OSX keychain password extraction''' + params = { + 'security': '/usr/bin/security', + 'command': 'find-internet-password', + 'account': account, + 'server': server, + 'keychain': expanduser('~') + '/Library/Keychains/login.keychain', + } + command = ("%(security)s -v %(command)s" + " -g -a %(account)s -s %(server)s %(keychain)s" % params) + output = subprocess.check_output( + command, shell=True, stderr=subprocess.STDOUT) + outtext = [l for l in output.splitlines() + if l.startswith('password: ')][0] + return find_password(outtext) + + +def find_password(text): + '''Helper method for osx password extraction''' + # a non-capturing group + r = re.match(r'password: (?:0x[A-F0-9]+ )?"(.*)"', text) + if r: + return r.group(1) + else: + logging.warn("Not found") + return None + + +def get_gpg_pass(account, storage): + '''GPG method''' + command = ("gpg", "-d", storage) + # get attention + print '\a' # BEL + output = subprocess.check_output(command) + # p = subprocess.Popen(command, stdout=subprocess.PIPE) + # output, err = p.communicate() + for line in output.split('\n'): + r = re.match(r'{} ([a-zA-Z0-9]+)'.format(account), line) + if r: + return r.group(1) + return None + + +def get_pass(account=None, server=None, passwd_file=None): + '''Main method''' + if not passwd_file: + storage = DEFAULT_PASSWORDS_FILE + else: + storage = os.path.join( + os.path.expanduser('~/Mail'), + passwd_file) + if os.path.exists('/usr/bin/security'): + return get_keychain_pass(account, server) + if os.path.exists(storage): + logging.info("Using {}".format(storage)) + return get_gpg_pass(account, storage) + else: + logging.warn("No password file found") + sys.exit(1) + return None + + +# test with: python -m unittest <this module name> +# really basic tests.. nothing to see. move along +class Tester(unittest.TestCase): + def testMatchSimple(self): + text = 'password: "exampleonetimepass "' + self.assertTrue(find_password(text)) + + def testMatchComplex(self): + text = r'password: 0x74676D62646D736B646970766C66696B0A "anotherexamplepass\012"' + self.assertTrue(find_password(text)) + + +if __name__ == "__main__": + print get_pass(argv[1], argv[2], argv[3]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.2.0/contrib/store-pw-with-gpg/offlineimaprc.sample new/offlineimap-7.2.1/contrib/store-pw-with-gpg/offlineimaprc.sample --- old/offlineimap-7.2.0/contrib/store-pw-with-gpg/offlineimaprc.sample 1970-01-01 01:00:00.000000000 +0100 +++ new/offlineimap-7.2.1/contrib/store-pw-with-gpg/offlineimaprc.sample 2018-06-16 15:08:07.000000000 +0200 @@ -0,0 +1,63 @@ +[general] +# GPG quirks, leave unconfigured +ui = ttyui +# you can use any name as long as it matches the 'account1, 'account2' in the rest +# of the file +accounts = account1, account2 +# this is where the `gpg-pw.py` file is on disk +pythonfile=~/where/is/the/file/gpg-pw.py +fsync = False + +# you can call this any way you like +[Account account1] +localrepository = account1-local +remoterepository = account1-remote +# no need to touch this +status_backend = sqlite + +[Account account2] +localrepository = account2-local +remoterepository = account2-remote +status_backend = sqlite + +# thi sis a gmail account +[Repository account1-local] +type = Maildir +# create with maildirmake or by hand by creating cur, new, tmp +localfolders = ~/Mail/Mailboxes/account1 +# standard Gmail stuff +nametrans = lambda folder: { 'drafts': '[Gmail]/Drafts', + 'sent': '[Gmail]/Sent mail', + 'flagged': '[Gmail]/Starred', + 'trash': '[Gmail]/Trash', + 'archive': '[Gmail]/All Mail' + }.get(folder, folder) + +[Repository account1-remote] +maxconnections = 1 +type = Gmail +ssl=yes +# for osx, you might need to download the certs by hand +#sslcacertfile=~/Mail/certs.pem +#sslcacertfile=~/Mail/imap.gmail.com.pem +# sslcacertfile=/etc/ssl/cert.pem + +# or use Linux's standard certs +sslcacertfile=/etc/ssl/certs/ca-certificates.crt +# your account +remoteuser = accou...@gmail.com +remotepasseval = get_pass(account="accou...@gmail.com", server="imap.gmail.com", passwd_file="passwords-gmail.txt.gpg") +realdelete = no +createfolders = no +nametrans = lambda folder: {'[Gmail]/Drafts': 'drafts', + '[Gmail]/Sent Mail': 'sent', + '[Gmail]/Starred': 'star', + '[Gmail]/Trash': 'trash', + '[Gmail]/All Mail': 'archive', + }.get(folder, folder) +folderfilter = lambda folder: folder not in ['[Gmail]/Trash', + '[Gmail]/Spam', + ] + +[Repository account2-remote] +# copy the stanza above, change the 'account' parameter of get_pass, etc. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.2.0/contrib/store-pw-with-gpg/passwords-gmail.txt new/offlineimap-7.2.1/contrib/store-pw-with-gpg/passwords-gmail.txt --- old/offlineimap-7.2.0/contrib/store-pw-with-gpg/passwords-gmail.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/offlineimap-7.2.1/contrib/store-pw-with-gpg/passwords-gmail.txt 2018-06-16 15:08:07.000000000 +0200 @@ -0,0 +1,2 @@ +accou...@gmail.com password1 +accou...@gmail.com password2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.2.0/docs/build-uploads.sh new/offlineimap-7.2.1/docs/build-uploads.sh --- old/offlineimap-7.2.0/docs/build-uploads.sh 1970-01-01 01:00:00.000000000 +0100 +++ new/offlineimap-7.2.1/docs/build-uploads.sh 2018-06-16 15:08:07.000000000 +0200 @@ -0,0 +1,34 @@ +#!/bin/sh +# +# vim: expandtab ts=2 : + +WEBSITE_UPLOADS='./website/_uploads' + +while true +do + test -d .git && break + cd .. +done + +set -e + +echo "make clean" +make clean >/dev/null +echo "make targz" +make targz >/dev/null + +# Defined in the root Makefile. +version="$(./offlineimap.py --version)" +abbrev="$(git log --format='%h' HEAD~1..)" +targz="../offlineimap-v${version}-${abbrev}.tar.gz" + +filename="offlineimap-v${version}.tar.gz" + +mv -v "$targz" "${WEBSITE_UPLOADS}/${filename}" +cd "$WEBSITE_UPLOADS" +for digest in sha1 sha256 sha512 +do + target="${filename}.${digest}" + echo "Adding digest ${WEBSITE_UPLOADS}/${target}" + "${digest}sum" "$filename" > "$target" +done diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.2.0/docs/website-doc.sh new/offlineimap-7.2.1/docs/website-doc.sh --- old/offlineimap-7.2.0/docs/website-doc.sh 2018-04-07 20:17:52.000000000 +0200 +++ new/offlineimap-7.2.1/docs/website-doc.sh 2018-06-16 15:08:07.000000000 +0200 @@ -11,6 +11,7 @@ DESTBASE="${DOCBASE}/versions" VERSIONS_YML="${WEBSITE}/_data/versions.yml" ANNOUNCES_YML="${WEBSITE}/_data/announces.yml" +ANNOUNCES_YML_LIMIT=31 ANNOUNCES_YML_TMP="${ANNOUNCES_YML}.tmp" CONTRIB_YML="${WEBSITE}/_data/contribs.yml" CONTRIB="${DOCBASE}/contrib" @@ -122,7 +123,7 @@ d="$(parse_releases_get_date "$title")" echo "- {date: '${d}', version: '${v}', link: 'Changelog.maint.html#${link}'}" done | tee -a "$ANNOUNCES_YML_TMP" - sort -nr "$ANNOUNCES_YML_TMP" >> "$ANNOUNCES_YML" + sort -nr "$ANNOUNCES_YML_TMP" | head -n $ANNOUNCES_YML_LIMIT >> "$ANNOUNCES_YML" rm -f "$ANNOUNCES_YML_TMP" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.2.0/offlineimap/__init__.py new/offlineimap-7.2.1/offlineimap/__init__.py --- old/offlineimap-7.2.0/offlineimap/__init__.py 2018-04-07 20:17:52.000000000 +0200 +++ new/offlineimap-7.2.1/offlineimap/__init__.py 2018-06-16 15:08:07.000000000 +0200 @@ -2,7 +2,7 @@ __productname__ = 'OfflineIMAP' # Expecting trailing "-rcN" or "" for stable releases. -__version__ = "7.2.0" +__version__ = "7.2.1" __copyright__ = "Copyright 2002-2018 John Goerzen & contributors" __author__ = "John Goerzen" __author_email__= "offlineimap-proj...@lists.alioth.debian.org" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.2.0/offlineimap/folder/Gmail.py new/offlineimap-7.2.1/offlineimap/folder/Gmail.py --- old/offlineimap-7.2.0/offlineimap/folder/Gmail.py 2018-04-07 20:17:52.000000000 +0200 +++ new/offlineimap-7.2.1/offlineimap/folder/Gmail.py 2018-06-16 15:08:07.000000000 +0200 @@ -79,7 +79,7 @@ # Embed the labels into the message headers if self.synclabels: - m = re.search('X-GM-LABELS\s*\(([^\)]*)\)', data[0][0]) + m = re.search('X-GM-LABELS\s*[(](.*)[)]', data[0][0]) if m: labels = set([imaputil.dequote(lb) for lb in imaputil.imapsplit(m.group(1))]) else: @@ -153,6 +153,7 @@ if messagestr == None: continue messagestr = messagestr.split(' ', 1)[1] + # e.g.: {'X-GM-LABELS': '("Webserver (RW.net)" "\\Inbox" GInbox)', 'FLAGS': '(\\Seen)', 'UID': '275440'} options = imaputil.flags2hash(messagestr) if not 'UID' in options: self.ui.warn('No UID in message with options %s' %\ @@ -162,7 +163,8 @@ uid = int(options['UID']) self.messagelist[uid] = self.msglist_item_initializer(uid) flags = imaputil.flagsimap2maildir(options['FLAGS']) - m = re.search('\(([^\)]*)\)', options['X-GM-LABELS']) + # e.g.: '("Webserver (RW.net)" "\\Inbox" GInbox)' + m = re.search('^[(](.*)[)]', options['X-GM-LABELS']) if m: labels = set([imaputil.dequote(lb) for lb in imaputil.imapsplit(m.group(1))]) else: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.2.0/offlineimap/folder/Maildir.py new/offlineimap-7.2.1/offlineimap/folder/Maildir.py --- old/offlineimap-7.2.0/offlineimap/folder/Maildir.py 2018-04-07 20:17:52.000000000 +0200 +++ new/offlineimap-7.2.1/offlineimap/folder/Maildir.py 2018-06-16 15:08:07.000000000 +0200 @@ -82,6 +82,10 @@ "general", "utime_from_header", False) self._utime_from_header = self.config.getdefaultboolean( self.repoconfname, "utime_from_header", utime_from_header_global) + # What do we substitute pathname separator in names (if any) + self.sep_subst = '-' + if os.path.sep == self.sep_subst: + self.sep_subst = '_' # Interface from BaseFolder def getfullname(self): @@ -286,9 +290,10 @@ :returns: String containing unique message filename""" timeval, timeseq = _gettimeseq(date) - return '%d_%d.%d.%s,U=%d,FMD5=%s%s2,%s'% \ + uniq_name = '%d_%d.%d.%s,U=%d,FMD5=%s%s2,%s' % \ (timeval, timeseq, os.getpid(), socket.gethostname(), uid, self._foldermd5, self.infosep, ''.join(sorted(flags))) + return uniq_name.replace(os.path.sep, self.sep_subst) def save_to_tmp_file(self, filename, content): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.2.0/offlineimap/imaplibutil.py new/offlineimap-7.2.1/offlineimap/imaplibutil.py --- old/offlineimap-7.2.0/offlineimap/imaplibutil.py 2018-04-07 20:17:52.000000000 +0200 +++ new/offlineimap-7.2.1/offlineimap/imaplibutil.py 2018-06-16 15:08:07.000000000 +0200 @@ -23,7 +23,7 @@ import errno import zlib from sys import exc_info -from hashlib import sha1 +from hashlib import sha512, sha384, sha256, sha224, sha1 import six @@ -201,15 +201,18 @@ "having SSL helps nothing.", OfflineImapError.ERROR.REPO) super(WrappedIMAP4_SSL, self).open(host, port) if self._fingerprint: + server_cert = self.sock.getpeercert(True) + hashes = sha512, sha384, sha256, sha224, sha1 + server_fingerprints = [hash(server_cert).hexdigest() for hash in hashes] # compare fingerprints - fingerprint = sha1(self.sock.getpeercert(True)).hexdigest() - if fingerprint not in self._fingerprint: - raise OfflineImapError("Server SSL fingerprint '%s' " + matches = [(server_fingerprint in self._fingerprint) for server_fingerprint in server_fingerprints] + if not any(matches): + raise OfflineImapError("Server SSL fingerprint(s) '%s' " "for hostname '%s' " "does not match configured fingerprint(s) %s. " "Please verify and set 'cert_fingerprint' accordingly " "if not set yet."% - (fingerprint, host, self._fingerprint), + (zip([hash.__name__ for hash in hashes], server_fingerprints), host, self._fingerprint), OfflineImapError.ERROR.REPO) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.2.0/offlineimap/imapserver.py new/offlineimap-7.2.1/offlineimap/imapserver.py --- old/offlineimap-7.2.0/offlineimap/imapserver.py 2018-04-07 20:17:52.000000000 +0200 +++ new/offlineimap-7.2.1/offlineimap/imapserver.py 2018-06-16 15:08:07.000000000 +0200 @@ -1,5 +1,5 @@ # IMAP server support -# Copyright (C) 2002-2016 John Goerzen & contributors. +# Copyright (C) 2002-2018 John Goerzen & contributors. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -280,7 +280,18 @@ # we'd be ready since krb5 always requests integrity and # confidentiality support. response = self.gss_vc.unwrap(token) - response = self.gss_vc.wrap(response.message, response.encrypted) + + # This is a behavior we got from pykerberos. First byte is one, + # first four bytes are preserved (pykerberos calls this a length). + # Any additional bytes are username. + reply = [] + reply[0:4] = response.message[0:4] + reply[0] = '\x01' + if self.username: + reply[5:] = self.username + reply = ''.join(reply) + + response = self.gss_vc.wrap(reply, response.encrypted) return response.message if response.message else "" except gssapi.exceptions.GSSError as err: # GSSAPI errored out on us; respond with None to cancel the diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.2.0/offlineimap/init.py new/offlineimap-7.2.1/offlineimap/init.py --- old/offlineimap-7.2.0/offlineimap/init.py 2018-04-07 20:17:52.000000000 +0200 +++ new/offlineimap-7.2.1/offlineimap/init.py 2018-06-16 15:08:07.000000000 +0200 @@ -433,8 +433,9 @@ accounts.Account.set_abort_event(self.config, 2) elif sig in (signal.SIGTERM, signal.SIGINT, signal.SIGHUP): # tell each account to ABORT ASAP (ctrl-c) - getglobalui().warn("Terminating NOW (this may "\ - "take a few seconds)...") + getglobalui().warn("Preparing to shutdown after sync (this may "\ + "take some time), press CTRL-C three "\ + "times to shutdown immediately") accounts.Account.set_abort_event(self.config, 3) if 'thread' in self.ui.debuglist: self.__dumpstacks(5) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.2.0/offlineimap/repository/IMAP.py new/offlineimap-7.2.1/offlineimap/repository/IMAP.py --- old/offlineimap-7.2.0/offlineimap/repository/IMAP.py 2018-04-07 20:17:52.000000000 +0200 +++ new/offlineimap-7.2.1/offlineimap/repository/IMAP.py 2018-06-16 15:08:07.000000000 +0200 @@ -293,7 +293,7 @@ comma-separated fingerprints in hex form.""" value = self.getconf('cert_fingerprint', "") - return [f.strip().lower() for f in value.split(',') if f] + return [f.strip().lower().replace(":", "") for f in value.split(',') if f] def setoauth2_request_url(self, url): self.oauth2_request_url = url diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.2.0/offlineimap.conf new/offlineimap-7.2.1/offlineimap.conf --- old/offlineimap-7.2.0/offlineimap.conf 2018-04-07 20:17:52.000000000 +0200 +++ new/offlineimap-7.2.1/offlineimap.conf 2018-06-16 15:08:07.000000000 +0200 @@ -365,7 +365,7 @@ # This option stands in the [Account Test] section. # # Maildir file format uses colon (:) separator between uniq name and info. -# Unfortunatelly colon is not allowed character in windows file name. If you +# Unfortunately colon is not allowed character in windows file name. If you # enable maildir-windows-compatible option, Offlineimap will be able to store # messages on windows drive, but you will probably loose compatibility with # other programs working with the maildir. @@ -420,7 +420,7 @@ # # This knob is respected only by IMAP-based accounts. Value of labelsheader # for GMail-based accounts is automatically added to this list, you don't -# need to specify it explicitely. +# need to specify it explicitly. # # Use ASCII characters only. # @@ -429,7 +429,7 @@ # This option stands in the [Account Test] section. # -# Use proxy connection for this account. Usefull to bypass the GFW in China. +# Use proxy connection for this account. Useful to bypass the GFW in China. # To specify a proxy connection, join proxy type, host and port with colons. # Available proxy types are SOCKS5, SOCKS4, HTTP. # You also need to install PySocks through pip. @@ -452,7 +452,7 @@ # in order to have nicely readable UTF-8 folder names in the local copy. # # WARNING: with this option enabled: -# - compatibility with any other version is NOT GUARANTED (including newer); +# - compatibility with any other version is NOT GUARANTEED (including newer); # - existing set-ups will probably break. # - no support is provided. # @@ -787,10 +787,14 @@ # # In Windows, Microsoft uses the term "thumbprint" instead of "fingerprint". # -# Fingerprints must be in hexadecimal form without leading '0x': -# 40 hex digits like bbfe29cf97acb204591edbafe0aa8c8f914287c9. +# Supported fingerprint hashes are sha512, sha384, sha256, sha224 and sha1. +# Fingerprints must be in hexadecimal form without leading '0x', and may have +# the separating colons. This is non case-sensitive. +# Examples: +# sha1 "bbfe29cf97acb204591edbafe0aa8c8f914287c9". +# sha1 with colons "BB:FE:29:CF:97:AC:B2:04:59:1E:DB:AF:E0:AA:8C:8F:91:42:87:C9" # -#cert_fingerprint = <SHA1_of_server_certificate_here>[, <another_SHA1>] +#cert_fingerprint = <SHAn_of_server_certificate_here>[, <another_SHAm>] # This option stands in the [Repository RemoteExample] section. @@ -901,7 +905,7 @@ # For Gmail (and maybe others), XOAUTH2 requires ssl. This means that STARTTLS # won't work and that Offlineimap will perform certificate validation. IOW, the # following configuration is used: -# - sslcacertfile: MUST BE correclty configured +# - sslcacertfile: MUST BE correctly configured # - ssl = yes (optional, will be used anyway) # - starttls = no (optional, will be tried but won't work anyway) # @@ -997,14 +1001,14 @@ # # 4. With a preauth tunnel. With this method, you invoke an external # program that is guaranteed *NOT* to ask for a password, but rather -# to read from stdin and write to stdout an IMAP procotol stream that +# to read from stdin and write to stdout an IMAP protocol stream that # begins life in the PREAUTH state. When you use a tunnel, you do # NOT specify a user or password (if you do, they'll be ignored.) # Instead, you specify a preauthtunnel, as this example illustrates # for Courier IMAP on Debian: #preauthtunnel = ssh -q imaphost '/usr/bin/imapd ./Maildir' # -# 5. If you are using Kerberos and have the Python Kerberos package +# 5. If you are using Kerberos and have the Python gssapi package # installed, you should not specify a remotepass. If the user has a # valid Kerberos TGT, Offlineimap will figure out the rest all by # itself, and fall back to password authentication if needed. @@ -1052,7 +1056,7 @@ # # This is most commonly needed with UW IMAP, where you might need to specify the # directory in which your mail is stored. The 'reference' value will be prefixed -# to all folder paths refering to that repository. E.g. accessing folder 'INBOX' +# to all folder paths referring to that repository. E.g. accessing folder 'INBOX' # with "reference = Mail" will try to access Mail/INBOX. # # The nametrans and folderfilter functions will apply to the full path, @@ -1394,7 +1398,7 @@ # # http://mail.google.com/support/bin/answer.py?answer=78799&topic=12814 # -# This means ssl is enabled and must be configured correcly when connecting to +# This means ssl is enabled and must be configured correctly when connecting to # Gmail. # # In addition we provide defaults for "oauth2_request_url", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/offlineimap-7.2.0/setup.py new/offlineimap-7.2.1/setup.py --- old/offlineimap-7.2.0/setup.py 2018-04-07 20:17:52.000000000 +0200 +++ new/offlineimap-7.2.1/setup.py 2018-06-16 15:08:07.000000000 +0200 @@ -5,7 +5,7 @@ # IMAP synchronization # Module: installer # COPYRIGHT # -# Copyright (C) 2002 - 2006 John Goerzen +# Copyright (C) 2002 - 2018 John Goerzen & contributors # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -53,6 +53,7 @@ setup(name = "offlineimap", version = offlineimap.__version__, description = offlineimap.__description__, + long_description = offlineimap.__description__, author = offlineimap.__author__, author_email = offlineimap.__author_email__, url = offlineimap.__homepage__,