Netsane ... getting better ...

becka@sunserver1.rz.uni-duesseldorf.de
Fri, 17 Jan 1997 21:46:56 +0100 (MET)

Hi Folks ...

After tracking down a nasty bug, netsane is now quickly improving.

Currently about 50% of the protocol have been implemented.

There are still lots of things to do, and I suppose a few of them will
prove to be quite nasty ...

I hope to be able to release a first preview after this weekend.

Authorization is not yet covered, but I have changed the protocol in a way
that allows to easily add this later.

Current protocol description (commented as far as implemented) follows :

*************************************************************************
The NETSANE - Protocol :

1.) Preface :
=============

Netsane is intended to bring SANE (Scanner Access Now Easy) to the
network.

Why this ?

There are several imaginable situations, where you would like to access
an image-source across the network :

1) You need access to a scanner which has to be to be attached to a machine
(for physical or administrative reasons) you have no account on.

2) You want to provide public access to a picture source while allowing the
user to use the enhanced capabilities of SANE to control the device
generating the pictures.

2.) The Protocol :
==================

2.1.) General Information
-------------------------

Netsane runs as a TCP service on the (prviledged ?) Port ????.

2.2.) Helper Library and Parameter Transfer
===========================================

SANE makes use of lots of parameters. They are transferred in the
following way :

- Structures are broken up into their individual members.
This is done recursively if necessary.
- Each field is sent as one command of the form length,value.
- Opaque Values (like SANE_HANDLE) are transferred "as_is"
- INT Values in SANE are always 32 bit and are transferred in
network-byte-order (using htonl).
- Strings are transferred as a C-string (\0-terminated).
As empty string generally do not make sense in SANE,
they are considered to be the equivalent of a "NULL" pointer.
The used character set is assumed to be latin1.
It is discouraged to use characters other than ASCII to be
compatible. As "long-range" network connections are not
the primary concern of SANE, you may choose to send strings
in your local encoding, though this should only be done, if
ASCII or latin1 are not sufficient.
- enum or #define values are encoded as INT and transferred
this way. Please note, that this makes it necessary, that
sane.h is identical in this respect on all systems and only
extended in a compatible way.

The example implementation contains routines that allow accessing the
SANE data transfer just like printf/scanf.

netsane_printf(char *param_string,int command,...);
netsane_scanf(char *param_string,int *command,...);

The corresponding option-string is included with every command.
Please note, that the command is treated as a normal INT Argument
and only "special-cased" here for clarity.

2.3.) CONNECTION SETUP (mandatory)
==================================

After it has established a connection, the server will issue a greeting
message. It is allowed to send several lines of greeting :

S: CMD_HELO [optional text]

Syntax: "%d %s\n",CMD_HELO,"Some greeting message"

The client should reply with a HELO message itself (e.g. for logging
puposes), but this may be skipped.

The server is now in "command-stage". However it will normally require
authentication. This can happen anytime during a NETSANE session, so your
client should probably work event-oriented. (The protocol is designed to
deliver all information necessary to process a given request within the
request itself.)

The same applies for cryto-negotiation which can be requested any time.

2.4.) AUTHENTICATION (optional)
===============================

If authentication is enabled, the client is now asked to log on
by the server :

S: CMD_USER

This is done by first sending a username with the USER command.

C: USER myusername

Sytax: "%d %s\n",CMD_USER,"My_Username"

The server may now ask for a pass-phrase which can be computed in
the following ways :

2.4.1.) "classic" Unix : (mandatory)
------------------------------------

The password is transferred in plaintext and compared to a crypted
version of it on the server.

S: CMD_PASS_REQ PASS_UNIX

Syntax: "%d %d\n",CMD_PASS_REQ,PASS_UNIX

C: CMD_PASS_RPLY PASS_UNIX password

Syntax: "%d %d %s\n",CMD_PASS_RPLY,PASS_UNIX,"My password"

This authentication method is only recommended for "safe" networks,
where you can safely assume, that no spies can catch network packages.

2.4.2.) "crypt" : (mandatory)
-----------------------------

The password must be crypted by the client with three seeds which
are provided by the server. The system works as follows :

