version 1.129, 2002/03/18 03:41:08 |
version 1.130, 2002/03/18 17:50:31 |
|
|
#include "serverloop.h" |
#include "serverloop.h" |
#include "canohost.h" |
#include "canohost.h" |
#include "session.h" |
#include "session.h" |
|
#include "monitor_wrap.h" |
|
|
/* types */ |
|
|
|
#define TTYSZ 64 |
|
typedef struct Session Session; |
|
struct Session { |
|
int used; |
|
int self; |
|
struct passwd *pw; |
|
Authctxt *authctxt; |
|
pid_t pid; |
|
/* tty */ |
|
char *term; |
|
int ptyfd, ttyfd, ptymaster; |
|
int row, col, xpixel, ypixel; |
|
char tty[TTYSZ]; |
|
/* X11 */ |
|
int display_number; |
|
char *display; |
|
int screen; |
|
char *auth_display; |
|
char *auth_proto; |
|
char *auth_data; |
|
int single_connection; |
|
/* proto 2 */ |
|
int chanid; |
|
int is_subsystem; |
|
}; |
|
|
|
/* func */ |
/* func */ |
|
|
Session *session_new(void); |
Session *session_new(void); |
void session_set_fds(Session *, int, int, int); |
void session_set_fds(Session *, int, int, int); |
static void session_pty_cleanup(void *); |
void session_pty_cleanup(void *); |
void session_proctitle(Session *); |
void session_proctitle(Session *); |
int session_setup_x11fwd(Session *); |
int session_setup_x11fwd(Session *); |
void do_exec_pty(Session *, const char *); |
void do_exec_pty(Session *, const char *); |
|
|
static void do_authenticated1(Authctxt *); |
static void do_authenticated1(Authctxt *); |
static void do_authenticated2(Authctxt *); |
static void do_authenticated2(Authctxt *); |
|
|
static void session_close(Session *); |
|
static int session_pty_req(Session *); |
static int session_pty_req(Session *); |
|
|
/* import */ |
/* import */ |
|
|
} |
} |
|
|
/* Set login name, uid, gid, and groups. */ |
/* Set login name, uid, gid, and groups. */ |
static void |
void |
do_setusercontext(struct passwd *pw) |
do_setusercontext(struct passwd *pw) |
{ |
{ |
if (getuid() == 0 || geteuid() == 0) { |
if (getuid() == 0 || geteuid() == 0) { |
|
|
fatal("Failed to set uids to %u.", (u_int) pw->pw_uid); |
fatal("Failed to set uids to %u.", (u_int) pw->pw_uid); |
} |
} |
|
|
|
void |
|
launch_login(struct passwd *pw, const char *hostname) |
|
{ |
|
/* Launch login(1). */ |
|
|
|
execl("/usr/bin/login", "login", "-h", hostname, |
|
"-p", "-f", "--", pw->pw_name, (char *)NULL); |
|
|
|
/* Login couldn't be executed, die. */ |
|
|
|
perror("login"); |
|
exit(1); |
|
} |
|
|
/* |
/* |
* Performs common processing for the child, such as setting up the |
* Performs common processing for the child, such as setting up the |
* environment, closing extra file descriptors, setting the user and group |
* environment, closing extra file descriptors, setting the user and group |
|
|
signal(SIGPIPE, SIG_DFL); |
signal(SIGPIPE, SIG_DFL); |
|
|
if (options.use_login) { |
if (options.use_login) { |
/* Launch login(1). */ |
launch_login(pw, hostname); |
|
/* NEVERREACHED */ |
execl("/usr/bin/login", "login", "-h", hostname, |
|
"-p", "-f", "--", pw->pw_name, (char *)NULL); |
|
|
|
/* Login couldn't be executed, die. */ |
|
|
|
perror("login"); |
|
exit(1); |
|
} |
} |
|
|
/* Get the last component of the shell name. */ |
/* Get the last component of the shell name. */ |
|
|
return 1; |
return 1; |
} |
} |
|
|
|
Session * |
|
session_by_tty(char *tty) |
|
{ |
|
int i; |
|
for (i = 0; i < MAX_SESSIONS; i++) { |
|
Session *s = &sessions[i]; |
|
if (s->used && s->ttyfd != -1 && strcmp(s->tty, tty) == 0) { |
|
debug("session_by_tty: session %d tty %s", i, tty); |
|
return s; |
|
} |
|
} |
|
debug("session_by_tty: unknown tty %.100s", tty); |
|
session_dump(); |
|
return NULL; |
|
} |
|
|
static Session * |
static Session * |
session_by_channel(int id) |
session_by_channel(int id) |
{ |
{ |
|
|
{ |
{ |
u_int len; |
u_int len; |
int n_bytes; |
int n_bytes; |
|
|
if (no_pty_flag) { |
if (no_pty_flag) { |
debug("Allocating a pty not permitted for this authentication."); |
debug("Allocating a pty not permitted for this authentication."); |
return 0; |
return 0; |
|
|
|
|
/* Allocate a pty and open it. */ |
/* Allocate a pty and open it. */ |
debug("Allocating pty."); |
debug("Allocating pty."); |
if (!pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty))) { |
if (!PRIVSEP(pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)))) { |
if (s->term) |
if (s->term) |
xfree(s->term); |
xfree(s->term); |
s->term = NULL; |
s->term = NULL; |
|
|
* time in case we call fatal() (e.g., the connection gets closed). |
* time in case we call fatal() (e.g., the connection gets closed). |
*/ |
*/ |
fatal_add_cleanup(session_pty_cleanup, (void *)s); |
fatal_add_cleanup(session_pty_cleanup, (void *)s); |
pty_setowner(s->pw, s->tty); |
if (!use_privsep) |
|
pty_setowner(s->pw, s->tty); |
|
|
/* Set window size from the packet. */ |
/* Set window size from the packet. */ |
pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); |
pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); |
|
|
* Function to perform pty cleanup. Also called if we get aborted abnormally |
* Function to perform pty cleanup. Also called if we get aborted abnormally |
* (e.g., due to a dropped connection). |
* (e.g., due to a dropped connection). |
*/ |
*/ |
static void |
void |
session_pty_cleanup(void *session) |
session_pty_cleanup2(void *session) |
{ |
{ |
Session *s = session; |
Session *s = session; |
|
|
|
|
record_logout(s->pid, s->tty); |
record_logout(s->pid, s->tty); |
|
|
/* Release the pseudo-tty. */ |
/* Release the pseudo-tty. */ |
pty_release(s->tty); |
if (getuid() == 0) |
|
pty_release(s->tty); |
|
|
/* |
/* |
* Close the server side of the socket pairs. We must do this after |
* Close the server side of the socket pairs. We must do this after |
|
|
* while we're still cleaning up. |
* while we're still cleaning up. |
*/ |
*/ |
if (close(s->ptymaster) < 0) |
if (close(s->ptymaster) < 0) |
error("close(s->ptymaster): %s", strerror(errno)); |
error("close(s->ptymaster/%d): %s", s->ptymaster, strerror(errno)); |
|
|
/* unlink pty from session */ |
/* unlink pty from session */ |
s->ttyfd = -1; |
s->ttyfd = -1; |
} |
} |
|
|
|
void |
|
session_pty_cleanup(void *session) |
|
{ |
|
PRIVSEP(session_pty_cleanup2(session)); |
|
} |
|
|
static void |
static void |
session_exit_message(Session *s, int status) |
session_exit_message(Session *s, int status) |
{ |
{ |
|
|
s->chanid = -1; |
s->chanid = -1; |
} |
} |
|
|
static void |
void |
session_close(Session *s) |
session_close(Session *s) |
{ |
{ |
debug("session_close: session %d pid %d", s->self, s->pid); |
debug("session_close: session %d pid %d", s->self, s->pid); |
|
|
} |
} |
|
|
void |
void |
session_destroy_all(void) |
session_destroy_all(void (*closefunc)(Session *)) |
{ |
{ |
int i; |
int i; |
for (i = 0; i < MAX_SESSIONS; i++) { |
for (i = 0; i < MAX_SESSIONS; i++) { |
Session *s = &sessions[i]; |
Session *s = &sessions[i]; |
if (s->used) |
if (s->used) { |
session_close(s); |
if (closefunc != NULL) |
|
closefunc(s); |
|
else |
|
session_close(s); |
|
} |
} |
} |
} |
} |
|
|