From 65f8e86e418a1601ec78c2c05780488f2afa5288 Mon Sep 17 00:00:00 2001 From: Aris Adamantiadis Date: Tue, 15 Dec 2009 23:37:53 +0100 Subject: [PATCH] Deleted obsolete documentation draft --- doc/libssh-0.2-api-1.txt | 385 --------------------------------------- 1 file changed, 385 deletions(-) delete mode 100644 doc/libssh-0.2-api-1.txt 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. -