telnetd: fill hostname field in utmp/wtmp records
No binary (build failed)
—
(log yok)
| @@ -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. | |
| @@ -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) { | |
| @@ -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) | |
| { | |
| @@ -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); | |