Network Working Group Max Wildgrube INTERNET-DRAFT Category: Informational June 2000 Expiration Date: Dezember 2000 GENERAL NETWORK PROTOCOL (GNP) FILED AS: draft-wildgrube-gnp-00.txt STATUS OF THIS MEMO: This document is an Internet-Draft and is in full conformance with all provisions of Section 10 of RFC2026. Internet-Drafts are working documents of the Internet Engineering Task Force (IETF), its areas, and its working groups. Note that other groups may also distribute working documents as Internet-Drafts. Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet- Drafts as reference material or to cite them other than as "work in progress." The list of current Internet-Drafts can be accessed at http://www.ietf.org/ietf/1id-abstracts.txt The list of Internet-Draft Shadow Directories can be accessed at http://www.ietf.org/shadow.html. Please send your comments to the author: max@wildgrube.com ABSTRACT: This specification describes an all-purpose platform independent networking protocol for use to realize client/server (or similar) applications. User and administration messages are transformed into special network format (SDXF, see [1]). This format is self-describing and cpu-independent. DIFFERENCE TO THE PREVIOUS DRAFT: - none: first version CONTENTS: 1. Introduction 2. General Message Format 3. User Messages (Payload) 4. Establishment of connection (Handshaking) 5. Administrator Messages 6. Security Considerations 7. New-Password protocol 8. List of chunk IDs 9. References 10. Author's Address 1. Introduction This proposal describes a multi-purpose networking protocol. In the following it is named "GNP" (General Network Protocol). This protocol describes several levels of operations. It may be helpful to assign these levels to the OSI 7-Layer model: +-----+--------------------+--------------+ |Level| Layer | assigned to: | +-----+--------------------+--------------+ | 7 | Application Layer | application | | 6 | Presentation Layer | SDXF 1) | | 5 | Session Layer | GNP | | 4 | Transport Layer | TCP 2) | | 3 | Network Layer | | | 2 | Data Link Layer | | | 1 | Physical Layer | | +-----+--------------------+--------------+ 1) SDXF stands for "Structured Data eXchange Format" and is described in [1]. For full understanding of this paper it is recommended to read [1] first. SDXF is chosen as the underlying message format, because it is selfdescribing and platform independent. 2) Even this proposal is independent of the Transport Layer, the terms of the TCP is used, specially of the sockets interface. This should not be a important restriction: The great majority of todays networking are using this interface. Nevertheless, what we assume is: a. The communication is connect-oriented. b. The session layer is responsible for a bidirectional, reliable, sequenced, and unduplicated flow of data. Record bounderies of messages must be preserved. (If stream sockets are chosen the session layer is responsible to read the correct amount of data: he can do it because the header of the SDXF chunk of the message contains the data length). 2. General Message Format Even we distinguish between three kind of messages - user (payload) messages, handshake messages and administrator messages û all of them has the same structure: A GNP message consists of exactly one SDXF chunk. After reading the SDXF header (the first 6 bytes of the message) the length of complete message is known: The SDXF header contains the length of the following SDXF data (L), therefore the complete length is: L + 6. As a summary: The structure of all GNP messages has following representation: +---+---+---+---+---+---+---+---+---+-...-+---+---+---+---+ |chunkID|fl | length | content | +---+---+---+---+---+---+---+---+---+-...-+---+---+---+---+ (fl = SDXF flag byte) The chunk ID determines the type of message. It is a 2-byte number in network format, that is a 2-byte integer in big- endian representation, as described in [1]. These 0-level chunk IDs are fixed in following manner: +----------+---------------+-------------------------+ | chunk ID | constant name | meaning | +----------+---------------+-------------------------+ | 32750 | ID_MESSAGE | user message | | 32751 | ID_CONNECT | connect message | | 32752 | ID_DISCONNECT | disconnect message | | 32753 | ID_ADMIN | administration message | | 32754 | ID_AUTH | authentication message | | 32755 | ID_HSHAKE | handshake message | +----------+---------------+-------------------------+ The flag byte determines the type of the SDXF content part. In most cases the SDXF chunk is "structured" that is: the content consists itself of a list of SDXF chunks. In the following we use lisp style notation for the SDXF chunks: (The chunk ID are noted without the prefix "ID_") (MESSAGE) : A message which consists of a single elementary chunk. (MESSAGE (ABC XYZ)) : A message which consists of a structured chunk containing chunks with chunk ID ID_ABC and ID_XYZ. (ADMIN (USERID CMD (PAR1 PAR2 PAR3) CONNID BUFFSIZE)) : A more complex message, the sub-chunk CMD is itself a structured message. If we want to note the type of a chunk, we use the notation CHUNKID:x with x = c for character, = n for numerical, = b for binary (bitstring) chunks. The last level of precision ist to note the type and content of a chunk: CHUNKID:x=content with 'content' as a value or a name which describes the content of the chunk. Besides the described protocol specific chunks any arbitrary additional chunks are possible: An implementation which does not knows these extensions has to ignore them, following the basic rule in [1] ("Ignore unknown chunks!"). Even we do not define implementation details in this proposal, we assume that there exists a data structure of central meaning, called here "connect handle": For every connection a connect handle exists. A conncect handle will be created after a connect() or accept() function call. At least a connect handle contains: - the socket number of the connection - the SDXF structure (or a pointer to it) for the message - authorization / encrypt token - a flag which marks partner as normal user or administrator Depending on a given implementation a connect handle may include also a pointer to a partner specific data area (server), statistical data for accounting and information, partner specific information (user ID), etc. In an object oriented environment, this handle can realized as a class, in C++ you can distinguish between private and public entries. 3. User Messages (Payload) The only rule for user messages is: the top-level chunk ID is ID_MESSAGE (32750). The chunk content is completely interpreted by the application. Or: the communication occurs completely in the Application Layer of the OSI model. In order to maintain the messages in the application layer the SDXF functions are to be used as described in [1]. But before user messages can be interchanged, a connection must be established. This is done by applying the "Handshake Protocol" which is described next. 4. Handshake Protocol A connection must first be established on a physical level (tcp/ip socket functions: connect() and accept(). A logical connect communication follows by interchanging some messages between the two partners. This phase is called "handshaking". Despite the real role-playing of the partners: The partner which starts the communication with a connect() request is called "client", the partner which listen() for connect requests and accept() them is called "server". A server may accept (in a logical sense) a connection request or not. A server may reject a connection request if authorization is requested and checking user ID and password is failed. These are the steps of hand-shaking: H1. client requests connecting to a server by executing the connect() function. H2. Server accepts connect request and sends the handshake- request: (HSHAKE (TOKEN STATUS BUFFSIZE CONNID)) with: TOKEN type binary Optional, a (pseudo-) random generated 64-bit number - if authentication is requested. STATUS type numeric Server status, is normally be READY (value=1), but may be QUIET (value=2) - see chap. 5. BUFFSIZE type numeric Maximal buffersize of server CONNID type binary Connect ID, an unequivocal 32-bit number to identify the connection, for information. H3. Client sends handshake-reply: (HSHAKE (USERID TOKEN ADMIN BUFFSIZE)) with: USERID type char If applicable (authentication !). TOKEN type binary Password encoded token, if a token was sent (authentication !). ADMIN empty If client claims to be administrator. BUFFSIZE type numeric Minimum of clients and servers buffersize. H4. Server sends acknowledgment: (HSHAKE (ACK:n=1 TOKEN:b=token)) or: (HSHAKE (ACK:n=0)) and server disconnects by close()ing the socket The role of "TOKEN" and "USERID" is explained in chap. 6. The maximum buffersize used for payload messages is negotiated between client and server, the minimum of both is then used. A given implementation may create a connect message on the server - created as a result of a successful authorization, not sended by the client. After receiving the positive acknowledge the client can send his requests to the server and receives the resposes. All this messages has ID_MESSAGE as top level chunk ID, as described in chap. 3. An administrator can send administrator messages, which has ID_ADMIN as top level chunk ID (see chap. 5). If the client has finish he invoke a disconnect function call, which sends a disconnect message (DISCONNECT:b=0) to the server and then closes the socket handle. The values of the involved chunk IDs are listed in chap. 8. 5. Administrator Messages A client can declare itself as an administrator. This must be done before it connects to the server to be administer (or as an option of the connect function call). If the server requests authorization, a special flag in the user table should be checked for to authorize an user as an administrator. The most important task for an administrator is to terminate a server in a proper way (instead of the operation system possibilities to terminate a program or task). An other task is to set the server to a QUIET state: In this state no further connections will be accepted (except for administrators of course), but the existing connections will continue to be working. Additionally the connected clients could be informed of this state: The QUIET state may be used as a first step to terminate the server session. Other administrator tasks are: - open and close of account file - get a list of connected users - statistical summaries. An administrator command consists of a small unstructured numerical chunk: (ADMIN:n) The value of this chunk acts as one of following predefined commands: ADMIN_stop = 1 terminates server immediately ADMIN_quiet = 2 sets server in QUIET status ADMIN_revive = 3 resets from QUIET status to READY again ADMIN_user = 4 requests a user table ADMIN_summary = 5 requests a activity statistic ADMIN_closeAcc = 6 closes an account file ADMIN_openAcc = 7 (re-)openes an account file ADMIN_reload = 8 reloads the user table Other commands may be implemented. The commands with value > 1 will be only supported if applicable: ADMIN_quiet and _revive only if the server supports a QUIET status, ADMIN_user and _summary if the server supports information requests about active users and statistics, ADMIN_closeAcc and _openAcc if accounting is supported. ADMIN_reload is designed for servers which loads the complete table of authorized users into memory: If a new user is added into an external table (database), this command may be helpful for to activate this user while the server is running. After receiving and processing an administration command, server replies an acknowledgment: (ADMIN (ACK:n=x)) with x=1 for a positive and x=0 for a negative acknowledgment. 6. Security Considerations There are two important points associated to security problems: a. The password may be spy out during authorization. b. The content of the messages may be spy out. To solve point (a) there is an important rule: Whenever possible we do not transfer a password through the network. Another rule is: As soon as possible an user-readable password is encrypted with a special key. This key is unique for a given application; An "application" in this context is the set of all programs which has to communicate via GNP. We call this key "application key". How does this work? We assume at first that the encrypted password is known on both side: On server side it is stored in an user table (or database: relation user ID / password), on client side the password is typed in at a login dialog (and password is encrypted immediately). The encrypted password is the same on both side (provided that the same application key is used.) After he accepts the connect request, the server generates a token which is unique for this session and connection (a random generated 64 bit value) and sends it with handshake message H2 (ID_TOKEN) to the client (see chap. 4). Client encrypts this token using his encrypted password as key. The encrypted token is sent back with H3 to the server (together with his user ID). The server itself looks in the user table (or data base) for an entry with this user ID, getting the associated encrypted password. With this password as key he encodes for his part the original token. This encrypted token and the token sent back from client must match. (For to encrypt the tokens a special one-way encryption routine may be applicable: This is the reason why the server encodes the original token and does not decode the token sent back from the client.) If the encrypted tokens matches, server generates another token (token2) and sends it to the client as part of a positive acknowledgement (handshake message H4). Also with reference to the security problem (b): With this new token the same play starts again: both server and client encrypts this token with the known encrypted password. This encrypted token (token3) servs as an encryption and decryption key for to encrypt data chunks if desired. Till now, the password - even in his encrypted form - is never sent over the line. An exception of this rule is described in the next chapter: While transferring a new password, some additional security steps will be introduced. Nevertheless: Also this new password is never transferred in a readable form. Another aspect of security is intactness of data, but: While using TCP/IP (more precisely: IP) as a transmission medium we can trust on his CRC check on the transport layer. 7. New-Password protocol Many security plans (demanded by user or administration) requires a change of the passwords from time to time. An implementation of GNP should provide a function to send a new password to the server. This function has to be realized by following special protocol: (As a shortcut we use "enpass" for "application key encrypted password".) At first the new password is encrypted by the client with the application key as described above. A connection to the server is established. Then following message is to be send: A1: (AUTH (PASS:b=enpassw)) After this, an authentication dialog follows: The server encrypts the new "enpassw" with the old "enpassw" and sends this message back to client: A2: (AUTH (PASS:b=enenpassw)) The client decrypts this with its old (encrypted) password. If the echoed new password in A2 is the same as in A1, we can be sure that the server got the proper password. If not, one of the messages A1 or A2 is corrupt. The client reports his check to the server: A3: (AUTH (ACK:n=x)) with x=1 as a positive, x=0 as a negative acknowledgment. Only if A3 was a positive acknowledge: The server tries to update the password of the user in the user table and reports the success via an acknowledge message: A4: (AUTH (ACK:n=x)) with x as above. "Of course" these messages (A1 - A4) are encrypted: The encrypt flag of the level 0 SDXF chunk is set, the encryption key is token3, that is the encrypted H4 (handshake) token (see chap. 4). 8. The complete list of chunk IDs Following values of chunk IDs are reserved for GNP. With regards to programming languages which cannot handle with unsigned integers these values ranges between 32750 up to 32767. chunk ID constant name meaning -------- ------------- --------------------------- top level IDs: 32750 ID_MESSAGE user message (payload) 32751 ID_CONNECT connect message 32752 ID_DISCONNECT disconnect message 32753 ID_ADMIN administration message 32754 ID_AUTH authentication message 32755 ID_HSHAKE handshake message elementary IDs: 32760 ID_TOKEN security token 32761 ID_OPTION additional parameter 32762 ID_STATUS server status: READY or QUIET 32763 ID_BUFFSIZE senders buffer size 32764 ID_CONNID handshaking: connect ID 32765 ID_USERID user ID 32766 ID_PASS authentication: Password 32767 ID_ACK acknowledgment 9. References [1] SDXF: Structured Data Exchange Format. Internet Draft "draft-wildgrube-sdxf-03.txt" (Work in progress) 10. Author's Address Max Wildgrube Schlossstrasse 120 60486 Frankfurt Germany EMail: max@wildgrube.com