static void ccn_publish_client_mountpoint() { dropbear_log(LOG_WARNING,"Enter ccn_publish_client_mountpoint"); int result; struct ccn_charbuf *mountpoint; char client_id_str[6]; char *client_name_str = NULL; mountpoint = ccn_charbuf_create(); if( mountpoint == NULL ) dropbear_exit("Failed to allocate client mountpoint charbuf"); client_name_str = strdup((const char*)cli_opts.ccnxdomain); strcat(client_name_str,"/ssh/"); sprintf(client_id_str,"%6d",rand()); strcat(client_name_str,client_id_str); cli_opts.ccnxdomain = client_name_str; result = ccn_name_from_uri(mountpoint,cli_opts.ccnxdomain); if( result < 0 ) dropbear_exit("Can't resolve client domain"); dropbear_log(LOG_WARNING,"Listening at"); print_ccnb_charbuf(mountpoint); result = ccn_set_interest_filter(cli_opts.ssh_ccn,mountpoint,&newServerAction); }
/* This is a slightly modification of code in OpenBSD's login.c */ static int utmp_write_direct(struct logininfo *li, struct utmp *ut) { return 1; #if 0 struct utmp old_ut; register int fd; int tty; /* FIXME: (ATL) ttyslot() needs local implementation */ #if defined(HAVE_GETTTYENT) register struct ttyent *ty; tty=0; setttyent(); while ((struct ttyent *)0 != (ty = getttyent())) { tty++; if (!strncmp(ty->ty_name, ut->ut_line, sizeof(ut->ut_line))) break; } endttyent(); if((struct ttyent *)0 == ty) { dropbear_log(LOG_WARNING, "utmp_write_entry: tty not found"); return(1); } #else /* FIXME */ tty = ttyslot(); /* seems only to work for /dev/ttyp? style names */ #endif /* HAVE_GETTTYENT */ if (tty > 0 && (fd = open(UTMP_FILE, O_RDWR|O_CREAT, 0644)) >= 0) { (void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET); /* * Prevent luser from zero'ing out ut_host. * If the new ut_line is empty but the old one is not * and ut_line and ut_name match, preserve the old ut_line. */ if (atomicio(read, fd, &old_ut, sizeof(old_ut)) == sizeof(old_ut) && (ut->ut_host[0] == '\0') && (old_ut.ut_host[0] != '\0') && (strncmp(old_ut.ut_line, ut->ut_line, sizeof(ut->ut_line)) == 0) && (strncmp(old_ut.ut_name, ut->ut_name, sizeof(ut->ut_name)) == 0)) { (void)memcpy(ut->ut_host, old_ut.ut_host, sizeof(ut->ut_host)); } (void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET); if (atomicio(write, fd, ut, sizeof(*ut)) != sizeof(*ut)) dropbear_log(LOG_WARNING, "utmp_write_direct: error writing %s: %s", UTMP_FILE, strerror(errno)); (void)close(fd); return 1; } else { return 0; } #endif }
/* Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ static int buf_writefile(buffer * buf, const char * filename) { int ret = DROPBEAR_FAILURE; int fd = -1; fd = open(filename, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); if (fd < 0) { dropbear_log(LOG_ERR, "Couldn't create new file %s: %s", filename, strerror(errno)); goto out; } /* write the file now */ while (buf->pos != buf->len) { int len = write(fd, buf_getptr(buf, buf->len - buf->pos), buf->len - buf->pos); if (errno == EINTR) { continue; } if (len <= 0) { dropbear_log(LOG_ERR, "Failed writing file %s: %s", filename, strerror(errno)); goto out; } buf_incrpos(buf, len); } ret = DROPBEAR_SUCCESS; out: if (fd >= 0) { m_close(fd); } return ret; }
void pty_setowner(struct passwd *pw, const char *tty_name) { struct group *grp; gid_t gid; mode_t mode; struct stat st; /* Determine the group to make the owner of the tty. */ grp = getgrnam("tty"); if (grp) { gid = grp->gr_gid; mode = S_IRUSR | S_IWUSR | S_IWGRP; } else { gid = pw->pw_gid; mode = S_IRUSR | S_IWUSR | S_IWGRP | S_IWOTH; } /* * Change owner and mode of the tty as required. * Warn but continue if filesystem is read-only and the uids match/ * tty is owned by root. */ if (stat(tty_name, &st)) { dropbear_exit("pty_setowner: stat(%.101s) failed: %.100s", tty_name, strerror(errno)); } if (st.st_uid != pw->pw_uid || st.st_gid != gid) { if (chown(tty_name, pw->pw_uid, gid) < 0) { if (errno == EROFS && (st.st_uid == pw->pw_uid || st.st_uid == 0)) { dropbear_log(LOG_ERR, "chown(%.100s, %u, %u) failed: %.100s", tty_name, (unsigned int)pw->pw_uid, (unsigned int)gid, strerror(errno)); } else { dropbear_exit("chown(%.100s, %u, %u) failed: %.100s", tty_name, (unsigned int)pw->pw_uid, (unsigned int)gid, strerror(errno)); } } } if ((st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) != mode) { if (chmod(tty_name, mode) < 0) { if (errno == EROFS && (st.st_mode & (S_IRGRP | S_IROTH)) == 0) { dropbear_log(LOG_ERR, "chmod(%.100s, 0%o) failed: %.100s", tty_name, mode, strerror(errno)); } else { dropbear_exit("chmod(%.100s, 0%o) failed: %.100s", tty_name, mode, strerror(errno)); } } } }
/* Process a password auth request, sending success or failure messages as * appropriate */ void svr_auth_password() { char * passwdcrypt = NULL; /* the crypt from /etc/passwd or /etc/shadow */ char * testcrypt = NULL; /* crypt generated from the user's password sent */ unsigned char * password; unsigned int passwordlen; unsigned int changepw; passwdcrypt = ses.authstate.pw_passwd; #ifdef DEBUG_HACKCRYPT /* debugging crypt for non-root testing with shadows */ passwdcrypt = DEBUG_HACKCRYPT; #endif /* check if client wants to change password */ changepw = buf_getbool(ses.payload); if (changepw) { /* not implemented by this server */ send_msg_userauth_failure(0, 1); return; } password = buf_getstring(ses.payload, &passwordlen); /* the first bytes of passwdcrypt are the salt */ testcrypt = crypt((char*)password, passwdcrypt); m_burn(password, passwordlen); m_free(password); /* check for empty password */ if (passwdcrypt[0] == '\0') { dropbear_log(LOG_WARNING, "User '%s' has blank password, rejected", ses.authstate.pw_name); send_msg_userauth_failure(0, 1); return; } if (strcmp(testcrypt, passwdcrypt) == 0) { /* successful authentication */ dropbear_log(LOG_NOTICE, "Password auth succeeded for '%s' from %s", ses.authstate.pw_name, svr_ses.addrstring); send_msg_userauth_success(); } else { dropbear_log(LOG_WARNING, "Bad password attempt for '%s' from %s", ses.authstate.pw_name, svr_ses.addrstring); send_msg_userauth_failure(0, 1); } }
void ccn_ssh_connect(char *remote_name_str) { dropbear_log(LOG_WARNING,"Enter ccn_ssh_connect"); int result; struct ccn_charbuf *remote_name; /* struct ccn_pkey *server_pkey; void *encrypted_local_name; size_t encrypted_local_name_length; */ struct ccn_charbuf *connect_template; remote_name = ccn_charbuf_create(); result = ccn_name_from_uri(remote_name,remote_name_str); if( result < 0 ) dropbear_exit("Could not parse server uri"); ccn_name_append_str(remote_name,"ssh"); ccn_name_append_str(remote_name,"client"); /* server_pkey = ssh_ccn_retrieve_public_key( cli_opts.ssh_ccn, cli_opts.remote_name_str, cli_opts.ccn_cached_keystore); if( server_pkey == NULL ) dropbear_exit("Could not get server public key"); result = ccn_pubkey_encrypt(server_pkey, cli_opts.ccnxdomain, strlen(cli_opts.ccnxdomain), &encrypted_local_name, &encrypted_local_name_length); ccn_name_append(remote_name,encrypted_local_name); */ ccn_name_append(remote_name,cli_opts.ccnxdomain,strlen(cli_opts.ccnxdomain)); dropbear_log(LOG_WARNING,"Connecting to remote:"); print_ccnb_charbuf(remote_name); connect_template = make_connect_template(); result = ccn_express_interest(cli_opts.ssh_ccn, remote_name, &newServerAction, connect_template); if( result < 0 ) dropbear_exit("Failed to express interest to server"); }
void pty_release(const char *tty_name) { if (chown(tty_name, (uid_t) 0, (gid_t) 0) < 0 && (errno != ENOENT)) { dropbear_log(LOG_ERR, "chown %.100s 0 0 failed: %.100s", tty_name, strerror(errno)); } if (chmod(tty_name, (mode_t) 0666) < 0 && (errno != ENOENT)) { dropbear_log(LOG_ERR, "chmod %.100s 0666 failed: %.100s", tty_name, strerror(errno)); } }
static void cli_dropbear_exit(int exitcode, const char* format, va_list param) { char fmtbuf[300]; char exitmsg[500]; if (!sessinitdone) { snprintf(fmtbuf, sizeof(fmtbuf), "Exited: %s", format); } else { snprintf(fmtbuf, sizeof(fmtbuf), "Connection to %s@%s:%s exited: %s", cli_opts.username, cli_opts.remotehost, cli_opts.remoteport, format); } /* Arguments to the exit printout may be unsafe to use after session_cleanup() */ vsnprintf(exitmsg, sizeof(exitmsg), fmtbuf, param); /* Do the cleanup first, since then the terminal will be reset */ session_cleanup(); /* Avoid printing onwards from terminal cruft */ fprintf(stderr, "\n"); dropbear_log(LOG_INFO, "%s", exitmsg);; exit(exitcode); }
static void cli_dropbear_exit(int exitcode, const char* format, va_list param) { char exitmsg[150]; char fullmsg[300]; /* Note that exit message must be rendered before session cleanup */ /* Render the formatted exit message */ vsnprintf(exitmsg, sizeof(exitmsg), format, param); /* Add the prefix depending on session/auth state */ if (!sessinitdone) { snprintf(fullmsg, sizeof(fullmsg), "Exited: %s", exitmsg); } else { snprintf(fullmsg, sizeof(fullmsg), "Connection to %s@%s:%s exited: %s", cli_opts.username, cli_opts.remotehost, cli_opts.remoteport, exitmsg); } /* Do the cleanup first, since then the terminal will be reset */ session_cleanup(); /* Avoid printing onwards from terminal cruft */ fprintf(stderr, "\n"); dropbear_log(LOG_INFO, "%s", fullmsg); exit(exitcode); }
/** ** login_write: Call low-level recording functions based on autoconf ** results **/ int login_write (struct logininfo *li) { #ifndef HAVE_CYGWIN if ((int)geteuid() != 0) { dropbear_log(LOG_WARNING, "Attempt to write login records by non-root user (aborting)"); return 1; } #endif /* set the timestamp */ login_set_current_time(li); #ifdef USE_LOGIN syslogin_write_entry(li); #endif #ifdef USE_LASTLOG if (li->type == LTYPE_LOGIN) { lastlog_write_entry(li); } #endif #ifdef USE_UTMP utmp_write_entry(li); #endif #ifdef USE_WTMP wtmp_write_entry(li); #endif #ifdef USE_UTMPX utmpx_write_entry(li); #endif #ifdef USE_WTMPX wtmpx_write_entry(li); #endif return 0; }
/* returns the port bound to, or -1 on failure. * Will attempt to bind to a port X11BINDBASE (6010 usually) or upwards */ static int bindport(int fd) { struct sockaddr_in addr; uint16_t port; memset((void*)&addr, 0x0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); /* if we can't find one in 2000 ports free, something's wrong */ for (port = X11BINDBASE; port < X11BINDBASE + 2000; port++) { addr.sin_port = htons(port); if (bind(fd, (struct sockaddr*)&addr, sizeof(struct sockaddr_in)) == 0) { /* success */ return port; } if (errno == EADDRINUSE) { /* try the next port */ continue; } /* otherwise it was an error we don't know about */ dropbear_log(LOG_DEBUG, "Failed to bind x11 socket"); break; } return -1; }
static int newtcpforwarded(struct Channel * channel) { char *origaddr = NULL; unsigned int origport; m_list_elem * iter = NULL; struct TCPFwdEntry *fwd; char portstring[NI_MAXSERV]; int err = SSH_OPEN_ADMINISTRATIVELY_PROHIBITED; origaddr = buf_getstring(ses.payload, NULL); origport = buf_getint(ses.payload); /* Find which port corresponds. First try and match address as well as port, in case they want to forward different ports separately ... */ for (iter = cli_opts.remotefwds->first; iter; iter = iter->next) { fwd = (struct TCPFwdEntry*)iter->item; if (origport == fwd->listenport && strcmp(origaddr, fwd->listenaddr) == 0) { break; } } if (!iter) { /* ... otherwise try to generically match the only forwarded port without address (also handles ::1 vs 127.0.0.1 vs localhost case). rfc4254 is vague about the definition of "address that was connected" */ for (iter = cli_opts.remotefwds->first; iter; iter = iter->next) { fwd = (struct TCPFwdEntry*)iter->item; if (origport == fwd->listenport) { break; } } } if (iter == NULL) { /* We didn't request forwarding on that port */ cleantext(origaddr); dropbear_log(LOG_INFO, "Server sent unrequested forward from \"%s:%d\"", origaddr, origport); goto out; } snprintf(portstring, sizeof(portstring), "%d", fwd->connectport); channel->conn_pending = connect_remote(AF_UNSPEC, fwd->connectaddr, portstring, channel_connect_done, channel); channel->prio = DROPBEAR_CHANNEL_PRIO_UNKNOWABLE; err = SSH_OPEN_IN_PROGRESS; out: m_free(origaddr); TRACE(("leave newtcpdirect: err %d", err)) return err; }
static void ccn_publish_host_key() { dropbear_log(LOG_WARNING,"Enter ccn_publish_host_key"); if( ccn_publish_key(cli_opts.ssh_ccn, cli_opts.ccn_cached_keystore, cli_opts.ccnxdomain) < 0 ) dropbear_exit("Could not publish ccn host key"); }
static int utmpx_perform_login(struct logininfo *li) { struct utmpx utx; construct_utmpx(li, &utx); # ifdef UTMPX_USE_LIBRARY if (!utmpx_write_library(li, &utx)) { dropbear_log(LOG_WARNING, "utmpx_perform_login: utmp_write_library() failed"); return 0; } # else if (!utmpx_write_direct(li, &ut)) { dropbear_log(LOG_WARNING, "utmpx_perform_login: utmp_write_direct() failed"); return 0; } # endif return 1; }
/* * newServerHandler * * Expecting a string containing the URI for the client */ static enum ccn_upcall_res newServerHandler(struct ccn_closure *selfp, enum ccn_upcall_kind kind, struct ccn_upcall_info *info) { dropbear_log(LOG_WARNING,"Enter newServerHandler"); dropbear_log(LOG_WARNING,"Got interest matching %d components, kind = %d\n", info->matched_comps, kind); int result; const unsigned char *ccnb = NULL; size_t ccnb_size; void *data = NULL; size_t data_size = 0; switch (kind) { case CCN_UPCALL_CONTENT: break; case CCN_UPCALL_INTEREST_TIMED_OUT: return CCN_UPCALL_RESULT_REEXPRESS; case CCN_UPCALL_CONTENT_UNVERIFIED: // TODO: fix verification break; default: return CCN_UPCALL_RESULT_ERR; } dropbear_log(LOG_WARNING,"Interest to"); print_ccnb_name(info); ccnb = info->content_ccnb; ccnb_size = info->pco->offset[CCN_PCO_E]; result = ccn_content_get_value(ccnb, ccnb_size, info->pco, (const unsigned char **)&data, &data_size); if( result < 0 ) dropbear_exit("Could not parse reply message"); dropbear_log(LOG_WARNING,"newServerHandler: parsing contents"); if( strncmp((char *)data,"ccnx:/",6) == 0 ) { cli_opts.remote_name_str = (char *)data; dropbear_log(LOG_WARNING,"newServerHandler: matches: %s (%d)",data,data_size); ses.remote_name = ccn_charbuf_create(); result = ccn_name_from_uri(ses.remote_name,cli_opts.remote_name_str); if( result < 0 ) dropbear_exit("Did not find expected uri in server response"); // Start a new session dropbear_log(LOG_WARNING,"Connected to server at"); print_ccnb_charbuf(ses.remote_name); cli_session(cli_opts.ccnxdomain,cli_opts.remote_name_str); return CCN_UPCALL_RESULT_OK; } else { dropbear_log(LOG_WARNING,"newServerHandler: doesn't match"); return CCN_UPCALL_RESULT_ERR; } }
/* open the file (using filemode) and seek to the login entry */ static int lastlog_openseek(struct logininfo *li, int *fd, int filemode) { off_t offset; int type; char lastlog_file[1024]; type = lastlog_filetype(LASTLOG_FILE); switch (type) { case LL_FILE: strlcpy(lastlog_file, LASTLOG_FILE, sizeof(lastlog_file)); break; case LL_DIR: snprintf(lastlog_file, sizeof(lastlog_file), "%s/%s", LASTLOG_FILE, li->username); break; default: dropbear_log(LOG_WARNING, "lastlog_openseek: %.100s is not a file or directory!", LASTLOG_FILE); return 0; } *fd = open(lastlog_file, filemode, 0600); if ( *fd < 0) { dropbear_log(LOG_INFO, "lastlog_openseek: Couldn't open %s: %s", lastlog_file, strerror(errno)); return 0; } if (type == LL_FILE) { /* find this uid's offset in the lastlog file */ offset = (off_t) ((long)li->uid * sizeof(struct lastlog)); if ( lseek(*fd, offset, SEEK_SET) != offset ) { dropbear_log(LOG_WARNING, "lastlog_openseek: %s->lseek(): %s", lastlog_file, strerror(errno)); return 0; } } return 1; }
void cli_recv_msg_request_failure() { m_list_elem *iter; for (iter = cli_opts.remotefwds->first; iter; iter = iter->next) { struct TCPFwdEntry *fwd = (struct TCPFwdEntry*)iter->item; if (!fwd->have_reply) { fwd->have_reply = 1; dropbear_log(LOG_WARNING, "Remote TCP forward request failed (port %d -> %s:%d)", fwd->listenport, fwd->connectaddr, fwd->connectport); return; } } }
int lastlog_write_entry(struct logininfo *li) { switch(li->type) { case LTYPE_LOGIN: return lastlog_perform_login(li); default: dropbear_log(LOG_WARNING, "lastlog_write_entry: Invalid type field"); return 0; } }
void parse_ciphers_macs() { if (opts.cipher_list) { if (strcmp(opts.cipher_list, "help") == 0) { char *ciphers = algolist_string(sshciphers); dropbear_log(LOG_INFO, "Available ciphers:\n%s\n", ciphers); m_free(ciphers); dropbear_exit("."); } if (strcmp(opts.cipher_list, "none") == 0) { /* Encryption is required during authentication */ opts.cipher_list = "none,aes128-ctr"; } if (check_user_algos(opts.cipher_list, sshciphers, "cipher") == 0) { dropbear_exit("No valid ciphers specified for '-c'"); } } if (opts.mac_list) { if (strcmp(opts.mac_list, "help") == 0) { char *macs = algolist_string(sshhashes); dropbear_log(LOG_INFO, "Available MACs:\n%s\n", macs); m_free(macs); dropbear_exit("."); } if (check_user_algos(opts.mac_list, sshhashes, "MAC") == 0) { dropbear_exit("No valid MACs specified for '-m'"); } } }
static FILE* open_known_hosts_file(int * readonly) { FILE * hostsfile = NULL; char * filename = NULL; char * homedir = NULL; homedir = getenv("HOME"); if (!homedir) { struct passwd * pw = NULL; pw = getpwuid(getuid()); if (pw) { homedir = pw->pw_dir; #ifdef ANDROID_CHANGES if (strlen(homedir) <= 1) { TRACE(("(hosts_file) forcing DROPBEAR_HOME folder for user .ssh: " DROPBEAR_HOME )) homedir = DROPBEAR_HOME; } #endif } } if (homedir) { unsigned int len; len = strlen(homedir); filename = m_malloc(len + 18); /* "/.ssh/known_hosts" and null-terminator*/ snprintf(filename, len+18, "%s/.ssh", homedir); /* Check that ~/.ssh exists - easiest way is just to mkdir */ if (mkdir(filename, S_IRWXU) != 0) { if (errno != EEXIST) { dropbear_log(LOG_INFO, "Warning: failed creating %s/.ssh: %s", homedir, strerror(errno)); TRACE(("mkdir didn't work: %s", strerror(errno))) goto out; } } snprintf(filename, len+18, "%s/.ssh/known_hosts", homedir); hostsfile = fopen(filename, "a+"); if (hostsfile != NULL) { *readonly = 0; fseek(hostsfile, 0, SEEK_SET); } else { /* We mightn't have been able to open it if it was read-only */ if (errno == EACCES || errno == EROFS) { TRACE(("trying readonly: %s", strerror(errno))) *readonly = 1; hostsfile = fopen(filename, "r"); } } }
/* This is a slight modification of code in OpenBSD's logwtmp.c */ static int wtmp_write(struct logininfo *li, struct utmp *ut) { struct stat buf; int fd, ret = 1; if ((fd = open(WTMP_FILE, O_WRONLY|O_APPEND, 0)) < 0) { dropbear_log(LOG_WARNING, "wtmp_write: problem writing %s: %s", WTMP_FILE, strerror(errno)); return 0; } if (fstat(fd, &buf) == 0) if (atomicio(write, fd, ut, sizeof(*ut)) != sizeof(*ut)) { ftruncate(fd, buf.st_size); dropbear_log(LOG_WARNING, "wtmp_write: problem writing %s: %s", WTMP_FILE, strerror(errno)); ret = 0; } (void)close(fd); return ret; }
static int newtcpforwarded(struct Channel * channel) { char *origaddr = NULL; unsigned int origport; m_list_elem * iter = NULL; struct TCPFwdEntry *fwd; char portstring[NI_MAXSERV]; int sock; int err = SSH_OPEN_ADMINISTRATIVELY_PROHIBITED; origaddr = buf_getstring(ses.payload, NULL); origport = buf_getint(ses.payload); /* Find which port corresponds */ for (iter = cli_opts.remotefwds->first; iter; iter = iter->next) { fwd = (struct TCPFwdEntry*)iter->item; if (origport == fwd->listenport && (strcmp(origaddr, fwd->listenaddr) == 0)) { break; } } if (iter == NULL) { /* We didn't request forwarding on that port */ cleantext(origaddr); dropbear_log(LOG_INFO, "Server sent unrequested forward from \"%s:%d\"", origaddr, origport); goto out; } snprintf(portstring, sizeof(portstring), "%d", fwd->connectport); sock = connect_remote(AF_UNSPEC, fwd->connectaddr, portstring, 1, NULL); if (sock < 0) { TRACE(("leave newtcpdirect: sock failed")) err = SSH_OPEN_CONNECT_FAILED; goto out; } ses.maxfd = MAX(ses.maxfd, sock); /* We don't set readfd, that will get set after the connection's * progress succeeds */ channel->writefd = sock; channel->initconn = 1; err = SSH_OPEN_IN_PROGRESS; out: m_free(origaddr); TRACE(("leave newtcpdirect: err %d", err)) return err; }
static void disablekey(int type, const char* filename) { int i; for (i = 0; sshhostkey[i].name != NULL; i++) { if (sshhostkey[i].val == type) { sshhostkey[i].usable = 0; break; } } dropbear_log(LOG_WARNING, "Failed reading '%s', disabling %s", filename, type == DROPBEAR_SIGNKEY_DSS ? "DSS" : "RSA"); }
int wtmp_write_entry(struct logininfo *li) { switch(li->type) { case LTYPE_LOGIN: return wtmp_perform_login(li); case LTYPE_LOGOUT: return wtmp_perform_logout(li); default: dropbear_log(LOG_WARNING, "wtmp_write_entry: invalid type field"); return 0; } }
static void try_add_algo(const char *algo_name, algo_type *algos, const char *algo_desc, algo_type * new_algos, int *num_ret) { algo_type *match_algo = check_algo(algo_name, algos); if (!match_algo) { dropbear_log(LOG_WARNING, "This Dropbear program does not support '%s' %s algorithm", algo_name, algo_desc); return; } new_algos[*num_ret] = *match_algo; (*num_ret)++; }
/* Set chansession command to the one forced * by any 'command' public key option. */ void svr_pubkey_set_forced_command(struct ChanSess *chansess) { if (ses.authstate.pubkey_options) { if (chansess->cmd) { /* original_command takes ownership */ chansess->original_command = chansess->cmd; } else { chansess->original_command = m_strdup(""); } chansess->cmd = m_strdup(ses.authstate.pubkey_options->forced_command); #ifdef LOG_COMMANDS dropbear_log(LOG_INFO, "Command forced to '%s'", chansess->original_command); #endif } }
static int syslogin_perform_login(struct logininfo *li) { struct utmp *ut; if (! (ut = (struct utmp *)malloc(sizeof(*ut)))) { dropbear_log(LOG_WARNING, "syslogin_perform_login: couldn't malloc()"); return 0; } construct_utmp(li, ut); login(ut); free(ut); return 1; }
static int lastlog_filetype(char *filename) { struct stat st; if (stat(filename, &st) != 0) { dropbear_log(LOG_WARNING, "lastlog_perform_login: Couldn't stat %s: %s", filename, strerror(errno)); return 0; } if (S_ISDIR(st.st_mode)) return LL_DIR; else if (S_ISREG(st.st_mode)) return LL_FILE; else return LL_OTHER; }
/* The only global success/failure messages are for remotetcp. * Since there isn't any identifier in these messages, we have to rely on them * being in the same order as we sent the requests. This is the ordering * of the cli_opts.remotefwds list. * If the requested remote port is 0 the listen port will be * dynamically allocated by the server and the port number will be returned * to client and the port number reported to the user. */ void cli_recv_msg_request_success() { /* We just mark off that we have received the reply, * so that we can report failure for later ones. */ m_list_elem * iter = NULL; for (iter = cli_opts.remotefwds->first; iter; iter = iter->next) { struct TCPFwdEntry *fwd = (struct TCPFwdEntry*)iter->item; if (!fwd->have_reply) { fwd->have_reply = 1; if (fwd->listenport == 0) { /* The server should let us know which port was allocated if we requestd port 0 */ int allocport = buf_getint(ses.payload); if (allocport > 0) { dropbear_log(LOG_INFO, "Allocated port %d for remote forward to %s:%d", allocport, fwd->connectaddr, fwd->connectport); } } return; } } }
/* Must be called after syslog/etc is working */ static void loadhostkey(const char *keyfile, int fatal_duplicate) { sign_key * read_key = new_sign_key(); enum signkey_type type = DROPBEAR_SIGNKEY_ANY; if (readhostkey(keyfile, read_key, &type) == DROPBEAR_FAILURE) { if (!svr_opts.delay_hostkey) { dropbear_log(LOG_WARNING, "Failed loading %s", keyfile); } } #ifdef DROPBEAR_RSA if (type == DROPBEAR_SIGNKEY_RSA) { loadhostkey_helper("RSA", (void**)&read_key->rsakey, (void**)&svr_opts.hostkey->rsakey, fatal_duplicate); } #endif #ifdef DROPBEAR_DSS if (type == DROPBEAR_SIGNKEY_DSS) { loadhostkey_helper("DSS", (void**)&read_key->dsskey, (void**)&svr_opts.hostkey->dsskey, fatal_duplicate); } #endif #ifdef DROPBEAR_ECDSA #ifdef DROPBEAR_ECC_256 if (type == DROPBEAR_SIGNKEY_ECDSA_NISTP256) { loadhostkey_helper("ECDSA256", (void**)&read_key->ecckey256, (void**)&svr_opts.hostkey->ecckey256, fatal_duplicate); } #endif #ifdef DROPBEAR_ECC_384 if (type == DROPBEAR_SIGNKEY_ECDSA_NISTP384) { loadhostkey_helper("ECDSA384", (void**)&read_key->ecckey384, (void**)&svr_opts.hostkey->ecckey384, fatal_duplicate); } #endif #ifdef DROPBEAR_ECC_521 if (type == DROPBEAR_SIGNKEY_ECDSA_NISTP521) { loadhostkey_helper("ECDSA521", (void**)&read_key->ecckey521, (void**)&svr_opts.hostkey->ecckey521, fatal_duplicate); } #endif #endif /* DROPBEAR_ECDSA */ sign_key_free(read_key); TRACE(("leave loadhostkey")) }