* called by a name other than "ssh" or "Secure Shell".
*
* SSH2 support by Markus Friedl.
- * Copyright (c) 2000 Markus Friedl. All rights reserved.
+ * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
*/
#include "includes.h"
-RCSID("$OpenBSD: session.c,v 1.94 2001/06/23 15:12:20 itojun Exp $");
+RCSID("$OpenBSD: session.c,v 1.100 2001/08/16 19:18:34 jakob Exp $");
#include "ssh.h"
#include "ssh1.h"
struct Session {
int used;
int self;
- struct passwd *pw;
+ struct passwd *pw;
+ Authctxt *authctxt;
pid_t pid;
/* tty */
char *term;
/* func */
Session *session_new(void);
-void session_set_fds(Session *, int, int, int);
-static void session_pty_cleanup(void *);
-void session_proctitle(Session *);
-int session_setup_x11fwd(Session *);
-void do_exec_pty(Session *, const char *);
-void do_exec_no_pty(Session *, const char *);
-void do_exec(Session *, const char *);
-void do_login(Session *, const char *);
-void do_child(Session *, const char *);
+void session_set_fds(Session *, int, int, int);
+static void session_pty_cleanup(void *);
+void session_proctitle(Session *);
+int session_setup_x11fwd(Session *);
+void do_exec_pty(Session *, const char *);
+void do_exec_no_pty(Session *, const char *);
+void do_exec(Session *, const char *);
+void do_login(Session *, const char *);
+void do_child(Session *, const char *);
void do_motd(void);
+int check_quietlogin(Session *, const char *);
static void do_authenticated1(Authctxt *);
static void do_authenticated2(Authctxt *);
-
+
static void session_close(Session *);
static int session_pty_req(Session *);
/* remove agent socket */
if (auth_get_socket_name())
auth_sock_cleanup_proc(authctxt->pw);
+#ifdef KRB4
+ if (options.kerberos_ticket_cleanup)
+ krb4_cleanup_proc(authctxt);
+#endif
+#ifdef KRB5
+ if (options.kerberos_ticket_cleanup)
+ krb5_cleanup_proc(authctxt);
+#endif
}
/*
u_int proto_len, data_len, dlen;
s = session_new();
+ s->authctxt = authctxt;
s->pw = authctxt->pw;
/*
if (packet_set_maxsize(packet_get_int()) > 0)
success = 1;
break;
+
+#if defined(AFS) || defined(KRB5)
+ case SSH_CMSG_HAVE_KERBEROS_TGT:
+ if (!options.kerberos_tgt_passing) {
+ verbose("Kerberos TGT passing disabled.");
+ } else {
+ char *kdata = packet_get_string(&dlen);
+ packet_integrity_check(plen, 4 + dlen, type);
+
+ /* XXX - 0x41, see creds_to_radix version */
+ if (kdata[0] != 0x41) {
+#ifdef KRB5
+ krb5_data tgt;
+ tgt.data = kdata;
+ tgt.length = dlen;
+
+ if (auth_krb5_tgt(s->authctxt, &tgt))
+ success = 1;
+ else
+ verbose("Kerberos v5 TGT refused for %.100s", s->authctxt->user);
+#endif /* KRB5 */
+ } else {
+#ifdef AFS
+ if (auth_krb4_tgt(s->authctxt, kdata))
+ success = 1;
+ else
+ verbose("Kerberos v4 TGT refused for %.100s", s->authctxt->user);
+#endif /* AFS */
+ }
+ xfree(kdata);
+ }
+ break;
+#endif /* AFS || KRB5 */
+
+#ifdef AFS
+ case SSH_CMSG_HAVE_AFS_TOKEN:
+ if (!options.afs_token_passing || !k_hasafs()) {
+ verbose("AFS token passing disabled.");
+ } else {
+ /* Accept AFS token. */
+ char *token = packet_get_string(&dlen);
+ packet_integrity_check(plen, 4 + dlen, type);
+
+ if (auth_afs_token(s->authctxt, token))
+ success = 1;
+ else
+ verbose("AFS token refused for %.100s",
+ s->authctxt->user);
+ xfree(token);
+ }
+ break;
+#endif /* AFS */
case SSH_CMSG_EXEC_SHELL:
case SSH_CMSG_EXEC_CMD:
/* Fork the child. */
if ((pid = fork()) == 0) {
+
/* Child. Reinitialize the log because the pid has changed. */
log_init(__progname, options.log_level, options.log_facility, log_stderr);
-
/* Close the master side of the pseudo tty. */
close(ptyfd);
original_command = NULL;
}
-/*
- * Check for quiet login, either .hushlogin or command given.
- */
-static int
-check_quietlogin(Session *s, const char *command)
-{
- char buf[256];
- struct passwd * pw = s->pw;
- struct stat st;
-
- /* Return 1 if .hushlogin exists or a command given. */
- if (command != NULL)
- return 1;
- snprintf(buf, sizeof(buf), "%.200s/.hushlogin", pw->pw_dir);
-#ifdef HAVE_LOGIN_CAP
- if (login_getcapbool(lc, "hushlogin", 0) || stat(buf, &st) >= 0)
- return 1;
-#else
- if (stat(buf, &st) >= 0)
- return 1;
-#endif
- return 0;
-}
-
/* administrative, login(1)-like work */
void
do_login(Session *s, const char *command)
}
}
+
+/*
+ * Check for quiet login, either .hushlogin or command given.
+ */
+int
+check_quietlogin(Session *s, const char *command)
+{
+ char buf[256];
+ struct passwd *pw = s->pw;
+ struct stat st;
+
+ /* Return 1 if .hushlogin exists or a command given. */
+ if (command != NULL)
+ return 1;
+ snprintf(buf, sizeof(buf), "%.200s/.hushlogin", pw->pw_dir);
+#ifdef HAVE_LOGIN_CAP
+ if (login_getcapbool(lc, "hushlogin", 0) || stat(buf, &st) >= 0)
+ return 1;
+#else
+ if (stat(buf, &st) >= 0)
+ return 1;
+#endif
+ return 0;
+}
+
/*
* Sets the value of the given variable in the environment. If the variable
* already exists, its value is overriden.
do_child(Session *s, const char *command)
{
const char *shell, *hostname = NULL, *cp = NULL;
- struct passwd * pw = s->pw;
+ struct passwd *pw = s->pw;
char buf[256];
char cmd[1024];
FILE *f = NULL;
if (options.use_login && command != NULL)
options.use_login = 0;
-#if !defined(USE_PAM) && !defined(HAVE_OSF_SIA)
+#if !defined(HAVE_OSF_SIA)
if (!options.use_login) {
# ifdef HAVE_LOGIN_CAP
if (!login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid)
exit(254);
}
}
-#endif /* USE_PAM || HAVE_OSF_SIA */
+#endif /* HAVE_OSF_SIA */
/* Set login name, uid, gid, and groups. */
/* Login(1) does this as well, and it needs uid 0 for the "-h"
/* Try to get AFS tokens for the local cell. */
if (k_hasafs()) {
char cell[64];
-
+
if (k_afs_cell_of_file(pw->pw_dir, cell, sizeof(cell)) == 0)
krb_afslog(cell, 0);
-
+
krb_afslog(0, 0);
}
#endif /* AFS */
child_set_env(&env, &envsize, "KRB5CCNAME", cp);
read_environment_file(&env, &envsize, "/etc/environment");
#endif
-
#ifdef KRB4
- {
- extern char *ticket;
-
- if (ticket)
- child_set_env(&env, &envsize, "KRBTKFILE", ticket);
- }
-#endif /* KRB4 */
-
+ if (s->authctxt->krb4_ticket_file)
+ child_set_env(&env, &envsize, "KRBTKFILE",
+ s->authctxt->krb4_ticket_file);
+#endif
+#ifdef KRB5
+ if (s->authctxt->krb5_ticket_file)
+ child_set_env(&env, &envsize, "KRB5CCNAME",
+ s->authctxt->krb5_ticket_file);
+#endif
#ifdef USE_PAM
/* Pull in any environment variables that may have been set by PAM. */
do_pam_environment(&env, &envsize);
if (!options.use_login) {
char buf[256];
- /*
- * Check for mail if we have a tty and it was enabled
- * in server options.
- */
- if (s->ttyfd != -1 && options.check_mail) {
- char *mailbox;
- struct stat mailstat;
-
- mailbox = getenv("MAIL");
- if (mailbox != NULL) {
- if (stat(mailbox, &mailstat) != 0 ||
- mailstat.st_size == 0)
- printf("No mail.\n");
- else if (mailstat.st_mtime < mailstat.st_atime)
- printf("You have mail.\n");
- else
- printf("You have new mail.\n");
- }
- }
/* Start the shell. Set initial character to '-'. */
buf[0] = '-';
strncpy(buf + 1, cp, sizeof(buf) - 1);
#ifdef LOGIN_NEEDS_TERM
s->term? s->term : "unknown",
#endif
- "-p", "-f", "--", pw->pw_name, NULL);
+ "-p", "-f", "--", pw->pw_name, (char *)NULL);
/* Login couldn't be executed, die. */
}
int
-session_open(int chanid)
+session_open(Authctxt *authctxt, int chanid)
{
Session *s = session_new();
debug("session_open: channel %d", chanid);
error("no more sessions");
return 0;
}
- s->pw = auth_get_user();
+ s->authctxt = authctxt;
+ s->pw = authctxt->pw;
if (s->pw == NULL)
fatal("no user for session %d", s->self);
debug("session_open: session %d: link with channel %d", s->self, chanid);
session_close(s);
}
+int
+session_have_children(void)
+{
+ int i;
+
+ for(i = 0; i < MAX_SESSIONS; i++) {
+ Session *s = &sessions[i];
+ if (s->used && s->pid != -1) {
+ debug("session_have_children: id %d pid %d", i, s->pid);
+ return 1;
+ }
+ }
+ debug("session_have_children: no more children");
+ return 0;
+}
+
/*
* this is called when a channel dies before
* the session 'child' itself dies
static void
do_authenticated2(Authctxt *authctxt)
{
- server_loop2();
+ server_loop2(authctxt);
}