Unify connection fields for the connected client

The connected client is currently described in two places in
the xrdp_client_info structure:-

1) In the connection_description field. This was introduced as
   field client_ip by commit d797b2cf49
   for xrdp v0.6.0

2) In the client_addr and client_port fields introduced by commit
   25369460a1 for xrdp v0.8.0

This commit unifies these two sets of fields into a single
set of fields describing the connection IP and port (for
AF_INET/AF_INET6 connections only) and a connection description
for all connection types.

The code in os_calls to provide client logging has been simplified
somewhat which should make it easier to add new connection types (e.g.
AF_VSOCK).

The old connection_description field used to be passed to sesman to
inform sesman of the IP address of the client, and also to provide
a string for 'C' field session policy matching. 'C' field session policy
matching does not actually need this string (see #2239), and so now only
the IP field is passed to sesman.
This commit is contained in:
matt335672 2022-04-22 11:56:23 +01:00
parent 608d91a68b
commit 79bec8110c
19 changed files with 314 additions and 472 deletions

View File

@ -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, "<unknown AF_INET>:%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, "[<unknown AF_INET6>]:%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, "<unknown>");
}
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)

View File

@ -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);

View File

@ -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)
{

View File

@ -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 */

View File

@ -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

View File

@ -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
* []:<port> 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)

View File

@ -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);
}
}
}

View File

@ -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)

View File

@ -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
};

View File

@ -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;

View File

@ -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,

View File

@ -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)

View File

@ -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
}

View File

@ -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;
};
/**

View File

@ -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);
}
}

View File

@ -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))
{

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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
{