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

Fail2ban support #1976

Merged
merged 3 commits into from
Nov 18, 2021
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
49 changes: 43 additions & 6 deletions common/os_calls.c
Original file line number Diff line number Diff line change
Expand Up @@ -1389,11 +1389,9 @@ g_sck_accept(int sck, char *addr, int addr_bytes, char *port, int port_bytes)
}

/*****************************************************************************/
/*
* TODO: this function writes not only IP address, name is confusing
*/

void
g_write_ip_address(int rcv_sck, char *ip_address, int bytes)
g_write_connection_description(int rcv_sck, char *description, int bytes)
{
char *addr;
int port;
Expand Down Expand Up @@ -1454,18 +1452,57 @@ g_write_ip_address(int rcv_sck, char *ip_address, int bytes)

if (ok)
{
g_snprintf(ip_address, bytes, "%s:%d - socket: %d", addr, port, rcv_sck);
g_snprintf(description, bytes, "%s:%d - socket: %d", addr, port, rcv_sck);
}
}

if (!ok)
{
g_snprintf(ip_address, bytes, "NULL:NULL - socket: %d", rcv_sck);
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)
{
if (bytes > 0)
{
/* Look for the space after ip:port */
const char *end = g_strchr(description, ' ');
if (end == NULL)
{
end = description; /* Means we've failed */
}
else
{
/* Look back for the last ':' */
while (end > description && *end != ':')
{
--end;
}
}

if (end == description)
{
g_snprintf(ip, bytes, "<unknown>");
}
else if ((end - description) < (bytes - 1))
{
g_strncpy(ip, description, end - description);
}
else
{
g_strncpy(ip, description, bytes - 1);
}
}

return ip;
}

/*****************************************************************************/
void
g_sleep(int msecs)
Expand Down
13 changes: 12 additions & 1 deletion common/os_calls.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,18 @@ 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_ip_address(int rcv_sck, char *ip_address, int bytes);
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())
* @param ip buffer to write IP address to
* @param bytes Size of ip buffer
* @return Pointer to IP for convenience
*/
const char *g_get_ip_from_description(const char *description,
char *ip, 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
2 changes: 1 addition & 1 deletion common/xrdp_client_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ struct xrdp_client_info
int rdp5_performanceflags;
int brush_cache_code; /* 0 = no cache 1 = 8x8 standard cache
2 = arbitrary dimensions */
char client_ip[256];
char connection_description[256];
int max_bpp;
int jpeg; /* non standard bitmap cache v2 cap */
int offscreen_support_level;
Expand Down
6 changes: 4 additions & 2 deletions libxrdp/xrdp_rdp.c
Original file line number Diff line number Diff line change
Expand Up @@ -378,8 +378,10 @@ 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.client_ip) - 1;
g_write_ip_address(trans->sck, self->client_info.client_ip, bytes);
bytes = sizeof(self->client_info.connection_description) - 1;
g_write_connection_description(trans->sck,
self->client_info.connection_description,
bytes);
self->mppc_enc = mppc_enc_new(PROTO_RDP_50);
#if defined(XRDP_NEUTRINORDP)
self->rfx_enc = rfx_context_new();
Expand Down
20 changes: 10 additions & 10 deletions sesman/libscp/libscp_session.c
Original file line number Diff line number Diff line change
Expand Up @@ -307,24 +307,24 @@ scp_session_set_directory(struct SCP_SESSION *s, const char *str)

/*******************************************************************/
int
scp_session_set_client_ip(struct SCP_SESSION *s, const char *str)
scp_session_set_connection_description(struct SCP_SESSION *s, const char *str)
{
if (0 == str)
{
LOG(LOG_LEVEL_WARNING, "[session:%d] set_client_ip: null ip", __LINE__);
LOG(LOG_LEVEL_WARNING, "[session:%d] set_connection_description: null description", __LINE__);
return 1;
}

if (0 != s->client_ip)
if (0 != s->connection_description)
{
g_free(s->client_ip);
g_free(s->connection_description);
}

s->client_ip = g_strdup(str);
s->connection_description = g_strdup(str);

if (0 == s->client_ip)
if (0 == s->connection_description)
{
LOG(LOG_LEVEL_WARNING, "[session:%d] set_client_ip: strdup error", __LINE__);
LOG(LOG_LEVEL_WARNING, "[session:%d] set_connection_description: strdup error", __LINE__);
return 1;
}

Expand Down Expand Up @@ -439,7 +439,7 @@ scp_session_destroy(struct SCP_SESSION *s)
g_free(s->domain);
g_free(s->program);
g_free(s->directory);
g_free(s->client_ip);
g_free(s->connection_description);
g_free(s->errstr);
g_free(s);
}
Expand All @@ -464,7 +464,7 @@ scp_session_clone(const struct SCP_SESSION *s)
result->domain = g_strdup(s->domain);
result->program = g_strdup(s->program);
result->directory = g_strdup(s->directory);
result->client_ip = g_strdup(s->client_ip);
result->connection_description = g_strdup(s->connection_description);

