Mercurial > dropbear
comparison svr-chansession.c @ 70:b0316ce64e4b
Merging in the changes from 0.41-0.43 main Dropbear tree
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Thu, 12 Aug 2004 16:41:58 +0000 |
parents | 20563735e8b5 |
children | 6539c9480b23 |
comparison
equal
deleted
inserted
replaced
69:59d16db56e9f | 70:b0316ce64e4b |
---|---|
271 | 271 |
272 /* Handle requests for a channel. These can be execution requests, | 272 /* Handle requests for a channel. These can be execution requests, |
273 * or x11/authagent forwarding. These are passed to appropriate handlers */ | 273 * or x11/authagent forwarding. These are passed to appropriate handlers */ |
274 static void chansessionrequest(struct Channel *channel) { | 274 static void chansessionrequest(struct Channel *channel) { |
275 | 275 |
276 unsigned char * type; | 276 unsigned char * type = NULL; |
277 unsigned int typelen; | 277 unsigned int typelen; |
278 unsigned char wantreply; | 278 unsigned char wantreply; |
279 int ret = 1; | 279 int ret = 1; |
280 struct ChanSess *chansess; | 280 struct ChanSess *chansess; |
281 | 281 |
318 } | 318 } |
319 | 319 |
320 out: | 320 out: |
321 | 321 |
322 if (wantreply) { | 322 if (wantreply) { |
323 if (ret == 0) { | 323 if (ret == DROPBEAR_SUCCESS) { |
324 send_msg_channel_success(channel); | 324 send_msg_channel_success(channel); |
325 } else { | 325 } else { |
326 send_msg_channel_failure(channel); | 326 send_msg_channel_failure(channel); |
327 } | 327 } |
328 } | 328 } |
334 | 334 |
335 /* Send a signal to a session's process as requested by the client*/ | 335 /* Send a signal to a session's process as requested by the client*/ |
336 static int sessionsignal(struct ChanSess *chansess) { | 336 static int sessionsignal(struct ChanSess *chansess) { |
337 | 337 |
338 int sig = 0; | 338 int sig = 0; |
339 unsigned char* signame; | 339 unsigned char* signame = NULL; |
340 int i; | 340 int i; |
341 | 341 |
342 if (chansess->pid == 0) { | 342 if (chansess->pid == 0) { |
343 /* haven't got a process pid yet */ | 343 /* haven't got a process pid yet */ |
344 return DROPBEAR_FAILURE; | 344 return DROPBEAR_FAILURE; |
526 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ | 526 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ |
527 static int sessioncommand(struct Channel *channel, struct ChanSess *chansess, | 527 static int sessioncommand(struct Channel *channel, struct ChanSess *chansess, |
528 int iscmd, int issubsys) { | 528 int iscmd, int issubsys) { |
529 | 529 |
530 unsigned int cmdlen; | 530 unsigned int cmdlen; |
531 int ret; | |
531 | 532 |
532 TRACE(("enter sessioncommand")); | 533 TRACE(("enter sessioncommand")); |
533 | 534 |
534 if (chansess->cmd != NULL) { | 535 if (chansess->cmd != NULL) { |
535 /* TODO - send error - multiple commands? */ | 536 /* Note that only one command can _succeed_. The client might try |
537 * one command (which fails), then try another. Ie fallback | |
538 * from sftp to scp */ | |
536 return DROPBEAR_FAILURE; | 539 return DROPBEAR_FAILURE; |
537 } | 540 } |
538 | 541 |
539 if (iscmd) { | 542 if (iscmd) { |
540 /* "exec" */ | 543 /* "exec" */ |
541 chansess->cmd = buf_getstring(ses.payload, &cmdlen); | 544 chansess->cmd = buf_getstring(ses.payload, &cmdlen); |
542 | 545 |
543 if (cmdlen > MAX_CMD_LEN) { | 546 if (cmdlen > MAX_CMD_LEN) { |
547 m_free(chansess->cmd); | |
544 /* TODO - send error - too long ? */ | 548 /* TODO - send error - too long ? */ |
545 return DROPBEAR_FAILURE; | 549 return DROPBEAR_FAILURE; |
546 } | 550 } |
547 if (issubsys) { | 551 if (issubsys) { |
548 #ifdef SFTPSERVER_PATH | 552 #ifdef SFTPSERVER_PATH |
550 m_free(chansess->cmd); | 554 m_free(chansess->cmd); |
551 chansess->cmd = m_strdup(SFTPSERVER_PATH); | 555 chansess->cmd = m_strdup(SFTPSERVER_PATH); |
552 } else | 556 } else |
553 #endif | 557 #endif |
554 { | 558 { |
559 m_free(chansess->cmd); | |
555 return DROPBEAR_FAILURE; | 560 return DROPBEAR_FAILURE; |
556 } | 561 } |
557 } | 562 } |
558 } | 563 } |
559 | 564 |
560 if (chansess->term == NULL) { | 565 if (chansess->term == NULL) { |
561 /* no pty */ | 566 /* no pty */ |
562 return noptycommand(channel, chansess); | 567 ret = noptycommand(channel, chansess); |
563 } else { | 568 } else { |
564 /* want pty */ | 569 /* want pty */ |
565 return ptycommand(channel, chansess); | 570 ret = ptycommand(channel, chansess); |
566 } | 571 } |
572 | |
573 if (ret == DROPBEAR_FAILURE) { | |
574 m_free(chansess->cmd); | |
575 } | |
576 return ret; | |
567 } | 577 } |
568 | 578 |
569 /* Execute a command and set up redirection of stdin/stdout/stderr without a | 579 /* Execute a command and set up redirection of stdin/stdout/stderr without a |
570 * pty. | 580 * pty. |
571 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ | 581 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ |
648 * redirection as appropriate. | 658 * redirection as appropriate. |
649 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ | 659 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ |
650 static int ptycommand(struct Channel *channel, struct ChanSess *chansess) { | 660 static int ptycommand(struct Channel *channel, struct ChanSess *chansess) { |
651 | 661 |
652 pid_t pid; | 662 pid_t pid; |
653 struct logininfo *li; | 663 struct logininfo *li = NULL; |
654 #ifdef DO_MOTD | 664 #ifdef DO_MOTD |
655 buffer * motdbuf = NULL; | 665 buffer * motdbuf = NULL; |
656 int len; | 666 int len; |
657 struct stat sb; | 667 struct stat sb; |
658 char *hushpath = NULL; | 668 char *hushpath = NULL; |
776 /* Clean up, drop to user privileges, set up the environment and execute | 786 /* Clean up, drop to user privileges, set up the environment and execute |
777 * the command/shell. This function does not return. */ | 787 * the command/shell. This function does not return. */ |
778 static void execchild(struct ChanSess *chansess) { | 788 static void execchild(struct ChanSess *chansess) { |
779 | 789 |
780 char *argv[4]; | 790 char *argv[4]; |
781 char * usershell; | 791 char * usershell = NULL; |
782 char * baseshell; | 792 char * baseshell = NULL; |
783 unsigned int i; | 793 unsigned int i; |
784 | 794 |
785 /* wipe the hostkey */ | 795 /* wipe the hostkey */ |
786 sign_key_free(svr_opts.hostkey); | 796 sign_key_free(svr_opts.hostkey); |
787 svr_opts.hostkey = NULL; | 797 svr_opts.hostkey = NULL; |
861 #ifndef DISABLE_AGENTFWD | 871 #ifndef DISABLE_AGENTFWD |
862 /* set up agent env variable */ | 872 /* set up agent env variable */ |
863 agentset(chansess); | 873 agentset(chansess); |
864 #endif | 874 #endif |
865 | 875 |
876 /* Re-enable SIGPIPE for the executed process */ | |
877 if (signal(SIGPIPE, SIG_DFL) == SIG_ERR) { | |
878 dropbear_exit("signal() error"); | |
879 } | |
880 | |
866 baseshell = basename(usershell); | 881 baseshell = basename(usershell); |
867 | 882 |
868 if (chansess->cmd != NULL) { | 883 if (chansess->cmd != NULL) { |
869 argv[0] = baseshell; | 884 argv[0] = baseshell; |
870 } else { | 885 } else { |
919 } | 934 } |
920 | 935 |
921 /* add a new environment variable, allocating space for the entry */ | 936 /* add a new environment variable, allocating space for the entry */ |
922 void addnewvar(const char* param, const char* var) { | 937 void addnewvar(const char* param, const char* var) { |
923 | 938 |
924 char* newvar; | 939 char* newvar = NULL; |
925 int plen, vlen; | 940 int plen, vlen; |
926 | 941 |
927 plen = strlen(param); | 942 plen = strlen(param); |
928 vlen = strlen(var); | 943 vlen = strlen(var); |
929 | 944 |