Giter VIP home page Giter VIP logo

dovecot-xaps-daemon's Introduction

Build Status

iOS Push Email for Dovecot

What is this?

This project, together with the dovecot-xaps-plugin project, will enable push email for iOS devices that talk to your Dovecot 2.0.x IMAP server. This is specially useful for people who are migrating away from running email services on OS X Server and want to keep the Push Email ability.

Please note that it is not possible to use this project without legally owning a copy of OS X Server. You can purchase OS X Server on the Mac App Store or download it for free if you are a registered Mac or iOS developer.

What is the advantage of push?

Without Push, your iPhone will Fetch email periodically. This means that mail is delayed and that your device will use precious power to connect to a remote IMAP server.

Using native Push messages means that your phone will receive new email notifications over a highly optimized connection to iCloud that it already has for other purposes.

High Level Overview

There are two parts to enabling iOS Push Email. You will need both parts for this to work.

First you need to install the Dovecot plugins from the dovecot-xaps-plugin project. How do to that is documented in the README file in that project. The Dovecot plugin adds support for the XAPPLEPUSHSERVICE IMAP extension that will let iOS devices register themselves to receive native push notifications for new email arrival.

(Apple did not document this feature, but it did publish the source code for all their Dovecot patches on the Apple Open Source project site, which include this feature. Although I was not able to follow a specification, I was able to read their open source project and do a clean implementation with all original code.)

Second, you need to install a daemon process (contained in this project) that will be responsible for receiving new email notifications from the Dovecot Local Delivery Agent and transforming those into native Apple Push Notifications.

Installation

Prerequisites

You are going to need the following things to get this going:

  • Some patience and willingness to experiment - Although I run this project in production, it is still a very early version and it may contain bugs.
  • Because you will need a certificate to talk to the Apple Push Notifications Service, you can only run this software if you are migrating away from an existing OS X Server setup where you had Push Email enabled.
  • Dovecot > 2.2.19 (which introduced the push-notification plugin)

Exporting and converting the certificate

First you have to export the certificate that is stored on your OS X Server. Do this by opening Keychain.app and select the System keychain and the Certificates category. Locate the right certificate by expanding those whose name start with APSP: and then look for the certificate with a private key that is named com.apple.servermgrd.apns.mail.

Now export that certficate by selecting it and then choose Export Items from the File menu. You want to store the certificate as PushEmail on your Desktop as a Personal Information Exchange (.p12) file. You will be asked to secure this exported certificate with a password. This is a new password and not your login password.

Then, start Terminal.app and execute the following commands:

cd ~/Desktop
openssl pkcs12 -in PushEmail.p12 -nocerts -nodes -out key.pem
openssl pkcs12 -in PushEmail.p12 -clcerts -nokeys -out certificate.pem

You will be asked for a password, which should be the same password that you entered when you exported the certificate.

You can test if the certificate and key are correct by making a connection to the apple push notifications gateway:

openssl s_client -connect gateway.push.apple.com:2195 -cert certificate.pem -key key.pem

The connection may close but check if you see something like Verify return code: 0 (ok) appear.

