#pragma once #include #include // This "SSH netcat" library is very specifically oriented on the use of SSH in // the tomsg protocol. That is: it is assumed that what you want is a // connection with one simple channel with a particular subsystem, and that you // need no authentication at all (i.e. authentication type 'none'). For // anything more involved, use libssh directly. struct sshnc_client; // Should return 'true' if the key is trusted, 'false' otherwise. The hash is // sha256 in byte form, not yet encoded in hexadecimal or similar. The // 'userdata' pointer comes from the 'sshnc_connect' invocation. typedef bool (*sshnc_hostkey_checker_t)( const unsigned char *hash, size_t length, void *userdata); // Convenience function to convert a hash to a human-readable form. Returns a // reference to an internal static buffer. const char* sshnc_print_hash(const unsigned char *hash, size_t length); enum sshnc_retval { // Successful result SSHNC_OK = 0, // Other status codes SSHNC_EOF, // connection closed (sshnc_send, sshnc_maybe_recv) SSHNC_AGAIN, // no data now, try again later (sshnc_maybe_recv) // Error codes SSHNC_ERR_CONNECT, // could not connect to host SSHNC_ERR_UNTRUSTED, // hostkey checker rejected key SSHNC_ERR_AUTH, // error authenticating to server SSHNC_ERR_DENIED, // server did not accept 'none' authentication SSHNC_ERR_CLOSED, // server unexpectedly closed connection SSHNC_ERR_SUBSYSTEM, // server did not accept the subsystem channel // Internal error codes SSHNC_ERR_SESSION, // could not open libssh session SSHNC_ERR_CHANNEL, // could not open libssh channel SSHNC_ERR_OPTIONS, // could not set libssh options SSHNC_ERR_GETKEY, // could not get key from libssh SSHNC_ERR_CALLBACKS, // sshnc would not accept our callbacks structure SSHNC_ERR_EVENT, // could not create libssh event poller SSHNC_ERR_WRITE, // could not write to ssh channel SSHNC_ERR_POLL, // could not poll the socket for activity }; // Returns reference to internal static buffer. // Additional error info may be stored in an internal thread_local buffer, and // returned as part of the description. const char* sshnc_strerror(enum sshnc_retval code); // If successful, stores a new connection structure in 'client' and returns // SSHNC_OK. On error, stores NULL in 'client' and returns an error code. // The hostkey checker is invoked with the 'userdata' pointer. enum sshnc_retval sshnc_connect( const char *hostname, int port, const char *username, const char *subsystem, sshnc_hostkey_checker_t checker, void *userdata, struct sshnc_client **client // output ); // Close the connection. This also frees the client structure. Note that even // in case of an error, you must still call this function to prevent a memory // leak. void sshnc_close(struct sshnc_client *client); // Returns a file descriptor that can be listened for read-ready events (using // e.g. select(2) or poll(2)). Whenever it becomes ready for reading, you // should call sshnc_maybe_recv(). If the connection was already closed // internally due to an error, returns -1. int sshnc_poll_fd(struct sshnc_client *client); // Returns SSHNC_OK if successful, SSHNC_EOF if the connection was closed, or // an error code otherwise. enum sshnc_retval sshnc_send( struct sshnc_client *client, const char *data, size_t length ); // Retrieves up to 'capacity' bytes from the connection, and writes them to the // buffer pointed to by 'data', and the number of bytes received to 'length'. // Returns SSHNC_OK if successful, SSHNC_EOF if the connection was closed // before any data was received, SSHNC_AGAIN if no data was available without // blocking, or an error code otherwise. // If the return value is not SSHNC_OK, 0 is stored in 'length'. // Note that because this operation is non-blocking, the caller should only // call this if it has a reason for suspecting there might be data (e.g. // because poll(2) reported as such). // This function also handles general ssh protocol messages, and must thus // ALWAYS be called if there is readable data on the socket. // NOTE: when calling this function, you must call it as long as it gives // SSHNC_OK, because there might be more data than your buffer's size. enum sshnc_retval sshnc_maybe_recv( struct sshnc_client *client, size_t capacity, char *data, // output size_t *length // output );