Lines Matching +full:use +full:- +full:pty
2 * libwebsockets - small server side websockets and web server implementation
4 * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
26 #include "lws-ssh.h"
96 pss->write_task[pss->wt_head] = (uint8_t)task; in write_task()
97 pss->write_channel[pss->wt_head] = ch; in write_task()
98 pss->wt_head = (pss->wt_head + 1) & 7; in write_task()
99 lws_callback_on_writable(pss->wsi); in write_task()
106 pss->wt_tail = (pss->wt_tail - 1) & 7; in write_task_insert()
107 pss->write_task[pss->wt_tail] = (uint8_t)task; in write_task_insert()
108 pss->write_channel[pss->wt_tail] = ch; in write_task_insert()
109 lws_callback_on_writable(pss->wsi); in write_task_insert()
120 if (keys->full_length) in lws_pad_set_length()
121 len -= 4; in lws_pad_set_length()
123 if ((len + padc) & (uint32_t)(keys->padding_alignment - 1)) in lws_pad_set_length()
124 padc = (uint8_t)((uint8_t)padc + (uint8_t)(keys->padding_alignment - in lws_pad_set_length()
125 ((len + padc) & (uint32_t)(keys->padding_alignment - 1)))); in lws_pad_set_length()
130 if (!keys->valid) /* no crypto = pad with 00 */ in lws_pad_set_length()
131 while (padc--) in lws_pad_set_length()
134 lws_get_random(pss->vhd->context, *p, padc); in lws_pad_set_length()
137 if (keys->full_length) in lws_pad_set_length()
140 lws_p32(start, len - 4); in lws_pad_set_length()
147 uint8_t *op = p, *lp, *end = p + len - 1; in offer()
168 * name-list kex_algorithms in offer()
169 * name-list server_host_key_algorithms in offer()
170 * name-list encryption_algorithms_client_to_server in offer()
171 * name-list encryption_algorithms_server_to_client in offer()
172 * name-list mac_algorithms_client_to_server in offer()
173 * name-list mac_algorithms_server_to_client in offer()
174 * name-list compression_algorithms_client_to_server in offer()
175 * name-list compression_algorithms_server_to_client in offer()
176 * name-list langua->es_client_to_server in offer()
177 * name-list langua->es_server_to_client in offer()
185 lws_get_random(pss->vhd->context, p, 16); in offer()
192 n = lws_snprintf((char *)p, lws_ptr_diff_size_t(end, p), "curve25519-sha256@libssh.org"); in offer()
202 /* Encryption Algorithms: C -> S */ in offer()
206 // n = lws_snprintf((char *)p, end - p, "aes256-gcm@openssh.com"); in offer()
207 n = lws_snprintf((char *)p, lws_ptr_diff_size_t(end, p), "chacha20-poly1305@openssh.com"); in offer()
210 /* Encryption Algorithms: S -> C */ in offer()
214 // n = lws_snprintf((char *)p, end - p, "aes256-gcm@openssh.com"); in offer()
215 n = lws_snprintf((char *)p, lws_ptr_diff_size_t(end, p), "chacha20-poly1305@openssh.com"); in offer()
218 /* MAC Algorithms: C -> S */ in offer()
222 /* bogus: chacha20 does not use MACs, but 'none' is not offered */ in offer()
223 n = lws_snprintf((char *)p, lws_ptr_diff_size_t(end, p), "hmac-sha2-256"); in offer()
226 /* MAC Algorithms: S -> C */ in offer()
230 /* bogus: chacha20 does not use MACs, but 'none' is not offered */ in offer()
231 n = lws_snprintf((char *)p, lws_ptr_diff_size_t(end, p), "hmac-sha2-256"); in offer()
234 /* Compression Algorithms: C -> S */ in offer()
241 /* Compression Algorithms: S -> C */ in offer()
248 if (p - op < 13 + padc + 8) in offer()
251 /* Languages: C -> S */ in offer()
258 /* Languages: S -> C */ in offer()
279 *payload_len = (int)(len - 5); in offer()
284 padc += 8 - (((int)len + padc) & 7); in offer()
289 while (padc--) in offer()
293 lws_p32(op, len - 4); in offer()
301 struct lws_kex *kex = pss->kex; in handle_name()
306 switch (pss->parser_state) { in handle_name()
308 if (!strcmp(pss->name, "curve25519-sha256@libssh.org")) in handle_name()
309 kex->match_bitfield |= 1; in handle_name()
320 if (!strcmp(pss->name, keyt)) { in handle_name()
321 kex->match_bitfield |= 2; in handle_name()
327 if (!strcmp(pss->name, "chacha20-poly1305@openssh.com")) in handle_name()
328 kex->match_bitfield |= 4; in handle_name()
331 if (!strcmp(pss->name, "chacha20-poly1305@openssh.com")) in handle_name()
332 kex->match_bitfield |= 8; in handle_name()
335 if (!strcmp(pss->name, "hmac-sha2-256")) in handle_name()
336 kex->match_bitfield |= 16; in handle_name()
339 if (!strcmp(pss->name, "hmac-sha2-256")) in handle_name()
340 kex->match_bitfield |= 32; in handle_name()
343 if (!strcmp(pss->name, "none")) in handle_name()
344 kex->match_bitfield |= 64; in handle_name()
347 if (!strcmp(pss->name, "none")) in handle_name()
348 kex->match_bitfield |= 128; in handle_name()
364 pss->kex = sshd_zalloc(sizeof(struct lws_kex)); in lws_kex_create()
366 return !pss->kex; in lws_kex_create()
372 if (!pss->kex) in lws_kex_destroy()
377 if (pss->kex->I_C) { in lws_kex_destroy()
378 free(pss->kex->I_C); in lws_kex_destroy()
379 pss->kex->I_C = NULL; in lws_kex_destroy()
381 if (pss->kex->I_S) { in lws_kex_destroy()
382 free(pss->kex->I_S); in lws_kex_destroy()
383 pss->kex->I_S = NULL; in lws_kex_destroy()
386 lws_explicit_bzero(pss->kex, sizeof(*pss->kex)); in lws_kex_destroy()
387 free(pss->kex); in lws_kex_destroy()
388 pss->kex = NULL; in lws_kex_destroy()
406 if (!pss->ua) in lws_ua_destroy()
411 if (pss->ua->username) in lws_ua_destroy()
412 ssh_free(pss->ua->username); in lws_ua_destroy()
413 if (pss->ua->service) in lws_ua_destroy()
414 ssh_free(pss->ua->service); in lws_ua_destroy()
415 if (pss->ua->alg) in lws_ua_destroy()
416 ssh_free(pss->ua->alg); in lws_ua_destroy()
417 if (pss->ua->pubkey) in lws_ua_destroy()
418 ssh_free(pss->ua->pubkey); in lws_ua_destroy()
419 if (pss->ua->sig) { in lws_ua_destroy()
420 lws_explicit_bzero(pss->ua->sig, pss->ua->sig_len); in lws_ua_destroy()
421 ssh_free(pss->ua->sig); in lws_ua_destroy()
424 lws_explicit_bzero(pss->ua, sizeof(*pss->ua)); in lws_ua_destroy()
425 free(pss->ua); in lws_ua_destroy()
426 pss->ua = NULL; in lws_ua_destroy()
433 if (strcmp(ident, "ssh-rsa") == 0 || in rsa_hash_alg_from_ident()
434 strcmp(ident, "ssh-rsa-cert-v01@openssh.com") == 0) in rsa_hash_alg_from_ident()
436 if (strcmp(ident, "rsa-sha2-256") == 0) in rsa_hash_alg_from_ident()
438 if (strcmp(ident, "rsa-sha2-512") == 0) in rsa_hash_alg_from_ident()
441 return -1; in rsa_hash_alg_from_ident()
447 pss->parser_state = SSHS_GET_STRING_LEN_ALLOC; in state_get_string_alloc()
448 pss->state_after_string = (char)next; in state_get_string_alloc()
454 pss->parser_state = SSHS_GET_STRING_LEN; in state_get_string()
455 pss->state_after_string = (char)next; in state_get_string()
461 pss->parser_state = SSHS_GET_U32; in state_get_u32()
462 pss->state_after_string = (char)next; in state_get_u32()
468 struct lws_ssh_channel *ch = pss->ch_list; in ssh_get_server_ch()
471 if (ch->server_ch == chi) in ssh_get_server_ch()
473 ch = ch->next; in ssh_get_server_ch()
483 struct lws_ssh_channel *ch = pss->ch_list;
486 if (ch->sender_ch == chi)
488 ch = ch->next;
499 lws_start_foreach_llp(struct lws_ssh_channel **, ppch, pss->ch_list) { in ssh_destroy_channel()
502 if (pss->vhd && pss->vhd->ops && in ssh_destroy_channel()
503 pss->vhd->ops->channel_destroy) in ssh_destroy_channel()
504 pss->vhd->ops->channel_destroy(ch->priv); in ssh_destroy_channel()
505 *ppch = ch->next; in ssh_destroy_channel()
506 if (ch->sub) in ssh_destroy_channel()
507 free(ch->sub); in ssh_destroy_channel()
521 struct per_session_data__sshd *pss = ch->pss; in lws_ssh_exec_finish()
523 ch->retcode = retcode; in lws_ssh_exec_finish()
525 ch->scheduled_close = 1; in lws_ssh_exec_finish()
543 while (len --) { in lws_ssh_parse_plaintext()
545 switch(pss->parser_state) { in lws_ssh_parse_plaintext()
547 pss->parser_state = SSHS_IDSTRING; in lws_ssh_parse_plaintext()
548 pss->ctr = 0; in lws_ssh_parse_plaintext()
549 pss->copy_to_I_C = 0; in lws_ssh_parse_plaintext()
554 pss->V_C[pss->npos] = '\0'; in lws_ssh_parse_plaintext()
555 pss->npos = 0; in lws_ssh_parse_plaintext()
556 lwsl_info("peer id: %s\n", pss->V_C); in lws_ssh_parse_plaintext()
558 pss->parser_state = SSHS_IDSTRING_CR; in lws_ssh_parse_plaintext()
561 if (pss->npos < sizeof(pss->V_C) - 1) in lws_ssh_parse_plaintext()
562 pss->V_C[pss->npos++] = (char)*p; in lws_ssh_parse_plaintext()
571 pss->ssh_sequence_ctr_cts = 0; in lws_ssh_parse_plaintext()
572 pss->parser_state = SSHS_MSG_LEN; in lws_ssh_parse_plaintext()
576 pss->msg_len = (pss->msg_len << 8) | *p++; in lws_ssh_parse_plaintext()
577 if (++pss->ctr != 4) in lws_ssh_parse_plaintext()
580 if (pss->active_keys_cts.valid) { in lws_ssh_parse_plaintext()
583 POKE_U32(b, (uint32_t)pss->msg_len); in lws_ssh_parse_plaintext()
584 pss->msg_len = lws_chachapoly_get_length( in lws_ssh_parse_plaintext()
585 &pss->active_keys_cts, in lws_ssh_parse_plaintext()
586 pss->ssh_sequence_ctr_cts, b); in lws_ssh_parse_plaintext()
588 pss->ssh_sequence_ctr_cts++; in lws_ssh_parse_plaintext()
590 lwsl_info("msg len %d\n", pss->msg_len); in lws_ssh_parse_plaintext()
592 pss->parser_state = SSHS_MSG_PADDING; in lws_ssh_parse_plaintext()
593 pss->ctr = 0; in lws_ssh_parse_plaintext()
594 pss->pos = 4; in lws_ssh_parse_plaintext()
595 if (pss->msg_len < 2 + 4) { in lws_ssh_parse_plaintext()
602 pss->msg_padding = *p++; in lws_ssh_parse_plaintext()
603 pss->parser_state = SSHS_MSG_ID; in lws_ssh_parse_plaintext()
607 pss->msg_id = *p++; in lws_ssh_parse_plaintext()
608 pss->ctr = 0; in lws_ssh_parse_plaintext()
609 switch (pss->msg_id) { in lws_ssh_parse_plaintext()
614 * string description in ISO-10646 in lws_ssh_parse_plaintext()
615 * UTF-8 encoding [RFC3629] in lws_ssh_parse_plaintext()
640 if (pss->kex_state != in lws_ssh_parse_plaintext()
642 pss->parser_state = SSH_KEX_STATE_SKIP; in lws_ssh_parse_plaintext()
645 if (!pss->kex) { in lws_ssh_parse_plaintext()
646 lwsl_notice("%s: SSH_MSG_KEXINIT: NULL pss->kex\n", __func__); in lws_ssh_parse_plaintext()
649 pss->parser_state = SSH_KEX_STATE_COOKIE; in lws_ssh_parse_plaintext()
650 pss->kex->I_C_payload_len = 0; in lws_ssh_parse_plaintext()
651 pss->kex->I_C_alloc_len = pss->msg_len; in lws_ssh_parse_plaintext()
652 pss->kex->I_C = sshd_zalloc(pss->kex->I_C_alloc_len); in lws_ssh_parse_plaintext()
653 if (!pss->kex->I_C) { in lws_ssh_parse_plaintext()
657 pss->kex->I_C[pss->kex->I_C_payload_len++] = in lws_ssh_parse_plaintext()
658 pss->msg_id; in lws_ssh_parse_plaintext()
659 pss->copy_to_I_C = 1; in lws_ssh_parse_plaintext()
662 pss->parser_state = SSH_KEX_STATE_ECDH_KEYLEN; in lws_ssh_parse_plaintext()
666 if (pss->kex_state != in lws_ssh_parse_plaintext()
668 pss->kex_state != in lws_ssh_parse_plaintext()
675 * it means we should now use the keys we in lws_ssh_parse_plaintext()
679 pss->active_keys_cts = pss->kex->keys_next_cts; in lws_ssh_parse_plaintext()
680 if (lws_chacha_activate(&pss->active_keys_cts)) in lws_ssh_parse_plaintext()
683 pss->kex->newkeys |= 2; in lws_ssh_parse_plaintext()
684 if (pss->kex->newkeys == 3) in lws_ssh_parse_plaintext()
687 if (pss->msg_padding) { in lws_ssh_parse_plaintext()
688 pss->copy_to_I_C = 0; in lws_ssh_parse_plaintext()
689 pss->parser_state = in lws_ssh_parse_plaintext()
693 pss->parser_state = SSHS_MSG_LEN; in lws_ssh_parse_plaintext()
700 * string user name in UTF-8 in lws_ssh_parse_plaintext()
702 * string service name in US-ASCII in lws_ssh_parse_plaintext()
709 if (pss->ua) { in lws_ssh_parse_plaintext()
710 lwsl_notice("pss->ua overwrite\n"); in lws_ssh_parse_plaintext()
715 pss->ua = sshd_zalloc(sizeof(*pss->ua)); in lws_ssh_parse_plaintext()
716 if (!pss->ua) in lws_ssh_parse_plaintext()
721 if (!pss->sent_banner) { in lws_ssh_parse_plaintext()
722 if (pss->vhd->ops->banner) in lws_ssh_parse_plaintext()
725 pss->sent_banner = 1; in lws_ssh_parse_plaintext()
744 * string "pty-req" in lws_ssh_parse_plaintext()
804 if (!pss->ch_list) in lws_ssh_parse_plaintext()
810 lwsl_notice("unk msg_id %d\n", pss->msg_id); in lws_ssh_parse_plaintext()
817 if (pss->msg_len < 16 + 1 + 1 + (10 * 4) + 5) { in lws_ssh_parse_plaintext()
821 pss->kex->kex_cookie[pss->ctr++] = *p++; in lws_ssh_parse_plaintext()
822 if (pss->ctr != sizeof(pss->kex->kex_cookie)) in lws_ssh_parse_plaintext()
824 pss->parser_state = SSH_KEX_NL_KEX_ALGS_LEN; in lws_ssh_parse_plaintext()
825 pss->ctr = 0; in lws_ssh_parse_plaintext()
839 pss->len = (pss->len << 8) | *p++; in lws_ssh_parse_plaintext()
840 if (++pss->ctr != 4) in lws_ssh_parse_plaintext()
843 switch (pss->parser_state) { in lws_ssh_parse_plaintext()
845 pss->parser_state = SSH_KEX_STATE_ECDH_Q_C; in lws_ssh_parse_plaintext()
848 pss->parser_state++; in lws_ssh_parse_plaintext()
849 if (pss->len == 0) in lws_ssh_parse_plaintext()
850 pss->parser_state++; in lws_ssh_parse_plaintext()
853 pss->ctr = 0; in lws_ssh_parse_plaintext()
854 pss->npos = 0; in lws_ssh_parse_plaintext()
855 if (pss->msg_len - pss->pos < pss->len) { in lws_ssh_parse_plaintext()
856 lwsl_notice("sanity: length %d - %d < %d\n", in lws_ssh_parse_plaintext()
857 pss->msg_len, pss->pos, pss->len); in lws_ssh_parse_plaintext()
873 if (pss->npos < sizeof(pss->name) - 1) in lws_ssh_parse_plaintext()
874 pss->name[pss->npos++] = (char)*p; in lws_ssh_parse_plaintext()
876 pss->name[pss->npos] = '\0'; in lws_ssh_parse_plaintext()
877 pss->npos = 0; in lws_ssh_parse_plaintext()
881 if (!--pss->len) { in lws_ssh_parse_plaintext()
882 pss->name[pss->npos] = '\0'; in lws_ssh_parse_plaintext()
883 if (pss->npos) in lws_ssh_parse_plaintext()
885 pss->parser_state++; in lws_ssh_parse_plaintext()
891 pss->first_coming = !!*p++; in lws_ssh_parse_plaintext()
892 pss->parser_state = SSH_KEX_RESERVED; in lws_ssh_parse_plaintext()
896 pss->len = (pss->len << 8) | *p++; in lws_ssh_parse_plaintext()
897 if (++pss->ctr != 4) in lws_ssh_parse_plaintext()
899 pss->ctr = 0; in lws_ssh_parse_plaintext()
900 if (pss->msg_padding) { in lws_ssh_parse_plaintext()
901 pss->copy_to_I_C = 0; in lws_ssh_parse_plaintext()
902 pss->parser_state = SSHS_MSG_EAT_PADDING; in lws_ssh_parse_plaintext()
905 pss->parser_state = SSHS_MSG_LEN; in lws_ssh_parse_plaintext()
909 if (pss->len != 32) { in lws_ssh_parse_plaintext()
913 pss->kex->Q_C[pss->ctr++] = *p++; in lws_ssh_parse_plaintext()
914 if (pss->ctr != 32) in lws_ssh_parse_plaintext()
917 pss->parser_state = SSHS_MSG_EAT_PADDING; in lws_ssh_parse_plaintext()
921 if (pss->pos - 4 < pss->msg_len) { in lws_ssh_parse_plaintext()
926 pss->pos, pss->msg_len, (long)len); in lws_ssh_parse_plaintext()
927 pss->parser_state = SSHS_MSG_LEN; in lws_ssh_parse_plaintext()
928 pss->ctr = 0; in lws_ssh_parse_plaintext()
933 if (--pss->msg_padding) in lws_ssh_parse_plaintext()
935 if (pss->msg_len + 4 != pss->pos) { in lws_ssh_parse_plaintext()
937 pss->pos, pss->msg_len); in lws_ssh_parse_plaintext()
941 switch (pss->msg_id) { in lws_ssh_parse_plaintext()
943 if (pss->kex->match_bitfield != 0xff) { in lws_ssh_parse_plaintext()
947 if (kex_ecdh(pss, pss->kex->kex_r, in lws_ssh_parse_plaintext()
948 &pss->kex->kex_r_len)) { in lws_ssh_parse_plaintext()
956 pss->parser_state = SSHS_MSG_LEN; in lws_ssh_parse_plaintext()
957 pss->ctr = 0; in lws_ssh_parse_plaintext()
961 pss->npos = 0; in lws_ssh_parse_plaintext()
962 pss->len = (pss->len << 8) | *p++; in lws_ssh_parse_plaintext()
963 if (++pss->ctr != 4) in lws_ssh_parse_plaintext()
965 pss->ctr = 0; in lws_ssh_parse_plaintext()
966 pss->parser_state = SSHS_GET_STRING; in lws_ssh_parse_plaintext()
970 if (pss->npos >= sizeof(pss->name) - 1) { in lws_ssh_parse_plaintext()
971 lwsl_notice("non-alloc string too big\n"); in lws_ssh_parse_plaintext()
974 pss->name[pss->npos++] = (char)*p++; in lws_ssh_parse_plaintext()
975 if (pss->npos != pss->len) in lws_ssh_parse_plaintext()
978 pss->name[pss->npos] = '\0'; in lws_ssh_parse_plaintext()
979 pss->parser_state = pss->state_after_string; in lws_ssh_parse_plaintext()
983 pss->npos = 0; in lws_ssh_parse_plaintext()
984 pss->len = (pss->len << 8) | *p++; in lws_ssh_parse_plaintext()
985 if (++pss->ctr != 4) in lws_ssh_parse_plaintext()
987 pss->ctr = 0; in lws_ssh_parse_plaintext()
988 pss->last_alloc = sshd_zalloc(pss->len + 1); in lws_ssh_parse_plaintext()
990 pss->last_alloc, pss->state_after_string); in lws_ssh_parse_plaintext()
991 if (!pss->last_alloc) { in lws_ssh_parse_plaintext()
995 pss->parser_state = SSHS_GET_STRING_ALLOC; in lws_ssh_parse_plaintext()
999 if (pss->npos >= pss->len) in lws_ssh_parse_plaintext()
1001 pss->last_alloc[pss->npos++] = *p++; in lws_ssh_parse_plaintext()
1002 if (pss->npos != pss->len) in lws_ssh_parse_plaintext()
1004 pss->last_alloc[pss->npos] = '\0'; in lws_ssh_parse_plaintext()
1005 pss->parser_state = pss->state_after_string; in lws_ssh_parse_plaintext()
1013 pss->okayed_userauth = 1; in lws_ssh_parse_plaintext()
1014 pss->parser_state = SSHS_MSG_EAT_PADDING; in lws_ssh_parse_plaintext()
1023 pss->ua->username = (char *)pss->last_alloc; in lws_ssh_parse_plaintext()
1024 pss->last_alloc = NULL; /* it was adopted */ in lws_ssh_parse_plaintext()
1030 pss->ua->service = (char *)pss->last_alloc; in lws_ssh_parse_plaintext()
1031 pss->last_alloc = NULL; /* it was adopted */ in lws_ssh_parse_plaintext()
1046 if (pss->seen_auth_req_before && ( in lws_ssh_parse_plaintext()
1047 strcmp(pss->ua->username, in lws_ssh_parse_plaintext()
1048 pss->last_auth_req_username) || in lws_ssh_parse_plaintext()
1049 strcmp(pss->ua->service, in lws_ssh_parse_plaintext()
1050 pss->last_auth_req_service))) { in lws_ssh_parse_plaintext()
1056 pss->seen_auth_req_before = 1; in lws_ssh_parse_plaintext()
1057 lws_strncpy(pss->last_auth_req_username, in lws_ssh_parse_plaintext()
1058 pss->ua->username, in lws_ssh_parse_plaintext()
1059 sizeof(pss->last_auth_req_username)); in lws_ssh_parse_plaintext()
1060 lws_strncpy(pss->last_auth_req_service, in lws_ssh_parse_plaintext()
1061 pss->ua->service, in lws_ssh_parse_plaintext()
1062 sizeof(pss->last_auth_req_service)); in lws_ssh_parse_plaintext()
1064 if (strcmp(pss->ua->service, "ssh-connection")) in lws_ssh_parse_plaintext()
1070 if (!strcmp(pss->name, "none")) { in lws_ssh_parse_plaintext()
1076 if (strcmp(pss->name, "publickey")) { in lws_ssh_parse_plaintext()
1078 pss->name); in lws_ssh_parse_plaintext()
1081 pss->parser_state = SSHS_DO_UAR_SIG_PRESENT; in lws_ssh_parse_plaintext()
1086 pss->ua->sig_present = (char)*p++; in lws_ssh_parse_plaintext()
1092 pss->ua->alg = (char *)pss->last_alloc; in lws_ssh_parse_plaintext()
1093 pss->last_alloc = NULL; /* it was adopted */ in lws_ssh_parse_plaintext()
1094 if (rsa_hash_alg_from_ident(pss->ua->alg) < 0) { in lws_ssh_parse_plaintext()
1103 pss->ua->pubkey = pss->last_alloc; in lws_ssh_parse_plaintext()
1104 pss->last_alloc = NULL; /* it was adopted */ in lws_ssh_parse_plaintext()
1105 pss->ua->pubkey_len = pss->npos; in lws_ssh_parse_plaintext()
1109 * ssh-rsa in lws_ssh_parse_plaintext()
1120 if (pss->vhd->ops && pss->vhd->ops->is_pubkey_authorized) in lws_ssh_parse_plaintext()
1121 n = pss->vhd->ops->is_pubkey_authorized( in lws_ssh_parse_plaintext()
1122 pss->ua->username, pss->ua->alg, in lws_ssh_parse_plaintext()
1123 pss->ua->pubkey, (int)pss->ua->pubkey_len); in lws_ssh_parse_plaintext()
1129 if (pss->ua->sig_present) { in lws_ssh_parse_plaintext()
1142 pss->parser_state = SSHS_MSG_EAT_PADDING; in lws_ssh_parse_plaintext()
1156 if (pss->ssh_auth_state == SSH_AUTH_STATE_GAVE_AUTH_IGNORE_REQS) { in lws_ssh_parse_plaintext()
1161 pss->ua->sig = pss->last_alloc; in lws_ssh_parse_plaintext()
1162 pss->last_alloc = NULL; /* it was adopted */ in lws_ssh_parse_plaintext()
1163 pss->ua->sig_len = pss->npos; in lws_ssh_parse_plaintext()
1164 pss->parser_state = SSHS_MSG_EAT_PADDING; in lws_ssh_parse_plaintext()
1192 4 + (int)strlen(pss->ua->username) + in lws_ssh_parse_plaintext()
1193 4 + (int)strlen(pss->ua->service) + in lws_ssh_parse_plaintext()
1196 4 + (int)strlen(pss->ua->alg) + in lws_ssh_parse_plaintext()
1197 4 + (int)pss->ua->pubkey_len; in lws_ssh_parse_plaintext()
1206 lws_buf(&pp, pss->session_id, 32); in lws_ssh_parse_plaintext()
1208 lws_cstr(&pp, pss->ua->username, 64); in lws_ssh_parse_plaintext()
1209 lws_cstr(&pp, pss->ua->service, 64); in lws_ssh_parse_plaintext()
1212 lws_cstr(&pp, pss->ua->alg, 64); in lws_ssh_parse_plaintext()
1213 lws_buf(&pp, pss->ua->pubkey, pss->ua->pubkey_len); in lws_ssh_parse_plaintext()
1217 if (lws_genhash_init(&pss->ua->hash_ctx, in lws_ssh_parse_plaintext()
1218 (enum lws_genhash_types)rsa_hash_alg_from_ident(pss->ua->alg))) { in lws_ssh_parse_plaintext()
1224 if (lws_genhash_update(&pss->ua->hash_ctx, ps, lws_ptr_diff_size_t(pp, ps))) { in lws_ssh_parse_plaintext()
1229 lws_genhash_destroy(&pss->ua->hash_ctx, hash); in lws_ssh_parse_plaintext()
1238 pp = pss->ua->pubkey; in lws_ssh_parse_plaintext()
1249 if (lws_genrsa_create(&ctx, e, pss->vhd->context, in lws_ssh_parse_plaintext()
1257 pp = pss->ua->sig; in lws_ssh_parse_plaintext()
1280 pss->ua->hash_ctx.type)) { in lws_ssh_parse_plaintext()
1282 (unsigned int)lws_genhash_size(pss->ua->hash_ctx.type)); in lws_ssh_parse_plaintext()
1297 ctx.ctx->MBEDTLS_PRIVATE(len) = m; in lws_ssh_parse_plaintext()
1299 (enum lws_genhash_types)rsa_hash_alg_from_ident(pss->ua->alg), in lws_ssh_parse_plaintext()
1323 pss->ssh_auth_state = SSH_AUTH_STATE_GAVE_AUTH_IGNORE_REQS; in lws_ssh_parse_plaintext()
1334 pss->len = (pss->len << 8) | *p++; in lws_ssh_parse_plaintext()
1335 if (++pss->ctr != 4) in lws_ssh_parse_plaintext()
1337 pss->ctr = 0; in lws_ssh_parse_plaintext()
1338 pss->parser_state = pss->state_after_string; in lws_ssh_parse_plaintext()
1346 pss->disconnect_reason = pss->len; in lws_ssh_parse_plaintext()
1351 pss->disconnect_desc = (char *)pss->last_alloc; in lws_ssh_parse_plaintext()
1352 pss->last_alloc = NULL; /* it was adopted */ in lws_ssh_parse_plaintext()
1358 if (pss->vhd->ops && pss->vhd->ops->disconnect_reason) in lws_ssh_parse_plaintext()
1359 pss->vhd->ops->disconnect_reason( in lws_ssh_parse_plaintext()
1360 pss->disconnect_reason, in lws_ssh_parse_plaintext()
1361 pss->disconnect_desc, pss->name); in lws_ssh_parse_plaintext()
1362 ssh_free_set_NULL(pss->last_alloc); in lws_ssh_parse_plaintext()
1371 if (strcmp(pss->name, "session")) { in lws_ssh_parse_plaintext()
1373 pss->reason = 3; in lws_ssh_parse_plaintext()
1377 pss->ch_temp = sshd_zalloc(sizeof(*pss->ch_temp)); in lws_ssh_parse_plaintext()
1378 if (!pss->ch_temp) in lws_ssh_parse_plaintext()
1379 return -1; in lws_ssh_parse_plaintext()
1381 pss->ch_temp->type = SSH_CH_TYPE_SESSION; in lws_ssh_parse_plaintext()
1382 pss->ch_temp->pss = pss; in lws_ssh_parse_plaintext()
1387 pss->ch_temp->sender_ch = pss->len; in lws_ssh_parse_plaintext()
1391 lwsl_info("Initial window set to %d\n", pss->len); in lws_ssh_parse_plaintext()
1392 pss->ch_temp->window = (int32_t)pss->len; in lws_ssh_parse_plaintext()
1396 pss->ch_temp->max_pkt = pss->len; in lws_ssh_parse_plaintext()
1397 pss->ch_temp->peer_window_est = LWS_SSH_INITIAL_WINDOW; in lws_ssh_parse_plaintext()
1398 pss->ch_temp->server_ch = (uint32_t)pss->next_ch_num++; in lws_ssh_parse_plaintext()
1404 pss->ch_temp->next = pss->ch_list; in lws_ssh_parse_plaintext()
1405 pss->ch_list = pss->ch_temp; in lws_ssh_parse_plaintext()
1406 if (pss->vhd->ops && pss->vhd->ops->channel_create) in lws_ssh_parse_plaintext()
1407 pss->vhd->ops->channel_create(pss->wsi, in lws_ssh_parse_plaintext()
1408 &pss->ch_temp->priv); in lws_ssh_parse_plaintext()
1409 write_task(pss, pss->ch_temp, SSH_WT_CH_OPEN_CONF); in lws_ssh_parse_plaintext()
1410 pss->parser_state = SSHS_MSG_EAT_PADDING; in lws_ssh_parse_plaintext()
1418 pss->ch_recip = pss->len; in lws_ssh_parse_plaintext()
1423 pss->parser_state = SSHS_CHRQ_WANT_REPLY; in lws_ssh_parse_plaintext()
1427 pss->rq_want_reply = *p++; in lws_ssh_parse_plaintext()
1429 pss->name, pss->rq_want_reply); in lws_ssh_parse_plaintext()
1431 pss->ch_temp = ssh_get_server_ch(pss, pss->ch_recip); in lws_ssh_parse_plaintext()
1436 * a PTY for a shell in lws_ssh_parse_plaintext()
1438 if (!strcmp(pss->name, "pty-req")) { in lws_ssh_parse_plaintext()
1445 if (!strcmp(pss->name, "shell")) { in lws_ssh_parse_plaintext()
1446 pss->channel_doing_spawn = pss->ch_temp->server_ch; in lws_ssh_parse_plaintext()
1447 if (pss->vhd->ops && pss->vhd->ops->shell && in lws_ssh_parse_plaintext()
1448 !pss->vhd->ops->shell(pss->ch_temp->priv, in lws_ssh_parse_plaintext()
1449 pss->wsi, in lws_ssh_parse_plaintext()
1450 lws_ssh_exec_finish, pss->ch_temp)) { in lws_ssh_parse_plaintext()
1452 if (pss->rq_want_reply) in lws_ssh_parse_plaintext()
1453 write_task_insert(pss, pss->ch_temp, in lws_ssh_parse_plaintext()
1455 pss->parser_state = SSHS_MSG_EAT_PADDING; in lws_ssh_parse_plaintext()
1464 if (!strcmp(pss->name, "env")) { in lws_ssh_parse_plaintext()
1472 if (!strcmp(pss->name, "exec")) { in lws_ssh_parse_plaintext()
1480 if (!strcmp(pss->name, "subsystem")) { in lws_ssh_parse_plaintext()
1486 if (!strcmp(pss->name, "window-change")) { in lws_ssh_parse_plaintext()
1487 lwsl_info("%s: window-change\n", __func__); in lws_ssh_parse_plaintext()
1493 if (pss->rq_want_reply) in lws_ssh_parse_plaintext()
1496 pss->parser_state = SSH_KEX_STATE_SKIP; in lws_ssh_parse_plaintext()
1499 /* CHRQ pty-req */ in lws_ssh_parse_plaintext()
1502 memcpy(pss->args.pty.term, pss->name, in lws_ssh_parse_plaintext()
1503 sizeof(pss->args.pty.term) - 1); in lws_ssh_parse_plaintext()
1507 pss->args.pty.width_ch = pss->len; in lws_ssh_parse_plaintext()
1511 pss->args.pty.height_ch = pss->len; in lws_ssh_parse_plaintext()
1515 pss->args.pty.width_px = pss->len; in lws_ssh_parse_plaintext()
1519 pss->args.pty.height_px = pss->len; in lws_ssh_parse_plaintext()
1523 /* modes is a stream of byte-pairs, not a string */ in lws_ssh_parse_plaintext()
1524 pss->args.pty.modes = (char *)pss->last_alloc; in lws_ssh_parse_plaintext()
1525 pss->last_alloc = NULL; /* it was adopted */ in lws_ssh_parse_plaintext()
1526 pss->args.pty.modes_len = pss->npos; in lws_ssh_parse_plaintext()
1528 if (pss->vhd->ops && pss->vhd->ops->pty_req) in lws_ssh_parse_plaintext()
1529 n = pss->vhd->ops->pty_req(pss->ch_temp->priv, in lws_ssh_parse_plaintext()
1530 &pss->args.pty); in lws_ssh_parse_plaintext()
1531 ssh_free_set_NULL(pss->args.pty.modes); in lws_ssh_parse_plaintext()
1534 if (pss->rq_want_reply) in lws_ssh_parse_plaintext()
1535 write_task(pss, pss->ch_temp, SSH_WT_CHRQ_SUCC); in lws_ssh_parse_plaintext()
1536 pss->parser_state = SSHS_MSG_EAT_PADDING; in lws_ssh_parse_plaintext()
1542 strcpy(pss->args.aux, pss->name); in lws_ssh_parse_plaintext()
1547 if (pss->vhd->ops && pss->vhd->ops->set_env) in lws_ssh_parse_plaintext()
1548 if (pss->vhd->ops->set_env(pss->ch_temp->priv, in lws_ssh_parse_plaintext()
1549 pss->args.aux, pss->name)) in lws_ssh_parse_plaintext()
1551 pss->parser_state = SSHS_MSG_EAT_PADDING; in lws_ssh_parse_plaintext()
1569 * scp sends "scp -t /path/..." in lws_ssh_parse_plaintext()
1571 lwsl_info("exec cmd: %s %02X\n", pss->last_alloc, *p); in lws_ssh_parse_plaintext()
1573 pss->channel_doing_spawn = pss->ch_temp->server_ch; in lws_ssh_parse_plaintext()
1575 if (pss->vhd->ops && pss->vhd->ops->exec && in lws_ssh_parse_plaintext()
1576 !pss->vhd->ops->exec(pss->ch_temp->priv, pss->wsi, in lws_ssh_parse_plaintext()
1577 (const char *)pss->last_alloc, in lws_ssh_parse_plaintext()
1578 lws_ssh_exec_finish, pss->ch_temp)) { in lws_ssh_parse_plaintext()
1579 ssh_free_set_NULL(pss->last_alloc); in lws_ssh_parse_plaintext()
1580 if (pss->rq_want_reply) in lws_ssh_parse_plaintext()
1581 write_task_insert(pss, pss->ch_temp, in lws_ssh_parse_plaintext()
1584 pss->parser_state = SSHS_MSG_EAT_PADDING; in lws_ssh_parse_plaintext()
1595 if (pss->last_alloc[0] != 's' || in lws_ssh_parse_plaintext()
1596 pss->last_alloc[1] != 'c' || in lws_ssh_parse_plaintext()
1597 pss->last_alloc[2] != 'p' || in lws_ssh_parse_plaintext()
1598 pss->last_alloc[3] != ' ') in lws_ssh_parse_plaintext()
1602 ssh_free_set_NULL(pss->last_alloc); in lws_ssh_parse_plaintext()
1610 return -1; in lws_ssh_parse_plaintext()
1612 pss->ch_temp->type = SSH_CH_TYPE_SCP; in lws_ssh_parse_plaintext()
1613 pss->ch_temp->sub = (lws_subprotocol *)scp; in lws_ssh_parse_plaintext()
1615 scp->ips = SSHS_SCP_COLLECTSTR; in lws_ssh_parse_plaintext()
1617 if (pss->rq_want_reply) in lws_ssh_parse_plaintext()
1618 write_task(pss, pss->ch_temp, SSH_WT_CHRQ_SUCC); in lws_ssh_parse_plaintext()
1621 write_task(pss, pss->ch_temp, SSH_WT_SCP_ACK_OKAY); in lws_ssh_parse_plaintext()
1623 pss->parser_state = SSHS_MSG_EAT_PADDING; in lws_ssh_parse_plaintext()
1627 lwsl_notice("subsystem: %s", pss->last_alloc); in lws_ssh_parse_plaintext()
1630 if (!strcmp(pss->name, "sftp")) { in lws_ssh_parse_plaintext()
1632 pss->ch_temp->type = SSH_CH_TYPE_SFTP; in lws_ssh_parse_plaintext()
1636 ssh_free_set_NULL(pss->last_alloc); in lws_ssh_parse_plaintext()
1640 if (pss->rq_want_reply) in lws_ssh_parse_plaintext()
1642 pss->ch_recip), SSH_WT_CHRQ_SUCC); in lws_ssh_parse_plaintext()
1643 pss->parser_state = SSHS_MSG_EAT_PADDING; in lws_ssh_parse_plaintext()
1647 /* CHRQ window-change */ in lws_ssh_parse_plaintext()
1650 pss->args.pty.width_ch = pss->len; in lws_ssh_parse_plaintext()
1654 pss->args.pty.height_ch = pss->len; in lws_ssh_parse_plaintext()
1658 pss->args.pty.width_px = pss->len; in lws_ssh_parse_plaintext()
1662 pss->args.pty.height_px = pss->len; in lws_ssh_parse_plaintext()
1663 pss->args.pty.term[0] = 0; in lws_ssh_parse_plaintext()
1664 pss->args.pty.modes = NULL; in lws_ssh_parse_plaintext()
1665 pss->args.pty.modes_len = 0; in lws_ssh_parse_plaintext()
1667 if (pss->vhd->ops && pss->vhd->ops->pty_req) in lws_ssh_parse_plaintext()
1668 n = pss->vhd->ops->pty_req(pss->ch_temp->priv, in lws_ssh_parse_plaintext()
1669 &pss->args.pty); in lws_ssh_parse_plaintext()
1672 pss->parser_state = SSHS_MSG_EAT_PADDING; in lws_ssh_parse_plaintext()
1678 pss->ch_recip = pss->len; in lws_ssh_parse_plaintext()
1680 ch = ssh_get_server_ch(pss, pss->ch_recip); in lws_ssh_parse_plaintext()
1681 ch->peer_window_est -= (int32_t)pss->msg_len; in lws_ssh_parse_plaintext()
1683 if (pss->msg_len < sizeof(pss->name)) in lws_ssh_parse_plaintext()
1695 if (pss->parser_state == SSHS_NVC_CD_DATA_ALLOC) in lws_ssh_parse_plaintext()
1696 pp = pss->last_alloc; in lws_ssh_parse_plaintext()
1698 pp = (uint8_t *)pss->name; in lws_ssh_parse_plaintext()
1701 ch = ssh_get_server_ch(pss, pss->ch_recip); in lws_ssh_parse_plaintext()
1702 switch (ch->type) { in lws_ssh_parse_plaintext()
1704 scp = &ch->sub->scp; in lws_ssh_parse_plaintext()
1705 switch (scp->ips) { in lws_ssh_parse_plaintext()
1707 /* gather the ascii-coded headers */ in lws_ssh_parse_plaintext()
1708 for (n = 0; n < (int)pss->npos; n++) in lws_ssh_parse_plaintext()
1713 if (pp[0] == 'C' && pp[pss->npos - 1] == '\x0a') { in lws_ssh_parse_plaintext()
1719 pss->parser_state = SSHS_MSG_EAT_PADDING; in lws_ssh_parse_plaintext()
1722 scp->len = (uint64_t)atoll((const char *)pp); in lws_ssh_parse_plaintext()
1724 (unsigned long long)scp->len); in lws_ssh_parse_plaintext()
1725 scp->ips = SSHS_SCP_PAYLOADIN; in lws_ssh_parse_plaintext()
1728 write_task(pss, pss->ch_temp, in lws_ssh_parse_plaintext()
1733 if (pss->vhd->ops) in lws_ssh_parse_plaintext()
1734 pss->vhd->ops->rx(ch->priv, in lws_ssh_parse_plaintext()
1735 pss->wsi, pp, pss->npos); in lws_ssh_parse_plaintext()
1736 if (scp->len >= pss->npos) in lws_ssh_parse_plaintext()
1737 scp->len -= pss->npos; in lws_ssh_parse_plaintext()
1739 scp->len = 0; in lws_ssh_parse_plaintext()
1740 if (!scp->len) { in lws_ssh_parse_plaintext()
1742 scp->ips = SSHS_SCP_COLLECTSTR; in lws_ssh_parse_plaintext()
1749 if (pss->vhd->ops) in lws_ssh_parse_plaintext()
1750 pss->vhd->ops->rx(ch->priv, pss->wsi, in lws_ssh_parse_plaintext()
1751 pp, pss->npos); in lws_ssh_parse_plaintext()
1754 if (pss->parser_state == SSHS_NVC_CD_DATA_ALLOC) in lws_ssh_parse_plaintext()
1755 ssh_free_set_NULL(pss->last_alloc); in lws_ssh_parse_plaintext()
1757 if (ch->peer_window_est < 32768) { in lws_ssh_parse_plaintext()
1759 ch->peer_window_est += 32768; in lws_ssh_parse_plaintext()
1761 ch->peer_window_est); in lws_ssh_parse_plaintext()
1764 pss->parser_state = SSHS_MSG_EAT_PADDING; in lws_ssh_parse_plaintext()
1768 pss->ch_recip = pss->len; in lws_ssh_parse_plaintext()
1773 ch = ssh_get_server_ch(pss, pss->ch_recip); in lws_ssh_parse_plaintext()
1775 ch->window += (int32_t)pss->len; in lws_ssh_parse_plaintext()
1777 pss->len, ch->window); in lws_ssh_parse_plaintext()
1779 pss->parser_state = SSHS_MSG_EAT_PADDING; in lws_ssh_parse_plaintext()
1797 lwsl_notice("SSH_MSG_CHANNEL_EOF: %d\n", pss->ch_recip); in lws_ssh_parse_plaintext()
1798 ch = ssh_get_server_ch(pss, pss->ch_recip); in lws_ssh_parse_plaintext()
1800 lwsl_notice("unknown ch %d\n", pss->ch_recip); in lws_ssh_parse_plaintext()
1801 return -1; in lws_ssh_parse_plaintext()
1804 if (!ch->scheduled_close) { in lws_ssh_parse_plaintext()
1806 ch->scheduled_close = 1; in lws_ssh_parse_plaintext()
1809 pss->parser_state = SSHS_MSG_EAT_PADDING; in lws_ssh_parse_plaintext()
1828 pss->ch_recip); in lws_ssh_parse_plaintext()
1829 ch = ssh_get_server_ch(pss, pss->ch_recip); in lws_ssh_parse_plaintext()
1833 pss->parser_state = SSHS_MSG_EAT_PADDING; in lws_ssh_parse_plaintext()
1835 if (ch->sent_close) { in lws_ssh_parse_plaintext()
1845 ch->received_close = 1; in lws_ssh_parse_plaintext()
1846 ch->scheduled_close = 1; in lws_ssh_parse_plaintext()
1855 write_task(pss, pss->ch_temp, SSH_WT_CHRQ_FAILURE); in lws_ssh_parse_plaintext()
1856 pss->parser_state = SSH_KEX_STATE_SKIP; in lws_ssh_parse_plaintext()
1860 if (pss->ch_temp) { in lws_ssh_parse_plaintext()
1861 free(pss->ch_temp); in lws_ssh_parse_plaintext()
1862 pss->ch_temp = NULL; in lws_ssh_parse_plaintext()
1864 write_task(pss, pss->ch_temp, SSH_WT_CH_FAILURE); in lws_ssh_parse_plaintext()
1865 pss->parser_state = SSH_KEX_STATE_SKIP; in lws_ssh_parse_plaintext()
1884 if (pss->count_auth_attempts++ > 20) in lws_ssh_parse_plaintext()
1887 pss->parser_state = SSH_KEX_STATE_SKIP; in lws_ssh_parse_plaintext()
1891 pss->pos++; in lws_ssh_parse_plaintext()
1905 while (len--) { in parse()
1907 if (pss->copy_to_I_C && pss->kex->I_C_payload_len < in parse()
1908 pss->kex->I_C_alloc_len && in parse()
1909 pss->parser_state != SSHS_MSG_EAT_PADDING) in parse()
1910 pss->kex->I_C[pss->kex->I_C_payload_len++] = *p; in parse()
1912 if (pss->active_keys_cts.valid && in parse()
1913 pss->parser_state == SSHS_MSG_LEN) in parse()
1915 pss->packet_assembly[pss->pa_pos++] = *p; in parse()
1917 if (pss->active_keys_cts.valid && in parse()
1918 pss->parser_state == SSHS_MSG_PADDING && in parse()
1919 pss->msg_len) { in parse()
1921 uint32_t cp, l = pss->msg_len + 4 + in parse()
1922 pss->active_keys_cts.MAC_length; in parse()
1928 if (cp > l - pss->pa_pos) in parse()
1929 cp = l - pss->pa_pos; in parse()
1931 if (cp > sizeof(pss->packet_assembly) - in parse()
1932 pss->pa_pos) { in parse()
1937 if (pss->msg_len < 2 + 4) { in parse()
1943 memcpy(&pss->packet_assembly[pss->pa_pos], p, cp); in parse()
1944 pss->pa_pos += cp; in parse()
1945 len -= cp; in parse()
1948 if (pss->pa_pos != l) in parse()
1952 cp = (uint32_t)lws_chacha_decrypt(&pss->active_keys_cts, in parse()
1953 pss->ssh_sequence_ctr_cts++, in parse()
1954 pss->packet_assembly, in parse()
1955 pss->pa_pos, pt); in parse()
1961 if (lws_ssh_parse_plaintext(pss, pt + 4, pss->msg_len)) in parse()
1964 pss->pa_pos = 0; in parse()
1965 pss->ctr = 0; in parse()
1991 lws_pad_set_length(pss, ps, &pp, &pss->active_keys_stc); in pad_and_encrypt()
1994 if (!pss->active_keys_stc.valid) { in pad_and_encrypt()
1999 lws_chacha_encrypt(&pss->active_keys_stc, pss->ssh_sequence_ctr_stc, in pad_and_encrypt()
2001 n += pss->active_keys_stc.MAC_length; in pad_and_encrypt()
2029 if (pss && pss->vhd) in lws_callback_raw_sshd()
2032 pss->vhd->protocol); in lws_callback_raw_sshd()
2038 lws_get_vhost(wsi), "lws-ssh-base")); in lws_callback_raw_sshd()
2047 vhd->context = lws_get_context(wsi); in lws_callback_raw_sshd()
2048 vhd->protocol = lws_get_protocol(wsi); in lws_callback_raw_sshd()
2049 vhd->vhost = lws_get_vhost(wsi); in lws_callback_raw_sshd()
2055 * using a pvo (per-vhost option) in lws_callback_raw_sshd()
2057 if (!strcmp(pvo->name, "ops")) in lws_callback_raw_sshd()
2058 vhd->ops = (const struct lws_ssh_ops *)pvo->value; in lws_callback_raw_sshd()
2064 if (!strcmp(pvo->name, "ops-from")) { in lws_callback_raw_sshd()
2065 prot = lws_vhost_name_to_protocol(vhd->vhost, in lws_callback_raw_sshd()
2066 pvo->value); in lws_callback_raw_sshd()
2068 vhd->ops = (const struct lws_ssh_ops *)prot->user; in lws_callback_raw_sshd()
2071 __func__, pvo->value); in lws_callback_raw_sshd()
2074 pvo = pvo->next; in lws_callback_raw_sshd()
2077 if (!vhd->ops) { in lws_callback_raw_sshd()
2084 if (vhd->ops->api_version != LWS_SSH_OPS_VERSION) { in lws_callback_raw_sshd()
2086 vhd->ops->api_version, LWS_SSH_OPS_VERSION); in lws_callback_raw_sshd()
2094 return -1; in lws_callback_raw_sshd()
2095 pss->next = vhd->live_pss_list; in lws_callback_raw_sshd()
2096 vhd->live_pss_list = pss; in lws_callback_raw_sshd()
2097 pss->parser_state = SSH_INITIALIZE_TRANSIENT; in lws_callback_raw_sshd()
2098 pss->wsi = wsi; in lws_callback_raw_sshd()
2099 pss->vhd = vhd; in lws_callback_raw_sshd()
2100 pss->kex_state = KEX_STATE_EXPECTING_CLIENT_OFFER; in lws_callback_raw_sshd()
2101 pss->active_keys_cts.padding_alignment = 8; in lws_callback_raw_sshd()
2102 pss->active_keys_stc.padding_alignment = 8; in lws_callback_raw_sshd()
2104 return -1; in lws_callback_raw_sshd()
2121 return -1; in lws_callback_raw_sshd()
2126 ssh_free_set_NULL(pss->last_alloc); in lws_callback_raw_sshd()
2128 while (pss->ch_list) in lws_callback_raw_sshd()
2129 ssh_destroy_channel(pss, pss->ch_list); in lws_callback_raw_sshd()
2131 lws_chacha_destroy(&pss->active_keys_cts); in lws_callback_raw_sshd()
2132 lws_chacha_destroy(&pss->active_keys_stc); in lws_callback_raw_sshd()
2134 p = &vhd->live_pss_list; in lws_callback_raw_sshd()
2138 *p = pss->next; in lws_callback_raw_sshd()
2141 p = &((*p)->next); in lws_callback_raw_sshd()
2147 return -1; in lws_callback_raw_sshd()
2149 return -1; in lws_callback_raw_sshd()
2156 o = pss->write_task[pss->wt_tail]; in lws_callback_raw_sshd()
2157 ch = pss->write_channel[pss->wt_tail]; in lws_callback_raw_sshd()
2159 if (pss->wt_head == pss->wt_tail) in lws_callback_raw_sshd()
2164 if (!pss->vhd) in lws_callback_raw_sshd()
2167 sizeof(buf) - LWS_PRE - 1, "%s\r\n", in lws_callback_raw_sshd()
2168 pss->vhd->ops->server_string); in lws_callback_raw_sshd()
2173 if (!pss->vhd) in lws_callback_raw_sshd()
2177 sizeof(buf) - LWS_PRE, 0, &m); in lws_callback_raw_sshd()
2181 return -1; in lws_callback_raw_sshd()
2184 if (!pss->kex) { in lws_callback_raw_sshd()
2185 lwsl_notice("%s: SSH_WT_OFFER: pss->kex is NULL\n", in lws_callback_raw_sshd()
2187 return -1; in lws_callback_raw_sshd()
2191 if (pss->kex->I_S) in lws_callback_raw_sshd()
2192 free(pss->kex->I_S); in lws_callback_raw_sshd()
2193 pss->kex->I_S = sshd_zalloc((unsigned int)m); in lws_callback_raw_sshd()
2194 if (!pss->kex->I_S) { in lws_callback_raw_sshd()
2197 return -1; in lws_callback_raw_sshd()
2200 memcpy(pss->kex->I_S, buf + LWS_PRE + 5, (unsigned int)m); in lws_callback_raw_sshd()
2201 pss->kex->I_S_payload_len = (uint32_t)m; /* without padding */ in lws_callback_raw_sshd()
2205 memcpy(ps, pss->kex->kex_r, pss->kex->kex_r_len); in lws_callback_raw_sshd()
2207 ps + pss->kex->kex_r_len, pss, 1); in lws_callback_raw_sshd()
2208 pss->kex_state = KEX_STATE_REPLIED_TO_OFFER; in lws_callback_raw_sshd()
2221 * the client to use it), it MUST respond with the in lws_callback_raw_sshd()
2229 lws_p32(pp, pss->npos); in lws_callback_raw_sshd()
2231 strcpy((char *)pp, pss->name); in lws_callback_raw_sshd()
2232 pp += pss->npos; in lws_callback_raw_sshd()
2248 if (pss->vhd && pss->vhd->ops->banner) in lws_callback_raw_sshd()
2249 n = (int)pss->vhd->ops->banner((char *)&buf[650], in lws_callback_raw_sshd()
2250 150 - 1, in lws_callback_raw_sshd()
2270 n = 74 + (int)pss->ua->pubkey_len; in lws_callback_raw_sshd()
2271 if (n > (int)sizeof(buf) - LWS_PRE) { in lws_callback_raw_sshd()
2281 if (lws_cstr(&pp, pss->ua->alg, 64)) { in lws_callback_raw_sshd()
2285 lws_p32(pp, pss->ua->pubkey_len); in lws_callback_raw_sshd()
2287 memcpy(pp, pss->ua->pubkey, pss->ua->pubkey_len); in lws_callback_raw_sshd()
2288 pp += pss->ua->pubkey_len; in lws_callback_raw_sshd()
2305 lws_p32(pp, pss->ch_temp->sender_ch); in lws_callback_raw_sshd()
2307 lws_p32(pp, pss->ch_temp->server_ch); in lws_callback_raw_sshd()
2316 /* it's on the linked-list */ in lws_callback_raw_sshd()
2317 pss->ch_temp = NULL; in lws_callback_raw_sshd()
2323 lws_p32(pp, ch->sender_ch); in lws_callback_raw_sshd()
2325 lws_p32(pp, ch->server_ch); in lws_callback_raw_sshd()
2335 lws_p32(pp, ch->sender_ch); in lws_callback_raw_sshd()
2343 lws_p32(pp, ch->sender_ch); in lws_callback_raw_sshd()
2351 lws_p32(pp, ch->sender_ch); in lws_callback_raw_sshd()
2359 lws_p32(pp, ch->sender_ch); in lws_callback_raw_sshd()
2369 lws_p32(pp, ch->sender_ch); in lws_callback_raw_sshd()
2384 lws_p32(pp, ch->sender_ch); in lws_callback_raw_sshd()
2394 lws_p32(pp, ch->sender_ch); in lws_callback_raw_sshd()
2398 strcpy((char *)pp, "exit-status"); in lws_callback_raw_sshd()
2401 lws_p32(pp, (uint32_t)ch->retcode); in lws_callback_raw_sshd()
2415 if (!pss->vhd || !pss->vhd->ops) in lws_callback_raw_sshd()
2417 n = pss->vhd->ops->tx_waiting(ch->priv); in lws_callback_raw_sshd()
2419 return -1; in lws_callback_raw_sshd()
2425 /* pick one using round-robin */ in lws_callback_raw_sshd()
2426 if (pss->serviced_stderr_last) in lws_callback_raw_sshd()
2432 pss->serviced_stderr_last = !!(n & LWS_STDERR); in lws_callback_raw_sshd()
2441 lws_p32(pp, pss->ch_list->sender_ch); in lws_callback_raw_sshd()
2453 pp += pss->vhd->ops->tx(ch->priv, n, pp, in lws_callback_raw_sshd()
2455 &buf[sizeof(buf) - 1], pp)); in lws_callback_raw_sshd()
2457 lws_p32(ps + m - 4, (uint32_t)lws_ptr_diff(pp, (ps + m))); in lws_callback_raw_sshd()
2459 if (pss->vhd->ops->tx_waiting(ch->priv) > 0) in lws_callback_raw_sshd()
2462 ch->window -= lws_ptr_diff(pp, ps) - m; in lws_callback_raw_sshd()
2463 //lwsl_debug("our send window: %d\n", ch->window); in lws_callback_raw_sshd()
2467 if (!pss->vhd) in lws_callback_raw_sshd()
2487 pss->active_keys_stc = pss->kex->keys_next_stc; in lws_callback_raw_sshd()
2488 lws_chacha_activate(&pss->active_keys_stc); in lws_callback_raw_sshd()
2489 pss->kex_state = KEX_STATE_CRYPTO_INITIALIZED; in lws_callback_raw_sshd()
2490 pss->kex->newkeys |= 1; in lws_callback_raw_sshd()
2491 if (pss->kex->newkeys == 3) in lws_callback_raw_sshd()
2498 if (ch->received_close) { in lws_callback_raw_sshd()
2508 ch->sent_close = 1; in lws_callback_raw_sshd()
2517 pss->ssh_sequence_ctr_stc++; in lws_callback_raw_sshd()
2520 pss->wt_tail = in lws_callback_raw_sshd()
2521 (pss->wt_tail + 1) & 7; in lws_callback_raw_sshd()
2528 if (pss->wt_head != pss->wt_tail || in lws_callback_raw_sshd()
2529 (ch && ch->priv && pss->vhd && in lws_callback_raw_sshd()
2530 pss->vhd->ops->tx_waiting(ch->priv))) in lws_callback_raw_sshd()
2552 if (pss->vhd && pss->vhd->ops && in lws_callback_raw_sshd()
2553 pss->vhd->ops->child_process_io && in lws_callback_raw_sshd()
2554 pss->vhd->ops->child_process_io(pss->ch_temp->priv, in lws_callback_raw_sshd()
2555 pss->wsi, (struct lws_cgi_args *)in)) in lws_callback_raw_sshd()
2556 return -1; in lws_callback_raw_sshd()
2562 ch = ssh_get_server_ch(pss, pss->channel_doing_spawn); in lws_callback_raw_sshd()
2564 ch->spawn_pid = (uint32_t)len; /* child process PID */ in lws_callback_raw_sshd()
2566 pss->channel_doing_spawn); in lws_callback_raw_sshd()
2573 if (pss->vhd && pss->vhd->ops && in lws_callback_raw_sshd()
2574 pss->vhd->ops->child_process_terminated) in lws_callback_raw_sshd()
2575 pss->vhd->ops->child_process_terminated(pss->ch_temp->priv, in lws_callback_raw_sshd()
2576 pss->wsi); in lws_callback_raw_sshd()
2581 ch = pss->ch_list; in lws_callback_raw_sshd()
2584 if (ch->spawn_pid == len) { in lws_callback_raw_sshd()
2587 ch->scheduled_close = 1; in lws_callback_raw_sshd()
2591 ch = ch->next; in lws_callback_raw_sshd()
2603 "lws-ssh-base", \