Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor ip address handling #2251

Merged
merged 6 commits into from
May 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
416 changes: 138 additions & 278 deletions common/os_calls.c

Large diffs are not rendered by default.

37 changes: 26 additions & 11 deletions common/os_calls.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,28 +84,43 @@ 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);
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_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_get_ip_from_description(const char *description,
char *ip, int bytes);
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);
Expand Down
87 changes: 87 additions & 0 deletions common/string_calls.c
Original file line number Diff line number Diff line change
Expand Up @@ -921,6 +921,7 @@ g_strnjoin(char *dest, int dest_len, const char *joiner, const char *src[], int
return dest;
}

/*****************************************************************************/
int
g_bitmask_to_str(int bitmask, const struct bitmask_string bitdefs[],
char delim, char *buff, int bufflen)
Expand Down Expand Up @@ -987,6 +988,7 @@ g_bitmask_to_str(int bitmask, const struct bitmask_string bitdefs[],
return rlen;
}

/*****************************************************************************/
int
g_str_to_bitmask(const char *str, const struct bitmask_string bitdefs[],
const char *delim, char *unrecognised, int unrecognised_len)
Expand Down Expand Up @@ -1055,3 +1057,88 @@ g_str_to_bitmask(const char *str, const struct bitmask_string bitdefs[],
return mask;
}

/*****************************************************************************/
int
g_bitmask_to_charstr(int bitmask, const struct bitmask_char bitdefs[],
char *buff, int bufflen, int *rest)
{
int rlen = 0; /* Returned length */

if (bufflen <= 0) /* Caller error */
{
rlen = -1;
}
else
{
char *p = buff;
/* Find the last writeable character in the buffer */
const char *last = buff + (bufflen - 1);

const struct bitmask_char *b;

for (b = &bitdefs[0] ; b->c != '\0'; ++b)
{
if ((bitmask & b->mask) != 0)
{
if (p < last)
{
*p++ = b->c;
}
++rlen;

/* Remove the bit so we don't report it back */
bitmask &= ~b->mask;
}
}
*p = '\0';

if (rest != NULL)
{
*rest = bitmask;
}
}

return rlen;
}

/*****************************************************************************/
int
g_charstr_to_bitmask(const char *str, const struct bitmask_char bitdefs[],
char *unrecognised, int unrecognised_len)
{
int bitmask = 0;
const char *cp;
int j = 0;

if (str != NULL && bitdefs != NULL)
{
for (cp = str ; *cp != '\0' ; ++cp)
{
const struct bitmask_char *b;
char c = toupper(*cp);

for (b = &bitdefs[0] ; b->c != '\0'; ++b)
{
if (toupper(b->c) == c)
{
bitmask |= b->mask;
break;
}
}
if (b->c == '\0')
{
if (unrecognised != NULL && j < (unrecognised_len - 1))
{
unrecognised[j++] = *cp;
}
}
}
}

if (unrecognised != NULL && j < unrecognised_len)
{
unrecognised[j] = '\0';
}

return bitmask;
}
68 changes: 65 additions & 3 deletions common/string_calls.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,21 @@ struct bitmask_string

#define BITMASK_STRING_END_OF_LIST { 0, NULL }

/**
* Map a bitmask to a char value
*
*
* This structure is used by g_bitmask_to_charstr() to specify the
* char for each bit in the bitmask
*/
struct bitmask_char
{
int mask;
char c;
};

#define BITMASK_CHAR_END_OF_LIST { 0, '\0' }

/**
* Processes a format string for general info
*
Expand Down Expand Up @@ -158,6 +173,9 @@ g_get_display_num_from_display(const char *display_text);
/**
* Converts a bitmask into a string for output purposes
*
* Similar to g_bitmask_to_charstr(), but tokens are strings, separated
* by delimiters.
*
* @param bitmask Bitmask to convert
* @param bitdefs Definitions for strings for bits
* @param delim Delimiter to use between strings
Expand All @@ -171,23 +189,67 @@ g_get_display_num_from_display(const char *display_text);
* a hexadecimal constant.
*/
int
g_bitmask_to_str(int bitmask, const struct bitmask_string[],
g_bitmask_to_str(int bitmask, const struct bitmask_string bitdefs[],
char delim, char *buff, int bufflen);

/***
* Converts a string containing a series of tokens to a bitmask.
*
* Similar to g_charstr_to_bitmask(), but tokens are strings, separated
* by delimiters.
*
* @param str Input string
* @param bitmask_string Array mapping tokens to bitmask values
* @param bitdefs Array mapping tokens to bitmask values
* @param delim Delimiter for tokens in str
* @param[out] unrecognised Buffer for any unrecognised tokens
* @param unrecognised_len Length of unrecognised including '\0';
* @return bitmask value for recognised tokens
*/
int
g_str_to_bitmask(const char *str, const struct bitmask_string[],
g_str_to_bitmask(const char *str, const struct bitmask_string bitdefs[],
const char *delim, char *unrecognised,
int unrecognised_len);

/**
* Converts a bitmask into a string for output purposes
*
* Similar to g_bitmask_to_str(), but tokens are individual characters, and
* there are no delimiters.
*
* @param bitmask Bitmask to convert
* @param bitdefs Definitions for strings for bits
* @param buff Output buff
* @param bufflen Length of buff, including terminator '`\0'
* @param[out] rest Any unused bits which weren't covered by bitdefs.
* May be NULL.
*
* @return Total length excluding terminator which would be written, as
* in snprintf(). Can be used to check for overflow
*
* @note Any undefined bits in the bitmask are appended to the output as
* a hexadecimal constant.
*/
int
g_bitmask_to_charstr(int bitmask, const struct bitmask_char bitdefs[],
char *buff, int bufflen, int *rest);

/***
* Converts a string containing a series of characters to a bitmask.
*
* Similar to g_str_to_bitmask(), but tokens are individual characters, and
* there are no delimiters.
*
* @param str Input string
* @param bitdefs Array mapping tokens to bitmask values
* @param delim Delimiter for tokens in str
* @param[out] unrecognised Buffer for any unrecognised tokens
* @param unrecognised_len Length of unrecognised including '\0';
* @return bitmask value for recognised tokens
*/
int
g_charstr_to_bitmask(const char *str, const struct bitmask_char bitdefs[],
char *unrecognised, int unrecognised_len);

int g_strlen(const char *text);
char *g_strchr(const char *text, int c);
char *g_strrchr(const char *text, int c);
Expand Down
8 changes: 1 addition & 7 deletions common/trans.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand All @@ -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)
{
Expand Down
2 changes: 0 additions & 2 deletions common/trans.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
9 changes: 5 additions & 4 deletions common/xrdp_client_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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;

Expand All @@ -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
15 changes: 15 additions & 0 deletions common/xrdp_constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Loading