summaryrefslogtreecommitdiff
path: root/session.c
diff options
context:
space:
mode:
Diffstat (limited to 'session.c')
-rw-r--r--session.c267
1 files changed, 150 insertions, 117 deletions
diff --git a/session.c b/session.c
index c75fea966..4497f5c0b 100644
--- a/session.c
+++ b/session.c
@@ -33,7 +33,7 @@
33 */ 33 */
34 34
35#include "includes.h" 35#include "includes.h"
36RCSID("$OpenBSD: session.c,v 1.154 2003/03/05 22:33:43 markus Exp $"); 36RCSID("$OpenBSD: session.c,v 1.163 2003/08/31 13:29:05 markus Exp $");
37 37
38#include "ssh.h" 38#include "ssh.h"
39#include "ssh1.h" 39#include "ssh1.h"
@@ -58,10 +58,8 @@ RCSID("$OpenBSD: session.c,v 1.154 2003/03/05 22:33:43 markus Exp $");
58#include "session.h" 58#include "session.h"
59#include "monitor_wrap.h" 59#include "monitor_wrap.h"
60 60
61#ifdef HAVE_CYGWIN 61#ifdef GSSAPI
62#include <windows.h> 62#include "ssh-gss.h"
63#include <sys/cygwin.h>
64#define is_winnt (GetVersion() < 0x80000000)
65#endif 63#endif
66 64
67/* func */ 65/* func */
@@ -95,6 +93,7 @@ extern int debug_flag;
95extern u_int utmp_len; 93extern u_int utmp_len;
96extern int startup_pipe; 94extern int startup_pipe;
97extern void destroy_sensitive_data(void); 95extern void destroy_sensitive_data(void);
96extern Buffer loginmsg;
98 97
99/* original command from peer. */ 98/* original command from peer. */
100const char *original_command = NULL; 99const char *original_command = NULL;
@@ -103,10 +102,6 @@ const char *original_command = NULL;
103#define MAX_SESSIONS 10 102#define MAX_SESSIONS 10
104Session sessions[MAX_SESSIONS]; 103Session sessions[MAX_SESSIONS];
105 104
106#ifdef WITH_AIXAUTHENTICATE
107char *aixloginmsg;
108#endif /* WITH_AIXAUTHENTICATE */
109
110#ifdef HAVE_LOGIN_CAP 105#ifdef HAVE_LOGIN_CAP
111login_cap_t *lc; 106login_cap_t *lc;
112#endif 107#endif
@@ -192,7 +187,7 @@ auth_input_request_forwarding(struct passwd * pw)
192 nc = channel_new("auth socket", 187 nc = channel_new("auth socket",
193 SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1, 188 SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1,
194 CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 189 CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
195 0, xstrdup("auth socket"), 1); 190 0, "auth socket", 1);
196 strlcpy(nc->path, auth_sock_name, sizeof(nc->path)); 191 strlcpy(nc->path, auth_sock_name, sizeof(nc->path));
197 return 1; 192 return 1;
198} 193}
@@ -225,10 +220,6 @@ do_authenticated(Authctxt *authctxt)
225 /* remove agent socket */ 220 /* remove agent socket */
226 if (auth_sock_name != NULL) 221 if (auth_sock_name != NULL)
227 auth_sock_cleanup_proc(authctxt->pw); 222 auth_sock_cleanup_proc(authctxt->pw);
228#ifdef KRB4
229 if (options.kerberos_ticket_cleanup)
230 krb4_cleanup_proc(authctxt);
231#endif
232#ifdef KRB5 223#ifdef KRB5
233 if (options.kerberos_ticket_cleanup) 224 if (options.kerberos_ticket_cleanup)
234 krb5_cleanup_proc(authctxt); 225 krb5_cleanup_proc(authctxt);
@@ -341,58 +332,6 @@ do_authenticated1(Authctxt *authctxt)
341 success = 1; 332 success = 1;
342 break; 333 break;
343 334
344#if defined(AFS) || defined(KRB5)
345 case SSH_CMSG_HAVE_KERBEROS_TGT:
346 if (!options.kerberos_tgt_passing) {
347 verbose("Kerberos TGT passing disabled.");
348 } else {
349 char *kdata = packet_get_string(&dlen);
350 packet_check_eom();
351
352 /* XXX - 0x41, see creds_to_radix version */
353 if (kdata[0] != 0x41) {
354#ifdef KRB5
355 krb5_data tgt;
356 tgt.data = kdata;
357 tgt.length = dlen;
358
359 if (auth_krb5_tgt(s->authctxt, &tgt))
360 success = 1;
361 else
362 verbose("Kerberos v5 TGT refused for %.100s", s->authctxt->user);
363#endif /* KRB5 */
364 } else {
365#ifdef AFS
366 if (auth_krb4_tgt(s->authctxt, kdata))
367 success = 1;
368 else
369 verbose("Kerberos v4 TGT refused for %.100s", s->authctxt->user);
370#endif /* AFS */
371 }
372 xfree(kdata);
373 }
374 break;
375#endif /* AFS || KRB5 */
376
377#ifdef AFS
378 case SSH_CMSG_HAVE_AFS_TOKEN:
379 if (!options.afs_token_passing || !k_hasafs()) {
380 verbose("AFS token passing disabled.");
381 } else {
382 /* Accept AFS token. */
383 char *token = packet_get_string(&dlen);
384 packet_check_eom();
385
386 if (auth_afs_token(s->authctxt, token))
387 success = 1;
388 else
389 verbose("AFS token refused for %.100s",
390 s->authctxt->user);
391 xfree(token);
392 }
393 break;
394#endif /* AFS */
395
396 case SSH_CMSG_EXEC_SHELL: 335 case SSH_CMSG_EXEC_SHELL:
397 case SSH_CMSG_EXEC_CMD: 336 case SSH_CMSG_EXEC_CMD:
398 if (type == SSH_CMSG_EXEC_CMD) { 337 if (type == SSH_CMSG_EXEC_CMD) {
@@ -412,7 +351,7 @@ do_authenticated1(Authctxt *authctxt)
412 * Any unknown messages in this phase are ignored, 351 * Any unknown messages in this phase are ignored,
413 * and a failure message is returned. 352 * and a failure message is returned.
414 */ 353 */
415 log("Unknown packet type received after authentication: %d", type); 354 logit("Unknown packet type received after authentication: %d", type);
416 } 355 }
417 packet_start(success ? SSH_SMSG_SUCCESS : SSH_SMSG_FAILURE); 356 packet_start(success ? SSH_SMSG_SUCCESS : SSH_SMSG_FAILURE);
418 packet_send(); 357 packet_send();
@@ -456,11 +395,12 @@ do_exec_no_pty(Session *s, const char *command)
456 session_proctitle(s); 395 session_proctitle(s);
457 396
458#if defined(USE_PAM) 397#if defined(USE_PAM)
459 do_pam_session(s->pw->pw_name, NULL); 398 if (options.use_pam) {
460 do_pam_setcred(1); 399 do_pam_setcred(1);
461 if (is_pam_password_change_required()) 400 if (is_pam_password_change_required())
462 packet_disconnect("Password change required but no " 401 packet_disconnect("Password change required but no "
463 "TTY available"); 402 "TTY available");
403 }
464#endif /* USE_PAM */ 404#endif /* USE_PAM */
465 405
466 /* Fork the child. */ 406 /* Fork the child. */
@@ -583,8 +523,10 @@ do_exec_pty(Session *s, const char *command)
583 ttyfd = s->ttyfd; 523 ttyfd = s->ttyfd;
584 524
585#if defined(USE_PAM) 525#if defined(USE_PAM)
586 do_pam_session(s->pw->pw_name, s->tty); 526 if (options.use_pam) {
587 do_pam_setcred(1); 527 do_pam_set_tty(s->tty);
528 do_pam_setcred(1);
529 }
588#endif 530#endif
589 531
590 /* Fork the child. */ 532 /* Fork the child. */
@@ -690,7 +632,7 @@ do_pre_login(Session *s)
690 } 632 }
691 633
692 record_utmp_only(pid, s->tty, s->pw->pw_name, 634 record_utmp_only(pid, s->tty, s->pw->pw_name,
693 get_remote_name_or_ip(utmp_len, options.verify_reverse_mapping), 635 get_remote_name_or_ip(utmp_len, options.use_dns),
694 (struct sockaddr *)&from, fromlen); 636 (struct sockaddr *)&from, fromlen);
695} 637}
696#endif 638#endif
@@ -708,6 +650,14 @@ do_exec(Session *s, const char *command)
708 debug("Forced command '%.900s'", command); 650 debug("Forced command '%.900s'", command);
709 } 651 }
710 652
653#ifdef GSSAPI
654 if (options.gss_authentication) {
655 temporarily_use_uid(s->pw);
656 ssh_gssapi_storecreds();
657 restore_uid();
658 }
659#endif
660
711 if (s->ttyfd != -1) 661 if (s->ttyfd != -1)
712 do_exec_pty(s, command); 662 do_exec_pty(s, command);
713 else 663 else
@@ -745,7 +695,7 @@ do_login(Session *s, const char *command)
745 if (!use_privsep) 695 if (!use_privsep)
746 record_login(pid, s->tty, pw->pw_name, pw->pw_uid, 696 record_login(pid, s->tty, pw->pw_name, pw->pw_uid,
747 get_remote_name_or_ip(utmp_len, 697 get_remote_name_or_ip(utmp_len,
748 options.verify_reverse_mapping), 698 options.use_dns),
749 (struct sockaddr *)&from, fromlen); 699 (struct sockaddr *)&from, fromlen);
750 700
751#ifdef USE_PAM 701#ifdef USE_PAM
@@ -753,9 +703,10 @@ do_login(Session *s, const char *command)
753 * If password change is needed, do it now. 703 * If password change is needed, do it now.
754 * This needs to occur before the ~/.hushlogin check. 704 * This needs to occur before the ~/.hushlogin check.
755 */ 705 */
756 if (is_pam_password_change_required()) { 706 if (options.use_pam && is_pam_password_change_required()) {
757 print_pam_messages(); 707 print_pam_messages();
758 do_pam_chauthtok(); 708 do_pam_chauthtok();
709 /* XXX - signal [net] parent to enable forwardings */
759 } 710 }
760#endif 711#endif
761 712
@@ -763,13 +714,16 @@ do_login(Session *s, const char *command)
763 return; 714 return;
764 715
765#ifdef USE_PAM 716#ifdef USE_PAM
766 if (!is_pam_password_change_required()) 717 if (options.use_pam && !is_pam_password_change_required())
767 print_pam_messages(); 718 print_pam_messages();
768#endif /* USE_PAM */ 719#endif /* USE_PAM */
769#ifdef WITH_AIXAUTHENTICATE 720
770 if (aixloginmsg && *aixloginmsg) 721 /* display post-login message */
771 printf("%s\n", aixloginmsg); 722 if (buffer_len(&loginmsg) > 0) {
772#endif /* WITH_AIXAUTHENTICATE */ 723 buffer_append(&loginmsg, "\0", 1);
724 printf("%s\n", (char *)buffer_ptr(&loginmsg));
725 }
726 buffer_free(&loginmsg);
773 727
774#ifndef NO_SSH_LASTLOG 728#ifndef NO_SSH_LASTLOG
775 if (options.print_lastlog && s->last_login_time != 0) { 729 if (options.print_lastlog && s->last_login_time != 0) {
@@ -840,7 +794,7 @@ check_quietlogin(Session *s, const char *command)
840 * Sets the value of the given variable in the environment. If the variable 794 * Sets the value of the given variable in the environment. If the variable
841 * already exists, its value is overriden. 795 * already exists, its value is overriden.
842 */ 796 */
843static void 797void
844child_set_env(char ***envp, u_int *envsizep, const char *name, 798child_set_env(char ***envp, u_int *envsizep, const char *name,
845 const char *value) 799 const char *value)
846{ 800{
@@ -848,6 +802,16 @@ child_set_env(char ***envp, u_int *envsizep, const char *name,
848 char **env; 802 char **env;
849 803
850 /* 804 /*
805 * If we're passed an uninitialized list, allocate a single null
806 * entry before continuing.
807 */
808 if (*envp == NULL && *envsizep == 0) {
809 *envp = xmalloc(sizeof(char *));
810 *envp[0] = NULL;
811 *envsizep = 1;
812 }
813
814 /*
851 * Find the slot where the value should be stored. If the variable 815 * Find the slot where the value should be stored. If the variable
852 * already exists, we reuse the slot; otherwise we append a new slot 816 * already exists, we reuse the slot; otherwise we append a new slot
853 * at the end of the array, expanding if necessary. 817 * at the end of the array, expanding if necessary.
@@ -923,6 +887,59 @@ read_environment_file(char ***env, u_int *envsize,
923 fclose(f); 887 fclose(f);
924} 888}
925 889
890#ifdef HAVE_ETC_DEFAULT_LOGIN
891/*
892 * Return named variable from specified environment, or NULL if not present.
893 */
894static char *
895child_get_env(char **env, const char *name)
896{
897 int i;
898 size_t len;
899
900 len = strlen(name);
901 for (i=0; env[i] != NULL; i++)
902 if (strncmp(name, env[i], len) == 0 && env[i][len] == '=')
903 return(env[i] + len + 1);
904 return NULL;
905}
906
907/*
908 * Read /etc/default/login.
909 * We pick up the PATH (or SUPATH for root) and UMASK.
910 */
911static void
912read_etc_default_login(char ***env, u_int *envsize, uid_t uid)
913{
914 char **tmpenv = NULL, *var;
915 u_int i;
916 size_t tmpenvsize = 0;
917 mode_t mask;
918
919 /*
920 * We don't want to copy the whole file to the child's environment,
921 * so we use a temporary environment and copy the variables we're
922 * interested in.
923 */
924 read_environment_file(&tmpenv, &tmpenvsize, "/etc/default/login");
925
926 if (uid == 0)
927 var = child_get_env(tmpenv, "SUPATH");
928 else
929 var = child_get_env(tmpenv, "PATH");
930 if (var != NULL)
931 child_set_env(env, envsize, "PATH", var);
932
933 if ((var = child_get_env(tmpenv, "UMASK")) != NULL)
934 if (sscanf(var, "%5lo", &mask) == 1)
935 umask(mask);
936
937 for (i = 0; tmpenv[i] != NULL; i++)
938 xfree(tmpenv[i]);
939 xfree(tmpenv);
940}
941#endif /* HAVE_ETC_DEFAULT_LOGIN */
942
926void copy_environment(char **source, char ***env, u_int *envsize) 943void copy_environment(char **source, char ***env, u_int *envsize)
927{ 944{
928 char *var_name, *var_val; 945 char *var_name, *var_val;
@@ -951,7 +968,7 @@ do_setup_env(Session *s, const char *shell)
951{ 968{
952 char buf[256]; 969 char buf[256];
953 u_int i, envsize; 970 u_int i, envsize;
954 char **env, *laddr; 971 char **env, *laddr, *path = NULL;
955 struct passwd *pw = s->pw; 972 struct passwd *pw = s->pw;
956 973
957 /* Initialize the environment. */ 974 /* Initialize the environment. */
@@ -967,6 +984,13 @@ do_setup_env(Session *s, const char *shell)
967 copy_environment(environ, &env, &envsize); 984 copy_environment(environ, &env, &envsize);
968#endif 985#endif
969 986
987#ifdef GSSAPI
988 /* Allow any GSSAPI methods that we've used to alter
989 * the childs environment as they see fit
990 */
991 ssh_gssapi_do_child(&env, &envsize);
992#endif
993
970 if (!options.use_login) { 994 if (!options.use_login) {
971 /* Set basic environment. */ 995 /* Set basic environment. */
972 child_set_env(&env, &envsize, "USER", pw->pw_name); 996 child_set_env(&env, &envsize, "USER", pw->pw_name);
@@ -988,12 +1012,15 @@ do_setup_env(Session *s, const char *shell)
988 * needed for loading shared libraries. So the path better 1012 * needed for loading shared libraries. So the path better
989 * remains intact here. 1013 * remains intact here.
990 */ 1014 */
991# ifdef SUPERUSER_PATH 1015# ifdef HAVE_ETC_DEFAULT_LOGIN
992 child_set_env(&env, &envsize, "PATH", 1016 read_etc_default_login(&env, &envsize, pw->pw_uid);
993 s->pw->pw_uid == 0 ? SUPERUSER_PATH : _PATH_STDPATH); 1017 path = child_get_env(env, "PATH");
994# else 1018# endif /* HAVE_ETC_DEFAULT_LOGIN */
995 child_set_env(&env, &envsize, "PATH", _PATH_STDPATH); 1019 if (path == NULL || *path == '\0') {
996# endif /* SUPERUSER_PATH */ 1020 child_set_env(&env, &envsize, "PATH",
1021 s->pw->pw_uid == 0 ?
1022 SUPERUSER_PATH : _PATH_STDPATH);
1023 }
997# endif /* HAVE_CYGWIN */ 1024# endif /* HAVE_CYGWIN */
998#endif /* HAVE_LOGIN_CAP */ 1025#endif /* HAVE_LOGIN_CAP */
999 1026
@@ -1062,11 +1089,6 @@ do_setup_env(Session *s, const char *shell)
1062 read_environment_file(&env, &envsize, "/etc/environment"); 1089 read_environment_file(&env, &envsize, "/etc/environment");
1063 } 1090 }
1064#endif 1091#endif
1065#ifdef KRB4
1066 if (s->authctxt->krb4_ticket_file)
1067 child_set_env(&env, &envsize, "KRBTKFILE",
1068 s->authctxt->krb4_ticket_file);
1069#endif
1070#ifdef KRB5 1092#ifdef KRB5
1071 if (s->authctxt->krb5_ticket_file) 1093 if (s->authctxt->krb5_ticket_file)
1072 child_set_env(&env, &envsize, "KRB5CCNAME", 1094 child_set_env(&env, &envsize, "KRB5CCNAME",
@@ -1077,10 +1099,9 @@ do_setup_env(Session *s, const char *shell)
1077 * Pull in any environment variables that may have 1099 * Pull in any environment variables that may have
1078 * been set by PAM. 1100 * been set by PAM.
1079 */ 1101 */
1080 { 1102 if (options.use_pam) {
1081 char **p; 1103 char **p = fetch_pam_environment();
1082 1104
1083 p = fetch_pam_environment();
1084 copy_environment(p, &env, &envsize); 1105 copy_environment(p, &env, &envsize);
1085 free_pam_environment(p); 1106 free_pam_environment(p);
1086 } 1107 }
@@ -1192,7 +1213,7 @@ do_nologin(struct passwd *pw)
1192#endif 1213#endif
1193 if (f) { 1214 if (f) {
1194 /* /etc/nologin exists. Print its contents and exit. */ 1215 /* /etc/nologin exists. Print its contents and exit. */
1195 log("User %.100s not allowed because %s exists", 1216 logit("User %.100s not allowed because %s exists",
1196 pw->pw_name, _PATH_NOLOGIN); 1217 pw->pw_name, _PATH_NOLOGIN);
1197 while (fgets(buf, sizeof(buf), f)) 1218 while (fgets(buf, sizeof(buf), f))
1198 fputs(buf, stderr); 1219 fputs(buf, stderr);
@@ -1212,7 +1233,8 @@ do_setusercontext(struct passwd *pw)
1212 { 1233 {
1213 1234
1214#ifdef HAVE_SETPCRED 1235#ifdef HAVE_SETPCRED
1215 setpcred(pw->pw_name); 1236 if (setpcred(pw->pw_name, (char **)NULL) == -1)
1237 fatal("Failed to set process credentials");
1216#endif /* HAVE_SETPCRED */ 1238#endif /* HAVE_SETPCRED */
1217#ifdef HAVE_LOGIN_CAP 1239#ifdef HAVE_LOGIN_CAP
1218# ifdef __bsdi__ 1240# ifdef __bsdi__
@@ -1248,7 +1270,10 @@ do_setusercontext(struct passwd *pw)
1248 * These will have been wiped by the above initgroups() call. 1270 * These will have been wiped by the above initgroups() call.
1249 * Reestablish them here. 1271 * Reestablish them here.
1250 */ 1272 */
1251 do_pam_setcred(0); 1273 if (options.use_pam) {
1274 do_pam_session();
1275 do_pam_setcred(0);
1276 }
1252# endif /* USE_PAM */ 1277# endif /* USE_PAM */
1253# if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) 1278# if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY)
1254 irix_setusercontext(pw); 1279 irix_setusercontext(pw);
@@ -1349,7 +1374,7 @@ do_child(Session *s, const char *command)
1349 /* we have to stash the hostname before we close our socket. */ 1374 /* we have to stash the hostname before we close our socket. */
1350 if (options.use_login) 1375 if (options.use_login)
1351 hostname = get_remote_name_or_ip(utmp_len, 1376 hostname = get_remote_name_or_ip(utmp_len,
1352 options.verify_reverse_mapping); 1377 options.use_dns);
1353 /* 1378 /*
1354 * Close the connection descriptors; note that this is the child, and 1379 * Close the connection descriptors; note that this is the child, and
1355 * the server will still have the socket open, and it is important 1380 * the server will still have the socket open, and it is important
@@ -1391,18 +1416,6 @@ do_child(Session *s, const char *command)
1391 */ 1416 */
1392 environ = env; 1417 environ = env;
1393 1418
1394#ifdef AFS
1395 /* Try to get AFS tokens for the local cell. */
1396 if (k_hasafs()) {
1397 char cell[64];
1398
1399 if (k_afs_cell_of_file(pw->pw_dir, cell, sizeof(cell)) == 0)
1400 krb_afslog(cell, 0);
1401
1402 krb_afslog(0, 0);
1403 }
1404#endif /* AFS */
1405
1406 /* Change current directory to the user\'s home directory. */ 1419 /* Change current directory to the user\'s home directory. */
1407 if (chdir(pw->pw_dir) < 0) { 1420 if (chdir(pw->pw_dir) < 0) {
1408 fprintf(stderr, "Could not chdir to home directory %s: %s\n", 1421 fprintf(stderr, "Could not chdir to home directory %s: %s\n",
@@ -1672,7 +1685,7 @@ session_subsystem_req(Session *s)
1672 int i; 1685 int i;
1673 1686
1674 packet_check_eom(); 1687 packet_check_eom();
1675 log("subsystem request for %.100s", subsys); 1688 logit("subsystem request for %.100s", subsys);
1676 1689
1677 for (i = 0; i < options.num_subsystems; i++) { 1690 for (i = 0; i < options.num_subsystems; i++) {
1678 if (strcmp(subsys, options.subsystem_name[i]) == 0) { 1691 if (strcmp(subsys, options.subsystem_name[i]) == 0) {
@@ -1691,7 +1704,7 @@ session_subsystem_req(Session *s)
1691 } 1704 }
1692 1705
1693 if (!success) 1706 if (!success)
1694 log("subsystem request for %.100s failed, subsystem not found", 1707 logit("subsystem request for %.100s failed, subsystem not found",
1695 subsys); 1708 subsys);
1696 1709
1697 xfree(subsys); 1710 xfree(subsys);
@@ -1739,6 +1752,20 @@ session_exec_req(Session *s)
1739} 1752}
1740 1753
1741static int 1754static int
1755session_break_req(Session *s)
1756{
1757 u_int break_length;
1758
1759 break_length = packet_get_int(); /* ignored */
1760 packet_check_eom();
1761
1762 if (s->ttyfd == -1 ||
1763 tcsendbreak(s->ttyfd, 0) < 0)
1764 return 0;
1765 return 1;
1766}
1767
1768static int
1742session_auth_agent_req(Session *s) 1769session_auth_agent_req(Session *s)
1743{ 1770{
1744 static int called = 0; 1771 static int called = 0;
@@ -1762,7 +1789,7 @@ session_input_channel_req(Channel *c, const char *rtype)
1762 Session *s; 1789 Session *s;
1763 1790
1764 if ((s = session_by_channel(c->self)) == NULL) { 1791 if ((s = session_by_channel(c->self)) == NULL) {
1765 log("session_input_channel_req: no session %d req %.100s", 1792 logit("session_input_channel_req: no session %d req %.100s",
1766 c->self, rtype); 1793 c->self, rtype);
1767 return 0; 1794 return 0;
1768 } 1795 }
@@ -1785,6 +1812,8 @@ session_input_channel_req(Channel *c, const char *rtype)
1785 success = session_auth_agent_req(s); 1812 success = session_auth_agent_req(s);
1786 } else if (strcmp(rtype, "subsystem") == 0) { 1813 } else if (strcmp(rtype, "subsystem") == 0) {
1787 success = session_subsystem_req(s); 1814 success = session_subsystem_req(s);
1815 } else if (strcmp(rtype, "break") == 0) {
1816 success = session_break_req(s);
1788 } 1817 }
1789 } 1818 }
1790 if (strcmp(rtype, "window-change") == 0) { 1819 if (strcmp(rtype, "window-change") == 0) {
@@ -2121,4 +2150,8 @@ static void
2121do_authenticated2(Authctxt *authctxt) 2150do_authenticated2(Authctxt *authctxt)
2122{ 2151{
2123 server_loop2(authctxt); 2152 server_loop2(authctxt);
2153#if defined(GSSAPI)
2154 if (options.gss_cleanup_creds)
2155 ssh_gssapi_cleanup_creds(NULL);
2156#endif
2124} 2157}