Beispiel #1
0
/* Records that the user has logged out. */
void
record_logout(pid_t pid, const char *tty, const char *user)
{
	struct logininfo *li;

	li = login_alloc_entry(pid, user, NULL, tty);
	login_logout(li);
	login_free_entry(li);
}
Beispiel #2
0
void
record_utmp_only(pid_t pid, const char *ttyname, const char *user,
		 const char *host, struct sockaddr *addr, socklen_t addrlen)
{
	struct logininfo *li;

	li = login_alloc_entry(pid, user, host, ttyname);
	login_set_addr(li, addr, addrlen);
	login_utmp_only(li);
	login_free_entry(li);
}
Beispiel #3
0
/* clean a session channel */
void closechansess(struct Channel *channel) {

	struct ChanSess *chansess;
	unsigned int i;
	struct logininfo *li;

	chansess = (struct ChanSess*)channel->typedata;

	TRACE(("enter closechansess"));
	if (chansess == NULL) {
		TRACE(("leave closechansess: chansess == NULL"));
		return;
	}

	m_free(chansess->cmd);
	m_free(chansess->term);

	if (chansess->tty) {
		/* write the utmp/wtmp login record */
		li = login_alloc_entry(chansess->pid, ses.authstate.username,
				ses.hostname, chansess->tty);
		login_logout(li);
		login_free_entry(li);

//BRCM commented next line
//      pty_release(chansess->tty);
		m_free(chansess->tty);
	}

#ifndef DISABLE_X11FWD
	x11cleanup(chansess);
#endif

#ifndef DISABLE_AGENTFWD
	agentcleanup(chansess);
#endif

	/* clear child pid entries */
	for (i = 0; i < ses.childpidsize; i++) {
		if (ses.childpids[i].chansess == chansess) {
			assert(ses.childpids[i].pid > 0);
			TRACE(("closing pid %d\n", ses.childpids[i].pid));
			TRACE(("exited = %d\n", chansess->exited));
			ses.childpids[i].pid = -1;
			ses.childpids[i].chansess = NULL;
		}
	}
				
	m_free(chansess);

	TRACE(("leave closechansess"));
}
Beispiel #4
0
/*
 * Records that the user has logged in.  I wish these parts of operating
 * systems were more standardized.
 */
