Skip to content

Commit

Permalink
Merge pull request #2251 from matt335672/refactor_ip_addr_handling
Browse files Browse the repository at this point in the history
Refactor ip address handling
  • Loading branch information
matt335672 committed May 19, 2022
2 parents 608d91a + 3e48877 commit 6c4bdf7
Show file tree
Hide file tree
Showing 32 changed files with 999 additions and 541 deletions.
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

0 comments on commit 6c4bdf7

Please sign in to comment.