comparison svr-chansession.c @ 1804:f0cd000f3bca

Prevent multiple shells being spawned Existing shells would be leaked. The old check only caught multiple commands, not shells.
author Matt Johnston <matt@ucc.asn.au>
date Sat, 06 Mar 2021 23:06:43 +0800
parents 837cc354b388
children 5120e22882de eaa2d7240a5d
comparison
equal deleted inserted replaced
1803:837cc354b388 1804:f0cd000f3bca
656 int iscmd, int issubsys) { 656 int iscmd, int issubsys) {
657 657
658 unsigned int cmdlen = 0; 658 unsigned int cmdlen = 0;
659 int ret; 659 int ret;
660 660
661 TRACE(("enter sessioncommand")) 661 TRACE(("enter sessioncommand %d", channel->index))
662 662
663 if (chansess->cmd != NULL) { 663 if (chansess->pid != 0) {
664 /* Note that only one command can _succeed_. The client might try 664 /* Note that only one command can _succeed_. The client might try
665 * one command (which fails), then try another. Ie fallback 665 * one command (which fails), then try another. Ie fallback
666 * from sftp to scp */ 666 * from sftp to scp */
667 TRACE(("leave sessioncommand, already have a command"))
667 return DROPBEAR_FAILURE; 668 return DROPBEAR_FAILURE;
668 } 669 }
669 670
670 if (iscmd) { 671 if (iscmd) {
671 /* "exec" */ 672 /* "exec" */
673 chansess->cmd = buf_getstring(ses.payload, &cmdlen); 674 chansess->cmd = buf_getstring(ses.payload, &cmdlen);
674 675
675 if (cmdlen > MAX_CMD_LEN) { 676 if (cmdlen > MAX_CMD_LEN) {
676 m_free(chansess->cmd); 677 m_free(chansess->cmd);
677 /* TODO - send error - too long ? */ 678 /* TODO - send error - too long ? */
679 TRACE(("leave sessioncommand, command too long %d", cmdlen))
678 return DROPBEAR_FAILURE; 680 return DROPBEAR_FAILURE;
679 } 681 }
680 } 682 }
681 if (issubsys) { 683 if (issubsys) {
682 #if DROPBEAR_SFTPSERVER 684 #if DROPBEAR_SFTPSERVER
685 chansess->cmd = m_strdup(SFTPSERVER_PATH); 687 chansess->cmd = m_strdup(SFTPSERVER_PATH);
686 } else 688 } else
687 #endif 689 #endif
688 { 690 {
689 m_free(chansess->cmd); 691 m_free(chansess->cmd);
692 TRACE(("leave sessioncommand, unknown subsystem"))
690 return DROPBEAR_FAILURE; 693 return DROPBEAR_FAILURE;
691 } 694 }
692 } 695 }
693 } 696 }
694 697
741 #endif 744 #endif
742 745
743 if (ret == DROPBEAR_FAILURE) { 746 if (ret == DROPBEAR_FAILURE) {
744 m_free(chansess->cmd); 747 m_free(chansess->cmd);
745 } 748 }
749 TRACE(("leave sessioncommand, ret %d", ret))
746 return ret; 750 return ret;
747 } 751 }
748 752
749 /* Execute a command and set up redirection of stdin/stdout/stderr without a 753 /* Execute a command and set up redirection of stdin/stdout/stderr without a
750 * pty. 754 * pty.
914 svr_ses.childpids = (struct ChildPid*)m_realloc(svr_ses.childpids, 918 svr_ses.childpids = (struct ChildPid*)m_realloc(svr_ses.childpids,
915 sizeof(struct ChildPid) * (svr_ses.childpidsize+1)); 919 sizeof(struct ChildPid) * (svr_ses.childpidsize+1));
916 svr_ses.childpidsize++; 920 svr_ses.childpidsize++;
917 } 921 }
918 922
923 TRACE(("addchildpid %d pid %d for chansess %p", i, pid, chansess))
919 svr_ses.childpids[i].pid = pid; 924 svr_ses.childpids[i].pid = pid;
920 svr_ses.childpids[i].chansess = chansess; 925 svr_ses.childpids[i].chansess = chansess;
921 926
922 } 927 }
923 928