/* Did all the string copies succeed? */
if ((s->username != NULL && result->username == NULL) ||
Expand All @@ -474,7 +474,7 @@ scp_session_clone(const struct SCP_SESSION *s)
(s->domain != NULL && result->domain == NULL) ||
(s->program != NULL && result->program == NULL) ||
(s->directory != NULL && result->directory == NULL) ||
(s->client_ip != NULL && result->client_ip == NULL))
(s->connection_description != NULL && result->connection_description == NULL))
{
scp_session_destroy(result);
result = NULL;
Expand Down
2 changes: 1 addition & 1 deletion sesman/libscp/libscp_session.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ int
scp_session_set_directory(struct SCP_SESSION *s, const char *str);

int
scp_session_set_client_ip(struct SCP_SESSION *s, const char *str);
scp_session_set_connection_description(struct SCP_SESSION *s, const char *str);

int
scp_session_set_hostname(struct SCP_SESSION *s, const char *str);
Expand Down
2 changes: 1 addition & 1 deletion sesman/libscp/libscp_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ struct SCP_SESSION
char *domain;
char *program;
char *directory;
char *client_ip;
char *connection_description;
tui8 guid[16];
/* added for state */
int current_cmd;
Expand Down
4 changes: 2 additions & 2 deletions sesman/libscp/libscp_v0.c
Original file line number Diff line number Diff line change
Expand Up @@ -355,13 +355,13 @@ scp_v0s_accept(struct trans *atrans, struct SCP_SESSION *session)
if (s_check_rem(in_s, 2))
{
/* reading client IP address */
if (!in_string16(in_s, buf, "client IP"))
if (!in_string16(in_s, buf, "connection description"))
{
return SCP_SERVER_STATE_SIZE_ERR;
}
if (buf[0] != '\0')
{
scp_session_set_client_ip(session, buf);
scp_session_set_connection_description(session, buf);
}
}
}
Expand Down
22 changes: 15 additions & 7 deletions sesman/scp_v0.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,17 +77,18 @@ scp_v0_process(struct trans *t, struct SCP_SESSION *s)
else if (data)
{
s_item = session_get_bydata(s->username, s->width, s->height,
s->bpp, s->type, s->client_ip);
s->bpp, s->type, s->connection_description);

if (s_item != 0)
{
display = s_item->display;
g_memcpy(s->guid, s_item->guid, 16);
if (0 != s->client_ip)
if (0 != s->connection_description)
{
LOG( LOG_LEVEL_INFO, "++ reconnected session: username %s, "
"display :%d.0, session_pid %d, ip %s",
s->username, display, s_item->pid, s->client_ip);
s->username, display, s_item->pid,
s->connection_description);
}
else
{
Expand All @@ -109,10 +110,10 @@ scp_v0_process(struct trans *t, struct SCP_SESSION *s)
g_random((char *)guid, 16);
scp_session_set_guid(s, guid);

if (0 != s->client_ip)
if (0 != s->connection_description)
{
LOG(LOG_LEVEL_INFO, "++ created session (access granted): "
"username %s, ip %s", s->username, s->client_ip);
"username %s, ip %s", s->username, s->connection_description);
}
else
{
Expand Down Expand Up @@ -157,8 +158,15 @@ scp_v0_process(struct trans *t, struct SCP_SESSION *s)
}
else
{
LOG(LOG_LEVEL_INFO, "Username or password error for user: %s",
s->username);
char ip[64];
g_get_ip_from_description(s->connection_description, ip, sizeof(ip));
/*
* The message is intended for use by fail2ban, so for
* future-proofing we only log the IP address rather than the
* connection description */
LOG(LOG_LEVEL_INFO,
"AUTHFAIL: user=%s ip=%s time=%d",
s->username, ip, g_time1());
scp_v0s_deny_connection(t);
}
if (do_auth_end)
Expand Down
20 changes: 14 additions & 6 deletions sesman/scp_v1.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,17 @@ scp_v1_process1(struct trans *t, struct SCP_SESSION *s)
}
else
{
char ip[64];
g_get_ip_from_description(s->connection_description,
ip, sizeof(ip));
/*
* The message is intended for use by fail2ban, so for
* future-proofing we only log the IP address rather than the
* connection description */
LOG(LOG_LEVEL_INFO,
"AUTHFAIL: user=%s ip=%s time=%d",
s->username, ip, g_time1());
scp_v1s_deny_connection(t, "Login failed");
LOG(LOG_LEVEL_INFO, "Login failed for user %s. "
"Connection terminated", s->username);
return SCP_SERVER_STATE_END;
}
return SCP_SERVER_STATE_OK;
Expand All @@ -108,10 +116,10 @@ scp_v1_process1(struct trans *t, struct SCP_SESSION *s)
LOG(LOG_LEVEL_DEBUG, "No disconnected sessions for this user "
"- we create a new one");

