comparison svr-chansession.c @ 297:79bf1023cf11 agent-client

propagate from branch 'au.asn.ucc.matt.dropbear' (head 0501e6f661b5415eb76f3b312d183c3adfbfb712) to branch 'au.asn.ucc.matt.dropbear.cli-agent' (head 01038174ec27245b51bd43a66c01ad930880f67b)
author Matt Johnston <matt@ucc.asn.au>
date Tue, 21 Mar 2006 16:20:59 +0000
parents 1f5ec029dfe8
children 5d5bbca82aba 3eea61bd9993 dba106bf6b34 8eaa6e3ca6eb
comparison
equal deleted inserted replaced
225:ca7e76d981d9 297:79bf1023cf11
146 146
147 /* send the exitstatus to the client */ 147 /* send the exitstatus to the client */
148 static void send_msg_chansess_exitstatus(struct Channel * channel, 148 static void send_msg_chansess_exitstatus(struct Channel * channel,
149 struct ChanSess * chansess) { 149 struct ChanSess * chansess) {
150 150
151 assert(chansess->exit.exitpid != -1); 151 dropbear_assert(chansess->exit.exitpid != -1);
152 assert(chansess->exit.exitsignal == -1); 152 dropbear_assert(chansess->exit.exitsignal == -1);
153 153
154 CHECKCLEARTOWRITE(); 154 CHECKCLEARTOWRITE();
155 155
156 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_REQUEST); 156 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_REQUEST);
157 buf_putint(ses.writepayload, channel->remotechan); 157 buf_putint(ses.writepayload, channel->remotechan);
168 struct ChanSess * chansess) { 168 struct ChanSess * chansess) {
169 169
170 int i; 170 int i;
171 char* signame = NULL; 171 char* signame = NULL;
172 172
173 assert(chansess->exit.exitpid != -1); 173 dropbear_assert(chansess->exit.exitpid != -1);
174 assert(chansess->exit.exitsignal > 0); 174 dropbear_assert(chansess->exit.exitsignal > 0);
175 175
176 CHECKCLEARTOWRITE(); 176 CHECKCLEARTOWRITE();
177 177
178 /* we check that we can match a signal name, otherwise 178 /* we check that we can match a signal name, otherwise
179 * don't send anything */ 179 * don't send anything */
203 /* set up a session channel */ 203 /* set up a session channel */
204 static int newchansess(struct Channel *channel) { 204 static int newchansess(struct Channel *channel) {
205 205
206 struct ChanSess *chansess; 206 struct ChanSess *chansess;
207 207
208 assert(channel->typedata == NULL); 208 dropbear_assert(channel->typedata == NULL);
209 209
210 chansess = (struct ChanSess*)m_malloc(sizeof(struct ChanSess)); 210 chansess = (struct ChanSess*)m_malloc(sizeof(struct ChanSess));
211 chansess->cmd = NULL; 211 chansess->cmd = NULL;
212 chansess->pid = 0; 212 chansess->pid = 0;
213 213
277 #endif 277 #endif
278 278
279 /* clear child pid entries */ 279 /* clear child pid entries */
280 for (i = 0; i < svr_ses.childpidsize; i++) { 280 for (i = 0; i < svr_ses.childpidsize; i++) {
281 if (svr_ses.childpids[i].chansess == chansess) { 281 if (svr_ses.childpids[i].chansess == chansess) {
282 assert(svr_ses.childpids[i].pid > 0); 282 dropbear_assert(svr_ses.childpids[i].pid > 0);
283 TRACE(("closing pid %d", svr_ses.childpids[i].pid)) 283 TRACE(("closing pid %d", svr_ses.childpids[i].pid))
284 TRACE(("exitpid = %d", chansess->exit.exitpid)) 284 TRACE(("exitpid = %d", chansess->exit.exitpid))
285 svr_ses.childpids[i].pid = -1; 285 svr_ses.childpids[i].pid = -1;
286 svr_ses.childpids[i].chansess = NULL; 286 svr_ses.childpids[i].chansess = NULL;
287 } 287 }
311 TRACE(("leave chansessionrequest: type too long")) /* XXX send error?*/ 311 TRACE(("leave chansessionrequest: type too long")) /* XXX send error?*/
312 goto out; 312 goto out;
313 } 313 }
314 314
315 chansess = (struct ChanSess*)channel->typedata; 315 chansess = (struct ChanSess*)channel->typedata;
316 assert(chansess != NULL); 316 dropbear_assert(chansess != NULL);
317 TRACE(("type is %s", type)) 317 TRACE(("type is %s", type))
318 318
319 if (strcmp(type, "window-change") == 0) { 319 if (strcmp(type, "window-change") == 0) {
320 ret = sessionwinchange(chansess); 320 ret = sessionwinchange(chansess);
321 } else if (strcmp(type, "shell") == 0) { 321 } else if (strcmp(type, "shell") == 0) {
621 if (pipe(outfds) != 0) 621 if (pipe(outfds) != 0)
622 return DROPBEAR_FAILURE; 622 return DROPBEAR_FAILURE;
623 if (pipe(errfds) != 0) 623 if (pipe(errfds) != 0)
624 return DROPBEAR_FAILURE; 624 return DROPBEAR_FAILURE;
625 625
626 #ifdef __uClinux__
627 pid = vfork();
628 #else
626 pid = fork(); 629 pid = fork();
630 #endif
631
627 if (pid < 0) 632 if (pid < 0)
628 return DROPBEAR_FAILURE; 633 return DROPBEAR_FAILURE;
629 634
630 if (!pid) { 635 if (!pid) {
631 /* child */ 636 /* child */
671 676
672 677
673 close(infds[FDIN]); 678 close(infds[FDIN]);
674 close(outfds[FDOUT]); 679 close(outfds[FDOUT]);
675 close(errfds[FDOUT]); 680 close(errfds[FDOUT]);
676 channel->infd = infds[FDOUT]; 681 channel->writefd = infds[FDOUT];
677 channel->outfd = outfds[FDIN]; 682 channel->readfd = outfds[FDIN];
678 channel->errfd = errfds[FDIN]; 683 channel->errfd = errfds[FDIN];
679 ses.maxfd = MAX(ses.maxfd, channel->infd); 684 ses.maxfd = MAX(ses.maxfd, channel->writefd);
680 ses.maxfd = MAX(ses.maxfd, channel->outfd); 685 ses.maxfd = MAX(ses.maxfd, channel->readfd);
681 ses.maxfd = MAX(ses.maxfd, channel->errfd); 686 ses.maxfd = MAX(ses.maxfd, channel->errfd);
682 687
683 setnonblocking(channel->outfd); 688 setnonblocking(channel->readfd);
684 setnonblocking(channel->infd); 689 setnonblocking(channel->writefd);
685 setnonblocking(channel->errfd); 690 setnonblocking(channel->errfd);
686 691
687 } 692 }
688 #undef FDIN 693 #undef FDIN
689 #undef FDOUT 694 #undef FDOUT
712 if (chansess->master == -1 || chansess->tty == NULL) { 717 if (chansess->master == -1 || chansess->tty == NULL) {
713 dropbear_log(LOG_WARNING, "no pty was allocated, couldn't execute"); 718 dropbear_log(LOG_WARNING, "no pty was allocated, couldn't execute");
714 return DROPBEAR_FAILURE; 719 return DROPBEAR_FAILURE;
715 } 720 }
716 721
722 #ifdef __uClinux__
723 pid = vfork();
724 #else
717 pid = fork(); 725 pid = fork();
726 #endif
718 if (pid < 0) 727 if (pid < 0)
719 return DROPBEAR_FAILURE; 728 return DROPBEAR_FAILURE;
720 729
721 if (pid == 0) { 730 if (pid == 0) {
722 /* child */ 731 /* child */
782 791
783 /* add a child pid */ 792 /* add a child pid */
784 addchildpid(chansess, pid); 793 addchildpid(chansess, pid);
785 794
786 close(chansess->slave); 795 close(chansess->slave);
787 channel->infd = chansess->master; 796 channel->writefd = chansess->master;
788 channel->outfd = chansess->master; 797 channel->readfd = chansess->master;
789 /* don't need to set stderr here */ 798 /* don't need to set stderr here */
790 ses.maxfd = MAX(ses.maxfd, chansess->master); 799 ses.maxfd = MAX(ses.maxfd, chansess->master);
791 800
792 setnonblocking(chansess->master); 801 setnonblocking(chansess->master);
793 802
808 } 817 }
809 818
810 /* need to increase size */ 819 /* need to increase size */
811 if (i == svr_ses.childpidsize) { 820 if (i == svr_ses.childpidsize) {
812 svr_ses.childpids = (struct ChildPid*)m_realloc(svr_ses.childpids, 821 svr_ses.childpids = (struct ChildPid*)m_realloc(svr_ses.childpids,
813 sizeof(struct ChildPid) * svr_ses.childpidsize+1); 822 sizeof(struct ChildPid) * (svr_ses.childpidsize+1));
814 svr_ses.childpidsize++; 823 svr_ses.childpidsize++;
815 } 824 }
816 825
817 svr_ses.childpids[i].pid = pid; 826 svr_ses.childpids[i].pid = pid;
818 svr_ses.childpids[i].chansess = chansess; 827 svr_ses.childpids[i].chansess = chansess;
826 char *argv[4]; 835 char *argv[4];
827 char * usershell = NULL; 836 char * usershell = NULL;
828 char * baseshell = NULL; 837 char * baseshell = NULL;
829 unsigned int i; 838 unsigned int i;
830 839
840 /* with uClinux we'll have vfork()ed, so don't want to overwrite the
841 * hostkey. can't think of a workaround to clear it */
842 #ifndef __uClinux__
831 /* wipe the hostkey */ 843 /* wipe the hostkey */
832 sign_key_free(svr_opts.hostkey); 844 sign_key_free(svr_opts.hostkey);
833 svr_opts.hostkey = NULL; 845 svr_opts.hostkey = NULL;
834 846
835 /* overwrite the prng state */ 847 /* overwrite the prng state */
836 seedrandom(); 848 reseedrandom();
849 #endif
837 850
838 /* close file descriptors except stdin/stdout/stderr 851 /* close file descriptors except stdin/stdout/stderr
839 * Need to be sure FDs are closed here to avoid reading files as root */ 852 * Need to be sure FDs are closed here to avoid reading files as root */
840 for (i = 3; i <= (unsigned int)ses.maxfd; i++) { 853 for (i = 3; i <= (unsigned int)ses.maxfd; i++) {
841 if (m_close(i) == DROPBEAR_FAILURE) { 854 m_close(i);
842 dropbear_exit("Error closing file desc");
843 }
844 } 855 }
845 856
846 /* clear environment */ 857 /* clear environment */
847 /* if we're debugging using valgrind etc, we need to keep the LD_PRELOAD 858 /* if we're debugging using valgrind etc, we need to keep the LD_PRELOAD
848 * etc. This is hazardous, so should only be used for debugging. */ 859 * etc. This is hazardous, so should only be used for debugging. */