Lines Matching refs:pss

93 write_task(struct per_session_data__sshd *pss, struct lws_ssh_channel *ch,
96 pss->write_task[pss->wt_head] = (uint8_t)task;
97 pss->write_channel[pss->wt_head] = ch;
98 pss->wt_head = (pss->wt_head + 1) & 7;
99 lws_callback_on_writable(pss->wsi);
103 write_task_insert(struct per_session_data__sshd *pss, struct lws_ssh_channel *ch,
106 pss->wt_tail = (pss->wt_tail - 1) & 7;
107 pss->write_task[pss->wt_tail] = (uint8_t)task;
108 pss->write_channel[pss->wt_tail] = ch;
109 lws_callback_on_writable(pss->wsi);
114 lws_pad_set_length(struct per_session_data__sshd *pss, void *start, uint8_t **p,
134 lws_get_random(pss->vhd->context, *p, padc);
144 offer(struct per_session_data__sshd *pss, uint8_t *p, uint32_t len, int first,
152 keylen = (int)get_gen_server_key_25519(pss, keybuf, (int)sizeof(keybuf));
185 lws_get_random(pss->vhd->context, p, 16);
299 handle_name(struct per_session_data__sshd *pss)
301 struct lws_kex *kex = pss->kex;
306 switch (pss->parser_state) {
308 if (!strcmp(pss->name, "curve25519-sha256@libssh.org"))
312 len = (int)get_gen_server_key_25519(pss, keybuf, (int)sizeof(keybuf));
320 if (!strcmp(pss->name, keyt)) {
327 if (!strcmp(pss->name, "chacha20-poly1305@openssh.com"))
331 if (!strcmp(pss->name, "chacha20-poly1305@openssh.com"))
335 if (!strcmp(pss->name, "hmac-sha2-256"))
339 if (!strcmp(pss->name, "hmac-sha2-256"))
343 if (!strcmp(pss->name, "none"))
347 if (!strcmp(pss->name, "none"))
362 lws_kex_create(struct per_session_data__sshd *pss)
364 pss->kex = sshd_zalloc(sizeof(struct lws_kex));
366 return !pss->kex;
370 lws_kex_destroy(struct per_session_data__sshd *pss)
372 if (!pss->kex)
377 if (pss->kex->I_C) {
378 free(pss->kex->I_C);
379 pss->kex->I_C = NULL;
381 if (pss->kex->I_S) {
382 free(pss->kex->I_S);
383 pss->kex->I_S = NULL;
386 lws_explicit_bzero(pss->kex, sizeof(*pss->kex));
387 free(pss->kex);
388 pss->kex = NULL;
404 lws_ua_destroy(struct per_session_data__sshd *pss)
406 if (!pss->ua)
411 if (pss->ua->username)
412 ssh_free(pss->ua->username);
413 if (pss->ua->service)
414 ssh_free(pss->ua->service);
415 if (pss->ua->alg)
416 ssh_free(pss->ua->alg);
417 if (pss->ua->pubkey)
418 ssh_free(pss->ua->pubkey);
419 if (pss->ua->sig) {
420 lws_explicit_bzero(pss->ua->sig, pss->ua->sig_len);
421 ssh_free(pss->ua->sig);
424 lws_explicit_bzero(pss->ua, sizeof(*pss->ua));
425 free(pss->ua);
426 pss->ua = NULL;
445 state_get_string_alloc(struct per_session_data__sshd *pss, int next)
447 pss->parser_state = SSHS_GET_STRING_LEN_ALLOC;
448 pss->state_after_string = (char)next;
452 state_get_string(struct per_session_data__sshd *pss, int next)
454 pss->parser_state = SSHS_GET_STRING_LEN;
455 pss->state_after_string = (char)next;
459 state_get_u32(struct per_session_data__sshd *pss, int next)
461 pss->parser_state = SSHS_GET_U32;
462 pss->state_after_string = (char)next;
466 ssh_get_server_ch(struct per_session_data__sshd *pss, uint32_t chi)
468 struct lws_ssh_channel *ch = pss->ch_list;
481 ssh_get_peer_ch(struct per_session_data__sshd *pss, uint32_t chi)
483 struct lws_ssh_channel *ch = pss->ch_list;
496 ssh_destroy_channel(struct per_session_data__sshd *pss,
499 lws_start_foreach_llp(struct lws_ssh_channel **, ppch, pss->ch_list) {
502 if (pss->vhd && pss->vhd->ops &&
503 pss->vhd->ops->channel_destroy)
504 pss->vhd->ops->channel_destroy(ch->priv);
521 struct per_session_data__sshd *pss = ch->pss;
524 write_task(pss, ch, SSH_WT_EXIT_STATUS);
526 write_task(pss, ch, SSH_WT_CH_CLOSE);
530 lws_ssh_parse_plaintext(struct per_session_data__sshd *pss, uint8_t *p, size_t len)
545 switch(pss->parser_state) {
547 pss->parser_state = SSHS_IDSTRING;
548 pss->ctr = 0;
549 pss->copy_to_I_C = 0;
554 pss->V_C[pss->npos] = '\0';
555 pss->npos = 0;
556 lwsl_info("peer id: %s\n", pss->V_C);
558 pss->parser_state = SSHS_IDSTRING_CR;
561 if (pss->npos < sizeof(pss->V_C) - 1)
562 pss->V_C[pss->npos++] = (char)*p;
571 pss->ssh_sequence_ctr_cts = 0;
572 pss->parser_state = SSHS_MSG_LEN;
576 pss->msg_len = (pss->msg_len << 8) | *p++;
577 if (++pss->ctr != 4)
580 if (pss->active_keys_cts.valid) {
583 POKE_U32(b, (uint32_t)pss->msg_len);
584 pss->msg_len = lws_chachapoly_get_length(
585 &pss->active_keys_cts,
586 pss->ssh_sequence_ctr_cts, b);
588 pss->ssh_sequence_ctr_cts++;
590 lwsl_info("msg len %d\n", pss->msg_len);
592 pss->parser_state = SSHS_MSG_PADDING;
593 pss->ctr = 0;
594 pss->pos = 4;
595 if (pss->msg_len < 2 + 4) {
602 pss->msg_padding = *p++;
603 pss->parser_state = SSHS_MSG_ID;
607 pss->msg_id = *p++;
608 pss->ctr = 0;
609 switch (pss->msg_id) {
619 state_get_u32(pss, SSHS_NVC_DISCONNECT_REASON);
633 state_get_string(pss, SSHS_DO_SERVICE_REQUEST);
640 if (pss->kex_state !=
642 pss->parser_state = SSH_KEX_STATE_SKIP;
645 if (!pss->kex) {
646 lwsl_notice("%s: SSH_MSG_KEXINIT: NULL pss->kex\n", __func__);
649 pss->parser_state = SSH_KEX_STATE_COOKIE;
650 pss->kex->I_C_payload_len = 0;
651 pss->kex->I_C_alloc_len = pss->msg_len;
652 pss->kex->I_C = sshd_zalloc(pss->kex->I_C_alloc_len);
653 if (!pss->kex->I_C) {
657 pss->kex->I_C[pss->kex->I_C_payload_len++] =
658 pss->msg_id;
659 pss->copy_to_I_C = 1;
662 pss->parser_state = SSH_KEX_STATE_ECDH_KEYLEN;
666 if (pss->kex_state !=
668 pss->kex_state !=
679 pss->active_keys_cts = pss->kex->keys_next_cts;
680 if (lws_chacha_activate(&pss->active_keys_cts))
683 pss->kex->newkeys |= 2;
684 if (pss->kex->newkeys == 3)
685 lws_kex_destroy(pss);
687 if (pss->msg_padding) {
688 pss->copy_to_I_C = 0;
689 pss->parser_state =
693 pss->parser_state = SSHS_MSG_LEN;
709 if (pss->ua) {
710 lwsl_notice("pss->ua overwrite\n");
715 pss->ua = sshd_zalloc(sizeof(*pss->ua));
716 if (!pss->ua)
719 state_get_string_alloc(pss, SSHS_DO_UAR_SVC);
721 if (!pss->sent_banner) {
722 if (pss->vhd->ops->banner)
723 write_task(pss, NULL,
725 pss->sent_banner = 1;
736 state_get_string(pss, SSHS_NVC_CHOPEN_TYPE);
755 state_get_u32(pss, SSHS_NVC_CHRQ_RECIP);
767 state_get_u32(pss, SSHS_NVC_CH_EOF);
784 state_get_u32(pss, SSHS_NVC_CH_CLOSE);
794 state_get_u32(pss, SSHS_NVC_CD_RECIP);
804 if (!pss->ch_list)
807 state_get_u32(pss, SSHS_NVC_WA_RECIP);
810 lwsl_notice("unk msg_id %d\n", pss->msg_id);
817 if (pss->msg_len < 16 + 1 + 1 + (10 * 4) + 5) {
821 pss->kex->kex_cookie[pss->ctr++] = *p++;
822 if (pss->ctr != sizeof(pss->kex->kex_cookie))
824 pss->parser_state = SSH_KEX_NL_KEX_ALGS_LEN;
825 pss->ctr = 0;
839 pss->len = (pss->len << 8) | *p++;
840 if (++pss->ctr != 4)
843 switch (pss->parser_state) {
845 pss->parser_state = SSH_KEX_STATE_ECDH_Q_C;
848 pss->parser_state++;
849 if (pss->len == 0)
850 pss->parser_state++;
853 pss->ctr = 0;
854 pss->npos = 0;
855 if (pss->msg_len - pss->pos < pss->len) {
857 pss->msg_len, pss->pos, pss->len);
873 if (pss->npos < sizeof(pss->name) - 1)
874 pss->name[pss->npos++] = (char)*p;
876 pss->name[pss->npos] = '\0';
877 pss->npos = 0;
878 handle_name(pss);
881 if (!--pss->len) {
882 pss->name[pss->npos] = '\0';
883 if (pss->npos)
884 handle_name(pss);
885 pss->parser_state++;
891 pss->first_coming = !!*p++;
892 pss->parser_state = SSH_KEX_RESERVED;
896 pss->len = (pss->len << 8) | *p++;
897 if (++pss->ctr != 4)
899 pss->ctr = 0;
900 if (pss->msg_padding) {
901 pss->copy_to_I_C = 0;
902 pss->parser_state = SSHS_MSG_EAT_PADDING;
905 pss->parser_state = SSHS_MSG_LEN;
909 if (pss->len != 32) {
913 pss->kex->Q_C[pss->ctr++] = *p++;
914 if (pss->ctr != 32)
917 pss->parser_state = SSHS_MSG_EAT_PADDING;
921 if (pss->pos - 4 < pss->msg_len) {
926 pss->pos, pss->msg_len, (long)len);
927 pss->parser_state = SSHS_MSG_LEN;
928 pss->ctr = 0;
933 if (--pss->msg_padding)
935 if (pss->msg_len + 4 != pss->pos) {
937 pss->pos, pss->msg_len);
941 switch (pss->msg_id) {
943 if (pss->kex->match_bitfield != 0xff) {
947 if (kex_ecdh(pss, pss->kex->kex_r,
948 &pss->kex->kex_r_len)) {
952 write_task(pss, NULL, SSH_WT_OFFER_REPLY);
956 pss->parser_state = SSHS_MSG_LEN;
957 pss->ctr = 0;
961 pss->npos = 0;
962 pss->len = (pss->len << 8) | *p++;
963 if (++pss->ctr != 4)
965 pss->ctr = 0;
966 pss->parser_state = SSHS_GET_STRING;
970 if (pss->npos >= sizeof(pss->name) - 1) {
974 pss->name[pss->npos++] = (char)*p++;
975 if (pss->npos != pss->len)
978 pss->name[pss->npos] = '\0';
979 pss->parser_state = pss->state_after_string;
983 pss->npos = 0;
984 pss->len = (pss->len << 8) | *p++;
985 if (++pss->ctr != 4)
987 pss->ctr = 0;
988 pss->last_alloc = sshd_zalloc(pss->len + 1);
990 pss->last_alloc, pss->state_after_string);
991 if (!pss->last_alloc) {
995 pss->parser_state = SSHS_GET_STRING_ALLOC;
999 if (pss->npos >= pss->len)
1001 pss->last_alloc[pss->npos++] = *p++;
1002 if (pss->npos != pss->len)
1004 pss->last_alloc[pss->npos] = '\0';
1005 pss->parser_state = pss->state_after_string;
1013 pss->okayed_userauth = 1;
1014 pss->parser_state = SSHS_MSG_EAT_PADDING;
1019 write_task(pss, NULL, SSH_WT_UA_ACCEPT);
1023 pss->ua->username = (char *)pss->last_alloc;
1024 pss->last_alloc = NULL; /* it was adopted */
1025 state_get_string_alloc(pss, SSHS_DO_UAR_PUBLICKEY);
1030 pss->ua->service = (char *)pss->last_alloc;
1031 pss->last_alloc = NULL; /* it was adopted */
1046 if (pss->seen_auth_req_before && (
1047 strcmp(pss->ua->username,
1048 pss->last_auth_req_username) ||
1049 strcmp(pss->ua->service,
1050 pss->last_auth_req_service))) {
1056 pss->seen_auth_req_before = 1;
1057 lws_strncpy(pss->last_auth_req_username,
1058 pss->ua->username,
1059 sizeof(pss->last_auth_req_username));
1060 lws_strncpy(pss->last_auth_req_service,
1061 pss->ua->service,
1062 sizeof(pss->last_auth_req_service));
1064 if (strcmp(pss->ua->service, "ssh-connection"))
1066 state_get_string(pss, SSHS_NVC_DO_UAR_CHECK_PUBLICKEY);
1070 if (!strcmp(pss->name, "none")) {
1076 if (strcmp(pss->name, "publickey")) {
1078 pss->name);
1081 pss->parser_state = SSHS_DO_UAR_SIG_PRESENT;
1086 pss->ua->sig_present = (char)*p++;
1087 state_get_string_alloc(pss, SSHS_NVC_DO_UAR_ALG);
1092 pss->ua->alg = (char *)pss->last_alloc;
1093 pss->last_alloc = NULL; /* it was adopted */
1094 if (rsa_hash_alg_from_ident(pss->ua->alg) < 0) {
1098 state_get_string_alloc(pss, SSHS_NVC_DO_UAR_PUBKEY_BLOB);
1103 pss->ua->pubkey = pss->last_alloc;
1104 pss->last_alloc = NULL; /* it was adopted */
1105 pss->ua->pubkey_len = pss->npos;
1120 if (pss->vhd->ops && pss->vhd->ops->is_pubkey_authorized)
1121 n = pss->vhd->ops->is_pubkey_authorized(
1122 pss->ua->username, pss->ua->alg,
1123 pss->ua->pubkey, (int)pss->ua->pubkey_len);
1129 if (pss->ua->sig_present) {
1130 state_get_string_alloc(pss, SSHS_NVC_DO_UAR_SIG);
1141 write_task(pss, NULL, SSH_WT_UA_PK_OK);
1142 pss->parser_state = SSHS_MSG_EAT_PADDING;
1156 if (pss->ssh_auth_state == SSH_AUTH_STATE_GAVE_AUTH_IGNORE_REQS) {
1161 pss->ua->sig = pss->last_alloc;
1162 pss->last_alloc = NULL; /* it was adopted */
1163 pss->ua->sig_len = pss->npos;
1164 pss->parser_state = SSHS_MSG_EAT_PADDING;
1192 4 + (int)strlen(pss->ua->username) +
1193 4 + (int)strlen(pss->ua->service) +
1196 4 + (int)strlen(pss->ua->alg) +
1197 4 + (int)pss->ua->pubkey_len;
1206 lws_buf(&pp, pss->session_id, 32);
1208 lws_cstr(&pp, pss->ua->username, 64);
1209 lws_cstr(&pp, pss->ua->service, 64);
1212 lws_cstr(&pp, pss->ua->alg, 64);
1213 lws_buf(&pp, pss->ua->pubkey, pss->ua->pubkey_len);
1217 if (lws_genhash_init(&pss->ua->hash_ctx,
1218 (enum lws_genhash_types)rsa_hash_alg_from_ident(pss->ua->alg))) {
1224 if (lws_genhash_update(&pss->ua->hash_ctx, ps, lws_ptr_diff_size_t(pp, ps))) {
1229 lws_genhash_destroy(&pss->ua->hash_ctx, hash);
1238 pp = pss->ua->pubkey;
1249 if (lws_genrsa_create(&ctx, e, pss->vhd->context,
1257 pp = pss->ua->sig;
1280 pss->ua->hash_ctx.type)) {
1282 (unsigned int)lws_genhash_size(pss->ua->hash_ctx.type));
1299 (enum lws_genhash_types)rsa_hash_alg_from_ident(pss->ua->alg),
1323 pss->ssh_auth_state = SSH_AUTH_STATE_GAVE_AUTH_IGNORE_REQS;
1325 write_task(pss, NULL, SSH_WT_UA_SUCCESS);
1326 lws_ua_destroy(pss);
1334 pss->len = (pss->len << 8) | *p++;
1335 if (++pss->ctr != 4)
1337 pss->ctr = 0;
1338 pss->parser_state = pss->state_after_string;
1346 pss->disconnect_reason = pss->len;
1347 state_get_string_alloc(pss, SSHS_NVC_DISCONNECT_DESC);
1351 pss->disconnect_desc = (char *)pss->last_alloc;
1352 pss->last_alloc = NULL; /* it was adopted */
1353 state_get_string(pss, SSHS_NVC_DISCONNECT_LANG);
1358 if (pss->vhd->ops && pss->vhd->ops->disconnect_reason)
1359 pss->vhd->ops->disconnect_reason(
1360 pss->disconnect_reason,
1361 pss->disconnect_desc, pss->name);
1362 ssh_free_set_NULL(pss->last_alloc);
1371 if (strcmp(pss->name, "session")) {
1373 pss->reason = 3;
1377 pss->ch_temp = sshd_zalloc(sizeof(*pss->ch_temp));
1378 if (!pss->ch_temp)
1381 pss->ch_temp->type = SSH_CH_TYPE_SESSION;
1382 pss->ch_temp->pss = pss;
1383 state_get_u32(pss, SSHS_NVC_CHOPEN_SENDER_CH);
1387 pss->ch_temp->sender_ch = pss->len;
1388 state_get_u32(pss, SSHS_NVC_CHOPEN_WINSIZE);
1391 lwsl_info("Initial window set to %d\n", pss->len);
1392 pss->ch_temp->window = (int32_t)pss->len;
1393 state_get_u32(pss, SSHS_NVC_CHOPEN_PKTSIZE);
1396 pss->ch_temp->max_pkt = pss->len;
1397 pss->ch_temp->peer_window_est = LWS_SSH_INITIAL_WINDOW;
1398 pss->ch_temp->server_ch = (uint32_t)pss->next_ch_num++;
1404 pss->ch_temp->next = pss->ch_list;
1405 pss->ch_list = pss->ch_temp;
1406 if (pss->vhd->ops && pss->vhd->ops->channel_create)
1407 pss->vhd->ops->channel_create(pss->wsi,
1408 &pss->ch_temp->priv);
1409 write_task(pss, pss->ch_temp, SSH_WT_CH_OPEN_CONF);
1410 pss->parser_state = SSHS_MSG_EAT_PADDING;
1418 pss->ch_recip = pss->len;
1419 state_get_string(pss, SSHS_NVC_CHRQ_TYPE);
1423 pss->parser_state = SSHS_CHRQ_WANT_REPLY;
1427 pss->rq_want_reply = *p++;
1429 pss->name, pss->rq_want_reply);
1431 pss->ch_temp = ssh_get_server_ch(pss, pss->ch_recip);
1438 if (!strcmp(pss->name, "pty-req")) {
1439 state_get_string(pss, SSHS_NVC_CHRQ_TERM);
1445 if (!strcmp(pss->name, "shell")) {
1446 pss->channel_doing_spawn = pss->ch_temp->server_ch;
1447 if (pss->vhd->ops && pss->vhd->ops->shell &&
1448 !pss->vhd->ops->shell(pss->ch_temp->priv,
1449 pss->wsi,
1450 lws_ssh_exec_finish, pss->ch_temp)) {
1452 if (pss->rq_want_reply)
1453 write_task_insert(pss, pss->ch_temp,
1455 pss->parser_state = SSHS_MSG_EAT_PADDING;
1464 if (!strcmp(pss->name, "env")) {
1465 state_get_string(pss, SSHS_NVC_CHRQ_ENV_NAME);
1472 if (!strcmp(pss->name, "exec")) {
1473 state_get_string_alloc(pss, SSHS_NVC_CHRQ_EXEC_CMD);
1480 if (!strcmp(pss->name, "subsystem")) {
1482 state_get_string_alloc(pss,
1486 if (!strcmp(pss->name, "window-change")) {
1488 state_get_u32(pss,
1493 if (pss->rq_want_reply)
1496 pss->parser_state = SSH_KEX_STATE_SKIP;
1502 memcpy(pss->args.pty.term, pss->name,
1503 sizeof(pss->args.pty.term) - 1);
1504 state_get_u32(pss, SSHS_NVC_CHRQ_TW);
1507 pss->args.pty.width_ch = pss->len;
1508 state_get_u32(pss, SSHS_NVC_CHRQ_TH);
1511 pss->args.pty.height_ch = pss->len;
1512 state_get_u32(pss, SSHS_NVC_CHRQ_TWP);
1515 pss->args.pty.width_px = pss->len;
1516 state_get_u32(pss, SSHS_NVC_CHRQ_THP);
1519 pss->args.pty.height_px = pss->len;
1520 state_get_string_alloc(pss, SSHS_NVC_CHRQ_MODES);
1524 pss->args.pty.modes = (char *)pss->last_alloc;
1525 pss->last_alloc = NULL; /* it was adopted */
1526 pss->args.pty.modes_len = pss->npos;
1528 if (pss->vhd->ops && pss->vhd->ops->pty_req)
1529 n = pss->vhd->ops->pty_req(pss->ch_temp->priv,
1530 &pss->args.pty);
1531 ssh_free_set_NULL(pss->args.pty.modes);
1534 if (pss->rq_want_reply)
1535 write_task(pss, pss->ch_temp, SSH_WT_CHRQ_SUCC);
1536 pss->parser_state = SSHS_MSG_EAT_PADDING;
1542 strcpy(pss->args.aux, pss->name);
1543 state_get_string(pss, SSHS_NVC_CHRQ_ENV_VALUE);
1547 if (pss->vhd->ops && pss->vhd->ops->set_env)
1548 if (pss->vhd->ops->set_env(pss->ch_temp->priv,
1549 pss->args.aux, pss->name))
1551 pss->parser_state = SSHS_MSG_EAT_PADDING;
1571 lwsl_info("exec cmd: %s %02X\n", pss->last_alloc, *p);
1573 pss->channel_doing_spawn = pss->ch_temp->server_ch;
1575 if (pss->vhd->ops && pss->vhd->ops->exec &&
1576 !pss->vhd->ops->exec(pss->ch_temp->priv, pss->wsi,
1577 (const char *)pss->last_alloc,
1578 lws_ssh_exec_finish, pss->ch_temp)) {
1579 ssh_free_set_NULL(pss->last_alloc);
1580 if (pss->rq_want_reply)
1581 write_task_insert(pss, pss->ch_temp,
1584 pss->parser_state = SSHS_MSG_EAT_PADDING;
1595 if (pss->last_alloc[0] != 's' ||
1596 pss->last_alloc[1] != 'c' ||
1597 pss->last_alloc[2] != 'p' ||
1598 pss->last_alloc[3] != ' ')
1602 ssh_free_set_NULL(pss->last_alloc);
1612 pss->ch_temp->type = SSH_CH_TYPE_SCP;
1613 pss->ch_temp->sub = (lws_subprotocol *)scp;
1617 if (pss->rq_want_reply)
1618 write_task(pss, pss->ch_temp, SSH_WT_CHRQ_SUCC);
1621 write_task(pss, pss->ch_temp, SSH_WT_SCP_ACK_OKAY);
1623 pss->parser_state = SSHS_MSG_EAT_PADDING;
1627 lwsl_notice("subsystem: %s", pss->last_alloc);
1630 if (!strcmp(pss->name, "sftp")) {
1632 pss->ch_temp->type = SSH_CH_TYPE_SFTP;
1636 ssh_free_set_NULL(pss->last_alloc);
1640 if (pss->rq_want_reply)
1641 write_task(pss, ssh_get_server_ch(pss,
1642 pss->ch_recip), SSH_WT_CHRQ_SUCC);
1643 pss->parser_state = SSHS_MSG_EAT_PADDING;
1650 pss->args.pty.width_ch = pss->len;
1651 state_get_u32(pss, SSHS_NVC_CHRQ_WNDCHANGE_TH);
1654 pss->args.pty.height_ch = pss->len;
1655 state_get_u32(pss, SSHS_NVC_CHRQ_WNDCHANGE_TWP);
1658 pss->args.pty.width_px = pss->len;
1659 state_get_u32(pss, SSHS_NVC_CHRQ_WNDCHANGE_THP);
1662 pss->args.pty.height_px = pss->len;
1663 pss->args.pty.term[0] = 0;
1664 pss->args.pty.modes = NULL;
1665 pss->args.pty.modes_len = 0;
1667 if (pss->vhd->ops && pss->vhd->ops->pty_req)
1668 n = pss->vhd->ops->pty_req(pss->ch_temp->priv,
1669 &pss->args.pty);
1672 pss->parser_state = SSHS_MSG_EAT_PADDING;
1678 pss->ch_recip = pss->len;
1680 ch = ssh_get_server_ch(pss, pss->ch_recip);
1681 ch->peer_window_est -= (int32_t)pss->msg_len;
1683 if (pss->msg_len < sizeof(pss->name))
1684 state_get_string(pss, SSHS_NVC_CD_DATA);
1686 state_get_string_alloc(pss,
1695 if (pss->parser_state == SSHS_NVC_CD_DATA_ALLOC)
1696 pp = pss->last_alloc;
1698 pp = (uint8_t *)pss->name;
1701 ch = ssh_get_server_ch(pss, pss->ch_recip);
1708 for (n = 0; n < (int)pss->npos; n++)
1713 if (pp[0] == 'C' && pp[pss->npos - 1] == '\x0a') {
1717 write_task(pss, ch,
1719 pss->parser_state = SSHS_MSG_EAT_PADDING;
1728 write_task(pss, pss->ch_temp,
1733 if (pss->vhd->ops)
1734 pss->vhd->ops->rx(ch->priv,
1735 pss->wsi, pp, pss->npos);
1736 if (scp->len >= pss->npos)
1737 scp->len -= pss->npos;
1749 if (pss->vhd->ops)
1750 pss->vhd->ops->rx(ch->priv, pss->wsi,
1751 pp, pss->npos);
1754 if (pss->parser_state == SSHS_NVC_CD_DATA_ALLOC)
1755 ssh_free_set_NULL(pss->last_alloc);
1758 write_task(pss, ch, SSH_WT_WINDOW_ADJUST);
1764 pss->parser_state = SSHS_MSG_EAT_PADDING;
1768 pss->ch_recip = pss->len;
1769 state_get_u32(pss, SSHS_NVC_WA_ADD);
1773 ch = ssh_get_server_ch(pss, pss->ch_recip);
1775 ch->window += (int32_t)pss->len;
1777 pss->len, ch->window);
1779 pss->parser_state = SSHS_MSG_EAT_PADDING;
1797 lwsl_notice("SSH_MSG_CHANNEL_EOF: %d\n", pss->ch_recip);
1798 ch = ssh_get_server_ch(pss, pss->ch_recip);
1800 lwsl_notice("unknown ch %d\n", pss->ch_recip);
1807 write_task(pss, ch, SSH_WT_CH_CLOSE);
1809 pss->parser_state = SSHS_MSG_EAT_PADDING;
1828 pss->ch_recip);
1829 ch = ssh_get_server_ch(pss, pss->ch_recip);
1833 pss->parser_state = SSHS_MSG_EAT_PADDING;
1841 ssh_destroy_channel(pss, ch);
1847 write_task(pss, ch, SSH_WT_CH_CLOSE);
1855 write_task(pss, pss->ch_temp, SSH_WT_CHRQ_FAILURE);
1856 pss->parser_state = SSH_KEX_STATE_SKIP;
1860 if (pss->ch_temp) {
1861 free(pss->ch_temp);
1862 pss->ch_temp = NULL;
1864 write_task(pss, pss->ch_temp, SSH_WT_CH_FAILURE);
1865 pss->parser_state = SSH_KEX_STATE_SKIP;
1873 write_task(pss, NULL, SSH_WT_UA_FAILURE);
1875 lws_ua_destroy(pss);
1884 if (pss->count_auth_attempts++ > 20)
1887 pss->parser_state = SSH_KEX_STATE_SKIP;
1891 pss->pos++;
1896 lws_kex_destroy(pss);
1897 lws_ua_destroy(pss);
1903 parse(struct per_session_data__sshd *pss, uint8_t *p, size_t len)
1907 if (pss->copy_to_I_C && pss->kex->I_C_payload_len <
1908 pss->kex->I_C_alloc_len &&
1909 pss->parser_state != SSHS_MSG_EAT_PADDING)
1910 pss->kex->I_C[pss->kex->I_C_payload_len++] = *p;
1912 if (pss->active_keys_cts.valid &&
1913 pss->parser_state == SSHS_MSG_LEN)
1915 pss->packet_assembly[pss->pa_pos++] = *p;
1917 if (pss->active_keys_cts.valid &&
1918 pss->parser_state == SSHS_MSG_PADDING &&
1919 pss->msg_len) {
1921 uint32_t cp, l = pss->msg_len + 4 +
1922 pss->active_keys_cts.MAC_length;
1928 if (cp > l - pss->pa_pos)
1929 cp = l - pss->pa_pos;
1931 if (cp > sizeof(pss->packet_assembly) -
1932 pss->pa_pos) {
1937 if (pss->msg_len < 2 + 4) {
1943 memcpy(&pss->packet_assembly[pss->pa_pos], p, cp);
1944 pss->pa_pos += cp;
1948 if (pss->pa_pos != l)
1952 cp = (uint32_t)lws_chacha_decrypt(&pss->active_keys_cts,
1953 pss->ssh_sequence_ctr_cts++,
1954 pss->packet_assembly,
1955 pss->pa_pos, pt);
1961 if (lws_ssh_parse_plaintext(pss, pt + 4, pss->msg_len))
1964 pss->pa_pos = 0;
1965 pss->ctr = 0;
1969 if (lws_ssh_parse_plaintext(pss, p, 1))
1978 lws_kex_destroy(pss);
1979 lws_ua_destroy(pss);
1986 struct per_session_data__sshd *pss, int skip_pad)
1991 lws_pad_set_length(pss, ps, &pp, &pss->active_keys_stc);
1994 if (!pss->active_keys_stc.valid) {
1999 lws_chacha_encrypt(&pss->active_keys_stc, pss->ssh_sequence_ctr_stc,
2001 n += pss->active_keys_stc.MAC_length;
2010 struct per_session_data__sshd *pss =
2026 * protocol from the wsi. If there's a pss already, we can get it from
2029 if (pss && pss->vhd)
2032 pss->vhd->protocol);
2093 if (!vhd || !pss)
2095 pss->next = vhd->live_pss_list;
2096 vhd->live_pss_list = pss;
2097 pss->parser_state = SSH_INITIALIZE_TRANSIENT;
2098 pss->wsi = wsi;
2099 pss->vhd = vhd;
2100 pss->kex_state = KEX_STATE_EXPECTING_CLIENT_OFFER;
2101 pss->active_keys_cts.padding_alignment = 8;
2102 pss->active_keys_stc.padding_alignment = 8;
2103 if (lws_kex_create(pss))
2105 write_task(pss, NULL, SSH_WT_VERSION);
2120 if (!pss)
2123 lws_kex_destroy(pss);
2124 lws_ua_destroy(pss);
2126 ssh_free_set_NULL(pss->last_alloc);
2128 while (pss->ch_list)
2129 ssh_destroy_channel(pss, pss->ch_list);
2131 lws_chacha_destroy(&pss->active_keys_cts);
2132 lws_chacha_destroy(&pss->active_keys_stc);
2137 if ((*p) == pss) {
2138 *p = pss->next;
2146 if (!pss)
2148 if (parse(pss, in, len))
2153 if (!pss)
2156 o = pss->write_task[pss->wt_tail];
2157 ch = pss->write_channel[pss->wt_tail];
2159 if (pss->wt_head == pss->wt_tail)
2164 if (!pss->vhd)
2168 pss->vhd->ops->server_string);
2169 write_task(pss, NULL, SSH_WT_OFFER);
2173 if (!pss->vhd)
2176 n = (int)offer(pss, buf + LWS_PRE,
2184 if (!pss->kex) {
2185 lwsl_notice("%s: SSH_WT_OFFER: pss->kex is NULL\n",
2191 if (pss->kex->I_S)
2192 free(pss->kex->I_S);
2193 pss->kex->I_S = sshd_zalloc((unsigned int)m);
2194 if (!pss->kex->I_S) {
2200 memcpy(pss->kex->I_S, buf + LWS_PRE + 5, (unsigned int)m);
2201 pss->kex->I_S_payload_len = (uint32_t)m; /* without padding */
2205 memcpy(ps, pss->kex->kex_r, pss->kex->kex_r_len);
2207 ps + pss->kex->kex_r_len, pss, 1);
2208 pss->kex_state = KEX_STATE_REPLIED_TO_OFFER;
2210 write_task(pss, NULL, SSH_WT_SEND_NEWKEYS);
2229 lws_p32(pp, pss->npos);
2231 strcpy((char *)pp, pss->name);
2232 pp += pss->npos;
2248 if (pss->vhd && pss->vhd->ops->banner)
2249 n = (int)pss->vhd->ops->banner((char *)&buf[650],
2270 n = 74 + (int)pss->ua->pubkey_len;
2281 if (lws_cstr(&pp, pss->ua->alg, 64)) {
2285 lws_p32(pp, pss->ua->pubkey_len);
2287 memcpy(pp, pss->ua->pubkey, pss->ua->pubkey_len);
2288 pp += pss->ua->pubkey_len;
2291 lws_ua_destroy(pss);
2305 lws_p32(pp, pss->ch_temp->sender_ch);
2307 lws_p32(pp, pss->ch_temp->server_ch);
2317 pss->ch_temp = NULL;
2410 ch = ssh_get_server_ch(pss, 0);
2415 if (!pss->vhd || !pss->vhd->ops)
2417 n = pss->vhd->ops->tx_waiting(ch->priv);
2426 if (pss->serviced_stderr_last)
2432 pss->serviced_stderr_last = !!(n & LWS_STDERR);
2441 lws_p32(pp, pss->ch_list->sender_ch);
2453 pp += pss->vhd->ops->tx(ch->priv, n, pp,
2459 if (pss->vhd->ops->tx_waiting(ch->priv) > 0)
2467 if (!pss->vhd)
2469 n = (int)pad_and_encrypt(&buf[LWS_PRE], ps, pp, pss, 0);
2473 lws_ua_destroy(pss);
2474 lws_kex_destroy(pss);
2487 pss->active_keys_stc = pss->kex->keys_next_stc;
2488 lws_chacha_activate(&pss->active_keys_stc);
2489 pss->kex_state = KEX_STATE_CRYPTO_INITIALIZED;
2490 pss->kex->newkeys |= 1;
2491 if (pss->kex->newkeys == 3)
2492 lws_kex_destroy(pss);
2505 ssh_destroy_channel(pss, ch);
2517 pss->ssh_sequence_ctr_stc++;
2520 pss->wt_tail =
2521 (pss->wt_tail + 1) & 7;
2526 ch = ssh_get_server_ch(pss, 0);
2528 if (pss->wt_head != pss->wt_tail ||
2529 (ch && ch->priv && pss->vhd &&
2530 pss->vhd->ops->tx_waiting(ch->priv)))
2550 if (!pss)
2552 if (pss->vhd && pss->vhd->ops &&
2553 pss->vhd->ops->child_process_io &&
2554 pss->vhd->ops->child_process_io(pss->ch_temp->priv,
2555 pss->wsi, (struct lws_cgi_args *)in))
2560 if (!pss)
2562 ch = ssh_get_server_ch(pss, pss->channel_doing_spawn);
2566 pss->channel_doing_spawn);
2571 if (!pss)
2573 if (pss->vhd && pss->vhd->ops &&
2574 pss->vhd->ops->child_process_terminated)
2575 pss->vhd->ops->child_process_terminated(pss->ch_temp->priv,
2576 pss->wsi);
2581 ch = pss->ch_list;
2588 write_task(pss, ch, SSH_WT_CH_CLOSE);