OfflineIMAP / offlineimap

Read/sync your IMAP mailboxes (python2) [LEGACY: move to offlineimap3]
http://www.offlineimap.org
Other
1.78k stars 360 forks source link

Offlineimap will work when run manually but not when run as a service through Homebrew #678

Closed apierz closed 4 years ago

apierz commented 4 years ago

General informations

Configuration file offlineimaprc

[general]
accounts = personal
maxsyncaccounts = 3
pythonfile = /Users/[my_name]/.offlineimap.py

[Account personal]
localrepository = personalLocal
remoterepository = personalRemote
quick = 0

[Repository personalLocal]
type = Maildir
localfolders = /Users/[my_name]/.Maildir/personal

[Repository personalRemote]
type = IMAP
remotehost = mail.hover.com
remoteuser = [my_email]
remotepasseval = get_keychain_pass_personal(account="[my_email]", server="mail.hover.com")

remoteport = 993
ssl = yes
maxconnections = 2
realdelete = no
cert_fingerprint = [my_fingerprint]

pythonfile (if any)

#!/usr/bin/python
import re, subprocess
def get_keychain_pass_work(account=None, server=None):
    params = {
        'security': '/usr/bin/security',
        'command': 'find-generic-password',
        'account': account,
        'server': server,
        'keychain': '/Users/${USER}/Library/Keychains/login.keychain',
    }
    command = "sudo -u ${USER} %(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 re.match(r'password: "(.*)"', outtext).group(1)

def get_keychain_pass_personal(account=None, server=None):
    params = {
        'security': '/usr/bin/security',
        'command': 'find-generic-password',
        'account': account,
        'server': server,
        'keychain': '/Users/${USER}/Library/Keychains/login.keychain',
    }
    command = "sudo -u ${USER} %(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 re.match(r'password: "(.*)"', outtext).group(1)

Logs, error

Traceback (most recent call last):
  File "/usr/local/Cellar/offlineimap/7.3.3/libexec/offlineimap.py", line 22, in <module>
    oi.run()
  File "/usr/local/Cellar/offlineimap/7.3.3/libexec/offlineimap/init.py", line 89, in run
    options, args = self.__parse_cmd_options()
  File "/usr/local/Cellar/offlineimap/7.3.3/libexec/offlineimap/init.py", line 265, in __parse_cmd_options
    config.set_if_not_exists('general', 'dry-run', 'False')
  File "/usr/local/Cellar/offlineimap/7.3.3/libexec/offlineimap/CustomConfig.py", line 135, in set_if_not_exists
    self.set(section, option, value)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ConfigParser.py", line 753, in set
    ConfigParser.set(self, section, option, value)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ConfigParser.py", line 396, in set
    raise NoSectionError(section)
ConfigParser.NoSectionError: No section: 'general'

Steps to reproduce the error

  1. Run offlineimap manually to confirm that it is working
  2. Makes changes to the Maildir on the machine running offlineimap
  3. Start offlineimap service with brew services start offlineimap
  4. Review error log to confirm that offlineimap error'd when run as a service

The error seems to say that my offlineimaprc is missing a general section but I clearly have that.

I have also tried editing the .plist file that controls the service to direct it to use my offlineimaprc specifically but that resulted in no change.

nicolas33 commented 4 years ago

Weird. I don't get a clue about what could happen, here.

apierz commented 4 years ago

It looks like the problem was a file access issue. MacOS now requires explicit permission for apps to access home folders (including the Documents folder where my offlineimaprc is stored). I was able to resolve the problem by going to:

Settings.app > Security & Privacy > Files and Folders

Unlocking the settings and giving the offlineimap binary explicit permission to access the folders necessary to read my .offlineimaprc file.

MacOS should have loaded a dialogue box asking for me to grant this permission the first time offlineimap tried to access it, but something about it being run from homebrew services bugged out Apples system.

nicolas33 commented 4 years ago

Thanks for the feedback!