/* This is called after switching to the user, and sets up the xauth * and environment variables. */ void x11setauth(struct ChanSess *chansess) { char display[20]; /* space for "localhost:12345.123" */ FILE * authprog = NULL; int val; if (chansess->x11listener == NULL) { return; } /* create the DISPLAY string */ val = snprintf(display, sizeof(display), "localhost:%d.%d", chansess->x11port - X11BASEPORT, chansess->x11screennum); if (val < 0 || val >= (int)sizeof(display)) { /* string was truncated */ return; } addnewvar("DISPLAY", display); /* create the xauth string */ val = snprintf(display, sizeof(display), "unix:%d.%d", chansess->x11port - X11BASEPORT, chansess->x11screennum); if (val < 0 || val >= (int)sizeof(display)) { /* string was truncated */ return; } /* popen is a nice function - code is strongly based on OpenSSH's */ authprog = popen(XAUTH_COMMAND, "w"); if (authprog) { fprintf(authprog, "add %s %s %s\n", display, chansess->x11authprot, chansess->x11authcookie); pclose(authprog); } else { fprintf(stderr, "Failed to run %s\n", XAUTH_COMMAND); } }
/* Clean up, drop to user privileges, set up the environment and execute * the command/shell. This function does not return. */ static void execchild(struct ChanSess *chansess) { // BRCM begin #ifndef SSHD_GENKEY char *argv[4]; char * usershell; char * baseshell; unsigned int i; /* wipe the hostkey */ sign_key_free(ses.opts->hostkey); /* overwrite the prng state */ seedrandom(); /* 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"); } } /* clear environment */ /* if we're debugging using valgrind etc, we need to keep the LD_PRELOAD * etc. This is hazardous, so should only be used for debugging. */ #ifndef DEBUG_KEEP_ENV #ifdef HAVE_CLEARENV clearenv(); #else /* don't HAVE_CLEARENV */ environ = (char**)m_malloc(ENV_SIZE * sizeof(char*)); environ[0] = NULL; #endif /* HAVE_CLEARENV */ #endif /* DEBUG_KEEP_ENV */ /* We can only change uid/gid as root ... */ if (getuid() == 0) { if ((setgid(ses.authstate.pw->pw_gid) < 0) || (initgroups(ses.authstate.pw->pw_name, ses.authstate.pw->pw_gid) < 0) || (setuid(ses.authstate.pw->pw_uid) < 0)) { dropbear_exit("error changing user"); } } else { /* ... but if the daemon is the same uid as the requested uid, we don't * need to */ /* XXX - there is a minor issue here, in that if there are multiple * usernames with the same uid, but differing groups, then the * differing groups won't be set (as with initgroups()). The solution * is for the sysadmin not to give out the UID twice */ if (getuid() != ses.authstate.pw->pw_uid) { dropbear_exit("couldn't change user as non-root"); } } /* set env vars */ addnewvar("USER", ses.authstate.pw->pw_name); addnewvar("LOGNAME", ses.authstate.pw->pw_name); addnewvar("HOME", ses.authstate.pw->pw_dir); addnewvar("SHELL", ses.authstate.pw->pw_shell); // BRCM next line dd this to have /sbin path addnewvar("PATH", "/bin:/sbin:/usr/bin"); if (chansess->term != NULL) { addnewvar("TERM", chansess->term); } /* change directory */ if (chdir(ses.authstate.pw->pw_dir) < 0) { dropbear_exit("error changing directory"); } #ifndef DISABLE_X11FWD /* set up X11 forwarding if enabled */ x11setauth(chansess); #endif #ifndef DISABLE_AGENTFWD /* set up agent env variable */ agentset(chansess); #endif /* an empty shell should be interpreted as "/bin/sh" */ if (ses.authstate.pw->pw_shell[0] == '\0') { usershell = "/bin/sh"; } else { usershell = ses.authstate.pw->pw_shell; } baseshell = basename(usershell); if (chansess->cmd != NULL) { argv[0] = baseshell; } else { /* a login shell should be "-bash" for "/bin/bash" etc */ argv[0] = (char*)m_malloc(strlen(baseshell) + 2); /* 2 for "-" */ strcpy(argv[0], "-"); strcat(argv[0], baseshell); } if (chansess->cmd != NULL) { argv[1] = "-c"; argv[2] = chansess->cmd; argv[3] = NULL; } else { /* construct a shell of the form "-bash" etc */ argv[1] = NULL; } // BRCM begin: // execv(ses.authstate.pw->pw_shell, argv); // printf("BCM96345 ADSL Router\n"); BcmCli_run(CLI_ACCESS_REMOTE_SSH); exit(0); // BRCM end /* only reached on error */ dropbear_exit("child failed"); #endif // BRCM end ifudef SSHD_GENKEY }