int signkey_generate(enum signkey_type keytype, int bits, const char* filename) { sign_key * key = NULL; buffer *buf = NULL; int ret = DROPBEAR_FAILURE; if (bits == 0) { bits = get_default_bits(keytype); } /* now we can generate the key */ key = new_sign_key(); seedrandom(); switch(keytype) { #ifdef DROPBEAR_RSA case DROPBEAR_SIGNKEY_RSA: key->rsakey = gen_rsa_priv_key(bits); break; #endif #ifdef DROPBEAR_DSS case DROPBEAR_SIGNKEY_DSS: key->dsskey = gen_dss_priv_key(bits); break; #endif #ifdef DROPBEAR_ECDSA case DROPBEAR_SIGNKEY_ECDSA_KEYGEN: case DROPBEAR_SIGNKEY_ECDSA_NISTP521: case DROPBEAR_SIGNKEY_ECDSA_NISTP384: case DROPBEAR_SIGNKEY_ECDSA_NISTP256: { ecc_key *ecckey = gen_ecdsa_priv_key(bits); keytype = ecdsa_signkey_type(ecckey); *signkey_key_ptr(key, keytype) = ecckey; } break; #endif default: dropbear_exit("Internal error"); } seedrandom(); buf = buf_new(MAX_PRIVKEY_SIZE); buf_put_priv_key(buf, key, keytype); sign_key_free(key); key = NULL; buf_setpos(buf, 0); ret = buf_writefile(buf, filename); buf_burn(buf); buf_free(buf); buf = NULL; return ret; }
/* return len bytes of pseudo-random data */ void genrandom(unsigned char* buf, unsigned int len) { hash_state hs; unsigned char hash[SHA1_HASH_SIZE]; unsigned int copylen; if (!donerandinit) { dropbear_exit("seedrandom not done"); } while (len > 0) { sha1_init(&hs); sha1_process(&hs, (void*)hashpool, sizeof(hashpool)); sha1_process(&hs, (void*)&counter, sizeof(counter)); sha1_done(&hs, hash); counter++; if (counter > MAX_COUNTER) { seedrandom(); } copylen = MIN(len, SHA1_HASH_SIZE); memcpy(buf, hash, copylen); len -= copylen; buf += copylen; } m_burn(hash, sizeof(hash)); }
void cli_session(int sock_in, int sock_out) { seedrandom(); crypto_init(); common_session_init(sock_in, sock_out); chaninitialise(cli_chantypes); /* Set up cli_ses vars */ cli_session_init(); /* Ready to go */ sessinitdone = 1; /* Exchange identification */ session_identification(); send_msg_kexinit(); session_loop(cli_sessionloop); /* Not reached */ }
int dropbearconvert_main(int argc, char ** argv) { #else int main(int argc, char ** argv) { #endif int intype, outtype; const char* infile; const char* outfile; crypto_init(); seedrandom(); #if DEBUG_TRACE /* It's hard for it to get in the way _too_ much */ debug_trace = 1; #endif /* get the commandline options */ if (argc != 5) { fprintf(stderr, "All arguments must be specified\n"); goto usage; } /* input type */ if (argv[1][0] == 'd') { intype = KEYFILE_DROPBEAR; } else if (argv[1][0] == 'o') { intype = KEYFILE_OPENSSH; } else { fprintf(stderr, "Invalid input key type\n"); goto usage; } /* output type */ if (argv[2][0] == 'd') { outtype = KEYFILE_DROPBEAR; } else if (argv[2][0] == 'o') { outtype = KEYFILE_OPENSSH; } else { fprintf(stderr, "Invalid output key type\n"); goto usage; } /* we don't want output readable by others */ umask(077); infile = argv[3]; outfile = argv[4]; return do_convert(intype, infile, outtype, outfile); usage: printhelp(argv[0]); return 1; }
int cli_main(int argc, char ** argv) { #else int main(int argc, char ** argv) { #endif int sock_in, sock_out; struct dropbear_progress_connection *progress = NULL; _dropbear_exit = cli_dropbear_exit; _dropbear_log = cli_dropbear_log; disallow_core(); seedrandom(); crypto_init(); cli_getopts(argc, argv); #ifndef DISABLE_SYSLOG if (opts.usingsyslog) { startsyslog("dbclient"); } #endif TRACE(("user='******' host='%s' port='%s' bind_address='%s' bind_port='%s'", cli_opts.username, cli_opts.remotehost, cli_opts.remoteport, cli_opts.bind_address, cli_opts.bind_port)) if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) { dropbear_exit("signal() error"); } pid_t proxy_cmd_pid = 0; #if DROPBEAR_CLI_PROXYCMD if (cli_opts.proxycmd) { cli_proxy_cmd(&sock_in, &sock_out, &proxy_cmd_pid); m_free(cli_opts.proxycmd); if (signal(SIGINT, kill_proxy_sighandler) == SIG_ERR || signal(SIGTERM, kill_proxy_sighandler) == SIG_ERR || signal(SIGHUP, kill_proxy_sighandler) == SIG_ERR) { dropbear_exit("signal() error"); } } else #endif { progress = connect_remote(cli_opts.remotehost, cli_opts.remoteport, cli_connected, &ses, cli_opts.bind_address, cli_opts.bind_port); sock_in = sock_out = -1; } cli_session(sock_in, sock_out, progress, proxy_cmd_pid); /* not reached */ return -1; }
int cli_main(int argc, char ** argv) { #else int main(int argc, char ** argv) { #endif int sock_in, sock_out; char* error = NULL; _dropbear_exit = cli_dropbear_exit; _dropbear_log = cli_dropbear_log; disallow_core(); seedrandom(); crypto_init(); cli_getopts(argc, argv); TRACE(("user='******' host='%s' port='%s'", cli_opts.username, cli_opts.remotehost, cli_opts.remoteport)) if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) { dropbear_exit("signal() error"); } #ifdef ENABLE_CLI_PROXYCMD if (cli_opts.proxycmd) { cli_proxy_cmd(&sock_in, &sock_out); m_free(cli_opts.proxycmd); } else #endif { int sock = connect_remote(cli_opts.ipfamily, cli_opts.remotehost, cli_opts.remoteport, 0, &error); sock_in = sock_out = sock; if (cli_opts.wantpty) { set_sock_priority(sock, DROPBEAR_PRIO_LOWDELAY); } } if (sock_in < 0) { dropbear_exit("%s", error); } cli_session(sock_in, sock_out); /* not reached */ return -1; }
int cli_main(int argc, char ** argv) { #else int main(int argc, char ** argv) { #endif int sock_in, sock_out; struct dropbear_progress_connection *progress = NULL; _dropbear_exit = cli_dropbear_exit; _dropbear_log = cli_dropbear_log; disallow_core(); seedrandom(); crypto_init(); cli_getopts(argc, argv); TRACE(("user='******' host='%s' port='%s'", cli_opts.username, cli_opts.remotehost, cli_opts.remoteport)) if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) { dropbear_exit("signal() error"); } #ifdef ENABLE_CLI_PROXYCMD if (cli_opts.proxycmd) { cli_proxy_cmd(&sock_in, &sock_out); m_free(cli_opts.proxycmd); } else #endif { progress = connect_remote(cli_opts.ipfamily, cli_opts.remotehost, cli_opts.remoteport, cli_connected, &ses); sock_in = sock_out = -1; } cli_session(sock_in, sock_out, progress); /* not reached */ return -1; }
dss_key * gen_dss_priv_key(unsigned int size) { dss_key *key; key = (dss_key*)m_malloc(sizeof(dss_key)); key->p = (mp_int*)m_malloc(sizeof(mp_int)); key->q = (mp_int*)m_malloc(sizeof(mp_int)); key->g = (mp_int*)m_malloc(sizeof(mp_int)); key->y = (mp_int*)m_malloc(sizeof(mp_int)); key->x = (mp_int*)m_malloc(sizeof(mp_int)); m_mp_init_multi(key->p, key->q, key->g, key->y, key->x, NULL); seedrandom(); getq(key); getp(key, size); getg(key); getx(key); gety(key); return key; }
void child_session(int sock, runopts *opts, int childpipe, struct sockaddr *remoteaddr) { fd_set readfd, writefd; struct timeval timeout; int val; crypto_init(); session_init(sock, opts, childpipe, remoteaddr); /* exchange identification, version etc */ session_identification(); seedrandom(); /* start off with key exchange */ send_msg_kexinit(); FD_ZERO(&readfd); FD_ZERO(&writefd); /* main loop, select()s for all sockets in use */ for(;;) { timeout.tv_sec = SELECT_TIMEOUT; timeout.tv_usec = 0; FD_ZERO(&writefd); FD_ZERO(&readfd); assert(ses.payload == NULL); if (ses.sock != -1) { FD_SET(ses.sock, &readfd); if (!isempty(&ses.writequeue)) { FD_SET(ses.sock, &writefd); } } /* set up for channels which require reading/writing */ if (ses.dataallowed) { setchannelfds(&readfd, &writefd); } val = select(ses.maxfd+1, &readfd, &writefd, NULL, &timeout); if (exitflag) { dropbear_exit("Terminated by signal"); } if (val < 0) { if (errno == EINTR) { continue; } else { dropbear_exit("Error in select"); } } /* check for auth timeout, rekeying required etc */ checktimeouts(); if (val == 0) { /* timeout */ TRACE(("select timeout")); continue; } /* process session socket's incoming/outgoing data */ if (ses.sock != -1) { if (FD_ISSET(ses.sock, &writefd) && !isempty(&ses.writequeue)) { write_packet(); } if (FD_ISSET(ses.sock, &readfd)) { read_packet(); } /* Process the decrypted packet. After this, the read buffer * will be ready for a new packet */ if (ses.payload != NULL) { process_packet(); } } /* process pipes etc for the channels, ses.dataallowed == 0 * during rekeying ) */ if (ses.dataallowed) { channelio(&readfd, &writefd); } } /* for(;;) */ }
int main(int argc, char **argv) { int i, len, controlfd; double eval, clk; long long ncycles_ref, counter; double eptime; double add_delay; struct cfg cf; char buf[256]; struct recfilter loop_error; struct PFD phase_detector; useconds_t usleep_time; struct sched_param sparam; #if RTPP_DEBUG double sleep_time, filter_lastval; #endif memset(&cf, 0, sizeof(cf)); cf.stable = malloc(sizeof(struct rtpp_cfg_stable)); if (cf.stable == NULL) { err(1, "can't allocate memory for the struct rtpp_cfg_stable"); /* NOTREACHED */ } memset(cf.stable, '\0', sizeof(struct rtpp_cfg_stable)); init_config(&cf, argc, argv); seedrandom(); cf.stable->sessions_ht = rtpp_hash_table_ctor(); if (cf.stable->sessions_ht == NULL) { err(1, "can't allocate memory for the hash table"); /* NOTREACHED */ } cf.stable->rtpp_stats = rtpp_stats_ctor(); if (cf.stable->rtpp_stats == NULL) { err(1, "can't allocate memory for the stats data"); /* NOTREACHED */ } init_port_table(&cf); controlfd = init_controlfd(&cf); if (cf.stable->nodaemon == 0) { if (rtpp_daemon(0, 0) == -1) err(1, "can't switch into daemon mode"); /* NOTREACHED */ } if (rtpp_notify_init() != 0) errx(1, "can't start notification thread"); cf.stable->glog = rtpp_log_open(cf.stable, "rtpproxy", NULL, LF_REOPEN); rtpp_log_setlevel(cf.stable->glog, cf.stable->log_level); _sig_cf = &cf; atexit(ehandler); rtpp_log_write(RTPP_LOG_INFO, cf.stable->glog, "rtpproxy started, pid %d", getpid()); i = open(pid_file, O_WRONLY | O_CREAT | O_TRUNC, DEFFILEMODE); if (i >= 0) { len = sprintf(buf, "%u\n", (unsigned int)getpid()); write(i, buf, len); close(i); } else { rtpp_log_ewrite(RTPP_LOG_ERR, cf.stable->glog, "can't open pidfile for writing"); } signal(SIGHUP, sighup); signal(SIGINT, fatsignal); signal(SIGKILL, fatsignal); signal(SIGPIPE, SIG_IGN); signal(SIGTERM, fatsignal); signal(SIGXCPU, fatsignal); signal(SIGXFSZ, fatsignal); signal(SIGVTALRM, fatsignal); signal(SIGPROF, fatsignal); signal(SIGUSR1, fatsignal); signal(SIGUSR2, fatsignal); if (cf.stable->sched_policy != SCHED_OTHER) { sparam.sched_priority = sched_get_priority_max(cf.stable->sched_policy); if (sched_setscheduler(0, cf.stable->sched_policy, &sparam) == -1) { rtpp_log_ewrite(RTPP_LOG_ERR, cf.stable->glog, "sched_setscheduler(SCHED_%s, %d)", (cf.stable->sched_policy == SCHED_FIFO) ? "FIFO" : "RR", sparam.sched_priority); } } if (cf.stable->run_uname != NULL || cf.stable->run_gname != NULL) { if (drop_privileges(&cf) != 0) { rtpp_log_ewrite(RTPP_LOG_ERR, cf.stable->glog, "can't switch to requested user/group"); exit(1); } } set_rlimits(&cf); cf.stable->controlfd = controlfd; cf.sessinfo.sessions[0] = NULL; cf.sessinfo.nsessions = 0; cf.rtp_nsessions = 0; rtpp_command_async_init(&cf); rtpp_proc_async_init(&cf); counter = 0; recfilter_init(&loop_error, 0.96, 0.0, 0); PFD_init(&phase_detector, 2.0); for (;;) { eptime = getdtime(); clk = (eptime + cf.stable->sched_offset) * cf.stable->target_pfreq; ncycles_ref = llrint(clk); eval = PFD_get_error(&phase_detector, clk); #if RTPP_DEBUG filter_lastval = loop_error.lastval; #endif if (eval != 0.0) { recfilter_apply(&loop_error, sigmoid(eval)); } #if RTPP_DEBUG if (counter % (unsigned int)cf.stable->target_pfreq == 0 || counter < 1000) { rtpp_log_write(RTPP_LOG_DBUG, cf.stable->glog, "run %lld ncycles %f raw error1 %f, filter lastval %f, filter nextval %f", counter, clk, eval, filter_lastval, loop_error.lastval); } #endif add_delay = freqoff_to_period(cf.stable->target_pfreq, 1.0, loop_error.lastval); usleep_time = add_delay * 1000000.0; #if RTPP_DEBUG if (counter % (unsigned int)cf.stable->target_pfreq == 0 || counter < 1000) { rtpp_log_write(RTPP_LOG_DBUG, cf.stable->glog, "run %lld filter lastval %f, filter nextval %f, error %f", counter, filter_lastval, loop_error.lastval, sigmoid(eval)); rtpp_log_write(RTPP_LOG_DBUG, cf.stable->glog, "run %lld extra sleeping time %llu", counter, usleep_time); } sleep_time = getdtime(); #endif rtpp_proc_async_wakeup(cf.stable->rtpp_proc_cf, counter, ncycles_ref); usleep(usleep_time); #if RTPP_DEBUG sleep_time = getdtime() - sleep_time; if (counter % (unsigned int)cf.stable->target_pfreq == 0 || counter < 1000 || sleep_time > add_delay * 2.0) { rtpp_log_write(RTPP_LOG_DBUG, cf.stable->glog, "run %lld sleeping time required %llu sleeping time actual %f, CSV: %f,%f,%f", \ counter, usleep_time, sleep_time, (double)counter / cf.stable->target_pfreq, ((double)usleep_time) / 1000.0, sleep_time * 1000.0); } #endif counter += 1; if (cf.stable->slowshutdown != 0) { pthread_mutex_lock(&cf.sessinfo.lock); if (cf.sessinfo.nsessions == 0) { /* The below unlock is not necessary, but does not hurt either */ pthread_mutex_unlock(&cf.sessinfo.lock); rtpp_log_write(RTPP_LOG_INFO, cf.stable->glog, "deorbiting-burn sequence completed, exiting"); break; } pthread_mutex_unlock(&cf.sessinfo.lock); } } exit(0); }
int main(int argc, char **argv) { int i, len, timeout, controlfd, alarm_tick; double sptime, eptime, last_tick_time; unsigned long delay; struct cfg cf; char buf[256]; memset(&cf, 0, sizeof(cf)); init_config(&cf, argc, argv); seedrandom(); init_hash_table(&cf.stable); init_port_table(&cf); controlfd = init_controlfd(&cf); if (cf.stable.nodaemon == 0) { if (rtpp_daemon(0, 0) == -1) err(1, "can't switch into daemon mode"); /* NOTREACHED */ } glog = cf.stable.glog = rtpp_log_open(&cf.stable, "rtpproxy", NULL, LF_REOPEN); atexit(ehandler); rtpp_log_write(RTPP_LOG_INFO, cf.stable.glog, "rtpproxy started, pid %d", getpid()); if (cf.timeout_socket != NULL) { cf.timeout_handler = rtpp_notify_init(glog, cf.timeout_socket); if (cf.timeout_handler == NULL) { rtpp_log_ewrite(RTPP_LOG_ERR, glog, "can't start notification thread"); exit(1); } } i = open(pid_file, O_WRONLY | O_CREAT | O_TRUNC, DEFFILEMODE); if (i >= 0) { len = sprintf(buf, "%u\n", (unsigned int)getpid()); write(i, buf, len); close(i); } else { rtpp_log_ewrite(RTPP_LOG_ERR, cf.stable.glog, "can't open pidfile for writing"); } signal(SIGHUP, fatsignal); signal(SIGINT, fatsignal); signal(SIGKILL, fatsignal); signal(SIGPIPE, SIG_IGN); signal(SIGTERM, fatsignal); signal(SIGXCPU, fatsignal); signal(SIGXFSZ, fatsignal); signal(SIGVTALRM, fatsignal); signal(SIGPROF, fatsignal); signal(SIGUSR1, fatsignal); signal(SIGUSR2, fatsignal); if (cf.stable.run_uname != NULL || cf.stable.run_gname != NULL) { if (drop_privileges(&cf) != 0) { rtpp_log_ewrite(RTPP_LOG_ERR, cf.stable.glog, "can't switch to requested user/group"); exit(1); } } cf.stable.controlfd = controlfd; cf.sessinfo.sessions[0] = NULL; cf.sessinfo.nsessions = 0; cf.rtp_nsessions = 0; rtpp_command_async_init(&cf); sptime = 0; last_tick_time = 0; for (;;) { pthread_mutex_lock(&cf.glock); pthread_mutex_lock(&cf.sessinfo.lock); if (cf.rtp_nsessions > 0 || cf.sessinfo.nsessions > 0) { timeout = RTPS_TICKS_MIN; } else { timeout = TIMETICK * 1000; } pthread_mutex_unlock(&cf.sessinfo.lock); pthread_mutex_unlock(&cf.glock); eptime = getdtime(); delay = (eptime - sptime) * 1000000.0; if (delay < (1000000 / POLL_LIMIT)) { usleep((1000000 / POLL_LIMIT) - delay); sptime = getdtime(); } else { sptime = eptime; } pthread_mutex_lock(&cf.sessinfo.lock); if (cf.sessinfo.nsessions > 0) { i = poll(cf.sessinfo.pfds, cf.sessinfo.nsessions, timeout); pthread_mutex_unlock(&cf.sessinfo.lock); if (i < 0 && errno == EINTR) continue; } else { pthread_mutex_unlock(&cf.sessinfo.lock); usleep(timeout * 1000); } eptime = getdtime(); pthread_mutex_lock(&cf.glock); if (cf.rtp_nsessions > 0) { process_rtp_servers(&cf, eptime); } pthread_mutex_unlock(&cf.glock); if (eptime > last_tick_time + TIMETICK) { alarm_tick = 1; last_tick_time = eptime; } else { alarm_tick = 0; } pthread_mutex_lock(&cf.glock); process_rtp(&cf, eptime, alarm_tick); pthread_mutex_unlock(&cf.glock); } exit(0); }
/* if skip_exist is set it will silently return if the key file exists */ int signkey_generate(enum signkey_type keytype, int bits, const char* filename, int skip_exist) { sign_key * key = NULL; buffer *buf = NULL; char *fn_temp = NULL; int ret = DROPBEAR_FAILURE; bits = signkey_generate_get_bits(keytype, bits); /* now we can generate the key */ key = new_sign_key(); seedrandom(); switch(keytype) { #if DROPBEAR_RSA case DROPBEAR_SIGNKEY_RSA: key->rsakey = gen_rsa_priv_key(bits); break; #endif #if DROPBEAR_DSS case DROPBEAR_SIGNKEY_DSS: key->dsskey = gen_dss_priv_key(bits); break; #endif #if DROPBEAR_ECDSA case DROPBEAR_SIGNKEY_ECDSA_KEYGEN: case DROPBEAR_SIGNKEY_ECDSA_NISTP521: case DROPBEAR_SIGNKEY_ECDSA_NISTP384: case DROPBEAR_SIGNKEY_ECDSA_NISTP256: { ecc_key *ecckey = gen_ecdsa_priv_key(bits); keytype = ecdsa_signkey_type(ecckey); *signkey_key_ptr(key, keytype) = ecckey; } break; #endif default: dropbear_exit("Internal error"); } seedrandom(); buf = buf_new(MAX_PRIVKEY_SIZE); buf_put_priv_key(buf, key, keytype); sign_key_free(key); key = NULL; buf_setpos(buf, 0); fn_temp = m_malloc(strlen(filename) + 30); snprintf(fn_temp, strlen(filename)+30, "%s.tmp%d", filename, getpid()); ret = buf_writefile(buf, fn_temp); if (ret == DROPBEAR_FAILURE) { goto out; } if (link(fn_temp, filename) < 0) { /* If generating keys on connection (skipexist) it's OK to get EEXIST - we probably just lost a race with another connection to generate the key */ if (!(skip_exist && errno == EEXIST)) { dropbear_log(LOG_ERR, "Failed moving key file to %s: %s", filename, strerror(errno)); /* XXX fallback to non-atomic copy for some filesystems? */ ret = DROPBEAR_FAILURE; goto out; } } out: if (buf) { buf_burn(buf); buf_free(buf); } if (fn_temp) { unlink(fn_temp); m_free(fn_temp); } return ret; }
/* 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 }
int dropbearkey_main(int argc, char ** argv) { #else int main(int argc, char ** argv) { #endif int i; char ** next = NULL; char * filename = NULL; enum signkey_type keytype = DROPBEAR_SIGNKEY_NONE; char * typetext = NULL; char * sizetext = NULL; unsigned int bits = 0; int printpub = 0; crypto_init(); seedrandom(); /* get the commandline options */ for (i = 1; i < argc; i++) { if (argv[i] == NULL) { continue; /* Whack */ } if (next) { *next = argv[i]; next = NULL; continue; } if (argv[i][0] == '-') { switch (argv[i][1]) { case 'f': next = &filename; break; case 't': next = &typetext; break; case 's': next = &sizetext; break; case 'y': printpub = 1; break; case 'h': printhelp(argv[0]); exit(EXIT_SUCCESS); break; #if DEBUG_TRACE case 'v': debug_trace = 1; break; #endif default: fprintf(stderr, "Unknown argument %s\n", argv[i]); printhelp(argv[0]); exit(EXIT_FAILURE); break; } } } if (!filename) { fprintf(stderr, "Must specify a key filename\n"); printhelp(argv[0]); exit(EXIT_FAILURE); } if (printpub) { int ret = printpubfile(filename); exit(ret); } /* check/parse args */ if (!typetext) { fprintf(stderr, "Must specify key type\n"); printhelp(argv[0]); exit(EXIT_FAILURE); } #if DROPBEAR_RSA if (strcmp(typetext, "rsa") == 0) { keytype = DROPBEAR_SIGNKEY_RSA; } #endif #if DROPBEAR_DSS if (strcmp(typetext, "dss") == 0) { keytype = DROPBEAR_SIGNKEY_DSS; } #endif #if DROPBEAR_ECDSA if (strcmp(typetext, "ecdsa") == 0) { keytype = DROPBEAR_SIGNKEY_ECDSA_KEYGEN; } #endif if (keytype == DROPBEAR_SIGNKEY_NONE) { fprintf(stderr, "Unknown key type '%s'\n", typetext); printhelp(argv[0]); exit(EXIT_FAILURE); } if (sizetext) { if (sscanf(sizetext, "%u", &bits) != 1) { fprintf(stderr, "Bits must be an integer\n"); exit(EXIT_FAILURE); } check_signkey_bits(keytype, bits);; } fprintf(stderr, "Generating key, this may take a while...\n"); if (signkey_generate(keytype, bits, filename, 0) == DROPBEAR_FAILURE) { dropbear_exit("Failed to generate key.\n"); } printpubfile(filename); return EXIT_SUCCESS; }
static int gettemp(char *path, apr_file_t **doopen, apr_int32_t flags, apr_pool_t *p) { register char *start, *trv, *suffp; char *pad; apr_finfo_t sbuf; apr_status_t rv; apr_uint32_t randnum; if (randseed==0) { randseed = (int)apr_time_now(); seedrandom(randseed); } for (trv = path; *trv; ++trv) ; suffp = trv; --trv; if (trv < path) { return APR_EINVAL; } /* Fill space with random characters */ while (*trv == 'X') { randnum = arc4random() % (sizeof(padchar) - 1); *trv-- = padchar[randnum]; } start = trv + 1; /* * check the target directory. */ for (;; --trv) { if (trv <= path) break; if (*trv == '/') { *trv = '\0'; rv = apr_stat(&sbuf, path, APR_FINFO_TYPE, p); *trv = '/'; if (rv != APR_SUCCESS) return rv; if (sbuf.filetype != APR_DIR) { return APR_ENOTDIR; } break; } } for (;;) { if ((rv = apr_file_open(doopen, path, flags, APR_UREAD | APR_UWRITE, p)) == APR_SUCCESS) return APR_SUCCESS; if (!APR_STATUS_IS_EEXIST(rv)) return rv; /* If we have a collision, cycle through the space of filenames */ for (trv = start;;) { if (*trv == '\0' || trv == suffp) return APR_EINVAL; /* XXX: is this the correct return code? */ pad = strchr((char *)padchar, *trv); if (pad == NULL || !*++pad) { *trv++ = padchar[0]; } else { *trv++ = *pad; break; } } } /*NOTREACHED*/ }