diff 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
line wrap: on
line diff
--- a/svr-chansession.c	Wed Feb 24 16:13:15 2010 +0000
+++ b/svr-chansession.c	Sat Feb 27 11:53:18 2010 +0000
@@ -222,6 +222,7 @@
 
 	chansess = (struct ChanSess*)m_malloc(sizeof(struct ChanSess));
 	chansess->cmd = NULL;
+	chansess->connection_string = NULL;
 	chansess->pid = 0;
 
 	/* pty details */
@@ -250,6 +251,14 @@
 
 }
 
+static struct logininfo* 
+chansess_login_alloc(struct ChanSess *chansess) {
+	struct logininfo * li;
+	li = login_alloc_entry(chansess->pid, ses.authstate.username,
+			svr_ses.remotehost, chansess->tty);
+	return li;
+}
+
 /* clean a session channel */
 static void closechansess(struct Channel *channel) {
 
@@ -273,8 +282,7 @@
 
 	if (chansess->tty) {
 		/* write the utmp/wtmp login record */
-		li = login_alloc_entry(chansess->pid, ses.authstate.username,
-				ses.remotehost, chansess->tty);
+		li = chansess_login_alloc(chansess);
 		login_logout(li);
 		login_free_entry(li);
 
@@ -287,7 +295,7 @@
 #endif
 
 #ifndef DISABLE_AGENTFWD
-	agentcleanup(chansess);
+	svr_agentcleanup(chansess);
 #endif
 
 	/* clear child pid entries */
@@ -346,7 +354,7 @@
 #endif
 #ifndef DISABLE_AGENTFWD
 	} else if (strcmp(type, "[email protected]") == 0) {
-		ret = agentreq(chansess);
+		ret = svr_agentreq(chansess);
 #endif
 	} else if (strcmp(type, "signal") == 0) {
 		ret = sessionsignal(chansess);
@@ -570,6 +578,21 @@
 	return DROPBEAR_SUCCESS;
 }
 
+static char* make_connection_string() {
+	char *local_ip, *local_port, *remote_ip, *remote_port;
+	size_t len;
+	char *ret;
+	get_socket_address(ses.sock_in, &local_ip, &local_port, &remote_ip, &remote_port, 0);
+	len = strlen(local_ip) + strlen(local_port) + strlen(remote_ip) + strlen(remote_port) + 4;
+	ret = m_malloc(len);
+	snprintf(ret, len, "%s %s %s %s", remote_ip, remote_port, local_ip, local_port);
+	m_free(local_ip);
+	m_free(local_port);
+	m_free(remote_ip);
+	m_free(remote_port);
+	return ret;
+}
+
 /* Handle a command request from the client. This is used for both shell
  * and command-execution requests, and passes the command to
  * noptycommand or ptycommand as appropriate.
@@ -589,9 +612,6 @@
 		return DROPBEAR_FAILURE;
 	}
 
-	/* take public key option 'command' into account */
-	svr_pubkey_set_forced_command(chansess);
-
 	if (iscmd) {
 		/* "exec" */
 		if (chansess->cmd == NULL) {
@@ -616,6 +636,9 @@
 			}
 		}
 	}
+	
+	/* take public key option 'command' into account */
+	svr_pubkey_set_forced_command(chansess);
 
 #ifdef LOG_COMMANDS
 	if (chansess->cmd) {
@@ -627,6 +650,12 @@
 	}
 #endif
 
+	/* uClinux will vfork(), so there'll be a race as 
+	connection_string is freed below. */
+#ifndef __uClinux__
+	chansess->connection_string = make_connection_string();
+#endif
+
 	if (chansess->term == NULL) {
 		/* no pty */
 		ret = noptycommand(channel, chansess);
@@ -635,6 +664,10 @@
 		ret = ptycommand(channel, chansess);
 	}
 
+#ifndef __uClinux__	
+	m_free(chansess->connection_string);
+#endif
+
 	if (ret == DROPBEAR_FAILURE) {
 		m_free(chansess->cmd);
 	}
@@ -736,13 +769,10 @@
 
 		/* 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.remotehost, chansess->tty);
+		li = chansess_login_alloc(chansess);
 		login_login(li);
 		login_free_entry(li);
 
-		m_free(chansess->tty);
-
 #ifdef DO_MOTD
 		if (svr_opts.domotd) {
 			/* don't show the motd if ~/.hushlogin exists */
@@ -883,6 +913,22 @@
 		addnewvar("TERM", chansess->term);
 	}
 
+	if (chansess->tty) {
+		addnewvar("SSH_TTY", chansess->tty);
+	}
+	
+	if (chansess->connection_string) {
+		addnewvar("SSH_CONNECTION", chansess->connection_string);
+	}
+	
+#ifdef ENABLE_SVR_PUBKEY_OPTIONS
+	if (ses.authstate.pubkey_options &&
+			ses.authstate.pubkey_options->original_command) {
+		addnewvar("SSH_ORIGINAL_COMMAND", 
+			ses.authstate.pubkey_options->original_command);
+	}
+#endif
+
 	/* change directory */
 	if (chdir(ses.authstate.pw_dir) < 0) {
 		dropbear_exit("error changing directory");
@@ -894,7 +940,7 @@
 #endif
 #ifndef DISABLE_AGENTFWD
 	/* set up agent env variable */
-	agentset(chansess);
+	svr_agentset(chansess);
 #endif
 
 	usershell = m_strdup(get_user_shell());