Go-ActiveSync

module
v0.0.0-...-9e684e1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 30, 2026 License: MIT

README

Go-ActiveSync

A production-grade Microsoft Exchange ActiveSync (EAS) 14.1 server and library written in Go, using the Echo v5 HTTP framework.

Inspired by Z-Push — the reference PHP implementation — reimplemented in idiomatic Go with a pluggable backend interface.


Features

  • Full WBXML encoder/decoder (pkg/wbxml) — no CGO, no dependencies
  • Supports all major ActiveSync 14.1 commands (see table below)
  • Pluggable backend — implement activesync.Backend to connect any data source
  • Embeddable library — import pkg/activesync and add AS support to any Go server
  • Test client (cmd/client) — exercises every command with real WBXML encoding
  • In-memory demo backend (internal/demo) for quick-start testing
  • Graceful shutdown, structured logging (zap), Echo v5 middleware

Quick Start

Build
make build
# Binaries land in ./bin/
Run the demo server
make run
# Server starts on :8080 with in-memory demo backend
# Any username + non-empty password is accepted
Test with the client
# In a second terminal:
./bin/go-activesync-client options
./bin/go-activesync-client provision
./bin/go-activesync-client foldersync
./bin/go-activesync-client sync inbox
./bin/go-activesync-client estimate inbox
./bin/go-activesync-client ping

Project Layout

go-activesync/
├── cmd/
│   ├── server/main.go        — standalone server binary
│   └── client/main.go        — WBXML test client CLI
├── pkg/
│   ├── wbxml/                — WBXML 1.3 encoder/decoder (AS subset)
│   │   ├── defs.go           — 26 code page tables
│   │   ├── decoder.go        — streaming WBXML decoder
│   │   ├── encoder.go        — WBXML encoder
│   │   └── wbxml_test.go
│   ├── protocol/             — AS protocol constants and shared types
│   │   ├── commands.go       — command codes, supported versions
│   │   ├── status.go         — status codes (Sync, FolderSync, Provision, ...)
│   │   └── types.go          — Folder, EmailItem, ContactItem, CalendarItem, ...
│   └── activesync/           — public embeddable library
│       ├── backend.go        — Backend interface
│       ├── server.go         — Server (Echo v5 wrapper)
│       ├── device.go         — DeviceState + DeviceStore
│       ├── options.go        — Options struct
│       ├── middleware.go     — BasicAuth, logging, recovery middleware
│       ├── dispatcher.go     — command routing
│       └── handler_*.go      — one handler per AS command
├── internal/
│   ├── demo/backend.go       — in-memory demo backend
│   └── middleware/           — shared middleware helpers
├── docs/
│   └── SPEC.md               — full implementation specification
├── Makefile
└── go.mod

Supported Commands

Command Status Description
OPTIONS ✅ HTTP OPTIONS — capability negotiation
FolderSync ✅ Sync folder hierarchy
Sync ✅ Sync items within a folder
GetItemEstimate ✅ Estimate items to sync
Ping ✅ Long-poll for server-side changes
Provision ✅ Device security policy exchange
SendMail ✅ Send email (MIME body)
SmartForward ✅ Forward email
SmartReply ✅ Reply to email
MoveItems ✅ Move items between folders
MeetingResponse ✅ Accept/Decline/Tentative meetings
Search ✅ Search mailbox / GAL
Settings ✅ Device info, OOF settings
Autodiscover ✅ Exchange Autodiscover endpoint
GetAttachment 🔧 Via Backend.GetAttachment
ItemOperations 🔧 Planned
ResolveRecipients 🔧 Planned
ValidateCert 🔧 Planned

Embedding in Your Project

Add the module:

go get github.com/jniltinho/Go-ActiveSync

Implement the Backend interface:

package main

import (
    "context"

    "github.com/jniltinho/Go-ActiveSync/pkg/activesync"
    "github.com/jniltinho/Go-ActiveSync/pkg/protocol"
)

type MyBackend struct{}

func (b *MyBackend) Logon(ctx context.Context, user, domain, pass string) bool {
    return user == "alice" && pass == "secret"
}

func (b *MyBackend) GetFolderList(ctx context.Context) ([]protocol.Folder, error) {
    return []protocol.Folder{
        {ServerID: "inbox", DisplayName: "Inbox", Type: protocol.FolderDefaultInbox},
    }, nil
}

// ... implement all Backend methods ...

func main() {
    srv := activesync.NewServer(activesync.Options{
        Addr: ":443",
        TLSCert: "/etc/ssl/cert.pem",
        TLSKey:  "/etc/ssl/key.pem",
    })

    srv.SetBackendFactory(func() activesync.Backend {
        return &MyBackend{}
    })

    ctx := context.Background()
    if err := srv.Start(ctx); err != nil {
        panic(err)
    }
}

WBXML Library Usage

import (
    "bytes"
    "github.com/jniltinho/Go-ActiveSync/pkg/wbxml"
)

// Encode
var buf bytes.Buffer
enc := wbxml.NewEncoder(&buf)
enc.StartTag("FolderSync")
enc.StringElement("SyncKey", "0")
enc.EndTag()
enc.Flush()

