summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--cli-kex.c2
-rw-r--r--cli-main.c11
-rw-r--r--cli-runopts.c10
-rw-r--r--cli-session.c4
-rw-r--r--common-session.c4
-rw-r--r--dbutil.c111
-rw-r--r--dbutil.h6
-rw-r--r--debug.h2
-rw-r--r--options.h4
-rw-r--r--packet.c17
-rw-r--r--runopts.h4
-rw-r--r--session.h8
-rw-r--r--svr-chansession.c22
-rw-r--r--svr-main.c49
-rw-r--r--svr-runopts.c8
-rw-r--r--svr-session.c18
16 files changed, 141 insertions, 139 deletions
diff --git a/cli-kex.c b/cli-kex.c
index c4048ec..0d5a9d2 100644
--- a/cli-kex.c
+++ b/cli-kex.c
@@ -304,7 +304,7 @@ static void checkhostkey(unsigned char* keyblob, unsigned int keybloblen) {
fseek(hostsfile, 0, SEEK_END); /* In case it wasn't opened append */
buf_setpos(line, 0);
buf_setlen(line, 0);
- buf_putbytes(line, ses.remotehost, hostlen);
+ buf_putbytes(line, cli_opts.remotehost, hostlen);
buf_putbyte(line, ' ');
buf_putbytes(line, algoname, algolen);
buf_putbyte(line, ' ');
diff --git a/cli-main.c b/cli-main.c
index e7ddaa8..b1a0053 100644
--- a/cli-main.c
+++ b/cli-main.c
@@ -45,8 +45,6 @@ int main(int argc, char ** argv) {
int sock_in, sock_out;
char* error = NULL;
- char* hostandport;
- int len;
_dropbear_exit = cli_dropbear_exit;
_dropbear_log = cli_dropbear_log;
@@ -78,14 +76,7 @@ int main(int argc, char ** argv) {
dropbear_exit("%s", error);
}
- /* Set up the host:port log */
- len = strlen(cli_opts.remotehost);
- len += 10; /* 16 bit port and leeway*/
- hostandport = (char*)m_malloc(len);
- snprintf(hostandport, len, "%s:%s",
- cli_opts.remotehost, cli_opts.remoteport);
-
- cli_session(sock_in, sock_out, hostandport);
+ cli_session(sock_in, sock_out);
/* not reached */
return -1;
diff --git a/cli-runopts.c b/cli-runopts.c
index eab33b7..e32d2fb 100644
--- a/cli-runopts.c
+++ b/cli-runopts.c
@@ -378,15 +378,19 @@ void cli_getopts(int argc, char ** argv) {
}
}
if (keepalive_arg) {
- if (m_str_to_uint(keepalive_arg, &opts.keepalive_secs) == DROPBEAR_FAILURE) {
+ unsigned int val;
+ if (m_str_to_uint(keepalive_arg, &val) == DROPBEAR_FAILURE) {
dropbear_exit("Bad keepalive '%s'", keepalive_arg);
}
+ opts.keepalive_secs = val;
}
if (idle_timeout_arg) {
- if (m_str_to_uint(idle_timeout_arg, &opts.idle_timeout_secs) == DROPBEAR_FAILURE) {
+ unsigned int val;
+ if (m_str_to_uint(idle_timeout_arg, &val) == DROPBEAR_FAILURE) {
dropbear_exit("Bad idle_timeout '%s'", idle_timeout_arg);
}
+ opts.idle_timeout_secs = val;
}
#ifdef ENABLE_CLI_NETCAT
@@ -454,7 +458,7 @@ multihop_passthrough_args() {
sign_key * key = (sign_key*)iter->item;
const size_t size = len - total;
int written = snprintf(ret+total, size, "-i %s", key->filename);
- dropbear_assert(written < size);
+ dropbear_assert((unsigned int)written < size);
total += written;
}
diff --git a/cli-session.c b/cli-session.c
index ed58a11..96a0929 100644
--- a/cli-session.c
+++ b/cli-session.c
@@ -82,13 +82,13 @@ static const struct ChanType *cli_chantypes[] = {
NULL /* Null termination */
};
-void cli_session(int sock_in, int sock_out, char* remotehost) {
+void cli_session(int sock_in, int sock_out) {
seedrandom();
crypto_init();
- common_session_init(sock_in, sock_out, remotehost);
+ common_session_init(sock_in, sock_out);
chaninitialise(cli_chantypes);
diff --git a/common-session.c b/common-session.c
index 1348da2..f2ad436 100644
--- a/common-session.c
+++ b/common-session.c
@@ -52,12 +52,10 @@ int exitflag = 0; /* GLOBAL */
/* called only at the start of a session, set up initial state */
-void common_session_init(int sock_in, int sock_out, char* remotehost) {
+void common_session_init(int sock_in, int sock_out) {
TRACE(("enter session_init"))
- ses.remotehost = remotehost;
-
ses.sock_in = sock_in;
ses.sock_out = sock_out;
ses.maxfd = MAX(sock_in, sock_out);
diff --git a/dbutil.c b/dbutil.c
index 73302e0..9fd90d1 100644
--- a/dbutil.c
+++ b/dbutil.c
@@ -539,14 +539,47 @@ void run_shell_command(const char* cmd, unsigned int maxfd, char* usershell) {
execv(usershell, argv);
}
+void get_socket_address(int fd, char **local_host, char **local_port,
+ char **remote_host, char **remote_port, int host_lookup)
+{
+ struct sockaddr_storage addr;
+ socklen_t addrlen;
+
+ if (local_host || local_port) {
+ addrlen = sizeof(addr);
+ if (getsockname(fd, (struct sockaddr*)&addr, &addrlen) < 0) {
+ dropbear_exit("Failed socket address: %s", strerror(errno));
+ }
+ getaddrstring(&addr, local_host, local_port, host_lookup);
+ }
+ if (remote_host || remote_port) {
+ addrlen = sizeof(addr);
+ if (getpeername(fd, (struct sockaddr*)&addr, &addrlen) < 0) {
+ dropbear_exit("Failed socket address: %s", strerror(errno));
+ }
+ getaddrstring(&addr, remote_host, remote_port, host_lookup);
+ }
+}
+
/* Return a string representation of the socket address passed. The return
* value is allocated with malloc() */
-unsigned char * getaddrstring(struct sockaddr_storage* addr, int withport) {
+void getaddrstring(struct sockaddr_storage* addr,
+ char **ret_host, char **ret_port,
+ int host_lookup) {
- char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
- char *retstring = NULL;
- int ret;
+ char host[NI_MAXHOST+1], serv[NI_MAXSERV+1];
unsigned int len;
+ int ret;
+
+ int flags = NI_NUMERICSERV | NI_NUMERICHOST;
+
+#ifndef DO_HOST_LOOKUP
+ host_lookup = 0;
+#endif
+
+ if (host_lookup) {
+ flags = NI_NUMERICSERV;
+ }
len = sizeof(struct sockaddr_storage);
/* Some platforms such as Solaris 8 require that len is the length
@@ -564,66 +597,28 @@ unsigned char * getaddrstring(struct sockaddr_storage* addr, int withport) {
#endif
#endif
- ret = getnameinfo((struct sockaddr*)addr, len, hbuf, sizeof(hbuf),
- sbuf, sizeof(sbuf), NI_NUMERICSERV | NI_NUMERICHOST);
+ ret = getnameinfo((struct sockaddr*)addr, len, host, sizeof(host)-1,
+ serv, sizeof(serv)-1, flags);
if (ret != 0) {
- /* This is a fairly bad failure - it'll fallback to IP if it
- * just can't resolve */
- dropbear_exit("failed lookup (%d, %d)", ret, errno);
+ if (host_lookup) {
+ /* On some systems (Darwin does it) we get EINTR from getnameinfo
+ * somehow. Eew. So we'll just return the IP, since that doesn't seem
+ * to exhibit that behaviour. */
+ getaddrstring(addr, ret_host, ret_port, 0);
+ return;
+ } else {
+ /* if we can't do a numeric lookup, something's gone terribly wrong */
+ dropbear_exit("Failed lookup: %s", gai_strerror(ret));
+ }
}
- if (withport) {
- len = strlen(hbuf) + 2 + strlen(sbuf);
- retstring = (char*)m_malloc(len);
- snprintf(retstring, len, "%s:%s", hbuf, sbuf);
- } else {
- retstring = m_strdup(hbuf);
+ if (ret_host) {
+ *ret_host = m_strdup(host);
}
-
- return retstring;
-}
-
-/* Get the hostname corresponding to the address addr. On failure, the IP
- * address is returned. The return value is allocated with strdup() */
-char* getaddrhostname(struct sockaddr_storage * addr) {
-
- char hbuf[NI_MAXHOST];
- char sbuf[NI_MAXSERV];
- int ret;
- unsigned int len;
-#ifdef DO_HOST_LOOKUP
- const int flags = NI_NUMERICSERV;
-#else
- const int flags = NI_NUMERICHOST | NI_NUMERICSERV;
-#endif
-
- len = sizeof(struct sockaddr_storage);
- /* Some platforms such as Solaris 8 require that len is the length
- * of the specific structure. */
-#ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY
- if (addr->ss_family == AF_INET) {
- len = sizeof(struct sockaddr_in);
+ if (ret_port) {
+ *ret_port = m_strdup(serv);
}
-#ifdef AF_INET6
- if (addr->ss_family == AF_INET6) {
- len = sizeof(struct sockaddr_in6);
- }
-#endif
-#endif
-
-
- ret = getnameinfo((struct sockaddr*)addr, len, hbuf, sizeof(hbuf),
- sbuf, sizeof(sbuf), flags);
-
- if (ret != 0) {
- /* On some systems (Darwin does it) we get EINTR from getnameinfo
- * somehow. Eew. So we'll just return the IP, since that doesn't seem
- * to exhibit that behaviour. */
- return getaddrstring(addr, 0);
- }
-
- return m_strdup(hbuf);
}
#ifdef DEBUG_TRACE
diff --git a/dbutil.h b/dbutil.h
index fe08f18..474db62 100644
--- a/dbutil.h
+++ b/dbutil.h
@@ -46,7 +46,10 @@ void printhex(const char * label, const unsigned char * buf, int len);
extern int debug_trace;
#endif
char * stripcontrol(const char * text);
-unsigned char * getaddrstring(struct sockaddr_storage* addr, int withport);
+void get_socket_address(int fd, char **local_host, char **local_port,
+ char **remote_host, char **remote_port, int host_lookup);
+void getaddrstring(struct sockaddr_storage* addr,
+ char **ret_host, char **ret_port, int host_lookup);
int dropbear_listen(const char* address, const char* port,
int *socks, unsigned int sockcount, char **errstring, int *maxfd);
int spawn_command(void(*exec_fn)(void *user_data), void *exec_data,
@@ -57,7 +60,6 @@ int connect_unix(const char* addr);
#endif
int connect_remote(const char* remotehost, const char* remoteport,
int nonblocking, char ** errstring);
-char* getaddrhostname(struct sockaddr_storage * addr);
int buf_readfile(buffer* buf, const char* filename);
int buf_getline(buffer * line, FILE * authfile);
diff --git a/debug.h b/debug.h
index b8c2a57..a9cc0bd 100644
--- a/debug.h
+++ b/debug.h
@@ -39,7 +39,7 @@
* Caution: Don't use this in an unfriendly environment (ie unfirewalled),
* since the printing may not sanitise strings etc. This will add a reasonable
* amount to your executable size. */
-/*#define DEBUG_TRACE*/
+#define DEBUG_TRACE
/* All functions writing to the cleartext payload buffer call
* CHECKCLEARTOWRITE() before writing. This is only really useful if you're
diff --git a/options.h b/options.h
index f151cdb..ee315d5 100644
--- a/options.h
+++ b/options.h
@@ -167,9 +167,9 @@ much traffic. */
* but there's an interface via a PAM module - don't bother using it otherwise.
* You can't enable both PASSWORD and PAM. */
-#define ENABLE_SVR_PASSWORD_AUTH
+/*#define ENABLE_SVR_PASSWORD_AUTH*/
/* PAM requires ./configure --enable-pam */
-/*#define ENABLE_SVR_PAM_AUTH*/
+#define ENABLE_SVR_PAM_AUTH
#define ENABLE_SVR_PUBKEY_AUTH
/* Whether to take public key options in
diff --git a/packet.c b/packet.c
index 9621bbd..ea96c04 100644
--- a/packet.c
+++ b/packet.c
@@ -157,9 +157,10 @@ void read_packet() {
static int read_packet_init() {
unsigned int maxlen;
- int len;
- unsigned char blocksize;
- unsigned char macsize;
+ int slen;
+ unsigned int len;
+ unsigned int blocksize;
+ unsigned int macsize;
blocksize = ses.keys->recv.algo_crypt->blocksize;
@@ -173,12 +174,12 @@ static int read_packet_init() {
maxlen = blocksize - ses.readbuf->pos;
/* read the rest of the packet if possible */
- len = read(ses.sock_in, buf_getwriteptr(ses.readbuf, maxlen),
+ slen = read(ses.sock_in, buf_getwriteptr(ses.readbuf, maxlen),
maxlen);
- if (len == 0) {
+ if (slen == 0) {
ses.remoteclosed();
}
- if (len < 0) {
+ if (slen < 0) {
if (errno == EINTR) {
TRACE(("leave read_packet_init: EINTR"))
return DROPBEAR_FAILURE;
@@ -186,9 +187,9 @@ static int read_packet_init() {
dropbear_exit("error reading: %s", strerror(errno));
}
- buf_incrwritepos(ses.readbuf, len);
+ buf_incrwritepos(ses.readbuf, slen);
- if ((unsigned int)len != maxlen) {
+ if ((unsigned int)slen != maxlen) {
/* don't have enough bytes to determine length, get next time */
return DROPBEAR_FAILURE;
}
diff --git a/runopts.h b/runopts.h
index 22376c1..9bf0c26 100644
--- a/runopts.h
+++ b/runopts.h
@@ -37,8 +37,8 @@ typedef struct runopts {
int listen_fwd_all;
#endif
unsigned int recv_window;
- unsigned int keepalive_secs;
- unsigned int idle_timeout_secs;
+ time_t keepalive_secs;
+ time_t idle_timeout_secs;
} runopts;
diff --git a/session.h b/session.h
index eec7f01..128214b 100644
--- a/session.h
+++ b/session.h
@@ -41,7 +41,7 @@
extern int sessinitdone; /* Is set to 0 somewhere */
extern int exitflag;
-void common_session_init(int sock_in, int sock_out, char* remotehost);
+void common_session_init(int sock_in, int sock_out);
void session_loop(void(*loophandler)());
void common_session_cleanup();
void session_identification();
@@ -51,12 +51,12 @@ const char* get_user_shell();
void fill_passwd(const char* username);
/* Server */
-void svr_session(int sock, int childpipe, char *remotehost, char *addrstring);
+void svr_session(int sock, int childpipe);
void svr_dropbear_exit(int exitcode, const char* format, va_list param);
void svr_dropbear_log(int priority, const char* format, va_list param);
/* Client */
-void cli_session(int sock_in, int sock_out, char *remotehost);
+void cli_session(int sock_in, int sock_out);
void cli_session_cleanup();
void cleantext(unsigned char* dirtytext);
@@ -110,8 +110,6 @@ struct sshsession {
int sock_in;
int sock_out;
- unsigned char *remotehost; /* the peer hostname */
-
unsigned char *remoteident;
int maxfd; /* the maximum file descriptor to check with select() */
diff --git a/svr-chansession.c b/svr-chansession.c
index 2664382..503e789 100644
--- a/svr-chansession.c
+++ b/svr-chansession.c
@@ -250,6 +250,17 @@ static int newchansess(struct Channel *channel) {
}
+static struct logininfo*
+chansess_login_alloc(struct ChanSess *chansess) {
+ char *remotehost;
+ struct logininfo * li;
+ get_socket_address(ses.sock_in, NULL, NULL, &remotehost, NULL, 1);
+ li = login_alloc_entry(chansess->pid, ses.authstate.username,
+ remotehost, chansess->tty);
+ m_free(remotehost);
+ return li;
+}
+
/* clean a session channel */
static void closechansess(struct Channel *channel) {
@@ -273,8 +284,7 @@ static void closechansess(struct Channel *channel) {
if (chansess->tty) {
/* write the utmp/wtmp login record */
- li = login_alloc_entry(chansess->pid, ses.authstate.username,
- ses.remotehost, chansess->tty);
+ li = chansess_login_alloc(chansess);
login_logout(li);
login_free_entry(li);
@@ -578,7 +588,6 @@ static int sessioncommand(struct Channel *channel, struct ChanSess *chansess,
int iscmd, int issubsys) {
unsigned int cmdlen;
- int is_forced;
int ret;
TRACE(("enter sessioncommand"))
@@ -628,6 +637,8 @@ static int sessioncommand(struct Channel *channel, struct ChanSess *chansess,
}
#endif
+ // XXX set SSH_CONNECTION string here, since about to close socket...
+
if (chansess->term == NULL) {
/* no pty */
ret = noptycommand(channel, chansess);
@@ -737,8 +748,7 @@ static int ptycommand(struct Channel *channel, struct ChanSess *chansess) {
/* write the utmp/wtmp login record - must be after changing the
* terminal used for stdout with the dup2 above */
- li= login_alloc_entry(getpid(), ses.authstate.username,
- ses.remotehost, chansess->tty);
+ li = chansess_login_alloc(chansess);
login_login(li);
login_free_entry(li);
@@ -886,6 +896,8 @@ static void execchild(void *user_data) {
addnewvar("SSH_TTY", chansess->tty);
}
+
+
#ifdef ENABLE_SVR_PUBKEY_OPTIONS
if (ses.authstate.pubkey_options &&
ses.authstate.pubkey_options->original_command) {
diff --git a/svr-main.c b/svr-main.c
index 45ea4be..712657e 100644
--- a/svr-main.c
+++ b/svr-main.c
@@ -77,22 +77,16 @@ int main(int argc, char ** argv)
#ifdef INETD_MODE
static void main_inetd() {
-
- struct sockaddr_storage remoteaddr;
- socklen_t remoteaddrlen;
- char * addrstring = NULL;
+ char *host, *port = NULL;
/* Set up handlers, syslog, seed random */
commonsetup();
- remoteaddrlen = sizeof(remoteaddr);
- if (getpeername(0, (struct sockaddr*)&remoteaddr, &remoteaddrlen) < 0) {
- dropbear_exit("Unable to getpeername: %s", strerror(errno));
- }
-
/* In case our inetd was lax in logging source addresses */
- addrstring = getaddrstring(&remoteaddr, 1);
- dropbear_log(LOG_INFO, "Child connection from %s", addrstring);
+ get_socket_address(0, NULL, NULL, &host, &port, 0);
+ dropbear_log(LOG_INFO, "Child connection from %s:%s", host, port);
+ m_free(host);
+ m_free(port);
/* Don't check the return value - it may just fail since inetd has
* already done setsid() after forking (xinetd on Darwin appears to do
@@ -102,7 +96,7 @@ static void main_inetd() {
/* Start service program
* -1 is a dummy childpipe, just something we can close() without
* mattering. */
- svr_session(0, -1, getaddrhostname(&remoteaddr), addrstring);
+ svr_session(0, -1);
/* notreached */
}
@@ -218,14 +212,13 @@ void main_noinetd() {
/* handle each socket which has something to say */
for (i = 0; i < listensockcount; i++) {
-
- struct sockaddr_storage remoteaddr;
- socklen_t remoteaddrlen = 0;
size_t num_unauthed_for_addr = 0;
size_t num_unauthed_total = 0;
- char * remote_addr_str = NULL;
+ char *remote_host = NULL, *remote_port = NULL;
pid_t fork_ret = 0;
size_t conn_idx = 0;
+ struct sockaddr_storage remoteaddr;
+ socklen_t remoteaddrlen;
if (!FD_ISSET(listensocks[i], &fds))
continue;
@@ -240,14 +233,14 @@ void main_noinetd() {
}
/* Limit the number of unauthenticated connections per IP */
- remote_addr_str = getaddrstring(&remoteaddr, 0);
+ getaddrstring(&remoteaddr, &remote_host, NULL, 0);
num_unauthed_for_addr = 0;
num_unauthed_total = 0;
for (j = 0; j < MAX_UNAUTH_CLIENTS; j++) {
if (childpipes[j] >= 0) {
num_unauthed_total++;
- if (strcmp(remote_addr_str, preauth_addrs[j]) == 0) {
+ if (strcmp(remote_host, preauth_addrs[j]) == 0) {
num_unauthed_for_addr++;
}
} else {
@@ -280,21 +273,21 @@ void main_noinetd() {
/* parent */
childpipes[conn_idx] = childpipe[0];
m_close(childpipe[1]);
- preauth_addrs[conn_idx] = remote_addr_str;
- remote_addr_str = NULL;
+ preauth_addrs[conn_idx] = remote_host;
+ remote_host = NULL;
} else {
/* child */
- char * addrstring = NULL;
#ifdef DEBUG_FORKGPROF
extern void _start(void), etext(void);
monstartup((u_long)&_start, (u_long)&etext);
#endif /* DEBUG_FORKGPROF */
- m_free(remote_addr_str);
- addrstring = getaddrstring(&remoteaddr, 1);
- dropbear_log(LOG_INFO, "Child connection from %s", addrstring);
+ getaddrstring(&remoteaddr, NULL, &remote_port, 0);
+ dropbear_log(LOG_INFO, "Child connection from %s:%s", remote_host, remote_port);
+ m_free(remote_host);
+ m_free(remote_port);
#ifndef DEBUG_NOFORK
if (setsid() < 0) {
@@ -310,9 +303,7 @@ void main_noinetd() {
m_close(childpipe[0]);
/* start the session */
- svr_session(childsock, childpipe[1],
- getaddrhostname(&remoteaddr),
- addrstring);
+ svr_session(childsock, childpipe[1]);
/* don't return */
dropbear_assert(0);
}
@@ -320,8 +311,8 @@ void main_noinetd() {
out:
/* This section is important for the parent too */
m_close(childsock);
- if (remote_addr_str) {
- m_free(remote_addr_str);
+ if (remote_host) {
+ m_free(remote_host);
}
}
} /* for(;;) loop */
diff --git a/svr-runopts.c b/svr-runopts.c
index 4f1355a..4e59b75 100644
--- a/svr-runopts.c
+++ b/svr-runopts.c
@@ -296,15 +296,19 @@ void svr_getopts(int argc, char ** argv) {
}
if (keepalive_arg) {
- if (m_str_to_uint(keepalive_arg, &opts.keepalive_secs) == DROPBEAR_FAILURE) {
+ unsigned int val;
+ if (m_str_to_uint(keepalive_arg, &val) == DROPBEAR_FAILURE) {
dropbear_exit("Bad keepalive '%s'", keepalive_arg);
}
+ opts.keepalive_secs = val;
}
if (idle_timeout_arg) {
- if (m_str_to_uint(idle_timeout_arg, &opts.idle_timeout_secs) == DROPBEAR_FAILURE) {
+ unsigned int val;
+ if (m_str_to_uint(idle_timeout_arg, &val) == DROPBEAR_FAILURE) {
dropbear_exit("Bad idle_timeout '%s'", idle_timeout_arg);
}
+ opts.idle_timeout_secs = val;
}
}
diff --git a/svr-session.c b/svr-session.c
index 89b16cb..a509906 100644
--- a/svr-session.c
+++ b/svr-session.c
@@ -74,27 +74,33 @@ static const struct ChanType *svr_chantypes[] = {
NULL /* Null termination is mandatory. */
};
-void svr_session(int sock, int childpipe,
- char* remotehost, char *addrstring) {
-
+void svr_session(int sock, int childpipe) {
+ char *host, *port;
+ size_t len;
reseedrandom();
crypto_init();
- common_session_init(sock, sock, remotehost);
+ common_session_init(sock, sock);
/* Initialise server specific parts of the session */
svr_ses.childpipe = childpipe;
- svr_ses.addrstring = addrstring;
#ifdef __uClinux__
svr_ses.server_pid = getpid();
#endif
- svr_ses.addrstring = addrstring;
svr_authinitialise();
chaninitialise(svr_chantypes);
svr_chansessinitialise();
ses.connect_time = time(NULL);
+ /* for logging the remote address */
+ get_socket_address(ses.sock_in, NULL, NULL, &host, &port, 0);
+ len = strlen(host) + strlen(port) + 2;
+ svr_ses.addrstring = m_malloc(len);
+ snprintf(svr_ses.addrstring, len, "%s:%s", host, port);
+ m_free(host);
+ m_free(port);
+
/* set up messages etc */
ses.remoteclosed = svr_remoteclosed;