2 * libwebsockets - lws-plugin-ssh-base
4 * Copyright (C) 2017 Andy Green <andy@warmcat.com>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation:
9 * version 2.1 of the License.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22 #if !defined(__LWS_SSH_H__)
25 #if defined(LWS_WITH_MBEDTLS)
26 #include "mbedtls/sha1.h"
27 #include "mbedtls/sha256.h"
28 #include "mbedtls/sha512.h"
29 #include "mbedtls/rsa.h"
32 #include "lws-plugin-ssh.h"
34 #define LWS_SIZE_EC25519 32
35 #define LWS_SIZE_EC25519_PUBKEY 32
36 #define LWS_SIZE_EC25519_PRIKEY 64
38 #define LWS_SIZE_SHA256 32
39 #define LWS_SIZE_SHA512 64
41 #define LWS_SIZE_AES256_KEY 32
42 #define LWS_SIZE_AES256_IV 12
43 #define LWS_SIZE_AES256_MAC 16
44 #define LWS_SIZE_AES256_BLOCK 16
46 #define LWS_SIZE_CHACHA256_KEY (2 * 32)
47 #define POLY1305_TAGLEN 16
48 #define POLY1305_KEYLEN 32
50 #define crypto_hash_sha512_BYTES 64U
53 (((uint64_t)(((const uint8_t *)(p))[0]) << 56) | \
54 ((uint64_t)(((const uint8_t *)(p))[1]) << 48) | \
55 ((uint64_t)(((const uint8_t *)(p))[2]) << 40) | \
56 ((uint64_t)(((const uint8_t *)(p))[3]) << 32) | \
57 ((uint64_t)(((const uint8_t *)(p))[4]) << 24) | \
58 ((uint64_t)(((const uint8_t *)(p))[5]) << 16) | \
59 ((uint64_t)(((const uint8_t *)(p))[6]) << 8) | \
60 (uint64_t)(((const uint8_t *)(p))[7]))
62 (((uint32_t)(((const uint8_t *)(p))[0]) << 24) | \
63 ((uint32_t)(((const uint8_t *)(p))[1]) << 16) | \
64 ((uint32_t)(((const uint8_t *)(p))[2]) << 8) | \
65 (uint32_t)(((const uint8_t *)(p))[3]))
67 (((uint16_t)(((const uint8_t *)(p))[0]) << 8) | \
68 (uint16_t)(((const uint8_t *)(p))[1]))
70 #define POKE_U64(p, v) \
72 const uint64_t __v = (v); \
73 ((uint8_t *)(p))[0] = (__v >> 56) & 0xff; \
74 ((uint8_t *)(p))[1] = (__v >> 48) & 0xff; \
75 ((uint8_t *)(p))[2] = (__v >> 40) & 0xff; \
76 ((uint8_t *)(p))[3] = (__v >> 32) & 0xff; \
77 ((uint8_t *)(p))[4] = (__v >> 24) & 0xff; \
78 ((uint8_t *)(p))[5] = (__v >> 16) & 0xff; \
79 ((uint8_t *)(p))[6] = (__v >> 8) & 0xff; \
80 ((uint8_t *)(p))[7] = __v & 0xff; \
82 #define POKE_U32(p, v) \
84 const uint32_t __v = (v); \
85 ((uint8_t *)(p))[0] = (__v >> 24) & 0xff; \
86 ((uint8_t *)(p))[1] = (__v >> 16) & 0xff; \
87 ((uint8_t *)(p))[2] = (__v >> 8) & 0xff; \
88 ((uint8_t *)(p))[3] = __v & 0xff; \
90 #define POKE_U16(p, v) \
92 const uint16_t __v = (v); \
93 ((uint8_t *)(p))[0] = (__v >> 8) & 0xff; \
94 ((uint8_t *)(p))[1] = __v & 0xff; \
99 SSH_MSG_DISCONNECT = 1,
101 SSH_MSG_UNIMPLEMENTED = 3,
103 SSH_MSG_SERVICE_REQUEST = 5,
104 SSH_MSG_SERVICE_ACCEPT = 6,
105 SSH_MSG_KEXINIT = 20,
106 SSH_MSG_NEWKEYS = 21,
108 /* 30 .. 49: KEX messages specific to KEX protocol */
109 SSH_MSG_KEX_ECDH_INIT = 30,
110 SSH_MSG_KEX_ECDH_REPLY = 31,
114 SSH_MSG_USERAUTH_REQUEST = 50,
115 SSH_MSG_USERAUTH_FAILURE = 51,
116 SSH_MSG_USERAUTH_SUCCESS = 52,
117 SSH_MSG_USERAUTH_BANNER = 53,
119 /* 60... publickey */
121 SSH_MSG_USERAUTH_PK_OK = 60,
123 /* 80... connection */
125 SSH_MSG_GLOBAL_REQUEST = 80,
126 SSH_MSG_REQUEST_SUCCESS = 81,
127 SSH_MSG_REQUEST_FAILURE = 82,
129 SSH_MSG_CHANNEL_OPEN = 90,
130 SSH_MSG_CHANNEL_OPEN_CONFIRMATION = 91,
131 SSH_MSG_CHANNEL_OPEN_FAILURE = 92,
132 SSH_MSG_CHANNEL_WINDOW_ADJUST = 93,
133 SSH_MSG_CHANNEL_DATA = 94,
134 SSH_MSG_CHANNEL_EXTENDED_DATA = 95,
135 SSH_MSG_CHANNEL_EOF = 96,
136 SSH_MSG_CHANNEL_CLOSE = 97,
137 SSH_MSG_CHANNEL_REQUEST = 98,
138 SSH_MSG_CHANNEL_SUCCESS = 99,
139 SSH_MSG_CHANNEL_FAILURE = 100,
141 SSH_EXTENDED_DATA_STDERR = 1,
143 SSH_CH_TYPE_SESSION = 1,
145 SSH_CH_TYPE_SFTP = 3,
147 SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT = 1,
148 SSH_DISCONNECT_PROTOCOL_ERROR = 2,
149 SSH_DISCONNECT_KEY_EXCHANGE_FAILED = 3,
150 SSH_DISCONNECT_RESERVED = 4,
151 SSH_DISCONNECT_MAC_ERROR = 5,
152 SSH_DISCONNECT_COMPRESSION_ERROR = 6,
153 SSH_DISCONNECT_SERVICE_NOT_AVAILABLE = 7,
154 SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED = 8,
155 SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE = 9,
156 SSH_DISCONNECT_CONNECTION_LOST = 10,
157 SSH_DISCONNECT_BY_APPLICATION = 11,
158 SSH_DISCONNECT_TOO_MANY_CONNECTIONS = 12,
159 SSH_DISCONNECT_AUTH_CANCELLED_BY_USER = 13,
160 SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE = 14,
161 SSH_DISCONNECT_ILLEGAL_USER_NAME = 15,
163 SSH_OPEN_ADMINISTRATIVELY_PROHIBITED = 1,
164 SSH_OPEN_CONNECT_FAILED = 2,
165 SSH_OPEN_UNKNOWN_CHANNEL_TYPE = 3,
166 SSH_OPEN_RESOURCE_SHORTAGE = 4,
168 KEX_STATE_EXPECTING_CLIENT_OFFER = 0,
169 KEX_STATE_REPLIED_TO_OFFER,
170 KEX_STATE_CRYPTO_INITIALIZED,
176 /* things we may write on the connection */
193 SSH_WT_SCP_ACK_ERROR,
196 SSH_WT_WINDOW_ADJUST,
199 /* RX parser states */
201 SSH_INITIALIZE_TRANSIENT = 0,
207 SSH_KEX_STATE_COOKIE,
208 SSH_KEX_NL_KEX_ALGS_LEN,
210 SSH_KEX_NL_SHK_ALGS_LEN,
212 SSH_KEX_NL_EACTS_ALGS_LEN,
213 SSH_KEX_NL_EACTS_ALGS,
214 SSH_KEX_NL_EASTC_ALGS_LEN,
215 SSH_KEX_NL_EASTC_ALGS,
216 SSH_KEX_NL_MACTS_ALGS_LEN,
217 SSH_KEX_NL_MACTS_ALGS,
218 SSH_KEX_NL_MASTC_ALGS_LEN,
219 SSH_KEX_NL_MASTC_ALGS,
220 SSH_KEX_NL_CACTS_ALGS_LEN,
221 SSH_KEX_NL_CACTS_ALGS,
222 SSH_KEX_NL_CASTC_ALGS_LEN,
223 SSH_KEX_NL_CASTC_ALGS,
224 SSH_KEX_NL_LCTS_ALGS_LEN,
225 SSH_KEX_NL_LCTS_ALGS,
226 SSH_KEX_NL_LSTC_ALGS_LEN,
227 SSH_KEX_NL_LSTC_ALGS,
231 SSH_KEX_STATE_ECDH_KEYLEN,
232 SSH_KEX_STATE_ECDH_Q_C,
234 SSHS_MSG_EAT_PADDING,
239 SSHS_GET_STRING_LEN_ALLOC,
240 SSHS_GET_STRING_ALLOC,
241 SSHS_DO_SERVICE_REQUEST,
244 SSHS_DO_UAR_PUBLICKEY,
245 SSHS_NVC_DO_UAR_CHECK_PUBLICKEY,
246 SSHS_DO_UAR_SIG_PRESENT,
248 SSHS_NVC_DO_UAR_PUBKEY_BLOB,
253 SSHS_NVC_CHOPEN_TYPE,
254 SSHS_NVC_CHOPEN_SENDER_CH,
255 SSHS_NVC_CHOPEN_WINSIZE,
256 SSHS_NVC_CHOPEN_PKTSIZE,
260 SSHS_CHRQ_WANT_REPLY,
268 SSHS_NVC_CHRQ_ENV_NAME,
269 SSHS_NVC_CHRQ_ENV_VALUE,
271 SSHS_NVC_CHRQ_EXEC_CMD,
273 SSHS_NVC_CHRQ_SUBSYSTEM,
280 SSHS_NVC_CD_DATA_ALLOC,
285 SSHS_NVC_DISCONNECT_REASON,
286 SSHS_NVC_DISCONNECT_DESC,
287 SSHS_NVC_DISCONNECT_LANG,
289 SSHS_SCP_COLLECTSTR = 0,
290 SSHS_SCP_PAYLOADIN = 1,
293 /* from https://tools.ietf.org/html/draft-ietf-secsh-filexfer-13 */
295 SECSH_FILEXFER_VERSION = 6,
297 /* sftp packet types */
308 SSH_FXP_FSETSTAT = 10,
309 SSH_FXP_OPENDIR = 11,
310 SSH_FXP_READDIR = 12,
314 SSH_FXP_REALPATH = 16,
317 SSH_FXP_READLINK = 19,
320 SSH_FXP_UNBLOCK = 23,
321 SSH_FXP_STATUS = 101,
322 SSH_FXP_HANDLE = 102,
326 SSH_FXP_EXTENDED = 200,
327 SSH_FXP_EXTENDED_REPLY = 201,
329 /* sftp return codes */
333 SSH_FX_NO_SUCH_FILE = 2,
334 SSH_FX_PERMISSION_DENIED = 3,
336 SSH_FX_BAD_MESSAGE = 5,
337 SSH_FX_NO_CONNECTION = 6,
338 SSH_FX_CONNECTION_LOST = 7,
339 SSH_FX_OP_UNSUPPORTED = 8,
340 SSH_FX_INVALID_HANDLE = 9,
341 SSH_FX_NO_SUCH_PATH = 10,
342 SSH_FX_FILE_ALREADY_EXISTS = 11,
343 SSH_FX_WRITE_PROTECT = 12,
344 SSH_FX_NO_MEDIA = 13,
345 SSH_FX_NO_SPACE_ON_FILESYSTEM = 14,
346 SSH_FX_QUOTA_EXCEEDED = 15,
347 SSH_FX_UNKNOWN_PRINCIPAL = 16,
348 SSH_FX_LOCK_CONFLICT = 17,
349 SSH_FX_DIR_NOT_EMPTY = 18,
350 SSH_FX_NOT_A_DIRECTORY = 19,
351 SSH_FX_INVALID_FILENAME = 20,
352 SSH_FX_LINK_LOOP = 21,
353 SSH_FX_CANNOT_DELETE = 22,
354 SSH_FX_INVALID_PARAMETER = 23,
355 SSH_FX_FILE_IS_A_DIRECTORY = 24,
356 SSH_FX_BYTE_RANGE_LOCK_CONFLICT = 25,
357 SSH_FX_BYTE_RANGE_LOCK_REFUSED = 26,
358 SSH_FX_DELETE_PENDING = 27,
359 SSH_FX_FILE_CORRUPT = 28,
360 SSH_FX_OWNER_INVALID = 29,
361 SSH_FX_GROUP_INVALID = 30,
362 SSH_FX_NO_MATCHING_BYTE_RANGE_LOCK = 31,
365 SSH_PENDING_TIMEOUT_CONNECT_TO_SUCCESSFUL_AUTH =
366 PENDING_TIMEOUT_USER_REASON_BASE + 0,
368 SSH_AUTH_STATE_NO_AUTH = 0,
369 SSH_AUTH_STATE_GAVE_AUTH_IGNORE_REQS = 1,
372 #define LWS_SSH_INITIAL_WINDOW 16384
374 struct lws_ssh_userauth {
375 struct lws_genhash_ctx hash_ctx;
386 struct lws_ssh_keys {
387 /* 3 == SSH_KEYIDX_IV (len=4), SSH_KEYIDX_ENC, SSH_KEYIDX_INTEG */
388 uint8_t key[3][LWS_SIZE_CHACHA256_KEY];
390 /* opaque allocation made when cipher activated */
394 uint8_t padding_alignment; /* block size */
396 uint8_t full_length:1;
401 uint8_t Q_C[LWS_SIZE_EC25519]; /* client eph public key aka 'e' */
402 uint8_t eph_pri_key[LWS_SIZE_EC25519]; /* server eph private key */
403 uint8_t Q_S[LWS_SIZE_EC25519]; /* server ephemeral public key */
404 uint8_t kex_cookie[16];
405 uint8_t *I_C; /* malloc'd copy of client KEXINIT payload */
406 uint8_t *I_S; /* malloc'd copy of server KEXINIT payload */
407 uint32_t I_C_payload_len;
408 uint32_t I_C_alloc_len;
409 uint32_t I_S_payload_len;
411 uint8_t match_bitfield;
412 uint8_t newkeys; /* which sides newkeys have been applied */
414 struct lws_ssh_keys keys_next_cts;
415 struct lws_ssh_keys keys_next_stc;
418 struct lws_subprotocol_scp {
427 struct lws_subprotocol_scp scp;
430 struct per_session_data__sshd;
432 struct lws_ssh_channel {
433 struct lws_ssh_channel *next;
435 struct per_session_data__sshd *pss;
437 lws_subprotocol *sub; /* NULL, or allocated subprotocol state */
438 void *priv; /* owned by user code */
443 int32_t peer_window_est;
449 uint8_t scheduled_close:1;
450 uint8_t sent_close:1;
451 uint8_t received_close:1;
454 struct per_vhost_data__sshd;
456 struct per_session_data__sshd {
457 struct per_session_data__sshd *next;
458 struct per_vhost_data__sshd *vhd;
462 char *disconnect_desc;
464 uint8_t K[LWS_SIZE_EC25519]; /* shared secret */
465 uint8_t session_id[LWS_SIZE_SHA256]; /* H from first working KEX */
467 char last_auth_req_username[32];
468 char last_auth_req_service[32];
470 struct lws_ssh_keys active_keys_cts;
471 struct lws_ssh_keys active_keys_stc;
472 struct lws_ssh_userauth *ua;
473 struct lws_ssh_channel *ch_list;
474 struct lws_ssh_channel *ch_temp;
479 struct lws_ssh_pty pty;
483 uint32_t ssh_sequence_ctr_cts;
484 uint32_t ssh_sequence_ctr_stc;
486 uint64_t payload_bytes_cts;
487 uint64_t payload_bytes_stc;
489 uint32_t disconnect_reason;
491 char V_C[64]; /* Client version String */
492 uint8_t packet_assembly[2048];
501 uint32_t channel_doing_spawn;
504 uint8_t K_S[LWS_SIZE_EC25519]; /* server public key */
506 uint32_t copy_to_I_C:1;
507 uint32_t okayed_userauth:1;
508 uint32_t sent_banner:1;
509 uint32_t seen_auth_req_before:1;
510 uint32_t serviced_stderr_last:1;
512 uint32_t chrq_server_port;
514 uint32_t count_auth_attempts;
517 char state_after_string;
519 uint8_t rq_want_reply;
520 uint8_t ssh_auth_state;
524 uint8_t write_task[8];
525 struct lws_ssh_channel *write_channel[8];
526 uint8_t wt_head, wt_tail;
529 struct per_vhost_data__sshd {
530 struct lws_context *context;
531 struct lws_vhost *vhost;
532 const struct lws_protocols *protocol;
533 struct per_session_data__sshd *live_pss_list;
534 const struct lws_ssh_ops *ops;
543 extern struct host_keys host_keys[];
546 crypto_scalarmult_curve25519(unsigned char *q, const unsigned char *n,
547 const unsigned char *p);
550 ed25519_key_parse(uint8_t *p, size_t len, char *type, size_t type_len,
551 uint8_t *pub, uint8_t *pri);
554 kex_ecdh(struct per_session_data__sshd *pss, uint8_t *result, uint32_t *plen);
557 lws_g32(uint8_t **p);
560 lws_p32(uint8_t *p, uint32_t v);
563 lws_timingsafe_bcmp(const void *a, const void *b, uint32_t len);
565 extern const char *lws_V_S;
568 lws_chacha_activate(struct lws_ssh_keys *keys);
571 lws_chacha_destroy(struct lws_ssh_keys *keys);
574 lws_chachapoly_get_length(struct lws_ssh_keys *keys, uint32_t seq,
578 poly1305_auth(u_char out[POLY1305_TAGLEN], const u_char *m, size_t inlen,
579 const u_char key[POLY1305_KEYLEN]);
582 lws_chacha_decrypt(struct lws_ssh_keys *keys, uint32_t seq,
583 const uint8_t *ct, uint32_t len, uint8_t *pt);
585 lws_chacha_encrypt(struct lws_ssh_keys *keys, uint32_t seq,
586 const uint8_t *ct, uint32_t len, uint8_t *pt);
589 lws_pad_set_length(struct per_session_data__sshd *pss, void *start, uint8_t **p,
590 struct lws_ssh_keys *keys);
593 get_gen_server_key_25519(struct per_session_data__sshd *pss, uint8_t *b, size_t len);
596 crypto_sign_ed25519(unsigned char *sm, unsigned long long *smlen,
597 const unsigned char *m, size_t mlen,
598 const unsigned char *sk);
601 crypto_sign_ed25519_keypair(struct lws_context *context, uint8_t *pk,