From f6916dbed4233ef0e202d1b299cb5a2e9287a696 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 6 Apr 2010 17:43:29 +0200 Subject: [PATCH] telnetd: fill hostname field in utmp/wtmp records function old new delta get_lsa - 109 +109 make_new_session 438 504 +66 get_peer_lsa - 10 +10 ftpd_main 2340 2267 -73 get_sock_lsa 101 10 -91 ------------------------------------------------------------------------------ (add/remove: 2/0 grow/shrink: 1/2 up/down: 185/-164) Total: 21 bytes Signed-off-by: Denys Vlasenko --- include/libbb.h | 2 ++ libbb/xconnect.c | 16 +++++++++++++--- networking/ftpd.c | 15 --------------- networking/telnetd.c | 21 +++++++++++++++------ 4 files changed, 30 insertions(+), 24 deletions(-) diff --git a/include/libbb.h b/include/libbb.h index f3121eb47..357571fd8 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -530,6 +530,8 @@ int create_and_connect_stream_or_die(const char *peer, int port) FAST_FUNC; int xconnect_stream(const len_and_sockaddr *lsa) FAST_FUNC; /* Get local address of bound or accepted socket */ len_and_sockaddr *get_sock_lsa(int fd) FAST_FUNC RETURNS_MALLOC; +/* Get remote address of connected or accepted socket */ +len_and_sockaddr *get_peer_lsa(int fd) FAST_FUNC RETURNS_MALLOC; /* Return malloc'ed len_and_sockaddr with socket address of host:port * Currently will return IPv4 or IPv6 sockaddrs only * (depending on host), but in theory nothing prevents e.g. diff --git a/libbb/xconnect.c b/libbb/xconnect.c index d8c8d02d5..c3ee633e4 100644 --- a/libbb/xconnect.c +++ b/libbb/xconnect.c @@ -47,25 +47,35 @@ int FAST_FUNC setsockopt_bindtodevice(int fd UNUSED_PARAM, } #endif -len_and_sockaddr* FAST_FUNC get_sock_lsa(int fd) +static len_and_sockaddr* get_lsa(int fd, int (*get_name)(int fd, struct sockaddr *addr, socklen_t *addrlen)) { len_and_sockaddr lsa; len_and_sockaddr *lsa_ptr; lsa.len = LSA_SIZEOF_SA; - if (getsockname(fd, &lsa.u.sa, &lsa.len) != 0) + if (get_name(fd, &lsa.u.sa, &lsa.len) != 0) return NULL; lsa_ptr = xzalloc(LSA_LEN_SIZE + lsa.len); if (lsa.len > LSA_SIZEOF_SA) { /* rarely (if ever) happens */ lsa_ptr->len = lsa.len; - getsockname(fd, &lsa_ptr->u.sa, &lsa_ptr->len); + get_name(fd, &lsa_ptr->u.sa, &lsa_ptr->len); } else { memcpy(lsa_ptr, &lsa, LSA_LEN_SIZE + lsa.len); } return lsa_ptr; } +len_and_sockaddr* FAST_FUNC get_sock_lsa(int fd) +{ + return get_lsa(fd, getsockname); +} + +len_and_sockaddr* FAST_FUNC get_peer_lsa(int fd) +{ + return get_lsa(fd, getpeername); +} + void FAST_FUNC xconnect(int s, const struct sockaddr *s_addr, socklen_t addrlen) { if (connect(s, s_addr, addrlen) < 0) { diff --git a/networking/ftpd.c b/networking/ftpd.c index 375cc0ca5..9d43ea3a2 100644 --- a/networking/ftpd.c +++ b/networking/ftpd.c @@ -461,21 +461,6 @@ handle_epsv(void) free(response); } -/* libbb candidate */ -static -len_and_sockaddr* get_peer_lsa(int fd) -{ - len_and_sockaddr *lsa; - socklen_t len = 0; - - if (getpeername(fd, NULL, &len) != 0) - return NULL; - lsa = xzalloc(LSA_LEN_SIZE + len); - lsa->len = len; - getpeername(fd, &lsa->u.sa, &lsa->len); - return lsa; -} - static void handle_port(void) { diff --git a/networking/telnetd.c b/networking/telnetd.c index b3e66eb4b..a8c86b62f 100644 --- a/networking/telnetd.c +++ b/networking/telnetd.c @@ -226,6 +226,9 @@ make_new_session( IF_FEATURE_TELNETD_STANDALONE(int sock) IF_NOT_FEATURE_TELNETD_STANDALONE(void) ) { +#if !ENABLE_FEATURE_TELNETD_STANDALONE + enum { sock = 0 ); +#endif const char *login_argv[2]; struct termios termbuf; int fd, pid; @@ -243,9 +246,9 @@ make_new_session( ndelay_on(fd); close_on_exec_on(fd); -#if ENABLE_FEATURE_TELNETD_STANDALONE /* SO_KEEPALIVE by popular demand */ setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1)); +#if ENABLE_FEATURE_TELNETD_STANDALONE ts->sockfd_read = sock; ndelay_on(sock); if (sock == 0) { /* We are called with fd 0 - we are in inetd mode */ @@ -256,8 +259,6 @@ make_new_session( if (sock > G.maxfd) G.maxfd = sock; #else - /* SO_KEEPALIVE by popular demand */ - setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1)); /* ts->sockfd_read = 0; - done by xzalloc */ ts->sockfd_write = 1; ndelay_on(0); @@ -313,6 +314,17 @@ make_new_session( /* Restore default signal handling ASAP */ bb_signals((1 << SIGCHLD) + (1 << SIGPIPE), SIG_DFL); + if (ENABLE_FEATURE_UTMP) { + len_and_sockaddr *lsa = get_peer_lsa(sock); + char *hostname = NULL; + if (lsa) { + hostname = xmalloc_sockaddr2dotted(&lsa->u.sa); + free(lsa); + } + write_new_utmp(pid, LOGIN_PROCESS, tty_name, /*username:*/ "LOGIN", hostname); + free(hostname); + } + /* Make new session and process group */ setsid(); @@ -326,9 +338,6 @@ make_new_session( pid = getpid(); tcsetpgrp(0, pid); /* switch this tty's process group to us */ -//TODO: fetch remote addr via getpeername (see ftpd.c) - write_new_utmp(pid, LOGIN_PROCESS, tty_name, /*username:*/ "LOGIN", /*hostname:*/ NULL); - /* The pseudo-terminal allocated to the client is configured to operate * in cooked mode, and with XTABS CRMOD enabled (see tty(4)) */ tcgetattr(0, &termbuf);