diff --git a/common/os_calls.c b/common/os_calls.c index 419a6bff..9f9c3f31 100644 --- a/common/os_calls.c +++ b/common/os_calls.c @@ -78,6 +78,7 @@ #include "os_calls.h" #include "string_calls.h" #include "log.h" +#include "xrdp_constants.h" /* for clearenv() */ #if defined(_WIN32) @@ -103,6 +104,22 @@ extern char **environ; #define INADDR_NONE ((unsigned long)-1) #endif +/** + * Type big enough to hold socket address information for any connecting type + */ +union sock_info +{ + struct sockaddr sa; + struct sockaddr_in sa_in; +#if defined(XRDP_ENABLE_IPV6) + struct sockaddr_in6 sa_in6; +#endif + struct sockaddr_un sa_un; +#if defined(XRDP_ENABLE_VSOCK) + struct sockaddr_vm sa_vm; +#endif +}; + /*****************************************************************************/ int g_rm_temp_dir(void) @@ -669,6 +686,83 @@ g_sck_get_peer_cred(int sck, int *pid, int *uid, int *gid) #endif } +/*****************************************************************************/ + +static const char * +get_peer_description(const union sock_info *sock_info, + char *desc, unsigned int bytes) +{ + if (bytes > 0) + { + int family = sock_info->sa.sa_family; + switch (family) + { + case AF_INET: + { + char ip[INET_ADDRSTRLEN]; + const struct sockaddr_in *sa_in = &sock_info->sa_in; + if (inet_ntop(family, &sa_in->sin_addr, + ip, sizeof(ip)) != NULL) + { + g_snprintf(desc, bytes, "%s:%d", ip, + ntohs(sa_in->sin_port)); + } + else + { + g_snprintf(desc, bytes, ":%d", + ntohs(sa_in->sin_port)); + } + break; + } + +#if defined(XRDP_ENABLE_IPV6) + case AF_INET6: + { + char ip[INET6_ADDRSTRLEN]; + const struct sockaddr_in6 *sa_in6 = &sock_info->sa_in6; + if (inet_ntop(family, &sa_in6->sin6_addr, + ip, sizeof(ip)) != NULL) + { + g_snprintf(desc, bytes, "[%s]:%d", ip, + ntohs(sa_in6->sin6_port)); + } + else + { + g_snprintf(desc, bytes, "[]:%d", + ntohs(sa_in6->sin6_port)); + } + break; + } +#endif + + case AF_UNIX: + { + g_snprintf(desc, bytes, "AF_UNIX"); + break; + } + +#if defined(XRDP_ENABLE_VSOCK) + + case AF_VSOCK: + { + const struct sockaddr_vm *sa_vm = &sock_info->sa_vm; + + g_snprintf(desc, bytes, "AF_VSOCK:cid=%u/port=%u", + sa_vm->svm_cid, sa_vm->svm_port); + + break; + } + +#endif + default: + g_snprintf(desc, bytes, "Unknown address family %d", family); + break; + } + } + + return desc; +} + /*****************************************************************************/ void g_sck_close(int sck) @@ -676,77 +770,15 @@ g_sck_close(int sck) #if defined(_WIN32) closesocket(sck); #else - char sockname[128]; - union - { - struct sockaddr sock_addr; - struct sockaddr_in sock_addr_in; -#if defined(XRDP_ENABLE_IPV6) - struct sockaddr_in6 sock_addr_in6; -#endif -#if defined(XRDP_ENABLE_VSOCK) - struct sockaddr_vm sock_addr_vm; -#endif - } sock_info; - socklen_t sock_len = sizeof(sock_info); + char sockname[MAX_PEER_DESCSTRLEN]; + union sock_info sock_info; + socklen_t sock_len = sizeof(sock_info); memset(&sock_info, 0, sizeof(sock_info)); - if (getsockname(sck, &sock_info.sock_addr, &sock_len) == 0) + if (getsockname(sck, &sock_info.sa, &sock_len) == 0) { - switch (sock_info.sock_addr.sa_family) - { - case AF_INET: - { - struct sockaddr_in *sock_addr_in = &sock_info.sock_addr_in; - - g_snprintf(sockname, sizeof(sockname), "AF_INET %s:%d", - inet_ntoa(sock_addr_in->sin_addr), - ntohs(sock_addr_in->sin_port)); - break; - } - -#if defined(XRDP_ENABLE_IPV6) - - case AF_INET6: - { - char addr[48]; - struct sockaddr_in6 *sock_addr_in6 = &sock_info.sock_addr_in6; - - g_snprintf(sockname, sizeof(sockname), "AF_INET6 %s port %d", - inet_ntop(sock_addr_in6->sin6_family, - &sock_addr_in6->sin6_addr, addr, sizeof(addr)), - ntohs(sock_addr_in6->sin6_port)); - break; - } - -#endif - - case AF_UNIX: - g_snprintf(sockname, sizeof(sockname), "AF_UNIX"); - break; - -#if defined(XRDP_ENABLE_VSOCK) - - case AF_VSOCK: - { - struct sockaddr_vm *sock_addr_vm = &sock_info.sock_addr_vm; - - g_snprintf(sockname, - sizeof(sockname), - "AF_VSOCK cid %d port %d", - sock_addr_vm->svm_cid, - sock_addr_vm->svm_port); - break; - } - -#endif - - default: - g_snprintf(sockname, sizeof(sockname), "unknown family %d", - sock_info.sock_addr.sa_family); - break; - } + get_peer_description(&sock_info, sockname, sizeof(sockname)); } else { @@ -1238,19 +1270,10 @@ g_sck_listen(int sck) /*****************************************************************************/ int -g_tcp_accept(int sck) +g_sck_accept(int sck) { int ret; - char msg[256]; - union - { - struct sockaddr sock_addr; - struct sockaddr_in sock_addr_in; -#if defined(XRDP_ENABLE_IPV6) - struct sockaddr_in6 sock_addr_in6; -#endif - } sock_info; - + union sock_info sock_info; socklen_t sock_len = sizeof(sock_info); memset(&sock_info, 0, sock_len); @@ -1258,141 +1281,10 @@ g_tcp_accept(int sck) if (ret > 0) { - switch (sock_info.sock_addr.sa_family) - { - case AF_INET: - { - struct sockaddr_in *sock_addr_in = &sock_info.sock_addr_in; - - g_snprintf(msg, sizeof(msg), "A connection received from %s port %d", - inet_ntoa(sock_addr_in->sin_addr), - ntohs(sock_addr_in->sin_port)); - LOG(LOG_LEVEL_INFO, "%s", msg); - - break; - } - -#if defined(XRDP_ENABLE_IPV6) - - case AF_INET6: - { - struct sockaddr_in6 *sock_addr_in6 = &sock_info.sock_addr_in6; - char addr[256]; - - inet_ntop(sock_addr_in6->sin6_family, - &sock_addr_in6->sin6_addr, addr, sizeof(addr)); - g_snprintf(msg, sizeof(msg), "A connection received from %s port %d", - addr, ntohs(sock_addr_in6->sin6_port)); - LOG(LOG_LEVEL_INFO, "%s", msg); - - break; - - } - -#endif - } - } - - return ret; -} - -/*****************************************************************************/ -int -g_sck_accept(int sck, char *addr, int addr_bytes, char *port, int port_bytes) -{ - int ret; - char msg[256]; - union - { - struct sockaddr sock_addr; - struct sockaddr_in sock_addr_in; -#if defined(XRDP_ENABLE_IPV6) - struct sockaddr_in6 sock_addr_in6; -#endif - struct sockaddr_un sock_addr_un; -#if defined(XRDP_ENABLE_VSOCK) - struct sockaddr_vm sock_addr_vm; -#endif - } sock_info; - - socklen_t sock_len = sizeof(sock_info); - memset(&sock_info, 0, sock_len); - - ret = accept(sck, (struct sockaddr *)&sock_info, &sock_len); - - if (ret > 0) - { - switch (sock_info.sock_addr.sa_family) - { - case AF_INET: - { - struct sockaddr_in *sock_addr_in = &sock_info.sock_addr_in; - - g_snprintf(addr, addr_bytes, "%s", inet_ntoa(sock_addr_in->sin_addr)); - g_snprintf(port, port_bytes, "%d", ntohs(sock_addr_in->sin_port)); - g_snprintf(msg, sizeof(msg), - "AF_INET connection received from %s port %s", - addr, port); - break; - } - -#if defined(XRDP_ENABLE_IPV6) - - case AF_INET6: - { - struct sockaddr_in6 *sock_addr_in6 = &sock_info.sock_addr_in6; - - inet_ntop(sock_addr_in6->sin6_family, - &sock_addr_in6->sin6_addr, addr, addr_bytes); - g_snprintf(port, port_bytes, "%d", ntohs(sock_addr_in6->sin6_port)); - g_snprintf(msg, sizeof(msg), - "AF_INET6 connection received from %s port %s", - addr, port); - break; - } - -#endif - - case AF_UNIX: - { - g_strncpy(addr, "", addr_bytes - 1); - g_strncpy(port, "", port_bytes - 1); - g_snprintf(msg, sizeof(msg), "AF_UNIX connection received"); - break; - } - -#if defined(XRDP_ENABLE_VSOCK) - - case AF_VSOCK: - { - struct sockaddr_vm *sock_addr_vm = &sock_info.sock_addr_vm; - - g_snprintf(addr, addr_bytes - 1, "%d", sock_addr_vm->svm_cid); - g_snprintf(port, addr_bytes - 1, "%d", sock_addr_vm->svm_port); - - g_snprintf(msg, - sizeof(msg), - "AF_VSOCK connection received from cid: %s port: %s", - addr, - port); - - break; - } - -#endif - default: - { - g_strncpy(addr, "", addr_bytes - 1); - g_strncpy(port, "", port_bytes - 1); - g_snprintf(msg, sizeof(msg), - "connection received, unknown socket family %d", - sock_info.sock_addr.sa_family); - break; - } - } - - - LOG(LOG_LEVEL_INFO, "Socket %d: %s", ret, msg); + char description[MAX_PEER_DESCSTRLEN]; + get_peer_description(&sock_info, description, sizeof(description)); + LOG(LOG_LEVEL_INFO, "Socket %d: connection accepted from %s", + ret, description); } @@ -1401,119 +1293,87 @@ g_sck_accept(int sck, char *addr, int addr_bytes, char *port, int port_bytes) /*****************************************************************************/ -void -g_write_connection_description(int rcv_sck, char *description, int bytes) -{ - char *addr; - int port; - int ok; - - union - { - struct sockaddr sock_addr; - struct sockaddr_in sock_addr_in; -#if defined(XRDP_ENABLE_IPV6) - struct sockaddr_in6 sock_addr_in6; -#endif - struct sockaddr_un sock_addr_un; - } sock_info; - - ok = 0; - socklen_t sock_len = sizeof(sock_info); - memset(&sock_info, 0, sock_len); -#if defined(XRDP_ENABLE_IPV6) - addr = (char *)g_malloc(INET6_ADDRSTRLEN, 1); -#else - addr = (char *)g_malloc(INET_ADDRSTRLEN, 1); -#endif - - if (getpeername(rcv_sck, (struct sockaddr *)&sock_info, &sock_len) == 0) - { - switch (sock_info.sock_addr.sa_family) - { - case AF_INET: - { - struct sockaddr_in *sock_addr_in = &sock_info.sock_addr_in; - g_snprintf(addr, INET_ADDRSTRLEN, "%s", inet_ntoa(sock_addr_in->sin_addr)); - port = ntohs(sock_addr_in->sin_port); - ok = 1; - break; - } - -#if defined(XRDP_ENABLE_IPV6) - - case AF_INET6: - { - struct sockaddr_in6 *sock_addr_in6 = &sock_info.sock_addr_in6; - inet_ntop(sock_addr_in6->sin6_family, - &sock_addr_in6->sin6_addr, addr, INET6_ADDRSTRLEN); - port = ntohs(sock_addr_in6->sin6_port); - ok = 1; - break; - } - -#endif - - default: - { - break; - } - - } - - if (ok) - { - g_snprintf(description, bytes, "%s:%d - socket: %d", addr, port, rcv_sck); - } - } - - if (!ok) - { - g_snprintf(description, bytes, "NULL:NULL - socket: %d", rcv_sck); - } - - g_free(addr); -} - -/*****************************************************************************/ - -const char *g_get_ip_from_description(const char *description, - char *ip, int bytes) +const char * +g_sck_get_peer_ip_address(int sck, + char *ip, unsigned int bytes, + unsigned short *port) { if (bytes > 0) { - /* Look for the space after ip:port */ - const char *end = g_strchr(description, ' '); - if (end == NULL) + int ok = 0; + union sock_info sock_info; + + socklen_t sock_len = sizeof(sock_info); + memset(&sock_info, 0, sock_len); + + if (getpeername(sck, (struct sockaddr *)&sock_info, &sock_len) == 0) { - end = description; /* Means we've failed */ - } - else - { - /* Look back for the last ':' */ - while (end > description && *end != ':') + int family = sock_info.sa.sa_family; + switch (family) { - --end; + case AF_INET: + { + struct sockaddr_in *sa_in = &sock_info.sa_in; + if (inet_ntop(family, &sa_in->sin_addr, ip, bytes) != NULL) + { + ok = 1; + if (port != NULL) + { + *port = ntohs(sa_in->sin_port); + } + } + break; + } + +#if defined(XRDP_ENABLE_IPV6) + + case AF_INET6: + { + struct sockaddr_in6 *sa_in6 = &sock_info.sa_in6; + if (inet_ntop(family, &sa_in6->sin6_addr, ip, bytes) != NULL) + { + ok = 1; + if (port != NULL) + { + *port = ntohs(sa_in6->sin6_port); + } + } + break; + } + +#endif + default: + break; } } - if (end == description) + if (!ok) { - g_snprintf(ip, bytes, ""); - } - else if ((end - description) < (bytes - 1)) - { - g_strncpy(ip, description, end - description); - } - else - { - g_strncpy(ip, description, bytes - 1); + ip[0] = '\0'; } } return ip; } +/*****************************************************************************/ + +const char * +g_sck_get_peer_description(int sck, + char *desc, unsigned int bytes) +{ + union sock_info sock_info; + socklen_t sock_len = sizeof(sock_info); + memset(&sock_info, 0, sock_len); + + if (getpeername(sck, (struct sockaddr *)&sock_info, &sock_len) == 0) + { + get_peer_description(&sock_info, desc, bytes); + } + + return desc; +} + /*****************************************************************************/ void g_sleep(int msecs) diff --git a/common/os_calls.h b/common/os_calls.h index cfa57dbb..9c8a200e 100644 --- a/common/os_calls.h +++ b/common/os_calls.h @@ -84,9 +84,7 @@ int g_sck_vsock_bind(int sck, const char *port); int g_sck_vsock_bind_address(int sck, const char *port, const char *address); int g_tcp_bind_address(int sck, const char *port, const char *address); int g_sck_listen(int sck); -int g_tcp_accept(int sck); -int g_sck_accept(int sck, char *addr, int addr_bytes, - char *port, int port_bytes); +int g_sck_accept(int sck); int g_sck_recv(int sck, void *ptr, int len, int flags); int g_sck_send(int sck, const void *ptr, int len, int flags); int g_sck_last_error_would_block(int sck); @@ -94,18 +92,35 @@ int g_sck_socket_ok(int sck); int g_sck_can_send(int sck, int millis); int g_sck_can_recv(int sck, int millis); int g_sck_select(int sck1, int sck2); -void g_write_connection_description(int rcv_sck, - char *description, int bytes); /** - * Extracts the IP address from the connection description - * @param description Connection description (from - * g_write_connection_description()) + * Gets the IP address of a connected peer, if it has one + * @param sck File descriptor for peer * @param ip buffer to write IP address to - * @param bytes Size of ip buffer + * @param bytes Size of ip buffer. Should be at least MAX_IP_ADDRSTRLEN + * @param[out] portptr Optional variable to receive the port number * @return Pointer to IP for convenience + * + * If the peer has no IP address (for example, it is a Unix Domain Socket), + * or the specified buffer is too small, the returned string is "" */ -const char *g_get_ip_from_description(const char *description, - char *ip, int bytes); +const char * +g_sck_get_peer_ip_address(int sck, + char *ip, unsigned int bytes, + unsigned short *port); +/** + * Gets a description for a connected peer + * @param sck File descriptor for peer + * @param desc buffer to write description to + * @param bytes Size of description buffer. Should be at least + * MAX_PEER_DESCSTRLEN + * @return Pointer to desc for convenience + * + * Unlike g_sck_get_peer_ip_address(), this will return a + * description of some sort for any socket type. + */ +const char * +g_sck_get_peer_description(int sck, + char *desc, unsigned int bytes); void g_sleep(int msecs); tintptr g_create_wait_obj(const char *name); tintptr g_create_wait_obj_from_socket(tintptr socket, int write); diff --git a/common/trans.c b/common/trans.c index eb451073..6b39243b 100644 --- a/common/trans.c +++ b/common/trans.c @@ -330,9 +330,7 @@ trans_check_wait_objs(struct trans *self) { if (g_sck_can_recv(self->sck, 0)) { - in_sck = g_sck_accept(self->sck, self->addr, sizeof(self->addr), - self->port, sizeof(self->port)); - + in_sck = g_sck_accept(self->sck); if (in_sck == -1) { if (g_tcp_last_error_would_block(self->sck)) @@ -357,10 +355,6 @@ trans_check_wait_objs(struct trans *self) in_trans->type1 = TRANS_TYPE_SERVER; in_trans->status = TRANS_STATUS_UP; in_trans->is_term = self->is_term; - g_strncpy(in_trans->addr, self->addr, - sizeof(self->addr) - 1); - g_strncpy(in_trans->port, self->port, - sizeof(self->port) - 1); g_sck_set_non_blocking(in_sck); if (self->trans_conn_in(self, in_trans) != 0) { diff --git a/common/trans.h b/common/trans.h index c6b6c4bb..3d3991ac 100644 --- a/common/trans.h +++ b/common/trans.h @@ -104,8 +104,6 @@ struct trans char *listen_filename; tis_term is_term; /* used to test for exit */ struct stream *wait_s; - char addr[256]; - char port[256]; int no_stream_init_on_data_in; int extra_flags; /* user defined */ void *extra_data; /* user defined */ diff --git a/common/xrdp_client_info.h b/common/xrdp_client_info.h index 0cd844d4..bf57de09 100644 --- a/common/xrdp_client_info.h +++ b/common/xrdp_client_info.h @@ -114,7 +114,7 @@ struct xrdp_client_info int rdp5_performanceflags; int brush_cache_code; /* 0 = no cache 1 = 8x8 standard cache 2 = arbitrary dimensions */ - char connection_description[256]; + int max_bpp; int jpeg; /* non standard bitmap cache v2 cap */ int offscreen_support_level; @@ -146,8 +146,6 @@ struct xrdp_client_info int pointer_flags; /* 0 color, 1 new, 2 no new */ int use_fast_path; int require_credentials; /* when true, credentials *must* be passed on cmd line */ - char client_addr[256]; - char client_port[256]; int security_layer; /* 0 = rdp, 1 = tls , 2 = hybrid */ int multimon; /* 0 = deny , 1 = allow */ @@ -191,6 +189,9 @@ struct xrdp_client_info long ssl_protocols; char *tls_ciphers; + char client_ip[MAX_PEER_ADDRSTRLEN]; + char client_description[MAX_PEER_DESCSTRLEN]; + int client_os_major; int client_os_minor; @@ -207,6 +208,6 @@ struct xrdp_client_info }; /* yyyymmdd of last incompatible change to xrdp_client_info */ -#define CLIENT_INFO_CURRENT_VERSION 20220320 +#define CLIENT_INFO_CURRENT_VERSION 20220428 #endif diff --git a/common/xrdp_constants.h b/common/xrdp_constants.h index 95bb1407..7adce229 100644 --- a/common/xrdp_constants.h +++ b/common/xrdp_constants.h @@ -37,7 +37,22 @@ * ms-erref.h ******************************************************************************/ +/** + * Size of buffer including terminator for an IP address as returned + * by g_sck_get_peer_ip_address(). See POSIX INET6_ADDRSTRLEN + */ +#define MAX_PEER_ADDRSTRLEN 46 + +/** + * Size of buffer including terminator for a socket description, as + * returned by g_sck_get_peer_description() + * Currently the largest is an IPv6 address (INET6_ADDRSTRLEN), plus + * []: characters + */ +#define MAX_PEER_DESCSTRLEN (46 + 2 + 1 + 5) + #define INFO_CLIENT_NAME_BYTES 32 + /** * Maximum length of a string including the mandatory null terminator * [MS-RDPBCGR] TS_INFO_PACKET(2.2.1.11.1.1) diff --git a/libipm/scp.c b/libipm/scp.c index a6cfd827..45f35e4b 100644 --- a/libipm/scp.c +++ b/libipm/scp.c @@ -217,7 +217,7 @@ int scp_send_gateway_request(struct trans *trans, const char *username, const char *password, - const char *connection_description) + const char *ip_addr) { int rv; @@ -227,7 +227,7 @@ scp_send_gateway_request(struct trans *trans, "sss", username, password, - connection_description); + ip_addr); /* Wipe the output buffer to remove the password */ libipm_msg_out_erase(trans); @@ -241,13 +241,13 @@ int scp_get_gateway_request(struct trans *trans, const char **username, const char **password, - const char **connection_description) + const char **ip_addr) { /* Make sure the buffer is cleared after processing this message */ libipm_set_flags(trans, LIBIPM_E_MSG_IN_ERASE_AFTER_USE); return libipm_msg_in_parse(trans, "sss", username, password, - connection_description); + ip_addr); } /*****************************************************************************/ @@ -290,7 +290,7 @@ scp_send_create_session_request(struct trans *trans, unsigned char bpp, const char *shell, const char *directory, - const char *connection_description) + const char *ip_addr) { int rv = libipm_msg_out_simple_send( trans, @@ -304,7 +304,7 @@ scp_send_create_session_request(struct trans *trans, bpp, shell, directory, - connection_description); + ip_addr); /* Wipe the output buffer to remove the password */ libipm_msg_out_erase(trans); @@ -324,7 +324,7 @@ scp_get_create_session_request(struct trans *trans, unsigned char *bpp, const char **shell, const char **directory, - const char **connection_description) + const char **ip_addr) { /* Intermediate values */ uint8_t i_type; @@ -346,7 +346,7 @@ scp_get_create_session_request(struct trans *trans, &i_bpp, shell, directory, - connection_description); + ip_addr); if (rv == 0) { @@ -475,7 +475,7 @@ scp_send_list_sessions_response( info->bpp, info->start_time, info->username, - info->connection_description); + info->start_ip_addr); } return rv; @@ -512,7 +512,7 @@ scp_get_list_sessions_response( uint8_t i_bpp; int64_t i_start_time; char *i_username; - char *i_connection_description; + char *i_start_ip_addr; rv = libipm_msg_in_parse( trans, @@ -525,7 +525,7 @@ scp_get_list_sessions_response( &i_bpp, &i_start_time, &i_username, - &i_connection_description); + &i_start_ip_addr); if (rv == 0) { @@ -533,7 +533,7 @@ scp_get_list_sessions_response( * structure result, and the strings it contains */ unsigned int len = sizeof(struct scp_session_info) + g_strlen(i_username) + 1 + - g_strlen(i_connection_description) + 1; + g_strlen(i_start_ip_addr) + 1; if ((p = (struct scp_session_info *)g_malloc(len, 1)) == NULL) { *status = E_SCP_LS_NO_MEMORY; @@ -543,7 +543,7 @@ scp_get_list_sessions_response( /* Set up the string pointers in the block to point * into the memory allocated after the block */ p->username = (char *)p + sizeof(struct scp_session_info); - p->connection_description = + p->start_ip_addr = p->username + g_strlen(i_username) + 1; /* Copy the data over */ @@ -555,8 +555,7 @@ scp_get_list_sessions_response( p->bpp = i_bpp; p->start_time = i_start_time; g_strcpy(p->username, i_username); - g_strcpy(p->connection_description, - i_connection_description); + g_strcpy(p->start_ip_addr, i_start_ip_addr); } } } diff --git a/libipm/scp.h b/libipm/scp.h index e2d87c3f..1409806f 100644 --- a/libipm/scp.h +++ b/libipm/scp.h @@ -177,7 +177,7 @@ scp_msg_in_reset(struct trans *trans); * @param trans SCP transport * @param username Username * @param password Password - * @param connection_description Description of the connection + * @param ip_addr IP address for the client (or "" if not known) * @return != 0 for error * * Server replies with E_SCP_GATEWAY_RESPONSE @@ -186,7 +186,7 @@ int scp_send_gateway_request(struct trans *trans, const char *username, const char *password, - const char *connection_description); + const char *ip_addr); /** * Parse an incoming E_SCP_GATEWAY_REQUEST message (SCP server) @@ -194,14 +194,14 @@ scp_send_gateway_request(struct trans *trans, * @param trans SCP transport * @param[out] username Username * @param[out] password Password - * @param[out] connection_description Description of the connection + * @param[out] ip_addr IP address for the client. May be "" * @return != 0 for error */ int scp_get_gateway_request(struct trans *trans, const char **username, const char **password, - const char **connection_description); + const char **ip_addr); /** * Send an E_SCP_GATEWAY_RESPONSE (SCP server) @@ -239,7 +239,7 @@ scp_get_gateway_response(struct trans *trans, * @param bpp Session bits-per-pixel (ignored for Xorg sessions) * @param shell User program to run. May be "" * @param directory Directory to run the program in. May be "" - * @param connection_description Description of the connection + * @param ip_addr IP address for the client (or "" if not known) * @return != 0 for error * * Server replies with E_SCP_CREATE_SESSION_RESPONSE @@ -254,7 +254,7 @@ scp_send_create_session_request(struct trans *trans, unsigned char bpp, const char *shell, const char *directory, - const char *connection_description); + const char *ip_addr); /** @@ -269,7 +269,7 @@ scp_send_create_session_request(struct trans *trans, * @param[out] bpp Session bits-per-pixel (ignored for Xorg sessions) * @param[out] shell User program to run. May be "" * @param[out] directory Directory to run the program in. May be "" - * @param[out] connection_description Description of the connection + * @param[out] ip_addr IP address for the client. May be "" * @return != 0 for error * * Returned string pointers are valid until scp_msg_in_reset() is @@ -285,7 +285,7 @@ scp_get_create_session_request(struct trans *trans, unsigned char *bpp, const char **shell, const char **directory, - const char **connection_description); + const char **ip_addr); /** * Send an E_SCP_CREATE_SESSION_RESPONSE (SCP server) diff --git a/libipm/scp_application_types.h b/libipm/scp_application_types.h index 007e86fa..cd21440e 100644 --- a/libipm/scp_application_types.h +++ b/libipm/scp_application_types.h @@ -58,7 +58,7 @@ struct scp_session_info unsigned char bpp; ///< Session bits-per-pixel time_t start_time; ///< When sesion was created char *username; ///< Username for session - char *connection_description; ///< Initial connection to session + char *start_ip_addr; ///< IP address of starting client }; diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c index d08f068a..f9196d4b 100644 --- a/libxrdp/xrdp_rdp.c +++ b/libxrdp/xrdp_rdp.c @@ -360,7 +360,6 @@ struct xrdp_rdp * xrdp_rdp_create(struct xrdp_session *session, struct trans *trans) { struct xrdp_rdp *self = (struct xrdp_rdp *)NULL; - int bytes; LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_create"); self = (struct xrdp_rdp *)g_malloc(sizeof(struct xrdp_rdp), 1); @@ -378,10 +377,13 @@ xrdp_rdp_create(struct xrdp_session *session, struct trans *trans) self->client_info.cache3_entries = 262; self->client_info.cache3_size = 4096; /* load client ip info */ - bytes = sizeof(self->client_info.connection_description) - 1; - g_write_connection_description(trans->sck, - self->client_info.connection_description, - bytes); + g_sck_get_peer_ip_address(trans->sck, + self->client_info.client_ip, + sizeof(self->client_info.client_ip), + NULL); + g_sck_get_peer_description(trans->sck, + self->client_info.client_description, + sizeof(self->client_info.client_description)); self->mppc_enc = mppc_enc_new(PROTO_RDP_50); #if defined(XRDP_NEUTRINORDP) self->rfx_enc = rfx_context_new(); @@ -914,6 +916,7 @@ int xrdp_rdp_incoming(struct xrdp_rdp *self) { struct xrdp_iso *iso; + iso = self->sec_layer->mcs_layer->iso_layer; if (xrdp_sec_incoming(self->sec_layer) != 0) @@ -924,18 +927,13 @@ xrdp_rdp_incoming(struct xrdp_rdp *self) self->mcs_channel = self->sec_layer->mcs_layer->userid + MCS_USERCHANNEL_BASE; LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_rdp->mcs_channel %d", self->mcs_channel); - g_strncpy(self->client_info.client_addr, iso->trans->addr, - sizeof(self->client_info.client_addr) - 1); - g_strncpy(self->client_info.client_port, iso->trans->port, - sizeof(self->client_info.client_port) - 1); /* log TLS version and cipher of TLS connections */ if (iso->selectedProtocol > PROTOCOL_RDP) { LOG(LOG_LEVEL_INFO, - "TLS connection established from %s port %s: %s with cipher %s", - self->client_info.client_addr, - self->client_info.client_port, + "TLS connection established from %s %s with cipher %s", + self->client_info.client_description, iso->trans->ssl_protocol, iso->trans->cipher_name); } @@ -952,11 +950,8 @@ xrdp_rdp_incoming(struct xrdp_rdp *self) /* default */ "unknown"; LOG(LOG_LEVEL_INFO, - "Non-TLS connection established from %s port %s: " - "with security level : %s", - self->client_info.client_addr, - self->client_info.client_port, - security_level); + "Non-TLS connection established from %s with security level : %s", + self->client_info.client_description, security_level); } return 0; diff --git a/neutrinordp/xrdp-neutrinordp.c b/neutrinordp/xrdp-neutrinordp.c index 5c741f20..0e59da1f 100644 --- a/neutrinordp/xrdp-neutrinordp.c +++ b/neutrinordp/xrdp-neutrinordp.c @@ -268,10 +268,9 @@ lxrdp_connect(struct mod *mod) } #endif LOG(LOG_LEVEL_ERROR, "NeutrinoRDP proxy connection: status [Failed]," - " RDP client [%s:%s], RDP server [%s:%d], RDP server username [%s]," + " RDP client [%s], RDP server [%s:%d], RDP server username [%s]," " xrdp pamusername [%s], xrdp process id [%d]", - mod->client_info.client_addr, - mod->client_info.client_port, + mod->client_info.client_description, mod->inst->settings->hostname, mod->inst->settings->port, mod->inst->settings->username, @@ -282,10 +281,9 @@ lxrdp_connect(struct mod *mod) else { LOG(LOG_LEVEL_INFO, "NeutrinoRDP proxy connection: status [Success]," - " RDP client [%s:%s], RDP server [%s:%d], RDP server username [%s]," + " RDP client [%s], RDP server [%s:%d], RDP server username [%s]," " xrdp pamusername [%s], xrdp process id [%d]", - mod->client_info.client_addr, - mod->client_info.client_port, + mod->client_info.client_description, mod->inst->settings->hostname, mod->inst->settings->port, mod->inst->settings->username, @@ -531,10 +529,9 @@ lxrdp_end(struct mod *mod) LOG_DEVEL(LOG_LEVEL_DEBUG, "lxrdp_end:"); LOG(LOG_LEVEL_INFO, "NeutrinoRDP proxy connection: status [Disconnect]," - " RDP client [%s:%s], RDP server [%s:%d], RDP server username [%s]," + " RDP client [%s], RDP server [%s:%d], RDP server username [%s]," " xrdp pamusername [%s], xrdp process id [%d]", - mod->client_info.client_addr, - mod->client_info.client_port, + mod->client_info.client_description, mod->inst->settings->hostname, mod->inst->settings->port, mod->inst->settings->username, diff --git a/sesman/scp_process.c b/sesman/scp_process.c index f4850a3b..822da41a 100644 --- a/sesman/scp_process.c +++ b/sesman/scp_process.c @@ -41,27 +41,19 @@ * Logs an authentication failure message * * @param username Username - * @param connection_description Connection details + * @param ip_addr IP address, if known * * The message is intended for use by fail2ban. Make changes with care. */ static void -log_authfail_message(const char *username, const char *connection_description) +log_authfail_message(const char *username, const char *ip_addr) { - char ip[64]; - const char *ipp; - if (connection_description != NULL && - connection_description[0] != '\0') + if (ip_addr == NULL || ip_addr[0] == '\0') { - g_get_ip_from_description(connection_description, ip, sizeof(ip)); - ipp = ip; - } - else - { - ipp = "unknown"; + ip_addr = "unknown"; } LOG(LOG_LEVEL_INFO, "AUTHFAIL: user=%s ip=%s time=%d", - username, ipp, g_time1()); + username, ip_addr, g_time1()); } /******************************************************************************/ @@ -72,10 +64,9 @@ process_gateway_request(struct trans *trans) int rv; const char *username; const char *password; - const char *connection_description; + const char *ip_addr; - rv = scp_get_gateway_request(trans, &username, &password, - &connection_description); + rv = scp_get_gateway_request(trans, &username, &password, &ip_addr); if (rv == 0) { int errorcode = 0; @@ -103,7 +94,7 @@ process_gateway_request(struct trans *trans) } else { - log_authfail_message(username, connection_description); + log_authfail_message(username, ip_addr); } rv = scp_send_gateway_response(trans, errorcode); auth_end(data); @@ -128,7 +119,7 @@ process_create_session_request(struct trans *trans) trans, &sp.username, &password, &sp.type, &sp.width, &sp.height, &sp.bpp, - &sp.shell, &sp.directory, &sp.connection_description); + &sp.shell, &sp.directory, &sp.ip_addr); if (rv == 0) { @@ -150,12 +141,11 @@ process_create_session_request(struct trans *trans) { display = s_item->display; guid = s_item->guid; - if (sp.connection_description[0] != '\0') + if (sp.ip_addr[0] != '\0') { LOG( LOG_LEVEL_INFO, "++ reconnected session: username %s, " "display :%d.0, session_pid %d, ip %s", - sp.username, display, s_item->pid, - sp.connection_description); + sp.username, display, s_item->pid, sp.ip_addr); } else { @@ -172,12 +162,11 @@ process_create_session_request(struct trans *trans) if (1 == access_login_allowed(sp.username)) { - if (sp.connection_description[0] != '\0') + if (sp.ip_addr[0] != '\0') { LOG(LOG_LEVEL_INFO, "++ created session (access granted): " - "username %s, ip %s", sp.username, - sp.connection_description); + "username %s, ip %s", sp.username, sp.ip_addr); } else { @@ -196,7 +185,7 @@ process_create_session_request(struct trans *trans) } else { - log_authfail_message(sp.username, sp.connection_description); + log_authfail_message(sp.username, sp.ip_addr); } if (do_auth_end) diff --git a/sesman/session.c b/sesman/session.c index 00594d1d..b59be93d 100644 --- a/sesman/session.c +++ b/sesman/session.c @@ -90,46 +90,33 @@ session_get_bydata(const struct session_parameters *sp) { struct session_chain *tmp; enum SESMAN_CFG_SESS_POLICY policy = g_cfg->sess.policy; - char ip[64]; - char tmp_ip[64]; - - if ((policy & SESMAN_CFG_SESS_POLICY_I) != 0) - { - /* We'll need to compare on IP addresses */ - g_get_ip_from_description(sp->connection_description, - ip, sizeof(ip)); - } - else - { - ip[0] = '\0'; - tmp_ip[0] = '\0'; - } LOG(LOG_LEVEL_DEBUG, "session_get_bydata: search policy %d U %s W %d H %d bpp %d T %d IP %s", policy, sp->username, sp->width, sp->height, sp->bpp, - sp->type, sp->connection_description); + sp->type, sp->ip_addr); + + if ((policy & SESMAN_CFG_SESS_POLICY_C) != 0) + { + /* Never matches */ + return NULL; + } for (tmp = g_sessions ; tmp != 0 ; tmp = tmp->next) { - - if ((policy & SESMAN_CFG_SESS_POLICY_I) != 0) - { - g_get_ip_from_description(tmp->item->connection_description, - tmp_ip, sizeof (tmp_ip)); - } + struct session_item *item = tmp->item; LOG(LOG_LEVEL_DEBUG, "session_get_bydata: try %p U %s W %d H %d bpp %d T %d IP %s", - tmp->item, - tmp->item->name, - tmp->item->width, tmp->item->height, - tmp->item->bpp, tmp->item->type, - tmp->item->connection_description); + item, + item->name, + item->width, item->height, + item->bpp, item->type, + item->start_ip_addr); - if (g_strncmp(sp->username, tmp->item->name, 255) != 0 || - tmp->item->bpp != sp->bpp || - tmp->item->type != sp->type) + if (g_strncmp(sp->username, item->name, 255) != 0 || + item->bpp != sp->bpp || + item->type != sp->type) { LOG(LOG_LEVEL_DEBUG, "session_get_bydata: Basic parameters don't match"); @@ -137,29 +124,23 @@ session_get_bydata(const struct session_parameters *sp) } if ((policy & SESMAN_CFG_SESS_POLICY_D) && - (tmp->item->width != sp->width || tmp->item->height != sp->height)) + (item->width != sp->width || item->height != sp->height)) { LOG(LOG_LEVEL_DEBUG, "session_get_bydata: Dimensions don't match for 'D' policy"); continue; } - if ((policy & SESMAN_CFG_SESS_POLICY_I) && g_strcmp(ip, tmp_ip) != 0) + if ((policy & SESMAN_CFG_SESS_POLICY_I) && + g_strcmp(item->start_ip_addr, sp->ip_addr) != 0) { LOG(LOG_LEVEL_DEBUG, "session_get_bydata: IPs don't match for 'I' policy"); continue; } - if ((policy & SESMAN_CFG_SESS_POLICY_C) && - g_strncmp(sp->connection_description, tmp->item->connection_description, 255) != 0) - { - LOG(LOG_LEVEL_DEBUG, - "session_get_bydata: connections don't match for 'C' policy"); - } - LOG(LOG_LEVEL_DEBUG, "session_get_bydata: Got match"); - return tmp->item; + return item; } return 0; @@ -959,14 +940,15 @@ session_start(long data, LOG(LOG_LEVEL_INFO, "Starting session: session_pid %d, " "display :%d.0, width %d, height %d, bpp %d, client ip %s, " "user name %s", - pid, display, s->width, s->height, s->bpp, s->connection_description, s->username); + pid, display, s->width, s->height, s->bpp, s->ip_addr, s->username); temp->item->pid = pid; temp->item->display = display; temp->item->width = s->width; temp->item->height = s->height; temp->item->bpp = s->bpp; temp->item->data = data; - g_strncpy(temp->item->connection_description, s->connection_description, 255); /* store client ip data */ + g_strncpy(temp->item->start_ip_addr, s->ip_addr, + sizeof(temp->item->start_ip_addr) - 1); g_strncpy(temp->item->name, s->username, 255); temp->item->guid = *guid; @@ -1071,7 +1053,7 @@ session_kill(int pid) /* deleting the session */ LOG(LOG_LEVEL_INFO, "++ terminated session: username %s, display :%d.0, session_pid %d, ip %s", - tmp->item->name, tmp->item->display, tmp->item->pid, tmp->item->connection_description); + tmp->item->name, tmp->item->display, tmp->item->pid, tmp->item->start_ip_addr); g_free(tmp->item); if (prev == 0) @@ -1227,11 +1209,10 @@ session_get_byuser(const char *user, unsigned int *cnt, unsigned char flags) (sess[index]).bpp = tmp->item->bpp; (sess[index]).start_time = tmp->item->start_time; (sess[index]).username = g_strdup(tmp->item->name); - (sess[index]).connection_description = - g_strdup(tmp->item->connection_description); + (sess[index]).start_ip_addr = g_strdup(tmp->item->start_ip_addr); if ((sess[index]).username == NULL || - (sess[index]).connection_description == NULL) + (sess[index]).start_ip_addr == NULL) { free_session_info_list(sess, *cnt); (*cnt) = 0; @@ -1259,7 +1240,7 @@ free_session_info_list(struct scp_session_info *sesslist, unsigned int cnt) for (i = 0 ; i < cnt ; ++i) { g_free(sesslist[i].username); - g_free(sesslist[i].connection_description); + g_free(sesslist[i].start_ip_addr); } } @@ -1374,7 +1355,7 @@ clone_session_params(const struct session_parameters *sp) len += g_strlen(sp->username) + 1; len += g_strlen(sp->shell) + 1; len += g_strlen(sp->directory) + 1; - len += g_strlen(sp->connection_description) + 1; + len += g_strlen(sp->ip_addr) + 1; if ((result = (struct session_parameters *)g_malloc(len, 0)) != NULL) { @@ -1394,8 +1375,7 @@ clone_session_params(const struct session_parameters *sp) COPY_STRING_MEMBER(sp->username, result->username); COPY_STRING_MEMBER(sp->shell, result->shell); COPY_STRING_MEMBER(sp->directory, result->directory); - COPY_STRING_MEMBER(sp->connection_description, - result->connection_description); + COPY_STRING_MEMBER(sp->ip_addr, result->ip_addr); #undef COPY_STRING_MEMBER } diff --git a/sesman/session.h b/sesman/session.h index d8a9fb82..7bcec957 100644 --- a/sesman/session.h +++ b/sesman/session.h @@ -32,6 +32,7 @@ #include "guid.h" #include "scp_application_types.h" +#include "xrdp_constants.h" #define SESMAN_SESSION_STATUS_ACTIVE 0x01 #define SESMAN_SESSION_STATUS_IDLE 0x02 @@ -68,7 +69,7 @@ struct session_item time_t start_time; // struct session_date disconnect_time; // Currently unused // struct session_date idle_time; // Currently unused - char connection_description[256]; + char start_ip_addr[MAX_PEER_ADDRSTRLEN]; struct guid guid; }; @@ -91,7 +92,7 @@ struct session_parameters const char *username; const char *shell; const char *directory; - const char *connection_description; + const char *ip_addr; }; /** diff --git a/sesman/tools/sesadmin.c b/sesman/tools/sesadmin.c index 4ef56a02..ba1cadaf 100644 --- a/sesman/tools/sesadmin.c +++ b/sesman/tools/sesadmin.c @@ -153,9 +153,9 @@ print_session(const struct scp_session_info *s) printf("\tScreen size: %dx%d, color depth %d\n", s->width, s->height, s->bpp); printf("\tStarted: %s", ctime(&s->start_time)); - if (s->connection_description[0] != '\0') + if (s->start_ip_addr[0] != '\0') { - printf("\tConnection Description: %s\n", s->connection_description); + printf("\tStart IP address: %s\n", s->start_ip_addr); } } diff --git a/tools/devel/tcp_proxy/main.c b/tools/devel/tcp_proxy/main.c index 13319f29..66dd9f31 100644 --- a/tools/devel/tcp_proxy/main.c +++ b/tools/devel/tcp_proxy/main.c @@ -112,7 +112,7 @@ main_loop(char *local_port, char *remote_ip, char *remote_port, int hexdump) { while ((!g_terminated) && (error == 0)) { - acc_sck = g_tcp_accept(lis_sck); + acc_sck = g_sck_accept(lis_sck); if ((acc_sck == -1) && g_tcp_last_error_would_block(lis_sck)) { diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c index 16497a89..22993d01 100644 --- a/xrdp/xrdp_mm.c +++ b/xrdp/xrdp_mm.c @@ -232,7 +232,7 @@ xrdp_mm_send_gateway_login(struct xrdp_mm *self, const char *username, return scp_send_gateway_request( self->sesman_trans, username, password, - self->wm->client_info->connection_description); + self->wm->client_info->client_ip); } /*****************************************************************************/ @@ -301,7 +301,7 @@ xrdp_mm_send_login(struct xrdp_mm *self) xserverbpp, self->wm->client_info->program, self->wm->client_info->directory, - self->wm->client_info->connection_description); + self->wm->client_info->client_ip); } } diff --git a/xrdp/xrdp_wm.c b/xrdp/xrdp_wm.c index caa1160a..6d5f1b89 100644 --- a/xrdp/xrdp_wm.c +++ b/xrdp/xrdp_wm.c @@ -683,12 +683,11 @@ xrdp_wm_init(struct xrdp_wm *self) if (file_read_section(fd, section_name, names, values) != 0) { LOG(LOG_LEVEL_INFO, - "Module \"%s\" specified by %s from %s port %s " + "Module \"%s\" specified by %s from %s " "is not configured. Using \"%s\" instead.", section_name, self->session->client_info->username, - self->session->client_info->client_addr, - self->session->client_info->client_port, + self->session->client_info->client_description, default_section_name); list_clear(names); list_clear(values); diff --git a/xup/xup.c b/xup/xup.c index 4ca395b9..cae29100 100644 --- a/xup/xup.c +++ b/xup/xup.c @@ -73,10 +73,9 @@ lib_mod_log_peer(struct mod *mod) { LOG(LOG_LEVEL_INFO, "lib_mod_log_peer: xrdp_pid=%d connected " "to X11rdp_pid=%d X11rdp_uid=%d X11rdp_gid=%d " - "client_ip=%s client_port=%s", + "client=%s", my_pid, pid, uid, gid, - mod->client_info.client_addr, - mod->client_info.client_port); + mod->client_info.client_description); } else {