|
libwebsockets
Lightweight C library for HTML5 websockets
|
Data Fields | |
| int(* | channel_create )(struct lws *wsi, void **priv) |
| int(* | channel_destroy )(void *priv) |
| int(* | rx )(void *priv, struct lws *wsi, const uint8_t *buf, uint32_t len) |
| int(* | tx_waiting )(void *priv) |
| size_t(* | tx )(void *priv, int stdch, uint8_t *buf, size_t len) |
| size_t(* | get_server_key )(struct lws *wsi, uint8_t *buf, size_t len) |
| size_t(* | set_server_key )(struct lws *wsi, uint8_t *buf, size_t len) |
| int(* | set_env )(void *priv, const char *name, const char *value) |
| int(* | exec )(void *priv, struct lws *wsi, const char *command, lws_ssh_finish_exec finish, void *finish_handle) |
| int(* | shell )(void *priv, struct lws *wsi, lws_ssh_finish_exec finish, void *finish_handle) |
| int(* | pty_req )(void *priv, struct lws_ssh_pty *pty) |
| int(* | child_process_io )(void *priv, struct lws *wsi, struct lws_cgi_args *args) |
| int(* | child_process_terminated )(void *priv, struct lws *wsi) |
| void(* | disconnect_reason )(uint32_t reason, const char *desc, const char *desc_lang) |
| int(* | is_pubkey_authorized )(const char *username, const char *type, const uint8_t *peer, int peer_len) |
| size_t(* | banner )(char *buf, size_t max_len, char *lang, size_t max_lang_len) |
| const char * | server_string |
| char | api_version |
| char lws_ssh_ops::api_version |
set to the API version you support (current is in LWS_SSH_OPS_VERSION) You should set it to an integer like 1, that reflects the latest api at the time your code was written. If the ops api_version is not equal to the LWS_SSH_OPS_VERSION of the plugin, it will error out at runtime.
| size_t(* lws_ssh_ops::banner) (char *buf, size_t max_len, char *lang, size_t max_lang_len) |
banner() - copy the connection banner to buffer
| buf | start of the buffer to copy to |
| max_len | maximum number of bytes the buffer can hold |
| lang | start of the buffer to copy language descriptor to |
| max_lang_len | maximum number of bytes lang can hold |
Copy the text banner to be returned to client on connect, before auth, into buf. The text should be in UTF-8. if none wanted then leave .banner as NULL.
lang should have a RFC3066 language descriptor like "en/US" copied to it.
Returns the number of bytes copies to buf.
| int(* lws_ssh_ops::channel_create) (struct lws *wsi, void **priv) |
channel_create() - Channel created
| wsi | raw wsi representing this connection |
| priv | pointer to void * you can allocate and attach to the channel |
Called when new channel created, *priv should be set to any allocation your implementation needs
You probably want to save the wsi inside your priv struct. Calling lws_callback_on_writable() on this wsi causes your ssh server instance to call .tx_waiting() next time you can write something to the client.
| int(* lws_ssh_ops::channel_destroy) (void *priv) |
channel_destroy() - Channel is being destroyed
| priv | void * you set when channel was created (or NULL) |
Called when channel destroyed, priv should be freed if you allocated into it.
| int(* lws_ssh_ops::child_process_io) (void *priv, struct lws *wsi, struct lws_cgi_args *args) |
child_process_io() - Child process has IO
| priv | void * you set when this channel was created |
| wsi | the struct lws the connection belongs to |
| args | information related to the cgi IO events |
Child process has IO
| int(* lws_ssh_ops::child_process_terminated) (void *priv, struct lws *wsi) |
child_process_io() - Child process has terminated
| priv | void * you set when this channel was created |
| wsi | the struct lws the connection belongs to |
Child process has terminated
| void(* lws_ssh_ops::disconnect_reason) (uint32_t reason, const char *desc, const char *desc_lang) |
disconnect_reason() - Optional notification why connection is lost
| reason | one of the SSH_DISCONNECT_ constants |
| desc | UTF-8 description of reason |
| desc_lang | RFC3066 language for description |
The remote peer may tell us why it's going to disconnect. Handling this is optional.
| int(* lws_ssh_ops::exec) (void *priv, struct lws *wsi, const char *command, lws_ssh_finish_exec finish, void *finish_handle) |
exec() - spawn command and wire up stdin/out/err to ssh channel
| priv | void * you set when this channel was created |
| wsi | the struct lws the connection belongs to |
| command | string containing path to app and arguments |
| finish | function to call to indicate the exec finished |
| finish_handle | opaque handle identifying this exec for use with finish |
Client requested to exec something. Return nonzero to fail.
| size_t(* lws_ssh_ops::get_server_key) (struct lws *wsi, uint8_t *buf, size_t len) |
get_server_key() - retreive the secret keypair for this server
| wsi | the wsi representing the connection to the client |
| buf | start of the buffer to copy the keypair into |
| len | length of the buffer in bytes |
load the server key into buf, max len len. Returns length of buf set to key, or 0 if no key or other error. If there is no key, the error isn't fatal... the plugin will generate a random key and store it using *get_server_key() for subsequent times.
| int(* lws_ssh_ops::is_pubkey_authorized) (const char *username, const char *type, const uint8_t *peer, int peer_len) |
is_pubkey_authorized() - check if auth pubkey is valid for user
| username | username the key attempted to authenticate |
| type | "ssh-rsa" |
| peer | start of Public key peer used to authenticate |
| peer_len | length of Public key at peer |
We confirmed the client has the private key for this public key... but is that keypair something authorized for this username on this server? 0 = OK, 1 = fail
Normally this checks for a copy of the same public key stored somewhere out of band, it's the same procedure as openssh does when looking in ~/.ssh/authorized_keys
| int(* lws_ssh_ops::pty_req) (void *priv, struct lws_ssh_pty *pty) |
pty_req() - Create a Pseudo-TTY as described in pty
| priv | void * you set when this channel was created |
| pty | pointer to struct describing the desired pty |
Client requested a pty. Return nonzero to fail.
| int(* lws_ssh_ops::rx) (void *priv, struct lws *wsi, const uint8_t *buf, uint32_t len) |
rx() - receive payload from peer
| priv | void * you set when this channel was created |
| wsi | struct lws * for the ssh connection |
| buf | pointer to start of received data |
| len | bytes of received data available at buf |
len bytes of payload from the peer arrived and is available at buf
| const char* lws_ssh_ops::server_string |
SSH version string sent to client (required) By convention a string like "SSH-2.0-Libwebsockets"
| int(* lws_ssh_ops::set_env) (void *priv, const char *name, const char *value) |
set_env() - Set environment variable
| priv | void * you set when this channel was created |
| name | env var name |
| value | value to set env var to |
Client requested to set environment var. Return nonzero to fail.
| size_t(* lws_ssh_ops::set_server_key) (struct lws *wsi, uint8_t *buf, size_t len) |
set_server_key() - store the secret keypair of this server
| wsi | the wsi representing the connection to the client |
| buf | start of the buffer containing the keypair |
| len | length of the keypair in bytes |
store the server key in buf, length len, to nonvolatile stg. Return length stored, 0 for fail.
| int(* lws_ssh_ops::shell) (void *priv, struct lws *wsi, lws_ssh_finish_exec finish, void *finish_handle) |
shell() - Spawn shell that is appropriate for user
| priv | void * you set when this channel was created |
| wsi | the struct lws the connection belongs to |
| finish | function to call to indicate the exec finished |
| finish_handle | opaque handle identifying this exec for use with finish |
Spawn the appropriate shell for this user. Return 0 for OK or nonzero to fail.
| size_t(* lws_ssh_ops::tx) (void *priv, int stdch, uint8_t *buf, size_t len) |
tx() - provide data to send on the channel
| priv | void * you set when this channel was created |
| stdch | LWS_STDOUT or LWS_STDERR |
| buf | start of the buffer to copy the transmit data into |
| len | max length of the buffer in bytes |
copy and consume up to len bytes into *buf, return the actual copied count.
You should use one of the lws_callback_on_writable() family to trigger the ssh protocol to ask if you have any tx waiting. If you do you will get calls here to fetch it, for each of LWS_STDOUT or LWS_STDERR that were reported to be waiting by tx_waiting().
| int(* lws_ssh_ops::tx_waiting) (void *priv) |
tx_waiting() - report if data waiting to transmit on the channel
| priv | void * you set when this channel was created |
returns a bitmask of LWS_STDOUT and LWS_STDERR, with the bits set if they have tx waiting to send, else 0 if nothing to send
You should use one of the lws_callback_on_writable() family to trigger the ssh protocol to ask if you have any tx waiting.
Returning -1 from here will close the tcp connection to the client.