// Decode
dec, _ := wbxml.NewDecoder(&buf)
tokens, _ := dec.DecodeAll()
for _, tok := range tokens {
    if tok.Type == wbxml.TokenTypeStartTag {
        fmt.Println(tok.Name)
    }
}

Makefile Targets

Target Description
make build Build server + client binaries
make run Start server on :8080 (debug logging)
make test Run all tests
make test-wbxml Run WBXML codec tests only
make cross Build for linux/darwin/windows amd64
make lint Run golangci-lint
make tidy Run go mod tidy
make clean Remove ./bin/

Protocol Reference

See docs/SPEC.md for the full implementation specification including:

  • WBXML encoding details and all 26 code pages
  • Request flow diagrams
  • Backend interface contract
  • State management approach
  • Security considerations

Official Microsoft protocol documentation:

  • [MS-ASHTTP] Exchange ActiveSync: HTTP Protocol
  • [MS-ASWBXML] Exchange ActiveSync: WAP Binary XML Algorithm
  • [MS-ASCMD] Exchange ActiveSync: Command Reference Protocol

License

MIT License. See LICENSE.


Contributing

  1. Implement a Backend for your data source
  2. Run make test to verify the codec
  3. Submit a PR — see docs/SPEC.md for the protocol specification

Directories

Path Synopsis
Package backends provides a factory that creates the correct activesync.Backend implementation based on the configuration backend.type value.
Package backends provides a factory that creates the correct activesync.Backend implementation based on the configuration backend.type value.
caldav
Package caldav implements an activesync.Backend for calendar and task synchronization against a CalDAV server (RFC 4791).
Package caldav implements an activesync.Backend for calendar and task synchronization against a CalDAV server (RFC 4791).
carddav
Package carddav implements an activesync.Backend for contact synchronization against a CardDAV server (RFC 6352).
Package carddav implements an activesync.Backend for contact synchronization against a CardDAV server (RFC 6352).
combined
Package combined implements an activesync.Backend that wires three specialized backends together:
Package combined implements an activesync.Backend that wires three specialized backends together:
httputil
Package httputil provides a shared HTTP client factory for backend drivers.
Package httputil provides a shared HTTP client factory for backend drivers.
imap
Package imap implements an activesync.Backend backed by an IMAP4rev1/rev2 server.
Package imap implements an activesync.Backend backed by an IMAP4rev1/rev2 server.
kopano
Package kopano implements an activesync.Backend backed by the Kopano Collaboration Suite (formerly Zarafa) using the kopano-grapi REST API.
Package kopano implements an activesync.Backend backed by the Kopano Collaboration Suite (formerly Zarafa) using the kopano-grapi REST API.
maildir
Package maildir implements an activesync.Backend backed by a Maildir++ filesystem.
Package maildir implements an activesync.Backend backed by a Maildir++ filesystem.
openxchange
Package openxchange implements an activesync.Backend backed by Open-Xchange App Suite using the OX HTTP API.
Package openxchange implements an activesync.Backend backed by Open-Xchange App Suite using the OX HTTP API.
zimbra
Package zimbra implements an activesync.Backend backed by the Zimbra Collaboration Suite SOAP API.
Package zimbra implements an activesync.Backend backed by the Zimbra Collaboration Suite SOAP API.
cmd
client command
Command client is a command-line test client for the Go-ActiveSync server.
Command client is a command-line test client for the Go-ActiveSync server.
server command
Command server is the Go-ActiveSync ActiveSync server.
Command server is the Go-ActiveSync ActiveSync server.
Package config defines the configuration schema for the Go-ActiveSync server.
Package config defines the configuration schema for the Go-ActiveSync server.
examples
existing-server command
Example: existing-server — mount Go-ActiveSync alongside your existing Echo v5 routes.
Example: existing-server — mount Go-ActiveSync alongside your existing Echo v5 routes.
minimal command
Example: minimal — the simplest possible Go-ActiveSync integration.
Example: minimal — the simplest possible Go-ActiveSync integration.
with-database command
Example: with-database — a realistic backend backed by a SQL database.
Example: with-database — a realistic backend backed by a SQL database.
internal
demo
Package demo provides a minimal in-memory Backend implementation for testing and demonstration purposes.
Package demo provides a minimal in-memory Backend implementation for testing and demonstration purposes.
pkg
activesync
Package activesync provides an embeddable Microsoft Exchange ActiveSync server built on Echo v5.
Package activesync provides an embeddable Microsoft Exchange ActiveSync server built on Echo v5.
protocol
Package protocol defines Microsoft ActiveSync protocol constants, command codes, status codes, and shared data types used across the server and client.
Package protocol defines Microsoft ActiveSync protocol constants, command codes, status codes, and shared data types used across the server and client.
wbxml
Package wbxml implements a WAP Binary XML (WBXML) encoder and decoder compatible with Microsoft Exchange ActiveSync protocol versions up to 14.1.
Package wbxml implements a WAP Binary XML (WBXML) encoder and decoder compatible with Microsoft Exchange ActiveSync protocol versions up to 14.1.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL