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.