Mercurial > dropbear
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 |