if (0 != s->client_ip)
if (0 != s->connection_description)
{
LOG(LOG_LEVEL_INFO, "++ created session (access granted): "
"username %s, ip %s", s->username, s->client_ip);
"username %s, ip %s", s->username, s->connection_description);
}
else
{
Expand Down Expand Up @@ -219,9 +227,9 @@ scp_v1_process43(struct trans *t, struct SCP_SESSION *s)
{
LOG(LOG_LEVEL_ERROR, "scp_v1s_reconnect_session failed");
}
if (0 != s->client_ip)
if (0 != s->connection_description)
{
LOG(LOG_LEVEL_INFO, "++ reconnected session: username %s, display :%d.0, session_pid %d, ip %s", s->username, display, sitem->pid, s->client_ip);
LOG(LOG_LEVEL_INFO, "++ reconnected session: username %s, display :%d.0, session_pid %d, ip %s", s->username, display, sitem->pid, s->connection_description);
}
else
{
Expand Down
39 changes: 31 additions & 8 deletions sesman/session.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,11 @@ dumpItemsToString(struct list *self, char *outstr, int len)
/******************************************************************************/
struct session_item *
session_get_bydata(const char *name, int width, int height, int bpp, int type,
const char *client_ip)
const char *connection_description)
{
struct session_chain *tmp;
enum SESMAN_CFG_SESS_POLICY policy = g_cfg->sess.policy;
char ip[64];

tmp = g_sessions;

Expand All @@ -115,27 +116,49 @@ session_get_bydata(const char *name, int width, int height, int bpp, int type,
return 0;
}

if ((policy & SESMAN_CFG_SESS_POLICY_I) != 0)
{
/* We'll need to compare on IP addresses */
g_get_ip_from_description(connection_description, ip, sizeof(ip));
}
else
{
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, name, width, height, bpp, type, client_ip);
policy, name, width, height, bpp, type, connection_description);

while (tmp != 0)
{
char tmp_ip[64];

if ((policy & SESMAN_CFG_SESS_POLICY_I) != 0)
{
g_get_ip_from_description(tmp->item->connection_description,
tmp_ip, sizeof (tmp_ip));
}
else
{
tmp_ip[0] = '\0';
}

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->client_ip);
tmp->item->connection_description);

if (g_strncmp(name, tmp->item->name, 255) == 0 &&
(!(policy & SESMAN_CFG_SESS_POLICY_D) ||
(tmp->item->width == width && tmp->item->height == height)) &&
(!(policy & SESMAN_CFG_SESS_POLICY_I) ||
(g_strncmp_d(client_ip, tmp->item->client_ip, ':', 255) == 0)) &&
(g_strcmp(ip, tmp_ip) == 0)) &&
(!(policy & SESMAN_CFG_SESS_POLICY_C) ||
(g_strncmp(client_ip, tmp->item->client_ip, 255) == 0)) &&
(g_strncmp(connection_description, tmp->item->connection_description, 255) == 0)) &&
tmp->item->bpp == bpp &&
tmp->item->type == type)
{
Expand Down Expand Up @@ -925,14 +948,14 @@ session_start_fork(tbus data, tui8 type, struct SCP_SESSION *s)
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->client_ip, s->username);
pid, display, s->width, s->height, s->bpp, s->connection_description, 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->client_ip, s->client_ip, 255); /* store client ip data */
g_strncpy(temp->item->connection_description, s->connection_description, 255); /* store client ip data */
g_strncpy(temp->item->name, s->username, 255);
g_memcpy(temp->item->guid, s->guid, 16);

Expand Down Expand Up @@ -1064,7 +1087,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->client_ip);
tmp->item->name, tmp->item->display, tmp->item->pid, tmp->item->connection_description);
g_free(tmp->item);

if (prev == 0)
Expand Down
Loading