Contents

Client Interface

This is the PSYC client interface to person entities. It includes how linking to the entity works and commands are issued.

NOTE: This is a work in progress!


Linking to an Identity

The main purpose for a location (usually a user's client) to be on the PSYC network is to get linked to one or several identities (usually a person entity) in order to be able to execute commands or send messages on its behalf. The location application was probably given a UNI, so it needs to resolve that uniform in order to create a circuit to it, then negotiate a link to it, which is done by subscribing to the links channel of the UNI.

The packet has to be _targeted at the UNI and optionally provide a UNL as _source. This is an example:

 |
 :_target        psyc://example.org/~fippo#_links
 :_tag           284232
 
 _request_context_enter
 |

It uses the context subscription protocol as defined earlier. When (after authentication) the link could be established, typically a _notice_context_enter packet is multicast from the identity to all subscribed locations. The _source variable must contain the UNI (the identity's uniform) and the _target variable the UNL (the location's uniform):

 |
 :_source        psyc://example.org/~fippo#_links
 :_target        psyc://ente.aquarium:-32872
 :_tag_relay     284232
   
 _notice_context_enter
 |

Authentication

Plain password authentication

If there is no security issue with a password traveling the wire in the clear, you can just set the _password variable when sending the _request_link packet:

 |
 :_target        psyc://example.org/~fippo#_links
 :_tag           284232
 
 :_password      godsecretXX332
 _request_context_enter
 |

Hash based authentication

In order for the identity to check whether the _source of the _request_link is allowed to link it sends a _request_password packet to the _source as reply to the _request_link packet. The reply contains a _nonce variable that is used to do hash-based authentication as follows as well as a _password variable with the ? query operator.

Such a _request_password packet may look like this:

 |     
 :_source        psyc://example.org/~fippo#_links
 :_target        psyc://ente.aquarium:-32872
 :_tag_relay     284232
 
 :_available_hashes     |sha1|md5
 :_nonce 6eaa3554
 _error_necessary_authentication
 Please show identification.
 |

You should proceed by sending a _request_context_enter again with the variable _method set to the hash function used and _password containing the hex encoded hash of the nonce and the password, concatenated.

The hash function to use can be chosen from the list in _available_hashes, which is one of these:

  • sha1 - SHA1 hash algorithm
  • md5 - MD5 hash algorithm

Such a packet may look like this:

 |
 :_source        psyc://ente.aquarium:-32872
 :_target        psyc://example.org/~fippo#_links
 :_tag           984383
 
 :_method        sha1
 :_password      68fe60d9b3989848c39842bb3038f515bf7979d3
 _request_context_enter
 |

The password field in the reply contains sha1(nonce + password) = sha1('6eaa3554xfippox') = '68fe60d9b3989848c39842bb3038f515bf7979d3'. The + operator in this case is intended as string concatenation. Note that you don't need to resend the _nonce.

If the password was correct you will receive a _notice_link as described earlier. But if the password was wrong a _error_invalid_password packet is generated as response, which looks similar to this:

 |
 :_source        psyc://example.org/~fippo#_links
 :_target        psyc://ente.aquarium:-32872 
 :_tag_relay     984383
 
 _error_invalid_password
 Wrong password for [_source]!
 |

Unlinking from a Person Entity

If you want to unlink from the person entity again send a packet with _request_context_leave method, according to the context subscription protocol.

The PSYC client interface to the person entity implements most of the commands described in the PSYC user manuals. Places implement the rest. Both persons and places use uniforms for addressing.

Sending Packets in name of the Entity

This part of the specification is frozen and should not change any further in this version.

There are two ways provided for an entity to send a packet with the authorisation or in the name of the person entity.

Direct approach

In the direct approach, the client sends the packet directly to the receiver context. The receiving context validates the identity. It is best used for cases when the UNI does not need to know about the packets from the _target entity, or the UNL is linked to the UNI from an external server, because it would save us the route over UNIs server and back to the UNL (as seen in the indirect approach). The packet has the following specification:

  • _source_identity set to the UNI
  • _target set to the receiving context
  • optionally _source

The receiving target SHOULD ask the UNI wether the UNL is allowed to send in its name. It SHOULD respond directly to the UNL and SHOULD avoid sending messages to the UNI.

See routing variables for general information.


Example:

  |
  :_source           psyc://clientip/
  :_source_identity  psyc://server.tld/~user
  :_target           psyc://otherserver.tld/@place
  
  _message_public
  whatever
  |

Indirect approach

The indirect approach is best used for the common case, when the UNL is directly connected to its home server. The UNL sends the packet to the UNI which will forward it to the original target. The receiving target will not know the UNL and only talks to the UNI.

Future: Of course there could be a setting allowing the UNI to switch to the direct approach if the UNL wants that and sends the UNL as source.

The packet is specified as follows:

It sets the routing variable

  • _target_relay to the final destination (that is, the entity to which it intends to send the packet.
  • _target to the UNI.

The UNI receives the packet, sets _target to the content of _target_relay, removes _target_relay and forwards the packet to the entity.

Example:

  |
  :_target        psyc://server.tld/~user
  :_target_relay  psyc://otherserver.tld/@place
  :_tag           284232
  
  _message_public
  whatever
  |

The UNI then changes this to

  |
  :_source        psyc://server.tld/~user
  :_target        psyc://otherserver.tld/@place
  :_tag           284232
  
  _message_public
  whatever
  |

_source_location

If a command caused the person entity to send a packet the routing variable _source_location SHOULD be set to the UNL of the location that issued the command.

Stored message delivery

After a UNL successfully linked to the UNI it will receive all stored messages from the UNI equipped with a timestamp.

Additional channels

  • #_links - The context all the connected links are member of.

Command execution

A person entity, if it implements this client protocol, provides a set of commands described in the next section.

Standard Person Commands

These are the commands PSYC person entities may want to implement:


_request_do...related variablesequivalent command
_action_whatever_focus/action
This command lets the person entity do a chat action, like _request_do_action_hug would virtually hug someone.
_add_friend_nick_person or _person, _trustee/friend
_cast_method, _amount_friendivity/cast (= /friendcast)
_clear_friend_nick_person or _person/cancel
_clear_log/logclear
_enter_group/enter
_enter_home(too psyced specific)/home
_examine_person _trustee _tag _format/examine /surf
_follow/follow
_help/help
_invite_person _focus/invite
_leave_group/leave
_list_peers/show *
_list_peers_JSON/show data
_list_places/list
_list_places_public/places
_list_users_public/people
_message_person, _group/tell and /
This sends a message to either a _person or a _group.
_presence_degree_mood _degree_availability
_degree_automation _description_presence
/availability /mood and many more
_quit/quit
_register_password/register
_remove_friend_nick_person or _person/unfriend
_retrieve
Generates a _status_storage with _application variables.
_save/save
_set_key _value/set
_show_log_amount _match _parameter/lastlog
_status/status
_store_application*
Stores all variables of the _application family in the entity storage. SHOULD also handle profile settings.
_subscribe_group/subscribe
_subscribe_permanent_group/subscribe
_time_boot/uptime
_unsubscribe_group/unsubscribe
_wake_person/wake

Presence with PSYC clients

In PSYC, clients are in charge of setting and resetting presence states on behalf of their users. That means, that a client will probably want to transmit a _request_do_presence soon after logging in and before logging out using _request_do_quit. Quitting does not automatically send offline presence. This only happens when the client loses contact to the server abnormally.

Entities that are not linked to the person entity MUST NOT be allowed to execute them, instead you MAY care to complain to the sender with a _request_failure_unsupported_execute.

Relaying for linked nodes

When a PSYC node receives a packet with _source_identification set and the uniform in that field addresses one of it's own entities, it has to check whether the _source of that packet is really linked to the person entity addressed by the uniform in _source_identification.

This still needs to be defined. TODO!

Syncing new links

When a new link is established with a person entity, the link needs to be brought up to speed with regard to the variables of the entered contexts. To update the link a _status_variables SHOULD be sent with _target containing the UNL, and _context containing the uniform of the context (which we want to sync).

Even though this is a unicast from the context to the member, it SHOULD be generated locally at the PSYC node the link is connected to.