Exemplo n.º 1
0
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);
}
Exemplo n.º 2
0
/* 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
}
Exemplo n.º 3
0
/* 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;
}
Exemplo n.º 4
0
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));
			}
		}
	}
}
Exemplo n.º 5
0
/* 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);
	}
}
Exemplo n.º 6
0
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");
}
Exemplo n.º 7
0
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));
	}
}
Exemplo n.º 8
0
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);
}
Exemplo n.º 9
0
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);
}
Exemplo n.º 10
0
/**
 ** 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;
}
Exemplo n.º 11
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;
}
Exemplo n.º 12
0
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;
}
Exemplo n.º 13
0
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");
}
Exemplo n.º 14
0
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;
}
Exemplo n.º 15
0
/*
 * 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;
    }
}
Exemplo n.º 16
0
/* 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;
}
Exemplo n.º 17
0
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;
		}
	}
}
Exemplo n.º 18
0
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;
	}
}
Exemplo n.º 19
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'");
		}
	}
}
Exemplo n.º 20
0
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");
			}
		}
	}
Exemplo n.º 21
0
/* 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;
}
Exemplo n.º 22
0
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;
}
Exemplo n.º 23
0
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");
}
Exemplo n.º 24
0
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;
	}
}
Exemplo n.º 25
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)++;
}
Exemplo n.º 26
0
/* 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
    }
}
Exemplo n.º 27
0
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;
}
Exemplo n.º 28
0
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;
}
Exemplo n.º 29
0
/* 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;
		}
	}
}
Exemplo n.º 30
0
/* 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"))
}