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 |
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.
Sending Packets in name of the Entity
There are two ways provided for an entity to send a packet with the authorisation or in the name of the person entity.
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.
| :_source psyc://clientip/ :_source_identity psyc://server.tld/~user :_target psyc://otherserver.tld/@place _message_public whatever |
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.
| :_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 |
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.
- #_links - The context all the connected links are member of.
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 variables||equivalent command|
|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|
|_enter_home||(too psyced specific)||/home|
|_examine||_person _trustee _tag _format||/examine /surf|
|_message||_person, _group||/tell and /|
|This sends a message to either a _person or a _group.|
|/availability /mood and many more|
|_remove_friend||_nick_person or _person||/unfriend|
|Generates a _status_storage with _application variables.|
|_show_log||_amount _match _parameter||/lastlog|
|Stores all variables of the _application family in the entity storage. SHOULD also handle profile settings.|
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.