void
record_login(pid_t pid, const char *tty, const char *user, uid_t uid,
    const char *host, struct sockaddr *addr, socklen_t addrlen)
{
	struct logininfo *li;

	/* save previous login details before writing new */
	store_lastlog_message(user, uid);

	li = login_alloc_entry(pid, user, host, tty);
	login_set_addr(li, addr, addrlen);
	login_login(li);
	login_free_entry(li);
}
Beispiel #5
0
int
testAPI()
{
	struct logininfo *li1;
	struct passwd *pw;
	struct hostent *he;
	struct sockaddr_in sa_in4;
	char cmdstring[256], stripline[8];
	char username[32];
#ifdef HAVE_TIME_H
	time_t t0, t1, t2, logintime, logouttime;
	char s_t0[64],s_t1[64],s_t2[64];
	char s_logintime[64], s_logouttime[64]; /* ctime() strings */
#endif

	printf("**\n** Testing the API...\n**\n");

	pw = getpwuid(getuid());
	strlcpy(username, pw->pw_name, sizeof(username));

	/* gethostname(hostname, sizeof(hostname)); */

	printf("login_alloc_entry test (no host info):\n");

	/* FIXME fake tty more effectively - this could upset some platforms */
	li1 = login_alloc_entry((int)getpid(), username, NULL, ttyname(0));
	strlcpy(li1->progname, "OpenSSH-logintest", sizeof(li1->progname));

	if (be_verbose)
		dump_logininfo(li1, "li1");

	printf("Setting host address info for 'localhost' (may call out):\n");
	if (! (he = gethostbyname("localhost"))) {
		printf("Couldn't set hostname(lookup failed)\n");
	} else {
		/* NOTE: this is messy, but typically a program wouldn't have to set
		 *  any of this, a sockaddr_in* would be already prepared */
		memcpy((void *)&(sa_in4.sin_addr), (void *)&(he->h_addr_list[0][0]),
		       sizeof(struct in_addr));
		login_set_addr(li1, (struct sockaddr *) &sa_in4, sizeof(sa_in4));
		strlcpy(li1->hostname, "localhost", sizeof(li1->hostname));
	}
	if (be_verbose)
		dump_logininfo(li1, "li1");

	if ((int)geteuid() != 0) {
		printf("NOT RUNNING LOGIN TESTS - you are not root!\n");
		return 1;
	}

	if (nologtest)
		return 1;

	line_stripname(stripline, li1->line, sizeof(stripline));

	printf("Performing an invalid login attempt (no type field)\n--\n");
	login_write(li1);
	printf("--\n(Should have written errors to stderr)\n");

#ifdef HAVE_TIME_H
	(void)time(&t0);
	strlcpy(s_t0, ctime(&t0), sizeof(s_t0));
	t1 = login_get_lastlog_time(getuid());
	strlcpy(s_t1, ctime(&t1), sizeof(s_t1));
	printf("Before logging in:\n\tcurrent time is %d - %s\t"
	       "lastlog time is %d - %s\n",
	       (int)t0, s_t0, (int)t1, s_t1);
#endif

	printf("Performing a login on line %s ", stripline);
#ifdef HAVE_TIME_H
	(void)time(&logintime);
	strlcpy(s_logintime, ctime(&logintime), sizeof(s_logintime));
	printf("at %d - %s", (int)logintime, s_logintime);
#endif
	printf("--\n");
	login_login(li1);

	snprintf(cmdstring, sizeof(cmdstring), "who | grep '%s '",
		 stripline);
	system(cmdstring);

	printf("--\nPausing for %d second(s)...\n", PAUSE_BEFORE_LOGOUT);
	sleep(PAUSE_BEFORE_LOGOUT);

	printf("Performing a logout ");
#ifdef HAVE_TIME_H
	(void)time(&logouttime);
	strlcpy(s_logouttime, ctime(&logouttime), sizeof(s_logouttime));
	printf("at %d - %s", (int)logouttime, s_logouttime);
#endif
	printf("\nThe root login shown above should be gone.\n"
	       "If the root login hasn't gone, but another user on the same\n"
	       "pty has, this is OK - we're hacking it here, and there\n"
	       "shouldn't be two users on one pty in reality...\n"
	       "-- ('who' output follows)\n");
	login_logout(li1);

	system(cmdstring);
	printf("-- ('who' output ends)\n");

#ifdef HAVE_TIME_H
	t2 = login_get_lastlog_time(getuid());
	strlcpy(s_t2, ctime(&t2), sizeof(s_t2));
	printf("After logging in, lastlog time is %d - %s\n", (int)t2, s_t2);
	if (t1 == t2)
		printf("The lastlog times before and after logging in are the "
		       "same.\nThis indicates that lastlog is ** NOT WORKING "
		       "CORRECTLY **\n");
	else if (t0 != t2)
		/* We can be off by a second or so, even when recording works fine.
		 * I'm not 100% sure why, but it's true. */
		printf("** The login time and the lastlog time differ.\n"
		       "** This indicates that lastlog is either recording the "
		       "wrong time,\n** or retrieving the wrong entry.\n"
		       "If it's off by less than %d second(s) "
		       "run the test again.\n", PAUSE_BEFORE_LOGOUT);
	else
		printf("lastlog agrees with the login time. This is a good thing.\n");

#endif

	printf("--\nThe output of 'last' shown next should have "
	       "an entry for root \n  on %s for the time shown above:\n--\n",
	       stripline);
	snprintf(cmdstring, sizeof(cmdstring), "last | grep '%s ' | head -3",
		 stripline);
	system(cmdstring);

	printf("--\nEnd of login test.\n");

	login_free_entry(li1);

	return 1;
} /* testAPI() */
Beispiel #6
0
/* Execute a command or shell within a pty environment, and set up
 * redirection as appropriate.
 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
static int ptycommand(struct Channel *channel, struct ChanSess *chansess) {

	pid_t pid;
	struct logininfo *li;

	TRACE(("enter ptycommand"));

	/* we already have a pty allocated */
	assert(chansess->master != -1 && chansess->tty != NULL);
	pid = fork();
	if (pid < 0)
		return DROPBEAR_FAILURE;

	if (pid == 0) {
		/* child */
		
		/* redirect stdin/stdout/stderr */
		close(chansess->master);

		pty_make_controlling_tty(&chansess->slave, chansess->tty);
		
		if ((dup2(chansess->slave, STDIN_FILENO) < 0) ||
			(dup2(chansess->slave, STDERR_FILENO) < 0) ||
			(dup2(chansess->slave, STDOUT_FILENO) < 0)) {
			TRACE(("leave ptycommand: error redirecting filedesc"));
			return DROPBEAR_FAILURE;
		}

		close(chansess->slave);

		/* write the utmp/wtmp login record - must be after changing the
		 * terminal used for stdout with the dup2 above */
		li= login_alloc_entry(getpid(), ses.authstate.username,
				ses.hostname, chansess->tty);
		login_login(li);
		login_free_entry(li);

		m_free(chansess->tty);

		execchild(chansess);
		/* not reached */

	} else {
		/* parent */
		TRACE(("continue ptycommand: parent"));
		chansess->pid = pid;

		/* add a child pid */
		addchildpid(chansess, pid);

		close(chansess->slave);
		channel->infd = chansess->master;
		channel->outfd = chansess->master;
		/* don't need to set stderr here */
		ses.maxfd = MAX(ses.maxfd, chansess->master);

		if (fcntl(chansess->master, F_SETFL, O_NONBLOCK) < 0) {
			dropbear_exit("Couldn't set nonblocking");
		}

	}

	TRACE(("leave ptycommand"));
	return DROPBEAR_SUCCESS;
}