If the connection fails and outputs Verify return code: 20 (unable to get local issuer certificate) the chain of trust might be broken. Download the root certificate entrust_2048_ca.cer from [Entrust] (https://www.entrust.net/downloads/root_index.cfm?) and issue the command appending -CAfile:

openssl s_client -connect gateway.push.apple.com:2195 -cert certificate.pem -key key.pem -CAfile entrust_2048_ca.cer

TODO: Does this mean we also need to pass the CA file to the xapsd process?

You now have your exported certificate and private key stored in two separate PEM encoded files that can be used by the xapsd daemon.

Copy these two files to your Dovecot server.

Note that the APNS certificates expire 1 year after they were originally issued by Apple, so they will need to be renewed or regenerated through the OS X Server application each year. Expiration information for these certificates can be found at the Apple Push Certificates Portal.

Compiling and Installing the Daemon

The daemon is written in Go. The easiest way to build it is with go itself.

git clone https://github.com/st3fan/dovecot-xaps-daemon.git
cd dovecot-xaps-daemon
go build -o xapsd

Running the Daemon

Because this code is work in progress, it currently is not packaged properly as a good behaving background process. I recommend following the instructions below in a screen or tmux session so that it is easy to keep the daemon running. The next release will have better support for running this as a background service.

You can run the daemon as follows:

bin/xapsd -key=$HOME/key.pem -certificate=$HOME/certificate.pem \
-database=$HOME/xapsd.json -socket=/var/run/xapsd/xapsd.sock \
-delayCheckInterval=20 -delayTime=30

This assumes that you have the exported certificate.pem and key.pem files in your home directory. The database file will be created by the daemon. It will contain the mappings between the IMAP users, their mail accounts and the iOS devices. It is a simple JSON file so you can look at it manually by opening it in a text editor.

The daemon is verbose and should print out a bunch of informational messages. If you see errors, please file a bug.

Setting up Devices

Your iOS devices will discover that the server supports Push automatically the first time they connect. To force them to reconnect you can reboot the iOS device or turn Airport Mode on and off with a little delay in between.

If you go to your Email settings, you should see that the account has switched to Push.

Privacy

Each time a message is received, dovecot-xaps-daemon sends Apple a TLS-secured HTTP request, which Apple uses to send a notification over a persistent connection maintained to between the user's device and Apple's push notification servers.

The request contains the following information: a device token (used by Apple to identify which device should be sent a push notification), an account ID (used by the user's device to identify which account it should poll for new messages), and a certificate topic. The certificate topic identifies the server to Apple and is hardcoded in the certificate issued by Apple and setup in the configuration for dovecot-xaps-daemon.

By virtue of having made the request, Apple also learns the IP address of the server sending the push notification, and the time at which the push notification is sent by the server to Apple.

While no information typically thought of as private is directly exposed to Apple, some difficult to avoid leaks still occur. For example, Apple could correlate that two or more users frequently receive a push notification at almost the exact same time. From this, Apple could potentially infer that these users are receiving the same message. For most users this may not be a significant new loss of privacy.

dovecot-xaps-daemon's People

Contributors

anaoum avatar freswa avatar st3fan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dovecot-xaps-daemon's Issues

Document metadata / privacy implications

It would be nice to document what additional information Apple receives when a server is configured with this plugin.

Is the protocol basically just a wakeup command instructing the device to fetch mail?

Possibilities:

  1. Apple learns the specific times new messages are received
  2. Apple learns the specific times new messages are received, and that a stream of messages are delivered to the same account
  3. Apple learns the specific times new messages are received, and that a stream of messages are delivered to the same account, and that they are delivered to a specifically named folder (perhaps this is only relevant if other open issues are resolved)
  4. Apple learns the date, time, sender, subject, and first few lines of newly received messages

Extremely quick/cursory inspection of the source indicates the answer is likely 2 or 3, but it seems safer to ask.

I think many users would benefit from adding this information to the README or other documentation.

Thanks for your work while developing this.

Helper Scripts

I run the daemon with screen and use monit to restart if necessary. Here's my script, with monit 5.16, I run it from my rc.local

/usr/scripts/xapsd:

!/bin/bash

RETVAL=0
PROG="xapsd"
EXEC="/etc/dovecot/dovecot-xaps-daemon-master/bin/$PROG"
LOGFILE="/var/log/$PROG.log"
CERTIFICATE="/etc/dovecot/apple_push_certs/certificate.pem"
DATABASE="/var/lib/$PROG/database.json"
DEBUG="true"
KEY="/etc/dovecot/apple_push_certs/key.pem"
SOCKET="/var/run/dovecot/$PROG.sock"
LOCKFILE="/var/lock/subsys/$PROG"
OPTIONS="-certificate=$CERTIFICATE -database=$DATABASE -debug=$DEBUG -key=$KEY -socket=$SOCKET"
SCREEN="/usr/bin/screen"
PS="/bin/ps"
GREP="/bin/grep"

$PS ax | $GREP -q "[b]in/xapsd" && echo "Apple-Push Daemon already up, exiting" && exit $RETVAL
$PS ax | $GREP -q "[S]CREEN -dmS $PROG" || $SCREEN -dmS "$PROG"
$SCREEN -S "$PROG" -p 0 -X stuff "$EXEC $OPTIONS >> $LOGFILE 2>&1 $(printf \r)"

exit $RETVAL

Here's my monit config:

check process xapsd
matching "/bin/xapsd"

Uncomment below with monit version > 5.17, remove /usr/scripts/xapsd from rc.local

onreboot start

start program = "/usr/scripts/xapsd"
stop program = "/usr/bin/killall xapsd && /usr/bin/screen -S 'xapsd' -p 0 -X quit"
if 5 restarts with 5 cycles then timeout

APNSProtocol.connectionLost since a few days

Since a few days my dovecote-xaps-daemon doesn't send push notifications anymore.

I get the following error every few seconds:

2016-05-06 09:57:50+0200 [-] Starting factory <xapsd.apns.APNSClientFactory instance at 0xa3a142c>
2016-05-06 09:57:50+0200 [-] APNSClientFactory.startedConnecting
2016-05-06 09:57:50+0200 [Uninitialized] APNSClientFactory.buildProtocol
2016-05-06 09:57:50+0200 [Uninitialized] APNSProtocol.connectionMade
2016-05-06 09:57:50+0200 [Uninitialized] APNSClientFactory.clientConnectionMadeCallback
2016-05-06 09:57:51+0200 [APNSProtocol (TLSMemoryBIOProtocol),client] APNSProtocol.connectionLost
2016-05-06 09:57:51+0200 [APNSProtocol (TLSMemoryBIOProtocol),client] APNSClientFactory.clientConnectionLostCallback
2016-05-06 09:57:51+0200 [APNSProtocol (TLSMemoryBIOProtocol),client] APNSClientFactory.clientConnectionLost: [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionDone'>: Connection was closed cleanly.
        ]
2016-05-06 09:57:51+0200 [APNSProtocol (TLSMemoryBIOProtocol),client] <twisted.internet.tcp.Connector instance at 0xa76844c> will retry in 66 seconds
2016-05-06 09:57:51+0200 [APNSProtocol (TLSMemoryBIOProtocol),client] Stopping factory <xapsd.apns.APNSClientFactory instance at 0xa3a142c>

Any ideas?

push not working (no errors on dovecot side)

I installed the software according to documentation (dovecot module and xapsd-daemon, extracted certificate from OS X server / working connection to apple push server).

I see no errors in the log, everything seems to be working. But no push is received by the iOS device.

This is the log from the xaps-daemon:
2016/04/18 17:48:49 [DEBUG] Accepted a connection
2016/04/18 17:48:49 [DEBUG] Received request: NOTIFY dovecot-username="mhostinsky" dovecot-mailbox="INBOX"
2016/04/18 17:48:49 [DEBUG] Sending notification to 023C540F-6BA7-4D15-AF27-6FAE230EEF8D / C7E48933EFC239A633FB56846C148B9260C79D9925732A683C0272F4C9436D16
2016/04/18 17:48:49 [DEBUG] Sending notification to E2666B84-A0EF-4883-A745-7AE01BB23C8E / C7E48933EFC239A633FB56846C148B9260C79D9925732A683C0272F4C9436D16
2016/04/18 17:48:49 [DEBUG] Sending notification to 79D8C83C-70A6-4253-AAE0-6A9E73921E9A / CCDB9BA57CB6C5818ED5972DAE03CC03809D93E1849A192BEBFF26DDBE488444
2016/04/18 17:48:49 [DEBUG] Returning success:

I have several iOS devices configured, but it didn't work either with one device.

Is this software still functional?

push isn't delivered unless daemon is restarted

I had the daemon running for a few days. Today one user reported that her Mail.app is no longer showing red badges and she doesn't get notifications. I then tested this with my own account and experienced the same.

I stopped the daemon and restarted it, then sent another test email, and notifications are coming again. The log looks exactly the same in both cases except for the number (0/412):

2014-10-31 12:02:39+0100 [XAPSProtocol,412,] lineReceived: NOTIFY dovecot-username="[email protected]"     dovecot-mailbox="INBOX"
2014-10-31 12:02:39+0100 [XAPSProtocol,412,] Command(name='NOTIFY', args={'dovecot-username': '[email protected]', 'dovecot-mailbox': 'INBOX'})
2014-10-31 12:02:39+0100 [XAPSProtocol,412,] handleNotify: Command(name='NOTIFY', args={'dovecot-username': '[email protected]', 'dovecot-mailbox': 'INBOX'})
2014-10-31 12:02:39+0100 [XAPSProtocol,412,] APNSClientFactory.queueNotification
2014-10-31 12:02:39+0100 [XAPSProtocol,412,] APNSClientFactory.queueNotification
2014-10-31 12:02:40+0100 [-] APNSProtocol.sendNotifications (2)
2014-10-31 12:05:10+0100 [XAPSProtocol,0,] lineReceived: NOTIFY dovecot-username="[email protected]"       dovecot-mailbox="INBOX"
2014-10-31 12:05:10+0100 [XAPSProtocol,0,] Command(name='NOTIFY', args={'dovecot-username': '[email protected]', 'dovecot-mailbox': 'INBOX'})
2014-10-31 12:05:10+0100 [XAPSProtocol,0,] handleNotify: Command(name='NOTIFY', args={'dovecot-username': '[email protected]', 'dovecot-mailbox': 'INBOX'})
2014-10-31 12:05:10+0100 [XAPSProtocol,0,] APNSClientFactory.queueNotification
2014-10-31 12:05:10+0100 [XAPSProtocol,0,] APNSClientFactory.queueNotification
2014-10-31 12:05:10+0100 [-] APNSProtocol.sendNotifications (2)

Daemon claims success, but device does not receive notification, xaps_plugin has error

Hello

From the daemon:

2015/10/30 00:32:52 [DEBUG] Accepted a connection
2015/10/30 00:32:52 [DEBUG] Received request: NOTIFY dovecot-username="andrew"  dovecot-mailbox="INBOX"
2015/10/30 00:32:52 [DEBUG] Sending notification to RED-ACT-ED / REDACTED
2015/10/30 00:32:52 [DEBUG] Returning success:

However, this notification never shows up on the device. Also, the mail logs show that the xaps plugin did not finish the socket connection cleanly:

Oct 30 00:32:52 jupiter dovecot: lda(andrew): Debug: xaps_plugin_init
Oct 30 00:32:52 jupiter dovecot: lda(andrew): Debug: xaps_transaction_begin
Oct 30 00:32:52 jupiter dovecot: lda(andrew): Debug: xaps_transaction_begin
Oct 30 00:32:52 jupiter dovecot: lda(andrew): Debug: xaps_save_finish
Oct 30 00:32:52 jupiter dovecot: lda(andrew): Debug: xaps_transaction_commit
Oct 30 00:32:52 jupiter dovecot: lda(andrew): Error: write(/var/run/dovecot/xapsd.sock) failed: Broken pipe
Oct 30 00:32:52 jupiter dovecot: lda(andrew): Error: cannot notify
Oct 30 00:32:52 jupiter dovecot: lda(andrew): msgid=<[email protected]>: saved mail to INBOX
Oct 30 00:32:52 jupiter dovecot: lda(andrew): Debug: xaps_plugin_deinit

Any tips on how to debug this? Is there a simple way to see if the notification is successfully being sent to Apple's servers? Right now the code says that it does not check for errors.

Thanks,
Andrew.

Typo in xapsd_plugin.py

Line 46 in xapsd_plugin.py contains a typo in the certificate path.
["certificate", "", "/etc/apsd/certificate.pem", "Path to the certificate PEM file"],

This should read:
["certificate", "", "/etc/xapsd/certificate.pem", "Path to the certificate PEM file"],

Since update to go xaps-daemon push not working

The new go-based xapsd doesn't seem to send out pushes for me. The old python-twisted-based version worked (and still works) in my setup as expected.

When a mail receive should be pushed to a client I get the following output by the daemon:

2015/09/07 12:19:28 [DEBUG] Opening database at /var/lib/xapsd/database.json
2015/09/07 12:19:28 [DEBUG] Listening on UNIX socket at /var/run/xapsd/xapsd.sock
2015/09/07 12:19:28 [DEBUG] Parsing /etc/xapsd/certificate.pem to obtain APNS Topic
2015/09/07 12:19:28 [DEBUG] Topic is com.apple.mail.XServer.[deleted]
2015/09/07 12:19:28 [DEBUG] Creating APNS client to gateway.push.apple.com:2195
2015/09/07 12:19:28 Starting xapsd 1.0b1 on /var/run/xapsd/xapsd.sock
2015/09/07 12:20:37 [DEBUG] Accepted a connection
2015/09/07 12:20:37 [DEBUG] Received request: NOTIFY dovecot-username="micha" dovecot-mailbox="INBOX"
2015/09/07 12:20:37 [DEBUG] Returning success:

Log stopped here, maybe there is something missing while trying to send out the push information to APNS?
Is there something that I could do wrong when compiling the daemon?

empty certificate.pem

When extracting the key.pem and certificate.pem from the .p12 file it seems the certificate.pem is empty.

openssl pkcs12 -in PushEmail.p12 -nocerts -nodes -out key.pem
openssl pkcs12 -in PushEmail.p12 -clcerts -nokeys -out certificate.pem

The key.pem is generated with content but the certificate.pem is not.
I might be doing something wrong, but i have repeatedly followed the instructions.
I'm on OSX El Capitan.

Cannot find package "github.com/sirupsen/logrus"

xapsd.go:34:2: cannot find package "github.com/sirupsen/logrus" in any of:
/usr/lib/go-1.7/src/github.com/sirupsen/logrus (from $GOROOT)
/root/work/src/github.com/sirupsen/logrus (from $GOPATH)
xapsd.go:29:2: cannot find package "github.com/st3fan/dovecot-xaps-daemon/aps" in any of:
/usr/lib/go-1.7/src/github.com/st3fan/dovecot-xaps-daemon/aps (from $GOROOT)
/root/work/src/github.com/st3fan/dovecot-xaps-daemon/aps (from $GOPATH)
xapsd.go:30:2: cannot find package "github.com/st3fan/dovecot-xaps-daemon/database" in any of:
/usr/lib/go-1.7/src/github.com/st3fan/dovecot-xaps-daemon/database (from $GOROOT)
/root/work/src/github.com/st3fan/dovecot-xaps-daemon/database (from $GOPATH)
xapsd.go:31:2: cannot find package "github.com/st3fan/dovecot-xaps-daemon/logger" in any of:
/usr/lib/go-1.7/src/github.com/st3fan/dovecot-xaps-daemon/logger (from $GOROOT)
/root/work/src/github.com/st3fan/dovecot-xaps-daemon/logger (from $GOPATH)
xapsd.go:32:2: cannot find package "github.com/st3fan/dovecot-xaps-daemon/socket" in any of:
/usr/lib/go-1.7/src/github.com/st3fan/dovecot-xaps-daemon/socket (from $GOROOT)
/root/work/src/github.com/st3fan/dovecot-xaps-daemon/socket (from $GOPATH)

Go build fails - no context for redisClient

Hi

When trying to build the daemon, I get these errors:

# dovecot-xaps-daemon/aps aps/apns.go:75:24: cannot use "xapsd" (type string) as type context.Context in argument to redisClient.cmdable.HSet: string does not implement context.Context (missing Deadline method) aps/apns.go:79:38: not enough arguments in call to redisClient.cmdable.HGetAll have (string) want (context.Context, string) aps/apns.go:89:25: cannot use "xapsd" (type string) as type context.Context in argument to redisClient.cmdable.HDel: string does not implement context.Context (missing Deadline method)

I think there might been a change to the used library?

Thanks for looking at the issue!

Restarting the daemon from supervisor fails because socket exists

2014-11-12 21:58:29+0100 [-] twistd 14.0.2 (/home/xapsd/env/bin/python 2.7.3) starting up.
2014-11-12 21:58:29+0100 [-] reactor class: twisted.internet.epollreactor.EPollReactor.
2014-11-12 21:58:29+0100 [-] XAPSFactory starting on '/tmp/xapsd.sock'
2014-11-12 21:58:29+0100 [-] Starting factory <xapsd.xaps.XAPSFactory instance at 0x3114710>
2014-11-12 21:58:29+0100 [-] Traceback (most recent call last):
2014-11-12 21:58:29+0100 [-]   File "/home/xapsd/env/bin/twistd", line 5, in <module>
2014-11-12 21:58:29+0100 [-]     pkg_resources.run_script('Twisted==14.0.2', 'twistd')
2014-11-12 21:58:29+0100 [-]   File "/home/xapsd/env/local/lib/python2.7/site-packages/distribute-0.6.24-py2.7.egg/pkg_resources.py", line 499, in run_script
2014-11-12 21:58:29+0100 [-]     self.require(requires)[0].run_script(script_name, ns)
2014-11-12 21:58:29+0100 [-]   File "/home/xapsd/env/local/lib/python2.7/site-packages/distribute-0.6.24-py2.7.egg/pkg_resources.py", line 1235, in run_script
2014-11-12 21:58:29+0100 [-]     execfile(script_filename, namespace, namespace)
2014-11-12 21:58:29+0100 [-]   File "/home/xapsd/env/lib/python2.7/site-packages/Twisted-14.0.2-py2.7-linux-x86_64.egg/EGG-INFO/scripts/twistd", line 14, in <module>
2014-11-12 21:58:29+0100 [-]     run()
2014-11-12 21:58:29+0100 [-]   File "/home/xapsd/env/local/lib/python2.7/site-packages/Twisted-14.0.2-py2.7-linux-x86_64.egg/twisted/scripts/twistd.py", line 27, in run
2014-11-12 21:58:29+0100 [-]     app.run(runApp, ServerOptions)
2014-11-12 21:58:29+0100 [-]   File "/home/xapsd/env/local/lib/python2.7/site-packages/Twisted-14.0.2-py2.7-linux-x86_64.egg/twisted/application/app.py", line 642, in run
2014-11-12 21:58:29+0100 [-]     runApp(config)
2014-11-12 21:58:29+0100 [-]   File "/home/xapsd/env/local/lib/python2.7/site-packages/Twisted-14.0.2-py2.7-linux-x86_64.egg/twisted/scripts/twistd.py", line 23, in runApp
2014-11-12 21:58:29+0100 [-]     _SomeApplicationRunner(config).run()
2014-11-12 21:58:29+0100 [-]   File "/home/xapsd/env/local/lib/python2.7/site-packages/Twisted-14.0.2-py2.7-linux-x86_64.egg/twisted/application/app.py", line 380, in run
2014-11-12 21:58:29+0100 [-]     self.postApplication()
2014-11-12 21:58:29+0100 [-]   File "/home/xapsd/env/local/lib/python2.7/site-packages/Twisted-14.0.2-py2.7-linux-x86_64.egg/twisted/scripts/_twistd_unix.py", line 193, in postApplication
2014-11-12 21:58:29+0100 [-]     self.startApplication(self.application)
2014-11-12 21:58:29+0100 [-]   File "/home/xapsd/env/local/lib/python2.7/site-packages/Twisted-14.0.2-py2.7-linux-x86_64.egg/twisted/scripts/_twistd_unix.py", line 381, in startApplication
2014-11-12 21:58:29+0100 [-]     service.IService(application).privilegedStartService()
2014-11-12 21:58:29+0100 [-]   File "/home/xapsd/env/local/lib/python2.7/site-packages/Twisted-14.0.2-py2.7-linux-x86_64.egg/twisted/application/service.py", line 277, in privilegedStartService
2014-11-12 21:58:29+0100 [-]     service.privilegedStartService()
2014-11-12 21:58:29+0100 [-]   File "/home/xapsd/env/local/lib/python2.7/site-packages/Twisted-14.0.2-py2.7-linux-x86_64.egg/twisted/application/service.py", line 277, in privilegedStartService
2014-11-12 21:58:29+0100 [-]     service.privilegedStartService()
2014-11-12 21:58:29+0100 [-]   File "/home/xapsd/env/local/lib/python2.7/site-packages/Twisted-14.0.2-py2.7-linux-x86_64.egg/twisted/application/internet.py", line 105, in privilegedStartService
2014-11-12 21:58:29+0100 [-]     self._port = self._getPort()
2014-11-12 21:58:29+0100 [-]   File "/home/xapsd/env/local/lib/python2.7/site-packages/Twisted-14.0.2-py2.7-linux-x86_64.egg/twisted/application/internet.py", line 133, in _getPort
2014-11-12 21:58:29+0100 [-]     'listen%s' % (self.method,))(*self.args, **self.kwargs)
2014-11-12 21:58:29+0100 [-]   File "/home/xapsd/env/local/lib/python2.7/site-packages/Twisted-14.0.2-py2.7-linux-x86_64.egg/twisted/internet/posixbase.py", line 408, in listenUNIX
2014-11-12 21:58:29+0100 [-]     p.startListening()
2014-11-12 21:58:29+0100 [-]   File "/home/xapsd/env/local/lib/python2.7/site-packages/Twisted-14.0.2-py2.7-linux-x86_64.egg/twisted/internet/unix.py", line 293, in startListening
2014-11-12 21:58:29+0100 [-]     raise CannotListenError, (None, self.port, le)
2014-11-12 21:58:29+0100 [-] twisted.internet.error.CannotListenError: Couldn't listen on any:/tmp/xapsd.sock: [Errno 98] Address already in use.

New Apple Root CA question

This plugin/daemon (so far) works great for me on Debian 10/Dovecot 2.3.4.1! Thank you so much, this is AWESOME!

I noticed this in the README:

TODO: Does this mean we also need to pass the CA file to the xapsd process?

And this page: Apple Push Notification service server certificate update

Will the daemon keep working after 3/29? Do I need to install the CA in my server root certs, or will I need to recompile the daemon (any changes?)?

Thanks so much!

Device registered, but no push notification received

I've done a fresh setup of your plugin & daemon and can see, that there are actually devices registered by checking the JSON file. Also on my device, I can see under the checking options that there's actually the "Push" option selected.

Additionally, when I check the daemons log I can see the following whenever an email is received:

2016/10/04 14:36:09 [DEBUG] Accepted a connection
2016/10/04 14:36:09 [DEBUG] Received request: NOTIFY dovecot-username="marco@man                                               delkind.swiss"  dovecot-mailbox="INBOX"
2016/10/04 14:36:09 [DEBUG] Sending notification to 57AD56F4-618F-4FD9-B25A-B9DF                                               10508F89 / E2D752BE257E5E54E6FD21F3F35384C7A0D2404B13032F00BA3102142C2DCB4F
2016/10/04 14:36:09 [DEBUG] Returning success:

So it seems, it's sending the push notification - but I can't see it on the device. Any ideas? FWYW: I've enabled Notifications for the Mail App in the settings on my iOS 10.

Running Dovecot 2.2.9 on Ubuntu 14.04.

Why not Z-Push

I am using Z-Push for some time now to enable push mail on my iOS devices.

I am curious: What are the advantages of this project if you compare it to Z-Push (https://z-push.org/). Are there some Apple specific features that do not work using Z-Push? I do not own a OSX server, so unfortunately I cannot try it myself.

Too many open files

Found the following in my logs:

2015/09/11 15:23:14 Failed to accept connection:
    accept unix /tmp/xapsd.sock: too many open files

xapsd does not send push notify to Apple push servers

I have an issue with xapsd-daemon. I have configured xapsd-daemon with xapsd-plugin-dovecot under RHEL8.

When mail arrives, I can see, that dovecot is notifying xapsd-daemon. Log output:

DEBU[252097] Accepted a connection
DEBU[252097] Received request: NOTIFY dovecot-username="[email protected]"      dovecot-mailbox="INBOX" events=("MessageNew")
DEBU[252097] Returning success:

But it seems that xapsd-daemon does not send message to Apple push servers.

But sometimes it works. Log output:

ESC[37mDEBUESC[0m[5820] Checking all delayed APNS
ESC[37mDEBUESC[0m[5820] Registration 510C4AF2-9B42-42C1-B1C2-7A07111D592E / 96D39E1470983D48389F11FA7EB5265889ECCBB0D140BFA59F8F619A5C553617 has been waiting for 4.628962097s
ESC[37mDEBUESC[0m[5840] Checking all delayed APNS
ESC[37mDEBUESC[0m[5840] Registration 510C4AF2-9B42-42C1-B1C2-7A07111D592E / 96D39E1470983D48389F11FA7EB5265889ECCBB0D140BFA59F8F619A5C553617 has been waiting for 24.629003552s
ESC[37mDEBUESC[0m[5860] Checking all delayed APNS
ESC[37mDEBUESC[0m[5860] Registration 510C4AF2-9B42-42C1-B1C2-7A07111D592E / 96D39E1470983D48389F11FA7EB5265889ECCBB0D140BFA59F8F619A5C553617 has been waiting for 44.629642389s
ESC[37mDEBUESC[0m[5860] Sending notification to 510C4AF2-9B42-42C1-B1C2-7A07111D592E / 96D39E1470983D48389F11FA7EB5265889ECCBB0D140BFA59F8F619A5C553617
ESC[37mDEBUESC[0m[5880] Checking all delayed APNS

It seems that notification is send when registration message appears before notification message.

My xapsd.json:

{
  "Users": {
    "user": {
      "Accounts": {
        "510C4AF2-9B42-42C1-B1C2-7A07111D592E": {
          "DeviceToken": "96D39E1470983D48389F11FA7EB5265889ECCBB0D140BFA59F8F619A5C553617",
          "Mailboxes": [
            "INBOX",
            "Sent"
          ],
          "RegistrationTime": "2020-03-28T12:07:41.066630532+01:00"
        }
      }
    }
  }
}

Probability ratio, that PUSH message is delivered is around 2-3%. Most of the emails does not trigger PUSH. Does anybody know what is the issue?

Reading froms socket: read unix /var/run/xapsd/xapsd.sock->@: read: connection reset by peer

Not sure what is going on. With CentOS 7 I built everything from scratch and it appears to start up and run but when a push is triggered I get an error.

Reading froms socket: read unix /var/run/xapsd/xapsd.sock->@: read: connection reset by peer

Permissions and ownership on the directory xapsd and the sock seem fine since it deletes the sock when it shuts down. Any ideas?

Devices not registering / push not advertised

This is an exciting project - and I'd like to contribute.

I am running Dovecot 2.0.19, with the map_xaps_plugin.so dynamically loaded in - I see:

Jul 19 18:36:44 myhostname dovecot: imap: Debug: Module loaded: /usr/lib/dovecot/modules/imap_xaps_plugin.so

I have the dovecot-xaps-daemon running fine, with a push certificate that looks fine (although needed the updated entrust certificate for the openssl check). With debugging on, I see:

$ dovecot-xaps-daemon bin/xapsd -key=/home/myusername/.applepush/key.pem -certificate=/home/myusername/.applepush/certificate.pem -database=/home/myusername/.applepush/xapsd.json -socket=/tmp/xapsd.sock -debug=true
2015/07/19 18:23:46 [DEBUG] Opening database at /home/myusername/.applepush/xapsd.json
2015/07/19 18:23:46 [DEBUG] Listening on UNIX socket at /tmp/xapsd.sock
2015/07/19 18:23:46 [DEBUG] Parsing /home/myusername/.applepush/certificate.pem to obtain APNS Topic
2015/07/19 18:23:46 [DEBUG] Topic is com.apple.mail.XServer....my_long_topic_hash....
2015/07/19 18:23:46 [DEBUG] Creating APNS client to gateway.push.apple.com:2195
2015/07/19 18:23:47 Starting xapsd 1.0b1 on /tmp/xapsd.sock
2015/07/19 18:24:25 [DEBUG] Accepted a connection
2015/07/19 18:24:25 [DEBUG] Received request: NOTIFY dovecot-username="myusername"  dovecot-mailbox="INBOX"
2015/07/19 18:24:25 [DEBUG] Returning success: 

All looks fine - except I do not see iOS devices discovering that the server supports Push (only 'fetch' and 'manual' on the account), and the JSON file is not updated by the daemon with account details and tokens. The daemon appears to be listening and hears connections through the socket. There is an established connection to 2195 (confirmed with netstat). It looks like an issue with the registration of devices? Advertising push services? A port access issue? What am I missing?

Thank you for your help - any comments or suggestions welcome!

Sending notifications does not trigger mail check

I'm not sure what is going on but sending notifications does not trigger mail check anymore.

Here is my debug log:

I've renewed by certificates by installing OS X Server on top of OS X 10.11. I enabled the mail server and push notifications. Exported the p12 and extracted the cert and key from it,

My client devices are a mix of iOS 10.0.1 and 9.3.2. Settings look good, notifications enabled. Visible on lock screen, etc.

The xaps-daemon connects to Apple's APNS service without complaints. I was worried that maybe the Entrust certificate was missing but that does not seem to make a difference. I even added a call to conn.ValidateHostname() to the code to make sure the Go TLS library is happy about the connection. It is.

I added a bunch more debug output and I see the xapsd server send notifications. They have the right format, they go to the APNS service. Does not trigger mail check though.

I added a feedback channel and check more explicitly for errors returned by Apple's APNS service. Nothing.

As another experiment I put together a minimal push client that uses https://github.com/sideshow/apns2 and just notifies my three iOS devices (2 on 10.0.1 and 1 on 9.3.2). Nothing happens.

... more later ...

Unhandled error after receiving feedback from the APNS connection

2014-10-29 19:40:31+0100 [APNSProtocol (TLSMemoryBIOProtocol),client] APNSProtocol.dataReceived: 080a00000000
2014-10-29 19:40:31+0100 [APNSProtocol (TLSMemoryBIOProtocol),client] APNSProtocol.connectionLost
2014-10-29 19:40:31+0100 [APNSProtocol (TLSMemoryBIOProtocol),client] APNSClientFactory.clientConnectionMade
2014-10-29 19:40:31+0100 [APNSProtocol (TLSMemoryBIOProtocol),client] Unhandled Error
        Traceback (most recent call last):
          File "/home/xapsd/env/local/lib/python2.7/site-packages/Twisted-14.0.2-py2.7-linux-x86_64.egg/twisted/application/app.py", line 313, in runReactorWithLogging
            reactor.run()
          File "/home/xapsd/env/local/lib/python2.7/site-packages/Twisted-14.0.2-py2.7-linux-x86_64.egg/twisted/internet/base.py", line 1192, in run
            self.mainLoop()
          File "/home/xapsd/env/local/lib/python2.7/site-packages/Twisted-14.0.2-py2.7-linux-x86_64.egg/twisted/internet/base.py", line 1204, in mainLoop
            self.doIteration(t)
          File "/home/xapsd/env/local/lib/python2.7/site-packages/Twisted-14.0.2-py2.7-linux-x86_64.egg/twisted/internet/epollreactor.py", line 396, in doPoll
            log.callWithLogger(selectable, _drdw, selectable, fd, event)
        --- <exception caught here> ---
          File "/home/xapsd/env/local/lib/python2.7/site-packages/Twisted-14.0.2-py2.7-linux-x86_64.egg/twisted/python/log.py", line 88, in callWithLogger
            return callWithContext({"system": lp}, func, *args, **kw)
          File "/home/xapsd/env/local/lib/python2.7/site-packages/Twisted-14.0.2-py2.7-linux-x86_64.egg/twisted/python/log.py", line 73, in callWithContext
            return context.call({ILogContext: newCtx}, func, *args, **kw)
          File "/home/xapsd/env/local/lib/python2.7/site-packages/Twisted-14.0.2-py2.7-linux-x86_64.egg/twisted/python/context.py", line 118, in callWithContext
            return self.currentContext().callWithContext(ctx, func, *args, **kw)
          File "/home/xapsd/env/local/lib/python2.7/site-packages/Twisted-14.0.2-py2.7-linux-x86_64.egg/twisted/python/context.py", line 81, in callWithContext
            return func(*args,**kw)
          File "/home/xapsd/env/local/lib/python2.7/site-packages/Twisted-14.0.2-py2.7-linux-x86_64.egg/twisted/internet/posixbase.py", line 627, in _doReadOrWrite
            self._disconnectSelectable(selectable, why, inRead)
          File "/home/xapsd/env/local/lib/python2.7/site-packages/Twisted-14.0.2-py2.7-linux-x86_64.egg/twisted/internet/posixbase.py", line 260, in _disconnectSelectable
            selectable.connectionLost(f)
          File "/home/xapsd/env/local/lib/python2.7/site-packages/Twisted-14.0.2-py2.7-linux-x86_64.egg/twisted/internet/tcp.py", line 484, in connectionLost
            self._commonConnection.connectionLost(self, reason)
          File "/home/xapsd/env/local/lib/python2.7/site-packages/Twisted-14.0.2-py2.7-linux-x86_64.egg/twisted/internet/tcp.py", line 298, in connectionLost
            protocol.connectionLost(reason)
          File "/home/xapsd/env/local/lib/python2.7/site-packages/Twisted-14.0.2-py2.7-linux-x86_64.egg/twisted/protocols/tls.py", line 477, in connectionLost
            ProtocolWrapper.connectionLost(self, reason)
          File "/home/xapsd/env/local/lib/python2.7/site-packages/Twisted-14.0.2-py2.7-linux-x86_64.egg/twisted/protocols/policies.py", line 125, in connectionLost
            self.wrappedProtocol.connectionLost(reason)
          File "/home/xapsd/env/local/lib/python2.7/site-packages/dovecot_xaps_daemon-0.2-py2.7.egg/xapsd/apns.py", line 72, in connectionLost
            self.factory.clientConnectionMade(self)
          File "/home/xapsd/env/local/lib/python2.7/site-packages/dovecot_xaps_daemon-0.2-py2.7.egg/xapsd/apns.py", line 116, in clientConnectionMade
            self.looper.start(2.5)
          File "/home/xapsd/env/local/lib/python2.7/site-packages/Twisted-14.0.2-py2.7-linux-x86_64.egg/twisted/internet/task.py", line 162, in start
            assert not self.running, ("Tried to start an already running "
        exceptions.AssertionError: Tried to start an already running LoopingCall.

Support subscribing to subfolders

When connected to the dovecot-xaps-plugin, iOS offers to choose which mailboxes/imap subfolders should be pushed.
Two parts are needed for this:

  • daemon part (will come to that later)
  • plugin part

The plugin only needs to notify the daemon when:

  • mail is flagged as unseen
  • new mail is saved that is unseen
  • mail is moved that is unseen

The daemon then looks up if the client is subscribed to this mailbox/subfolder and sends a notification.

There is still some work to be done:
At the moment we only send a notification to the client, which then automatically fetches the INBOX. But even though other folders are marked as subscribed, they do not get fetched upon notification.
So there must be some information that needs to be added to the notification which then triggers a certain folder to be fetched.

Compile error: redefinition of ‘SyscallNoError’

root@darkstar:/tmp/dovecot-xaps-daemon# go build -o xapsd
go: downloading github.com/sirupsen/logrus v0.0.0-20180129181852-768a92a02685
go: downloading github.com/st3fan/dovecot-xaps-daemon v0.0.0-20190315235014-af50c8175e09
go: downloading golang.org/x/crypto v0.0.0-20180127211104-1875d0a70c90
go: downloading golang.org/x/sys v0.0.0-20180126165840-ff2a66f350ce
go: downloading github.com/go-redis/redis v6.15.2+incompatible
go: downloading github.com/timehop/apns v0.0.0-20160922055839-7dfe710e494f

golang.org/x/sys/unix

/root/go/pkg/mod/golang.org/x/[email protected]/unix/syscall_linux.go:20:1: error: redefinition of ‘SyscallNoError’
20 | func SyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr)
| ^
/root/go/pkg/mod/golang.org/x/[email protected]/unix/gccgo.go:20:1: note: previous definition of ‘SyscallNoError’ was here
20 | func SyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr) {
| ^
/root/go/pkg/mod/golang.org/x/[email protected]/unix/syscall_linux.go:24:1: error: redefinition of ‘RawSyscallNoError’
24 | func RawSyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr)
| ^
/root/go/pkg/mod/golang.org/x/[email protected]/unix/gccgo.go:48:1: note: previous definition of ‘RawSyscallNoError’ was here
48 | func RawSyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr) {
| ^

Reported on golang under golang/go#18312. Fixed in a newer version of golang.org/x/sys.

Error launching dovecot-xaps-daemon

Very interesting project and right up my alley since I'm currently moving from local OS X Server to AWS.

I'm having troubles getting the daemon to launch. I get the following error when launching the daemon:

twistd -n xapsd --key=/etc/xapsd/key.pem --certificate=/etc/xapsd/certificate.pem --database=/var/lib/dovecot/xapsd.json --socket=/var/run/dovecot/xapsd.sock

2014-10-09 06:50:58+0000 [-] Log opened.
2014-10-09 06:50:58+0000 [-] twistd 13.2.0 (/usr/bin/python 2.7.6) starting up.
2014-10-09 06:50:58+0000 [-] reactor class: twisted.internet.epollreactor.EPollReactor.
2014-10-09 06:50:58+0000 [-] XAPSFactory starting on '/var/run/dovecot/xapsd.sock'
2014-10-09 06:50:58+0000 [-] Starting factory <xaps.XAPSFactory instance at 0x7f6f3831c518>
2014-10-09 06:50:58+0000 [-] Starting factory <apns.APNSClientFactory instance at 0x7f6f3831c3f8>
2014-10-09 06:50:58+0000 [-] APNSClientFactory.startedConnecting
2014-10-09 06:50:58+0000 [Uninitialized] APNSClientFactory.buildProtocol
2014-10-09 06:50:58+0000 [Uninitialized] APNSProtocol.connectionMade
2014-10-09 06:50:58+0000 [Uninitialized] APNSClientFactory.clientConnectionMade
2014-10-09 06:50:58+0000 [APNSProtocol (TLSMemoryBIOProtocol),client] APNSProtocol.connectionLost
2014-10-09 06:50:58+0000 [APNSProtocol (TLSMemoryBIOProtocol),client] APNSClientFactory.clientConnectionMade
2014-10-09 06:50:58+0000 [APNSProtocol (TLSMemoryBIOProtocol),client] Unhandled Error
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/twisted/application/app.py", line 313, in runReactorWithLogging
reactor.run()
File "/usr/lib/python2.7/dist-packages/twisted/internet/base.py", line 1192, in run
self.mainLoop()
File "/usr/lib/python2.7/dist-packages/twisted/internet/base.py", line 1204, in mainLoop
self.doIteration(t)
File "/usr/lib/python2.7/dist-packages/twisted/internet/epollreactor.py", line 396, in doPoll
log.callWithLogger(selectable, _drdw, selectable, fd, event)
--- ---
File "/usr/lib/python2.7/dist-packages/twisted/python/log.py", line 88, in callWithLogger
return callWithContext({"system": lp}, func, _args, *_kw)
File "/usr/lib/python2.7/dist-packages/twisted/python/log.py", line 73, in callWithContext
return context.call({ILogContext: newCtx}, func, _args, *_kw)
File "/usr/lib/python2.7/dist-packages/twisted/python/context.py", line 118, in callWithContext
return self.currentContext().callWithContext(ctx, func, _args, *_kw)
File "/usr/lib/python2.7/dist-packages/twisted/python/context.py", line 81, in callWithContext
return func(args,*kw)
File "/usr/lib/python2.7/dist-packages/twisted/internet/posixbase.py", line 627, in _doReadOrWrite
self._disconnectSelectable(selectable, why, inRead)
File "/usr/lib/python2.7/dist-packages/twisted/internet/posixbase.py", line 260, in _disconnectSelectable
selectable.connectionLost(f)
File "/usr/lib/python2.7/dist-packages/twisted/internet/tcp.py", line 485, in connectionLost
self._commonConnection.connectionLost(self, reason)
File "/usr/lib/python2.7/dist-packages/twisted/internet/tcp.py", line 299, in connectionLost
protocol.connectionLost(reason)
File "/usr/lib/python2.7/dist-packages/twisted/protocols/tls.py", line 466, in connectionLost
ProtocolWrapper.connectionLost(self, reason)
File "/usr/lib/python2.7/dist-packages/twisted/protocols/policies.py", line 125, in connectionLost
self.wrappedProtocol.connectionLost(reason)
File "/home/jhansen/dovecot-xaps-daemon/apns.py", line 72, in connectionLost
self.factory.clientConnectionMade(self)
File "/home/jhansen/dovecot-xaps-daemon/apns.py", line 116, in clientConnectionMade
self.looper.start(2.5)
File "/usr/lib/python2.7/dist-packages/twisted/internet/task.py", line 162, in start
assert not self.running, ("Tried to start an already running "
exceptions.AssertionError: Tried to start an already running LoopingCall.

Prior to this I tested the exported certificate and key using:

openssl s_client -connect gateway.push.apple.com:2195 -cert /etc/xapsd/certificate.pem -key /etc/xapsd/key.pem

However, the only way to make this work and give a "Verify return code: 0 (ok)" is by appending -CAfile /etc/ssl/certs/entrust_2048_ca.cer to the command. This ensures the chain of trust and might be a clue to the above error.

macOS Server v5.7 no longer supports APSP Mail etc. Certificates

The dependency on Server.app to generate APNS certificates for Mail, Calendar, and Contacts will not work with Server version 5.7 and Mojave.

However, I believe it may be possible to create APNS certificates without Server.app for OpenBSD mail servers at https://identity.apple.com/pushcert/.

I haven’t worked the details yet, but if you have a running server patched to handle APNS, it’s a quick test to generate a signing certificate in Keychain Access’s Certificate Assistant, then generate a certificate signing request, post it to https://identity.apple.com/pushcert/, and use the resulting cert in the mail server’s configuration. There is no Apple documentation on how to create APNS certificates for the open source Mail/Contacts/Calendar alternatives.

It appears that going forward it may be possible to replicate APNS certificate creation by hand (once per year) using Keychain Access to generate the correctly configured certificates and a CSR that can be uploaded to https://identity.apple.com/pushcert/ for signing.

These certificates could then be used in the configuration of a self-hosted mail and calendar server that is patched to support APNS.

Does anyone know how to create a correctly formatted APNS certificate from Keychain Access that can be signed by Apple? My own certificates at https://identity.apple.com/pushcert/ look like this. If this approach works, I expect that one would need to generate APNS certificates for apns:com.apple.calendar, apns:com.apple.contact, and apns:com.apple.mail. This would be easy to script once the details are determined.

server.domain.tld - apns:com.apple.calendar
server.domain.tld - apns:com.apple.contact
server.domain.tld - apns:com.apple.mail
server.domain.tld - apns:com.apple.mgmt
server.domain.tld - apns:com.apple.alerts

What are your thoughts on this moving forward without a functioning Server.app in Mojave?

Are you aware of comparable push notification patches for Calendar and Contact servers?

Replicating what I see on my server, the APNS certificate configuration details are (with a random Version 1 UUID generated here):

Field Value
User ID com.apple.mail.XServer.674783d8-cbd0-11e8-a8d5-f2801f1b9fd1
Common Name APSP:674783d8-cbd0-11e8-a8d5-f2801f1b9fd1
Key Usage Encrypt, Verify, Derive
Extension>Key Usage>Critical NO
Extension>Key Usage>Digital Signature Digital Signature
Extension>Extended Key Usage>Critical NO
Extension> Extended Key Usage>Purpose #1 Client Authentication

There is an "identity preference" in the Keychain named apns:com.apple.mail (with same "Where" field) with "Preferred Certificate" APSP:674783d8-cbd0-11e8-a8d5-f2801f1b9fd1 , also in the Keychain.

I presume the other fields are added or modified by the signing authority. I do not see how or where the specific domain information server.domain.tld - apns:com.apple.mail is added, or whether this is necessary.

Related issues:

CentOS 6 init script

I figured I could contribute this. I have the daemon up and running but the plugin is not registering for some reason. That is next to figure out.

#!/bin/bash
#
# xapsd init script for CentOS 6
#
# chkconfig: 345 99 01
# description: Apple Push Notification Service
# processname: xapsd

# Source function library.
. /etc/init.d/functions

# Declare variables for xapsd daemon
RETVAL=0
PROG="xapsd"
EXEC="/usr/local/sbin/$PROG"
LOGFILE="/var/log/$PROG.log"
CERTIFICATE="/etc/$PROG/certificate.pem"
DATABASE="/var/lib/$PROG/database.json"
DEBUG="false"
KEY="/etc/$PROG/key.pem"
SOCKET="/var/run/$PROG/$PROG.sock"
LOCKFILE="/var/lock/subsys/$PROG"
OPTIONS="-certificate=$CERTIFICATE -database=$DATABASE -debug=$DEBUG -key=$KEY -socket=$SOCKET"

start() {
        [ -x $EXEC ] || exit 5
        echo -n "Starting $PROG: "
        daemon $EXEC $OPTIONS >> $LOGFILE 2>&1 &        
        RETVAL=$?
        [ $RETVAL -eq 0 ] && touch $LOCKFILE
        [ $RETVAL -eq 0 ] && success $"[ OK ]" || failure $"[ Failed! ] See log file $LOGFILE"
        echo
        return $RETVAL
}

stop() {
        echo -n "Shutting down $PROG: "
        kill $(pidof $PROG)
        RETVAL=$?
        [ $RETVAL -eq 0 ] && rm -f $SOCKET
        [ $RETVAL -eq 0 ] && rm -f $LOCKFILE
        [ $RETVAL -eq 0 ] && success $"[ OK ]" || failure $"[ Failed! ]"
        echo
        return $RETVAL
}

status() {
        echo -n "Checking $PROG status: "
        PID=$(pidof $PROG)
        [[ -n $PID ]] && success $"$PROG service is running as pid $PID" || failure $"$PROG service is not running"
        RETVAL=$?
        return $RETVAL
}

case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    status)
        status
        ;;
    restart)
        stop
        start
        ;;
    *)
        echo "Usage: $PROG {start|stop|status|restart}"
        exit 1
        ;;
esac
exit $RETVAL

no push until restart of daemon

After the daemon was started push works normal
After a while push does not work any more.
mail.log is exactly the same for both cases.

May 29 23:04:49 mail dovecot: lda(widder): Debug: xaps_plugin_init
May 29 23:04:49 mail dovecot: lda(widder): Debug: xaps_transaction_begin
May 29 23:04:49 mail dovecot: lda(widder): Debug: xaps_transaction_begin
May 29 23:04:49 mail dovecot: lda(widder): Debug: xaps_save_finish
May 29 23:04:49 mail dovecot: lda(widder): Debug: xaps_transaction_commit
May 29 23:04:49 mail dovecot: lda(widder): sieve: msgid=unspecified: stored mail into mailbox 'INBOX'
May 29 23:04:49 mail dovecot: lda(widder): Debug: xaps_plugin_deinit
May 29 23:04:49 mail postfix/pipe[583]: B797B21946: to=<widder@X>, orig_to=<widder@X>, relay=dovecot, delay=0.19, delays=0.17/0/0/0.03, dsn=2.0.0, status=sent (delivered via dovecot service)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.