Basic principles
Prev | Chapter 23. The RefDB client/server communication protocol | Next

## Basic principles

refdbd is implemented as a forking server. The parent process waits to accept connections from the clients. If a valid connection request is detected, the server forks. The parent closes the connection and is ready to respond to further requests. The child processes the client request and terminates when done.

The communication between the client and the server is at least a two-stage process. In the first stage, the validity of the client request is checked, the protocol version is checked and the password encryption is initiated. In the second stage, the command proper is executed and the results are sent back to the client. The second stage may use several iterations of client/server messages in order to transfer larger amounts of data.

### Message format

All data, that is client commands as well as the server-generated results, are sent as plain text. We have to distinguish between three types of messages:

Status messages

  Status messages are unterminated three-byte sequences which encode the client or server status. They may precede terminated messages, but they can also appear alone. The three bytes are a text representation of the client or server status. E.g. the sequence "000" (that is, three times the ASCII character 48 representing the digit 'zero') denotes an OK status. A listing of the status messages used by RefDB is shown in the section Status Messages.

Terminated messages

  Most of the data transfer between client and server uses terminated messages. Due to the support of multibyte character sets the string termination character is not a single '\0' character as in a C string, but a sequence of four consecutive '\0' bytes (sequences of up to three '\0' bytes may occur as part of multibyte Unicode characters). It is best to think of the messages as binary strings. A custom client has to terminate its messages to the server appropriately, and it has to scan the data sent back by the server for the terminating sequence.

Messages of a specified length

  In a few cases, the client asks the server to provide a buffer of a certain size, and will subsequently transfer exactly the requested number of bytes. These messages are unterminated.

### First stage

The purpose of the first stage is to check whether the client request makes sense at all, and if so, to initiate the exchange of the password encryption information.

#### Sanity and permission check

Unless told otherwise, refdbd accepts only local connections. If the client request stems from a computer with a different IP address than the computer that runs refdbd, the connection request is refused without any further attempt to talk to the client. From the client side the connection will simply time out. This "unfriendly" behaviour minimizes the risk of remote exploits.

If the client is allowed to connect, refdbd tries to read a terminated string from the client. If this string is too short or too long to represent the protocol number which the client is supposed to send, the connection request is refused by sending back an appropriate status message. The same occurs if the protocol version of the client is not supported by the server.

#### Password encryption

The RefDB clients may have to transmit the database username and password in order to authenticate the user with the database server. In order to avoid sending the password across the network as plain text, the clients send encrypted versions, which the refdbd server decrypts again. Database engine client libraries usually employ their own means to encrypt the passwords when they are sent from refdbd to the database engine.

RefDB uses a fairly simple password encryption. It is still too cumbersome to decrypt for bored script kiddies so it should serve it's purpose. The encryption is somewhat modeled after the (in)famous ENIGMA boxes used by the bad guys in WWII. The basic idea is that refdbd sends a string to the client which encodes the (randomly generated) rotor sequence and positions for this particular connection. The client uses this information to encode the password. The server can decrypt the password using the sequence and position information that it previously generated.

The rotor wirings are hardcoded. Any client or library has to use the same wirings as in `src/filename.c`. The encoding string has the format "ABC-DE-FG-HI", which stands for:

ABC

  This three-digit string denotes the sequence of the wheels. ABC denote the wheels in slots 0, 1, and 2, respectively. The wheels are also numbered 0 through 2, and each wheel can be used only once. That is, all valid combinations are "012", "021", "102", "120", "210", "201". For example, the string "120" means that wheel 1 is inserted in slot 0, wheel 2 in slot 1, and wheel 0 in slot 2.

DE

  The position of the wheel in slot 0. A two-digit integer equal to or larger than 0 and smaller than 94. For example, the string "05" means the wheel in slot 0 has to advance 5 positions.

FG

  Same as DE, but for slot 1.

HI

  Same as DE, but for slot 2.

