summaryrefslogtreecommitdiffhomepage
path: root/svr-chansession.c
diff options
context:
space:
mode:
Diffstat (limited to 'svr-chansession.c')
-rw-r--r--svr-chansession.c39
1 files changed, 31 insertions, 8 deletions
diff --git a/svr-chansession.c b/svr-chansession.c
index 5ddb8d4..b6544e6 100644
--- a/svr-chansession.c
+++ b/svr-chansession.c
@@ -89,6 +89,8 @@ static void sesssigchild_handler(int UNUSED(dummy)) {
TRACE(("enter sigchld handler"))
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
+
+ exit = NULL;
/* find the corresponding chansess */
for (i = 0; i < svr_ses.childpidsize; i++) {
if (svr_ses.childpids[i].pid == pid) {
@@ -100,7 +102,7 @@ static void sesssigchild_handler(int UNUSED(dummy)) {
/* If the pid wasn't matched, then we might have hit the race mentioned
* above. So we just store the info for the parent to deal with */
- if (i == svr_ses.childpidsize) {
+ if (exit == NULL) {
exit = &svr_ses.lastexit;
}
@@ -119,7 +121,6 @@ static void sesssigchild_handler(int UNUSED(dummy)) {
/* we use this to determine how pid exited */
exit->exitsignal = -1;
}
- exit = NULL;
}
@@ -410,7 +411,7 @@ static int sessionwinchange(struct ChanSess *chansess) {
pty_change_window_size(chansess->master, termr, termc, termw, termh);
- return DROPBEAR_FAILURE;
+ return DROPBEAR_SUCCESS;
}
static void get_termmodes(struct ChanSess *chansess) {
@@ -588,6 +589,16 @@ static int sessioncommand(struct Channel *channel, struct ChanSess *chansess,
}
}
+#ifdef LOG_COMMANDS
+ if (chansess->cmd) {
+ dropbear_log(LOG_INFO, "user %s executing '%s'",
+ ses.authstate.printableuser, chansess->cmd);
+ } else {
+ dropbear_log(LOG_INFO, "user %s executing login shell",
+ ses.authstate.printableuser);
+ }
+#endif
+
if (chansess->term == NULL) {
/* no pty */
ret = noptycommand(channel, chansess);
@@ -623,7 +634,12 @@ static int noptycommand(struct Channel *channel, struct ChanSess *chansess) {
if (pipe(errfds) != 0)
return DROPBEAR_FAILURE;
+#ifdef __uClinux__
+ pid = vfork();
+#else
pid = fork();
+#endif
+
if (pid < 0)
return DROPBEAR_FAILURE;
@@ -714,7 +730,11 @@ static int ptycommand(struct Channel *channel, struct ChanSess *chansess) {
return DROPBEAR_FAILURE;
}
+#ifdef __uClinux__
+ pid = vfork();
+#else
pid = fork();
+#endif
if (pid < 0)
return DROPBEAR_FAILURE;
@@ -810,7 +830,7 @@ static void addchildpid(struct ChanSess *chansess, pid_t pid) {
/* need to increase size */
if (i == svr_ses.childpidsize) {
svr_ses.childpids = (struct ChildPid*)m_realloc(svr_ses.childpids,
- sizeof(struct ChildPid) * svr_ses.childpidsize+1);
+ sizeof(struct ChildPid) * (svr_ses.childpidsize+1));
svr_ses.childpidsize++;
}
@@ -828,19 +848,21 @@ static void execchild(struct ChanSess *chansess) {
char * baseshell = NULL;
unsigned int i;
+ /* with uClinux we'll have vfork()ed, so don't want to overwrite the
+ * hostkey. can't think of a workaround to clear it */
+#ifndef __uClinux__
/* wipe the hostkey */
sign_key_free(svr_opts.hostkey);
svr_opts.hostkey = NULL;
/* overwrite the prng state */
- seedrandom();
+ reseedrandom();
+#endif
/* close file descriptors except stdin/stdout/stderr
* Need to be sure FDs are closed here to avoid reading files as root */
for (i = 3; i <= (unsigned int)ses.maxfd; i++) {
- if (m_close(i) == DROPBEAR_FAILURE) {
- dropbear_exit("Error closing file desc");
- }
+ m_close(i);
}
/* clear environment */
@@ -986,6 +1008,7 @@ void addnewvar(const char* param, const char* var) {
newvar[plen] = '=';
memcpy(&newvar[plen+1], var, vlen);
newvar[plen+vlen+1] = '\0';
+ /* newvar is leaked here, but that's part of putenv()'s semantics */
if (putenv(newvar) < 0) {
dropbear_exit("environ error");
}