• Stars
    star
    156
  • Rank 239,589 (Top 5 %)
  • Language
    Go
  • License
    MIT License
  • Created about 10 years ago
  • Updated about 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

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.

More Repositories

1

ios-openssl

Port of OpenSSL for iOS
Objective-C
393
star
2

tinydoh

Minimal DNS-Over-HTTPS Server
Go
131
star
3

osx-10.9

OS X 10.9 Public Sources
C
99
star
4

iphone-twitter

iPhone Twitter Framework
Objective-C
90
star
5

dovecot-xaps-plugin

C
88
star
6

iphone-bookreader

Simple EPUB Book Reader for the iPhone
C
81
star
7

SadMacScreenSaver

Sad Mac Screen Saver
Objective-C
78
star
8

arduino-aws-hsm

Arduino AWS HSM
Arduino
62
star
9

iphone-bitly

iPhone bit.ly API
Objective-C
38
star
10

cocoa-utils

Misc utility classes for Cocoa
Objective-C
38
star
11

gohawk

Server-Side Hawk Implementation in Go
Go
37
star
12

ewm

Emulated Woz Machine - Apple ][+ Emulator
C
37
star
13

usbmux-proxy

Proxy to run on OS X that allows direct communications with iPhone or iPod Touch devices
C++
35
star
14

iphone-experiments

Code experiments to discover the iPhone APIs
Objective-C
26
star
15

clj-angularjs-recipes

Example Angular.js and Clojure web application
JavaScript
26
star
16

departures-board

Clojure Transit Tracker
JavaScript
20
star
17

krusader

Ken's Rather Useless Symbolic Assembly Development Environment for the Replica 1
Assembly
16
star
18

fxos-repl

Firefox OS REPL
Python
16
star
19

iphone-animation

iPhone Animation Framework
Objective-C
15
star
20

pythoncodeanalysis

Python Code Analysis
Python
11
star
21

jsonfeed

Minimal JSON Feed Package for Go
Go
9
star
22

iphone-transitions

Small category for UIViewController that allows arbitrary present and dismiss transitions.
Objective-C
8
star
23

MozillaScreenSaver

Mozilla Screen Saver
Objective-C
7
star
24

cocoa-xml

Cocoa XML Utilities
Objective-C
7
star
25

moz-syncserver

Mozilla Sync Server
Python
6
star
26

mijia-hub

Mijia Hub
Go
6
star
27

iphone-beacon

Objective-C
5
star
28

xliff

Go XLIFF Abstraction
Go
5
star
29

FirefoxHomeDeux

Firefox Home Deux
5
star
30

Security-55471

Apple's Security-55471 Source Dump
C
5
star
31

py-deb

Python package to create debian packages programatically
5
star
32

PuzzleScreenSaver

Puzzle Screen Saver
Objective-C
5
star
33

cocoa-crypto

Simple wrapper for crypto primitives like MessageDigest and HMAC
Objective-C
5
star
34

gigahub

GigaHub Scripts
Python
4
star
35

dotfiles

Shell
3
star
36

StackOverflow-28777670-TrackingArea

Swift
3
star
37

iphone-player

Simple Media Player
Objective-C
3
star
38

ios-jpake

J-PAKE Wrapper for iOS
Objective-C
3
star
39

config.emacs

Stefan's Emacs Configuration
Emacs Lisp
3
star
40

hello-pi-zero

Cross compiling Go to run on the Raspberry Pi Zero
Go
3
star
41

gocrypto

Go Crypto
Go
3
star
42

LongBranch

iPhone app to show TTC stop information
Objective-C
3
star
43

mod_mediarss

Apache 2.0 module to generate directory indexes in media rss format
C
3
star
44

moz-csp-dashboard

CSP Report Dashboard
JavaScript
3
star
45

TTCRoutes

iPhone Application that shows all TTC Streetcar Routes and Stops
Objective-C
3
star
46

LocalizationTest

Swift
3
star
47

StackOverflow

Code for my StackOverflow Answers
Objective-C
3
star
48

ios-jpake-test

iOS J-PAKE Test
C
2
star
49

firefox-ios-builder

Swift
2
star
50

pic32hacks

PIC32 Hacks and Experiments
C
2
star
51

mqs

Mini Queue Service
2
star
52

aoc

Advent of Code
Python
2
star
53

cocoa-atom

Objective-C
2
star
54

caddy-requestinfo

Caddy Request Info Plugin
Go
2
star
55

block-advertisers

Mute Twitter Advertisers
Python
2
star
56

dswg

Distributed Services With Go - Book Code
Go
2
star
57

hue-motion-events

Hue Motion Events Recorder
Python
2
star
58

WebKitExperiments

Swift
2
star
59

tiny2313hacks-003-adc

Tiny2313 Hacks #003 - ADC
2
star
60

electronics

Stefan's Electronics Projects
C
2
star
61

deno-playground

Deno Playground
TypeScript
2
star
62

dotfilesold

Shell
2
star
63

moz-csp-collector

CSP Dashboard
Go
2
star
64

b2g-python

Python for B2G
Python
2
star
65

ios-utils

iOS Utilities
Objective-C
2
star
66

bcrypt_pbkdf

Package bcrypt_pbkdf implements bcrypt_pbkdf(3) from OpenBSD.
Go
2
star
67

exercism

Exercism Solutions (Spoiler Alert - Don't Peek)
Rust
2
star
68

cocoa-wsf-client

Cocoa client for web services exposed with the Polar Rose Web Service Foundation
Objective-C
2
star
69

moz-syncapi

REST API for Firefox Sync
Go
2
star
70

spdy-server

SPDY Server
Java
2
star
71

clojure-experiments

My Clojure Experiments
2
star
72

jpake-test

JPAKE Test Client
Python
2
star
73

ios-hacks

Random iOS Hacks
Python
1
star
74

alexa-top-million

Alexa Top Million Sites
1
star
75

env

Somewhat easier access to environment variables
Go
1
star
76

sensor-firmware

ESP32/DHT22 Sensor Firmware
Python
1
star
77

deployments

Deployments Are Cool
Go
1
star
78

config.nvim

My Neovim Config
Lua
1
star
79

moz-websecbugs

Mozilla Web Security Bugs Dashboard
JavaScript
1
star
80

LaunchBarActions

LaunchBar Actions
JavaScript
1
star
81

ios-minimal-persona

Minimal app for Persona integration testing
Objective-C
1
star
82

satk

Python
1
star
83

disable-all-retweets

Disable All Retweets
Python
1
star
84

moz-tokenserver

Token Server
Go
1
star
85

License-Breaker

BeOS Screensaver that outputs the disassembly of the kernel
C++
1
star
86

moz-go-persona

Go Persona Client
Go
1
star
87

shttpd

Static HTTPD
HTML
1
star
88

ifmetrics

Interface Metrics for InfluxDB
Go
1
star
89

gohacks

Random Go Hacks & Experiments
Go
1
star
90

cocoa-rss

Objective-C
1
star
91

TwitterHacksWebExtension

Twitter Hacks Web Extension
JavaScript
1
star
92

expander

Web Service to Expand Short URLs
Clojure
1
star
93

delete-junk

Delete Junk Email
Go
1
star
94

tumblr2twitter

Tumbler to Twitter
Go
1
star
95

dovecot-empty-plugin

C
1
star
96

lambda-firefox-ios-builds

Lambda-Powered Micro-Site that shows Firefox iOS Build Status
HTML
1
star
97

moz-mockmyid-api

API for MockMyID
Go
1
star
98

fxios

Swift
1
star
99

proxxxxxxy

Proxxxxxxy - IPv6 HTTP Proxy
Go
1
star
100

moz-middleman

Session Broker
Python
1
star