SNP 3.0

Message Structure

An SNP 3.0 message consists of:
  • A header;
  • One or more lines of content;
  • A terminator.
The header, all content lines, and the terminator must all end with a CR/LF pair. The header and content lines vary depending on whether the message is a request or response; the terminator is always END.

Two types of message are currently defined: a request and a response.


An SNP 3.0 request is sent from a client (which may be Snarl but more likely will part of an application) to a computer running Snarl. An SNP 3.0 request consists of:
  • A header;
  • One or more actions;
  • A terminator.
The header, all request lines, and the terminator must all end with a CR/LF pair.

Example Request

With no hashing:


With SHA-256 hashing:

SNP/3.0 SHA256:4509405940583953094503945

Request Header

The SNP 3.0 header is as follows:

{id/version} [hash_type:key_hash.salt [cypher_type:key]]

id/version is always required; hash_type and cypher_type are optional, however if cypher_type is specified then hash_type must also be specified.
Currently, the only valid value for id/version is SNP/3.0.

Request Content

Each action must be on a seperate line and there must be at least one action contained within the message, otherwise you'll receive a SNARL_ERROR_BAD_PACKET response.

See [[#Security]] for details of supported hashing and encryption algorithms.
Actions follow the [[Generic_API#Request_Structure|standard SNP 2.0 format]].

Some points to note:
  • Actions cannot contain CR or LF characters - use '\n' to include line feeds within actions (for example, within notification text);
  • '&' and '=' characters are reserved; use '&&' and '==' respectively or URL-encode any content which may include these characters;
  • Similarly, Base64 encoded icon data must not contain CR, LF, or '=' characters (which typically appear in most Base64 encoding algorithms). To avoid this, replace CR/LF pairs with hashes ('#') and equals signs with percent ('%') symbols before including the the request.


An SNP 3.0 response is received by a client from Snarl. An SNP 3.0 response consists of:
  • A header
  • Zero or more lines of content
  • A terminator
The header, all content lines, and the terminator all end with a CR/LF pair.

Response Header

The SNP 3.0 response header is as follows:

{id/version} {OK|FAILED} [hash_type [cypher_type]]

At present hash_type and cypher_type are not provided.

Success Response

SNP/3.0 OK
x-timestamp: 29/06/2011 12:04:59
x-daemon: Snarl 2.4
x-host: cornerstone

Failure Response

A failure response provides the same content as a success response. In some cases, a "hint" line will indicate more specific information about the error that occurred.

error-code: 211
error-name: AuthenticationFailure
error-hint: Digest Mismatch
x-timestamp: 29/06/2011 12:24:59
x-daemon: Snarl 2.4
x-host: conerstone

Status codes can be found here.


== Security ==

=== Authorisation ===

Authorisation ensures only applications that share a common secret (in this case, a password) can communicate with Snarl. The password is entered on the remote computer running Snarl and is used in the construction of the key and key hash on the client, consequently it is never transmitted in clear text between the client and remote computer.

Currently, three forms of hashing are supported:

* MD5
* SHA-1
* SHA-256

Due to deficiencies identified in both MD5 and SHA-1, it is recommended that SHA-256 should always be used when communication may occur over a WAN or across the Internet in an unsecured channel.

The authorisation type used is determined by the sender and is included in the SNP 3.0 header, along with the key hash and salt value used. A new salt value should be used for each request.

The key hash is computed as follows:

* A salt value is created and converted to ASCII hex (e.g. "0036CA21C91F")
* The salt value is appended to the password
* The hash of the combined password+salt string is calculated and included in the SNP 3.0 header

==== Example ====

Using a password of "abcdef" and random salt of "1A2B3C4D5E6F" and MD5 and the hashing algorithm:

* Combined password and salt: "abcdef1A2B3C4D5E6F"
* MD5 hash: "b7c903901cab976ee5db15792eb15a03"

Resulting SNP 3.0 header:

SNP/3.0 MD5:b7c903901cab976ee5db15792eb15a03.1A2B3C4D5E6F

=== Encryption ===

=== Digital Signatures ===

== Subscribing and Forwarding ==

Subscribing and forwarding achieve a similar end result but are subtly different.

As the name implies, a subscription is an open-ended connection initiated by a client to a known remote computer, both running Snarl. Some examples of subscriptions:

* a central office server which propagates company-wide notifications;
* part of a help-desk system which notifies referral groups of ticket changes;
* a centralised source control server which notifies interested parties when a commit had occured.

To summarise: a subscription takes place between two instances of Snarl, is initiated by the client computer and remains in place until the client unsubscribes.

Conversely, forwarding is effectively a wrapper for an SNP 3.0 register/notify action pair. Forwarding is still initiated by a client, however it's the client that is wishing to '''send''' notifications to an instance of Snarl, not receive them. The instance of Snarl may be running on the same computer, but more often than not it will be running on a remote computer. The client may use Snarl to send the register/notify message, although it's more likely it will be an application which creates the message itself. Some examples of forwarding:

* a printer driver installed on a computer that sends events (e.g. paper jam, toner low) to a central management server;
* a user who wants to send simple ad-hoc IM-style messages to one or more other users;
* an application that monitors and reports on activity on a computer to a central server.

=== Subscribing ===

The subscribe action is documented as part of the Snarl [[Generic_API#subscribe|generic API]]

==== Examples ====


Subscribes to notifications from all applications


Subscribes to notifications from only the applications with signatures "foo/bar" and "bar/qux"


Subscribes to notifications from application "foo/bar" but '''fails''' to subscribe to notifications from "wont/work" because the password supplied during the initial subscription was not provided.

Note that neither the IP address or the port number of the subscriber are required - these are derived directly from the subscriber's socket in order to avoid IP address spoofing.

Future revisions of the SNP 3.0 specification may allow the subscriber to provide a friendly name that the remote instance of Snarl will display in the subscriber list. The friendly name would be most likely be passed as a message parameter, as follows:

#sender-name: Tom's desktop PC

=== Forwarding ===

== Examples ==

Response Format