SNP 3

Introduction

SNP 3 builds on both SNP 1 and  SNP 2 with a much more user-friendly and extensible protocol that also supports authorisation and encrypting of request content, and advanced features such as subscribing to notifications from remote sources and forwarding on notifications to remote computers.  SNP 3 also supports multiple Snarl commands per single request.

SNP 3 remains TCP/IP-based and can be bound to any port.  For historical reasons, applications may expect SNP 3 to be bound to port 9887 or 5233.

Message Structure

Request Structure

A SNP 3 request comprises of a header, one or more commands, and a terminator.  Unlike earlier iterations of SNP, a SNP 3 request spans multiple lines and can be a variable number of lines (although, of course, the minimum is three).

Header

The header describes the nature of the request:

SNP/<version> [<request_type> [hash_type:key_hash.salt [cypher_type:key]]]\r\n

version is always “3.0”.  request_type is optional in most cases, but can be either NOTIFY or FORWARD.  If the request type is omitted, it is assumed to be NOTIFY.  If the request uses encryption and/or authorisation, then request_type must be specified.

Commands

Each command is a standard Snarl API request, formatted in the traditional way, with a trailing CRLF pair.  For example:

notify?title=Hello, world!\r\n

Terminator

The terminator is always: END\r\n

Example

SNP/3.0\r\n
notify?title=Testing...&text=Hello, world!&icon=!system-info\r\n
END\r\n

Response Structure

A SNP 3 response is received by a client from Snarl and consists of a header, zero or more lines of content, and a terminator.
The header, all content lines, and the terminator all end with a CRLF pair.  Unlike a SNP 3 request, a SNP 3 response follows a MIME style format with each line of content a key/value pair separated with a colon and a space character.  There are currently three types of SNP 3 response: the first two (success and failure) are typically received immediately after a request is sent; the third (callback) can be received at any time.

Header

The SNP 3 response header is as follows:

{id/version} {success=OK|FAILED|CALLBACK} [hash_type:hash]\r\n

id/version is always “SNP/3.0”.  success indicates whether the previous request completed successfully or not, or whether this is a callback in response to the user taking some action on a previously generated notification.  It will either be “OK” (if the request completed), “FAILED” (if not), or “CALLBACK” – see Callbacks below for more details about the callback response.

Content

TBA

Terminator

The response terminator is always: END\r\n

Examples

The following indicates a previous request was processed successfully.  The request included a single command which also completed successfully:

SNP/3.0 OK
command-notify: 0,Ok
command-bleh: 102,BadCommand
command-notify: 109,ArgMissing
sender: GANYMEDE
timestamp: Sun, 31 Jul 2016 14:30:02 GMT
time-local: Sun, 31 Jul 2016 15:30:02
platform: Windows
platform-version: 6.1.7601
agent: Snarl 5.0
agent-version: 47
END

Example failure response, in this case indicating no requests were actually supplied:

SNP/3.0 FAILED
error-code: 132
error-name: NothingToDo
sender: GANYMEDE
timestamp: Sun, 07 Aug 2016 08:20:56 GMT
time-local: Sun, 7 Aug 2016 09:20:56
platform: Windows
platform-version: 6.1.7601
agent: Snarl 5.0
agent-version: 47
END

Callbacks

Snarl will send a callback to an application when the user takes some action on a notification, or the notification disappears without any user interaction.  Callbacks take the form of a standard response message, with additional information included that explains the nature of the callback, and to help the receiving application identify the notification the callback refers to.

Callbacks are asynchronous in nature and therefore can arrive at any time.  Callbacks do not need to be acknowledged by the receiving application.

Notes

  • Callbacks are only generated by notifications that are displayed on screen
  • If a UID was supplied when the notification was created, the same UID will be returned in the callback
  • Any data-* or x-* parameters supplied when the notification was created will also be returned in the callback

 

Example

The following callback message indicates that a notification was closed by the end user.  The notification was created with a UID of “testing…” and included some addition data- and x- headers:

SNP/3.0 CALLBACK
event-code: 307
event-name: WasClosed
uid: testing...
data-400: 400
data-abc: abc
x-something: something
sender: GANYMEDE
timestamp: Sun, 31 Jul 2016 14:08:58 GMT
time-local: Sun, 31 Jul 2016 15:08:58
platform: Windows
platform-version: 6.1.7601
agent: Snarl 5.0
agent-version: 47
END

 

Forwarding and Subscribing

Forwarding

SNP 3.0 supports the concept of forwarded notifications.  A forwarded notification will have originated from somewhere other than the instance of Snarl that is displaying it, however to all intents and purposes, it will appear no different to the end user.

Message Format

A forwarded message is similar to a standard request, however the descriptor is required and must be set to “FORWARD”.  A forwarded message may contain any number of notify requests (note that only notify requests are allowed, other requests may be ignored or cause the entire message to be rejected).  The receiving machine will use the sending machine’s IP address to identify the source of the forwarded message.

Multiple notifications forwards should be grouped together into a single message, rather than sent as multiple messages, as this is a more efficient use of the protocol.

Example

SNP/3.0 FORWARD
notify?title=Daily Notice&text=The fire alarm will be tested at 11am&icon=!system-info&priority=0
notify?title=Message of the Day&text=Today is bring-your-pet-to-work day!&priority=0
notify?title=Project Update&text=Building 806 has been earmarked for demolition W/C 12 Dec&priority=0
END

Subscribing

SNP 3.0 also supports notification subscriptions.  A subscription is a formal request from a computer running Snarl to receive notifications sent to it from a remote computer.  The notifications will be sent as forwarded messages, however because this is a formal agreement between the two computers, they will be handled by Snarl, rather than as unsolicited notifications from an anonymous source.

Examples

Straightforward “subscribe to everything” request:

SNP/3.0
subscribe
END

Subscribe to everything using authorisation:

SNP/3.0 NOTIFY MD5:ABCDEF1234.9876543210
subscribe
END

Subscribe to events generated by “app/my_app” and “foo/bar” only:

SNP/3.0
subscribe?filter=app/myapp foo/bar
END

Security

Authentication

Authentication can be applied such that the sender of any message and the receiver of the message share a common secret – specifically a password – that isn’t communicated directly between the two.

To authenticate a message, the header must contain a valid descriptor, authentication algorithm and associated key hash and salt.  The header therefore looks thus:

SNP/3.0 [FORWARD|NOTIFY] <algorithm:key_hash.salt>

Algorithm

Defines the algorithm used to create the key hash. Supported algorithms are:

  • MD5
  • SHA512
  • SHA256

Key Hash

TBC – a hash of the key basis created by hashing the password and salt.

Salt

A cryptographically secure 8-32 byte array encoded as ASCII hexadecimal used to generate the key hash.

Example

SNP/3.0 FORWARD MD5:123456789ABCDEF.9876543210\r\n
notify?text=Hello, world!\r\n
END\r\n