The server has a crypt()ed version of the password stored.
The client uses crypt() to achieve the same data by using crypt()
with the same seed (#1 sent by the server). ( This stage is to be
able to send an already crypted password to the site-admin, so even
(s)he doesn' know the plaintext).

Both systems then use crypt(crypted_passwd+2,seed#2) and
crypt(crypted_passwd+5,seed#3) to generate two passwords
which are then compared over the net. An example :

S: CMD_PASS_REQ PASS_CRYPT AB CD EF

Syntax: "%d %d %s %s %s\n",CMD_PASS_REQ,PASS_CRYPT,"Seed1","Seed2","Seed3"

The client now uses the password it is given (password) to calculate
the password stored on the server : ABRCL9ijBr2LY
Both systems then calculate crypt("RCL9ijBr2LY","CD")=CDcC3uINqJo7Q
and crypt("9ijBr2LY","EF")=EFIBfTmJjGhtM .

C: CMD_PASS_RPLY PASS_CRYPT CDcC3uINqJo7Q EFIBfTmJjGhtM

Syntax: "%d %d %s %s\n",CMD_PASS_RPLY,PASS_CRYPT,"Response1","Response2"

This scheme should reduce the risk of network-spies, but it will
not completely eliminate it. Note that only 24 bits are used for
distinguishing different accesses. I.e. a network spy has a
2^24 : number of monitored transmissions chance to have the
right password.

Hopefully this scheme does not introduce a vulnerability for the
(crypted) password itself, as parts of it are encrypted twice.
I do not think the crypt algorithm is weakened very much by the
knowledge, that the last 5 letters of crypt A are the same as
the first 5 of crypt B.

2.4.3. More protocols
---------------------

can be implemented. They are identified by the second field of
the PASS request. (Any suggestions ?)

2.4.4. Authentication failure
-----------------------------

If authentication fails, the server will go back to stage 2) and
re-ask for USER and PASS. After a number of unsuccessful tries,
the connection should be terminated.

The client may ask the server for another authentication method
by replying

C: CMD_FAIL CMD_PASS [Allowed protocols]

Syntax: "%d %d %*d\n",CMD_FAIL,CMD_PASS,NumOfProtocols,&Protlist,...

In this case the server may choose to send the PASS again with
another protocol (should be configureable on the server side)
or to count the attempt as failed and go to Stage 2).

2.5. Crypto negotiation (optional)
==================================

No crypto-methods are used up to now. In case it is supported,
the protocol is as follows :

S: CRPT_REQ [allowed protocols]

Syntax: "%d %*d\n",CMD_CRPT_REQ,NumOfProtocols,&Protlist,...

The client MUST choose one of the allowed protocols (or NONE, if
this "protocol" is in the list) by:

C: CRPT chosen_protocol

Syntax: "%d %d\n",CMD_CRPT_RPLY,Protokol

All further communication will use the chose protocol.

Each protocol may exchange the necessary setup-data using a
protocol-specific extension.

2.6.) Command Stage
===================

The Sane server will go to command stage after authentication.
No more authority-checking is done. I.e. the connection could be
captured using IP-spoofing, but this is probably not that
critical.

No crypto-methods are used

The following commands are defined which closely map to the SANE
calls :

INIT sane_init
EXIT sane_exit
GDEV sane_get_devices
OPEN sane_open
CLOS sane_close
GOPT sane_get_option_descriptor
COPT sane_control_option
PARM sane_get_parameters
STAR sane_start
READ sane_read
ABRT sane_cancel
IOMO sane_set_io_mode
GSFD sane_get_select_fd
STRS sane_strstatus

2.7. The individual commands
============================

2.7.1. sane_init
----------------

INIT sane_init
This should be the first command to call after authentication.
It will return the version of SANE in use on the server side.

Syntax: "%d\n",CMD_INIT
Reply : "%d %d %d\n",CMD_INIT,sane_rc,sane_version_code

2.7.2. sane_exit
----------------

EXIT sane_exit
This should be the last command in command stage

Syntax: "%d\n",CMD_EXIT
Reply : "%d\n",CMD_EXIT

2.7.3. sane_strstatus
---------------------

STRS sane_strstatus
Convert a sane_status reply to a string.

Syntax: "%d %d\n",CMD_STRS,sane_rc
Reply : "%d %s\n",CMD_STRS,"Descriptive error message"

2.7.4. sane_get_devices
-----------------------

GDEV sane_get_devices
Get the supported devices.

Syntax: "%d\n",CMD_GDEV
Reply : "%d %d %s %s %s %s ...\n",CMD_GDEV,
sane_rc,dev1.name,dev1.,dev1.,dev1., ... , ... ,NULL

Please note, that ns_scanf returns 0, if no more data can be read from the
current message.

2.7.5. sane_open
----------------

OPEN sane_open
Open a sane_device.

Syntax: "%d %s\n",CMD_OPEN,devname
Reply : "%d %d %*c\n",CMD_OPEN,sane_rc,sizeof(SANE_Handle),SANE_Handle

2.7.6. sane_close
-----------------

CLOS sane_close
Close a sane_device.

Syntax: "%d %*c\n",CMD_CLOS,sizeof(SANE_Handle),SANE_Handle
Reply : "%d\n",CMD_CLOS

2.7.7. sane_get_option_descriptor
---------------------------------

GOPT sane_get_option_descriptor
Get an option descriptor

Syntax: "%d %*c %d\n",CMD_GOPT,sizeof(SANE_Handle),SANE_Handle,optnum
Reply : "%d %s %s %s %d %d %d %d %d",CMD_GOPT,
name,title,desc, type,unit,size,cap, constraint_type
The constraint-field is then transferred (in the same message) as a
series of "%s","%d" or "%d %d %d" type strings depending on constraint-
type. Transmission is terminated by "\n".

2.7.8. sane_control_option
--------------------------

COPT sane_control_option
Get/Set an option.

PARM sane_get_parameters
STAR sane_start
READ sane_read
ABRT sane_cancel
IOMO sane_set_io_mode
GSFD sane_get_select_fd

5. Logging out

The sane server will react to a connection-close by stopping all
current activities and cleanly shutting down the scanner interface.

This way of terminating a session is discouraged and included for
compatibility/network-failure.

The normal way of logging out should be to shutdown SANE as if using
the library (call sane_cancel and _exit) and then issue the command

QUIT

This command will result in the same behaviour as a connection close
(which will be induced by the server, then), i.e. the server has to
shut down the scanner cleanly, no matter what state it is in.
*************************************************************************

CU,Andy

-- 
==============================================================================
Andreas Beck              |  Email :  <becka@sunserver1.rz.uni-duesseldorf.de>
===  World-Wide-Web URL :  http://sunserver1.rz.uni-duesseldorf.de/~becka  ===
==============================================================================

---
Source code, list archive, and docs: http://www.azstarnet.com/~axplinux/sane/
To unsubscribe:    echo unsubscribe sane-devel | mail majordomo@azstarnet.com