The encryption and decryption itself is described in sufficient detail in the source file `src/enigma.c` or in the `Client.pm` file of the RefDBClient Perl module. If you cannot implement this mechanism in your favourite programming language, there is also an external program eenc as part of the RefDB distribution which performs the encryption/decryption and sends the result to `stdout`. Use it like this:

    	  ~$
    	  eenc -p ABC-DE-FG-HI password

Most programming languages allow to read the results from `stdout` into a variable and use it as the encrypted or decrypted string.

### Note

There is no switch for encryption or decryption as the ENIGMA mechanism is symmetrical.

### Second stage

As the first step of the second stage the client sends the command string proper. These strings are commands as you know them from your shell. They are roughly equivalent to the command strings that you type into the C clients. refdbd parses the command string internally with the getopt library, just as your shell does. After the command string is parsed, refdbd executes the command. The result is returned in at least two steps. With one exception, refdbd first sends back the command result, followed by a command summary. For example, the listdb command first sends back a newline-separated list of database names (the command result proper), followed by the number of available databases (the command summary). These steps are explained in more detail in the following sections. First we'll have a look at the internal command syntax.

#### Command syntax

Each command consists of the command word proper, optionally followed by switches, options, and arguments. As the string is parsed by the getopt library, the sequence of options, commands, and arguments does not matter. The following synopsis shows all possible switches and options.

`command` [-a] [-A `in_format`] [-b `listname`] [-d `database`] [-E `encoding`] [-G `URL`] [-H `host`] [-k] [-n] [-N `limit[:offset]`] [-o `number`] [-p] [-P] [-r] [-R `pdfroot`] [-s `format_string`] [-S `sort_string`] [-t `ref_format`] [-u `username`] [-U `name`] [-w `password`] [-W `newuser_password`]

-a

  The commands getjo, getjf, getj1, and getj2 use this switch to request all journal names (short, full, user abbrev1, and user abbrev2) instead of only the one used to match the query.

-A `in_format`

  The input data format for addref, updateref, and checkref. Currently supported values are "ris" and "risx".

-b `listname`

  Specifies the name of a personal reference list.

-d `database`

  This option sets the name of the database to be used with the current command.

-E `encoding`

  This option sets the character encoding for the current command.

-G `URL`

  The getref command uses this option to pass the URL of a CSS stylesheet to the server.

-H `host`

  The adduser command uses this option to set the hostname or IP address of the user to be added.

-k

  This switch tells the addref command to preserve the numerical ID of the datasets in the U5 field.

-n `namespace`

  This option passes a namespace prefix to the getref and getnote commands (applies only to XML output)

-N `limit[:offset]`

  The getref command and all other get* commands use this option to limit the range of datasets to return. `limit` denotes the number of references to return, and `offset` is an optional number of references to skip at the beginning.

-o `number`

  This option is used to set a custom starting number for numeric bibliographies.

-p

  This option is used with the addref command. The allowed values mean: 0=add entry, 1=update according to ID field, 2=update personal info only.

-P

  If used with the getref command, only references in the personal interest list will be returned.

-r

  This switch is used with several commands to turn an "add" operation into a "remove" operation.

-R `pdfroot`

  This option tells the getref command the variant part of the link to an electronic offprint.

-s `format_string`

  This option can have the values "ris" or "risx" and denotes the type of the references to be added with the addref command.

-S `sort_string`

  The name of the bibliography style to be used with the getbib command.

-t `ref_format`

  The output format of the references retrieved with the getref and getbib commands.

-u `username`

  The username to be used to authenticate with the database engine.

-U `name`

  The name of the user to be associated with a query.

-w `password`

  The password to be used to authenticate with the database engine.

-W `newuser_password`

  The adduser command uses this option to set the password of the new user.

Prev | Up | Next
Chapter 23. The RefDB client/server communication protocol | Home | Commented abstract representation of the client/server protocol