aboutsummaryrefslogtreecommitdiff
path: root/doc/libssh-0.2-api-1.txt
diff options
context:
space:
mode:
Diffstat (limited to 'doc/libssh-0.2-api-1.txt')
-rw-r--r--doc/libssh-0.2-api-1.txt385
1 files changed, 0 insertions, 385 deletions
diff --git a/doc/libssh-0.2-api-1.txt b/doc/libssh-0.2-api-1.txt
deleted file mode 100644
index 22d08e58..00000000
--- a/doc/libssh-0.2-api-1.txt
+++ /dev/null
@@ -1,385 +0,0 @@
- The new libssh 0.2 API
- ----------------------
-
-Version 1
-
-A. Introduction
----------------
-
-With the time from the first release of libssh, I have received lots of
-comments about the current API. Myself, I found it quite limiting when doing
-my first libssh-server drafts. Thus, I am moving to a stronger API.
-This API must still be simple. I am not introducing complex changes. An API
-well designed must hide the implementation details. Implementation can change
-easily within bugfixes - but API cannot change each release.
-
-To the people already using libssh 0.11 : sorry. Once I have the complete API
-redesigned, I will write a migration paper. It won't be too hard normally.
-
-Here are the things that were lacking in the previous API and *must* change:
-
-* A non-blocking mode connection type
-* Functions to relegate File descriptor listening to Calling functions and to
- the programmer. (I'll explain later).
-* Along with that, good buffering system (well, it's not an API but).
-* Leave the "functions returns a pointer when it works and NULL when it does
- not work". It gives serious problems to implement bindings (A C++
- constructor should not fail and should not depend on a network thing
-* Make the Session structure an abstract structure that can work with both
- client and *servers*. That mean we should have a Server object which listen
- to clients on a bound port, does the different handshakes and return a
- session.
- Since C is not per se an Object language, I won't use inheritance between
- objects.
-* This same server thing must provide the reverse capabilities than the
- client. That is, accept the handshake, in a nonblocking way. Accept channel
- requests, or send them to the controller program.
-* Support for program forking : Imagine you have a Ssh server object. You
- accept a connection and receive a session, then you receive a channel. You
- may want to keep the good old days fork() tricks. Libssh will give a way to
- destroy handlers from sessions which belong to an other process without
- disturbing the session.
-* So often I received the comment back saying that it was not clear why a
- session or a channel was terminated. This is over.
-* And of course I received lot of mails about the fact I'm doing namespace
- polution. this will be resolved this time.
-So, please read this draft not as a formal documentation but like a roadmap of
-things that each kind of object must do.
-
-B. Description of objects and functions
-
-Initialization and finalization
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Initialization is for now called automatically, so you don't have to take care
-of that.
-As for finalization, we need to finalize the underlying cryptographic library
-(either OpenSSL or libgcrypt). Be sure that you call ssh_finalize when this
-library won't be used anymore, even by other libraries (i.e. if you use libssh
-and another library that uses OpenSSL, call ssh_finalize when any function of
-both these libraries won't be called).
-If you trust your operating system to clean up the mess after a process
-terminates, you can skip this call.
-
-Options structure
-~~~~~~~~~~~~~~~~~
-
-struct ssh_options *ssh_options_new()
-
-ssh_options_getopt(options, *argc, argv)
-
-ssh_options_copy(options)
-
-char ** ssh_options_get_supported_algos(options,type)
- returns a list of the algos supported by libssh, type being one of
- SSH_HOSTKEYS, SSH_KEX, SSH_CRYPT, SSH_MAC, SSH_COMP, SSH_LANG
-
-ssh_options_set_wanted_algos(options,type, char *list)
-list being comma-separated list of algos, and type being the upper constants
-but with _C_S or _S_V added to them.
-
-ssh_options_set_port(options, port)
-
-ssh_options_set_host(options, host)
-
-ssh_options_set_fd(options, fd)
-
-ssh_options_set_bind(options, bindaddr, port)
-this options sets the address to bind for a client *or* a server. a port of
-zero means whatever port is free (what most clients want).
-
-ssh_options_set_username(options, username)
-
-ssh_options_set_connect_timeout(options, seconds, usec)
-
-ssh_options_set_ssh_dir(options, dir)
-ssh_options_set_known_hosts_file(options, file)
-ssh_options_set_identity(options, file)
-
-ssh_options_set_banner(options, banner)
-ssh_options_allow_ssh1(options, bool allow)
-ssh_options_allow_ssh2(options, bool allow)
-
-options_set_status_callback has moved into ssh_* functions.
-
-ssh_session Structure
-~~~~~~~~~~~~~~~~~~~~~
-
-This session structure represents a ssh socket to a server *or* a client.
-
-ssh_session *ssh_new()
-
-ssh_set_options(ssh_session,ssh_options)
-
-ssh_connect(session);
- it will return some status describing at which point of the connection it is,
- or an error code. If the connection method is non-blocking, the function
- will be called more than once, though the return value SSH_AGAIN.
-
-ssh_set_blocking(session, bool blocking)
- set blocking mode or non blocking mode.
-
-ssh_get_fd(session)
- get the currently used connection file descriptor or equivalent (windows)
-
-ssh_set_fd_toread(session)
-ssh_set_fd_towrite(session)
-ssh_set_fd_except(session)
- Serve to notify the library that data is actualy available to be read on the
- file descriptor socket. why ? because on most platforms select can't be done
- twice on the same socket when the first reported data to read or to write
-
-ssh_get_status(session)
- Returns the current status bitmask : connection Open or closed, data
- pending to read or not (even if connection closed), connection closed on
- error or on an exit message
-
-ssh_get_disconnect_message(session)
- Returns the connection disconnect error/exit message
-
-ssh_get_pubkey_hash(session, hash)
- get the public key hash from the server.
-
-ssh_is_server_known(session)
-ssh_write_knownhost(session)
- these 2 functions will be kept
-
-ssh_disconnect(session)
- standard disconnect
-
-ssh_disconnect_error(session,error code, message)
- disconnect with a message
-
-ssh_set_username(session)
- set the user name to log in
-
-ssh_userauth_* functions will be kept as they are now, excepted the fact that
-the username field will disapear.
-the public key mechanism may get some more functions, like retrieving a public
-key from a private key and authenticating without a public key.
-
-ssh_get_issue_banner(session)
- get the issue banner from the server, that is the welcome message.
-
-ssh_silent_free(session)
- This function silently free all data structures used by the session and
- closes the socket. It may be used for instance when the process forked and
- doesn't want to keep track of this session. This is obviously not possible to
- do with separate channels.
-
-The channel_struct structure
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The channels will change a bit. the constructor thing will change, and the way
-to multiplex different connections will change too. channel functions will be
-prefixed with "ssh_"
-
-struct channel_struct *ssh_channel_new()
-
-ssh_channel_open_session(channel)
- will return if the channel allocation failed or not.
-
-ssh_channel_open_forward(channel, ...) won't change. it will report an error if
-the channel allocation failed.
-
-ssh_channel_send_eof(channel)
- send EOF
-ssh_channel_close(channel)
- closes a channel but doesn't destroy it. you may read unread data still in
- the buffer. Once you closed the buffer, the other party can't send you data,
- while it could still do it if you only sent an EOF.
-ssh_channel_is_closed(channel)
- returns true if the channel was closed at one of both sides. a closed chan
- may still have data to read, if you closed yourself the connection. otherwise
- (you didn't close it) the closed notification only comes when you read the
- last buffer byte, or when trying to write into the channel (the SIGPIPE-like
- behaviour).
-
-ssh_channel_is_eof(channel)
- reports if the other side has sent an EOF. This functions returns FALSE if
- there is still data to read. A closed channel is always EOF.
-ssh_channel_free(channel)
- completely free the channel. closes it before if it was not done.
-
-ssh_channel_request_env(channel, name, value)
- set an environment variable.
-
-ssh_channel_request_pty(channel)
-ssh_channel_request_pty_size()
-ssh_channel_change_pty_size()
-ssh_channel_request_shell()
-ssh_channel_request_exec()
-ssh_channel_request_subsystem()
-These functions won't change.
-
-int ssh_channel_write(channel,data, len,stderr)
- Depending on the blocking/non blocking mode of the channel, the behaviour may
- change.
- stderr is the extended buffer. It's generaly only a server->client stream.
-
-ssh_channel_set_blocking(bool blocking)
-
-int ssh_channel_read(channel, buffer, maxlen, is_stderr)
- the behaviour will be this one:
- -if the chan is in non blocking mode, it will poll what's available to read
- and return this. otherwise (nothing to read) it will return 0.
- -if the chan is blocking, it will block until at least one byte is
- available.
-ssh_channel_nonblocking disapears for the later reason.
-
-int channel_poll(channel, is_stderr)
- polls the network and reports the number of bytes ready to be read in the
- chan.
-
-ssh_session ssh_channel_get_session(channel)
- returns the session pointer associated to the channel, for simplicity
- reasons.
-
-int ssh_channel_select(CHANNELS *readchans, CHANNELS *writechans, CHANNELS
- *exceptchans, struct timeval *timeout)
- This function won't work the same way ssh_select did.
- I removed the custom file descriptor thing for 2 reasons:
- 1- it's not windows compliant. D'ouh !
- 2- most programmers won't want to depend on libssh for socket multiplexing.
- that's why i let the programmer poll the fds himself and then use
- ssh_set_fd_toread, towrite or except. Then, he may use ssh_channel_select
- with a NULL timeout to poll which channels have something to read, write or
- error report.
- Here is how it's going to work. The coder sets 3 different arrays with the
- channels he wants to select(), the last entry being a NULL pointer. The
- function will first poll them and return the chans that must be
- read/write/excepted. If nothing has this state, the function will select()
- using the timeout.
- The function will return 0 if everything is ok, SSH_TIMEOUT or SSH_EINTR if
- the select was interrupted by a signal. It is dangerous to execute any
- channel-related functions into signal handlers. they should set a flag that
- you read into your loop. this "trap" (SSH_EINTR) will permit you to catch
- them faster and make your program responsive and look fast.
- the function will return -1 if a serious problem happens.
-
-
-Error handling
-~~~~~~~~~~~~~~
-
-when an error happens, the programmer can get the error code and description
-with ssh_get_error(session). the creation of a failess constructor for
-ssh_session was needed for this reason.
-
-ssh_get_error_code(session) will return an error code into this subset:
- SSH_NO_ERROR : no error :)
- SSH_REQUEST_DENIED : you request for a functionality or a service that is not
- allowed. The session can continue.
- SSH_FATAL : Unrecoverable error. The session can't continue and you should
- disconnect the session. It includes the connection being cut without a
- disconnect() message.
- If a disconnect() message or the channel was closed, a read on such a channel
- won't produce an error. otherwise it will return -1 with a SSH_FATAL error
- code.
-
-Server socket binding
-~~~~~~~~~~~~~~~~~~~~~
-
-It is not possible to bind a socket for ssh with a SSH_SESSION type, because a
-single bound port may lead to multiple ssh connections. That's why the
-SSH_BIND structure must be created. It uses options from the SSH_OPTIONS
-structure.
-
-SSH_BIND *ssh_bind_new()
-creates a structure
-ssh_bind_set_options(bind, options)
-set the option structure
-int ssh_bind_listen(bind)
- bind and listen to the port. This call is not blocking. if some error
- happens, it returns -1 and the error code can be found with perror().
-
-ssh_bind_set_blocking(bind, bool blocking)
- should ssh_bind_accept() block or not.
-
-int ssh_bind_get_fd(bind)
- return the bound file descriptor, that is the listener socket. you may put it
- into a select() in your code to detect a connection attempt.
-
-ssh_bind_set_fd_toaccept(bind)
- say that the listener socket has a connection to accept (to avoid
- ssh_bind_accept() to do a select on it).
-
-SSH_SESSION *ssh_bind_accept(bind)
- return a server handle to a ssh session. if the mode is blocking, the
- function will always return a pointer to a session. if the mode is not
- blocking, the function can return NULL if there is no connection to accept.
-
-This SSH_SESSION handle must then pass through the functions explained above.
-
-
-*server functions *
-
-int ssh_accept(session)
- when a new connection is accepted, the handshake must be done. this function
- will do the banner handshake and the key exchange.
- it will return SSH_AGAIN if the session mode is non blocking, and the
- function must be called again until an error occurs or the kex is done.
-
-Here, I had a few choises about *how* to implement the message parsing as a
-server. There are multiple ways to do it, one being callbacks and one being
-"Message" reading, parsing and then choice going to the user to use it and
-answer. I've choosen the latter because i believe it's the stronger method.
-A ssh server can receive 30 different kind of messages having to be dealt by
-the high level routines, like channel request_shell or authentication. Having
-a callback for all of them would produce a huge kludge of callbacks, with
-no relations on when there were called etc.
-A message based parsing allows the user to filtrate the messages he's
-interested into and to use a default answer for the others. Then, the callback
-thing is still possible to handle through a simple message code/callback
-function array.
-
-I did not define yet what it would look like, but i'm sure there will be a
-SSH_MESSAGE (they won't have a 1/1 correspondance with ssh packets) which will
-be read through
-SSH_MESSAGE *ssh_server_read_message(session).
-with all of the non-blocking stuff in head like returning NULL if the message
-is not full.
-Then, the message can be parsed, ie
-int ssh_message_get_code(message)
-which will return SSH_MESSAGE_AUTH
-then
-int ssh_message_get_subcode(message)
-which then will returh SSH_MESSAGE_AUTH_PASSWORD or _NONE or _PUBKEY etc.
-
-Then, once the message was parsed, the message will have to be answered, ie
-with the generic functions like
-ssh_message_accept(message) which says 'Ok your request is accepted' or
-ssh_message_deny(message) which says 'Your request is refused'.
-
-There would be specific message answer functions for some kind of messages
-like the authentication one. you may want to reply that the authentication is
-Partial rather than denied, and that you still accept some kind of auths, like
-ssh_message_auth_reply(message,SSH_AUTH_PARTIAL,SSH_AUTH_PASSWORD |
-SSH_AUTH_PUBKEY | SSH_AUTH_KEYBINT);
-
-I won't let the user have to deal with the channels himself. When a channel is
-going to be created by the remote size, a message will come asking to open a
-channel. the programmer can either deny or accept, in which case a CHANNEL
-object will be created and returned to the programmer. then, all standard
-channel functions will run.
-
-C. Change log of this document
-
-3. Add paragraph about initalization and finalization.
-
-2. ssh_options_set_username finaly is kept into the options, because it can be
-set by ssh_options_getopt()
-
-1. first release
-
-D. End notes
-
-I think libssh must have a very simple to use, powerful and exhaustive API. It
-must have no design flaw either.
-While I got some good experience at the SSH protocol, I've never writen
-more-than-100 lines programs than use libssh and I don't really know the
-problems of the library. I'd like people who don't understand some detail into
-the API I describe here, who have comments or opinions about it to write me
-the soonest possible to limit the damages if I made something the completely
-wrong way.
-Thanks for your patience.
-