comparison svr-chansession.c @ 579:8c737cd7c1af

merge of '48fdaa8706d1acda35e9d564adc9a1fbc96c18c8' and '658fd03abd21e0da7c4c89b9fff9dc693c72daae'
author Matt Johnston <matt@ucc.asn.au>
date Sat, 27 Feb 2010 11:53:18 +0000
parents 8fd0ac8c8cab
children 6cb1bd7be8b3
comparison
equal deleted inserted replaced
577:69e98c45db7c 579:8c737cd7c1af
220 220
221 dropbear_assert(channel->typedata == NULL); 221 dropbear_assert(channel->typedata == NULL);
222 222
223 chansess = (struct ChanSess*)m_malloc(sizeof(struct ChanSess)); 223 chansess = (struct ChanSess*)m_malloc(sizeof(struct ChanSess));
224 chansess->cmd = NULL; 224 chansess->cmd = NULL;
225 chansess->connection_string = NULL;
225 chansess->pid = 0; 226 chansess->pid = 0;
226 227
227 /* pty details */ 228 /* pty details */
228 chansess->master = -1; 229 chansess->master = -1;
229 chansess->slave = -1; 230 chansess->slave = -1;
248 249
249 return 0; 250 return 0;
250 251
251 } 252 }
252 253
254 static struct logininfo*
255 chansess_login_alloc(struct ChanSess *chansess) {
256 struct logininfo * li;
257 li = login_alloc_entry(chansess->pid, ses.authstate.username,
258 svr_ses.remotehost, chansess->tty);
259 return li;
260 }
261
253 /* clean a session channel */ 262 /* clean a session channel */
254 static void closechansess(struct Channel *channel) { 263 static void closechansess(struct Channel *channel) {
255 264
256 struct ChanSess *chansess; 265 struct ChanSess *chansess;
257 unsigned int i; 266 unsigned int i;
271 m_free(chansess->cmd); 280 m_free(chansess->cmd);
272 m_free(chansess->term); 281 m_free(chansess->term);
273 282
274 if (chansess->tty) { 283 if (chansess->tty) {
275 /* write the utmp/wtmp login record */ 284 /* write the utmp/wtmp login record */
276 li = login_alloc_entry(chansess->pid, ses.authstate.username, 285 li = chansess_login_alloc(chansess);
277 ses.remotehost, chansess->tty);
278 login_logout(li); 286 login_logout(li);
279 login_free_entry(li); 287 login_free_entry(li);
280 288
281 pty_release(chansess->tty); 289 pty_release(chansess->tty);
282 m_free(chansess->tty); 290 m_free(chansess->tty);
285 #ifndef DISABLE_X11FWD 293 #ifndef DISABLE_X11FWD
286 x11cleanup(chansess); 294 x11cleanup(chansess);
287 #endif 295 #endif
288 296
289 #ifndef DISABLE_AGENTFWD 297 #ifndef DISABLE_AGENTFWD
290 agentcleanup(chansess); 298 svr_agentcleanup(chansess);
291 #endif 299 #endif
292 300
293 /* clear child pid entries */ 301 /* clear child pid entries */
294 for (i = 0; i < svr_ses.childpidsize; i++) { 302 for (i = 0; i < svr_ses.childpidsize; i++) {
295 if (svr_ses.childpids[i].chansess == chansess) { 303 if (svr_ses.childpids[i].chansess == chansess) {
344 } else if (strcmp(type, "x11-req") == 0) { 352 } else if (strcmp(type, "x11-req") == 0) {
345 ret = x11req(chansess); 353 ret = x11req(chansess);
346 #endif 354 #endif
347 #ifndef DISABLE_AGENTFWD 355 #ifndef DISABLE_AGENTFWD
348 } else if (strcmp(type, "[email protected]") == 0) { 356 } else if (strcmp(type, "[email protected]") == 0) {
349 ret = agentreq(chansess); 357 ret = svr_agentreq(chansess);
350 #endif 358 #endif
351 } else if (strcmp(type, "signal") == 0) { 359 } else if (strcmp(type, "signal") == 0) {
352 ret = sessionsignal(chansess); 360 ret = sessionsignal(chansess);
353 } else { 361 } else {
354 /* etc, todo "env", "subsystem" */ 362 /* etc, todo "env", "subsystem" */
568 576
569 TRACE(("leave sessionpty")) 577 TRACE(("leave sessionpty"))
570 return DROPBEAR_SUCCESS; 578 return DROPBEAR_SUCCESS;
571 } 579 }
572 580
581 static char* make_connection_string() {
582 char *local_ip, *local_port, *remote_ip, *remote_port;
583 size_t len;
584 char *ret;
585 get_socket_address(ses.sock_in, &local_ip, &local_port, &remote_ip, &remote_port, 0);
586 len = strlen(local_ip) + strlen(local_port) + strlen(remote_ip) + strlen(remote_port) + 4;
587 ret = m_malloc(len);
588 snprintf(ret, len, "%s %s %s %s", remote_ip, remote_port, local_ip, local_port);
589 m_free(local_ip);
590 m_free(local_port);
591 m_free(remote_ip);
592 m_free(remote_port);
593 return ret;
594 }
595
573 /* Handle a command request from the client. This is used for both shell 596 /* Handle a command request from the client. This is used for both shell
574 * and command-execution requests, and passes the command to 597 * and command-execution requests, and passes the command to
575 * noptycommand or ptycommand as appropriate. 598 * noptycommand or ptycommand as appropriate.
576 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ 599 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
577 static int sessioncommand(struct Channel *channel, struct ChanSess *chansess, 600 static int sessioncommand(struct Channel *channel, struct ChanSess *chansess,
587 * one command (which fails), then try another. Ie fallback 610 * one command (which fails), then try another. Ie fallback
588 * from sftp to scp */ 611 * from sftp to scp */
589 return DROPBEAR_FAILURE; 612 return DROPBEAR_FAILURE;
590 } 613 }
591 614
592 /* take public key option 'command' into account */
593 svr_pubkey_set_forced_command(chansess);
594
595 if (iscmd) { 615 if (iscmd) {
596 /* "exec" */ 616 /* "exec" */
597 if (chansess->cmd == NULL) { 617 if (chansess->cmd == NULL) {
598 chansess->cmd = buf_getstring(ses.payload, &cmdlen); 618 chansess->cmd = buf_getstring(ses.payload, &cmdlen);
599 619
614 m_free(chansess->cmd); 634 m_free(chansess->cmd);
615 return DROPBEAR_FAILURE; 635 return DROPBEAR_FAILURE;
616 } 636 }
617 } 637 }
618 } 638 }
639
640 /* take public key option 'command' into account */
641 svr_pubkey_set_forced_command(chansess);
619 642
620 #ifdef LOG_COMMANDS 643 #ifdef LOG_COMMANDS
621 if (chansess->cmd) { 644 if (chansess->cmd) {
622 dropbear_log(LOG_INFO, "user %s executing '%s'", 645 dropbear_log(LOG_INFO, "user %s executing '%s'",
623 ses.authstate.pw_name, chansess->cmd); 646 ses.authstate.pw_name, chansess->cmd);
625 dropbear_log(LOG_INFO, "user %s executing login shell", 648 dropbear_log(LOG_INFO, "user %s executing login shell",
626 ses.authstate.pw_name); 649 ses.authstate.pw_name);
627 } 650 }
628 #endif 651 #endif
629 652
653 /* uClinux will vfork(), so there'll be a race as
654 connection_string is freed below. */
655 #ifndef __uClinux__
656 chansess->connection_string = make_connection_string();
657 #endif
658
630 if (chansess->term == NULL) { 659 if (chansess->term == NULL) {
631 /* no pty */ 660 /* no pty */
632 ret = noptycommand(channel, chansess); 661 ret = noptycommand(channel, chansess);
633 } else { 662 } else {
634 /* want pty */ 663 /* want pty */
635 ret = ptycommand(channel, chansess); 664 ret = ptycommand(channel, chansess);
636 } 665 }
666
667 #ifndef __uClinux__
668 m_free(chansess->connection_string);
669 #endif
637 670
638 if (ret == DROPBEAR_FAILURE) { 671 if (ret == DROPBEAR_FAILURE) {
639 m_free(chansess->cmd); 672 m_free(chansess->cmd);
640 } 673 }
641 return ret; 674 return ret;
734 767
735 close(chansess->slave); 768 close(chansess->slave);
736 769
737 /* write the utmp/wtmp login record - must be after changing the 770 /* write the utmp/wtmp login record - must be after changing the
738 * terminal used for stdout with the dup2 above */ 771 * terminal used for stdout with the dup2 above */
739 li= login_alloc_entry(getpid(), ses.authstate.username, 772 li = chansess_login_alloc(chansess);
740 ses.remotehost, chansess->tty);
741 login_login(li); 773 login_login(li);
742 login_free_entry(li); 774 login_free_entry(li);
743
744 m_free(chansess->tty);
745 775
746 #ifdef DO_MOTD 776 #ifdef DO_MOTD
747 if (svr_opts.domotd) { 777 if (svr_opts.domotd) {
748 /* don't show the motd if ~/.hushlogin exists */ 778 /* don't show the motd if ~/.hushlogin exists */
749 779
881 addnewvar("PATH", DEFAULT_PATH); 911 addnewvar("PATH", DEFAULT_PATH);
882 if (chansess->term != NULL) { 912 if (chansess->term != NULL) {
883 addnewvar("TERM", chansess->term); 913 addnewvar("TERM", chansess->term);
884 } 914 }
885 915
916 if (chansess->tty) {
917 addnewvar("SSH_TTY", chansess->tty);
918 }
919
920 if (chansess->connection_string) {
921 addnewvar("SSH_CONNECTION", chansess->connection_string);
922 }
923
924 #ifdef ENABLE_SVR_PUBKEY_OPTIONS
925 if (ses.authstate.pubkey_options &&
926 ses.authstate.pubkey_options->original_command) {
927 addnewvar("SSH_ORIGINAL_COMMAND",
928 ses.authstate.pubkey_options->original_command);
929 }
930 #endif
931
886 /* change directory */ 932 /* change directory */
887 if (chdir(ses.authstate.pw_dir) < 0) { 933 if (chdir(ses.authstate.pw_dir) < 0) {
888 dropbear_exit("error changing directory"); 934 dropbear_exit("error changing directory");
889 } 935 }
890 936
892 /* set up X11 forwarding if enabled */ 938 /* set up X11 forwarding if enabled */
893 x11setauth(chansess); 939 x11setauth(chansess);
894 #endif 940 #endif
895 #ifndef DISABLE_AGENTFWD 941 #ifndef DISABLE_AGENTFWD
896 /* set up agent env variable */ 942 /* set up agent env variable */
897 agentset(chansess); 943 svr_agentset(chansess);
898 #endif 944 #endif
899 945
900 usershell = m_strdup(get_user_shell()); 946 usershell = m_strdup(get_user_shell());
901 run_shell_command(chansess->cmd, ses.maxfd, usershell); 947 run_shell_command(chansess->cmd, ses.maxfd, usershell);
902 948