mirror of https://github.com/neutrinolabs/xrdp
sesman: work on moving sesman to trans, v0 scp working
This commit is contained in:
parent
7e95576849
commit
738e346f81
|
@ -31,6 +31,7 @@
|
|||
#include "parse.h"
|
||||
#include "arch.h"
|
||||
#include "log.h"
|
||||
#include "trans.h"
|
||||
|
||||
#define SCP_SID tui32
|
||||
#define SCP_DISPLAY tui16
|
||||
|
|
|
@ -89,8 +89,9 @@ int in_string16(struct stream *s, char str[], const char *param)
|
|||
return result;
|
||||
}
|
||||
/* client API */
|
||||
#if 0
|
||||
/******************************************************************************/
|
||||
enum SCP_CLIENT_STATES_E
|
||||
static enum SCP_CLIENT_STATES_E
|
||||
scp_v0c_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
{
|
||||
tui32 version;
|
||||
|
@ -216,6 +217,9 @@ scp_v0c_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
|||
LOG_DEVEL(LOG_LEVEL_DEBUG, "connection terminated");
|
||||
return SCP_CLIENT_STATE_END;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* server API */
|
||||
|
||||
/**
|
||||
* Initialises a V0 session object
|
||||
|
@ -227,38 +231,24 @@ scp_v0c_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
|||
* @return SCP_SERVER_STATE_OK for success
|
||||
*/
|
||||
static enum SCP_SERVER_STATES_E
|
||||
scp_v0s_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session)
|
||||
scp_v0s_init_session(struct trans *atrans, struct SCP_SESSION *session)
|
||||
{
|
||||
int size;
|
||||
tui16 height;
|
||||
tui16 width;
|
||||
tui16 bpp;
|
||||
tui32 code = 0;
|
||||
char buf[STRING16_MAX_LEN + 1];
|
||||
struct stream *in_s = atrans->in_s;
|
||||
|
||||
scp_session_set_version(session, 0);
|
||||
|
||||
/* Check for a header and a code value in the length */
|
||||
in_uint32_be(c->in_s, size);
|
||||
if (size < (8 + 2) || size > SCP_MAX_MESSAGE_SIZE)
|
||||
if (!s_check_rem(in_s, 6))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "connection aborted: msg size = %d", size);
|
||||
return SCP_SERVER_STATE_SIZE_ERR;
|
||||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
|
||||
init_stream(c->in_s, size - 8);
|
||||
|
||||
if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "connection aborted: network error");
|
||||
return SCP_SERVER_STATE_NETWORK_ERR;
|
||||
}
|
||||
|
||||
c->in_s->end = c->in_s->data + (size - 8);
|
||||
|
||||
in_uint16_be(c->in_s, code);
|
||||
|
||||
if (code == 0 || code == 10 || code == 20)
|
||||
in_uint8s(in_s, 4); /* size */
|
||||
in_uint16_be(in_s, code);
|
||||
if ((code == 0) || (code == 10) || (code == 20))
|
||||
{
|
||||
if (code == 0)
|
||||
{
|
||||
|
@ -274,7 +264,7 @@ scp_v0s_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session)
|
|||
}
|
||||
|
||||
/* reading username */
|
||||
if (!in_string16(c->in_s, buf, "username"))
|
||||
if (!in_string16(in_s, buf, "username"))
|
||||
{
|
||||
return SCP_SERVER_STATE_SIZE_ERR;
|
||||
}
|
||||
|
@ -285,7 +275,7 @@ scp_v0s_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session)
|
|||
}
|
||||
|
||||
/* reading password */
|
||||
if (!in_string16(c->in_s, buf, "passwd"))
|
||||
if (!in_string16(in_s, buf, "passwd"))
|
||||
{
|
||||
return SCP_SERVER_STATE_SIZE_ERR;
|
||||
}
|
||||
|
@ -296,16 +286,16 @@ scp_v0s_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session)
|
|||
}
|
||||
|
||||
/* width + height + bpp */
|
||||
if (!s_check_rem(c->in_s, 2 + 2 + 2))
|
||||
if (!s_check_rem(in_s, 2 + 2 + 2))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "connection aborted: width+height+bpp missing");
|
||||
return SCP_SERVER_STATE_SIZE_ERR;
|
||||
}
|
||||
in_uint16_be(c->in_s, width);
|
||||
in_uint16_be(in_s, width);
|
||||
scp_session_set_width(session, width);
|
||||
in_uint16_be(c->in_s, height);
|
||||
in_uint16_be(in_s, height);
|
||||
scp_session_set_height(session, height);
|
||||
in_uint16_be(c->in_s, bpp);
|
||||
in_uint16_be(in_s, bpp);
|
||||
if (0 != scp_session_set_bpp(session, (tui8)bpp))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING,
|
||||
|
@ -313,10 +303,10 @@ scp_v0s_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session)
|
|||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
|
||||
if (s_check_rem(c->in_s, 2))
|
||||
if (s_check_rem(in_s, 2))
|
||||
{
|
||||
/* reading domain */
|
||||
if (!in_string16(c->in_s, buf, "domain"))
|
||||
if (!in_string16(in_s, buf, "domain"))
|
||||
{
|
||||
return SCP_SERVER_STATE_SIZE_ERR;
|
||||
}
|
||||
|
@ -326,10 +316,10 @@ scp_v0s_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session)
|
|||
}
|
||||
}
|
||||
|
||||
if (s_check_rem(c->in_s, 2))
|
||||
if (s_check_rem(in_s, 2))
|
||||
{
|
||||
/* reading program */
|
||||
if (!in_string16(c->in_s, buf, "program"))
|
||||
if (!in_string16(in_s, buf, "program"))
|
||||
{
|
||||
return SCP_SERVER_STATE_SIZE_ERR;
|
||||
}
|
||||
|
@ -340,10 +330,10 @@ scp_v0s_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session)
|
|||
}
|
||||
}
|
||||
|
||||
if (s_check_rem(c->in_s, 2))
|
||||
if (s_check_rem(in_s, 2))
|
||||
{
|
||||
/* reading directory */
|
||||
if (!in_string16(c->in_s, buf, "directory"))
|
||||
if (!in_string16(in_s, buf, "directory"))
|
||||
{
|
||||
return SCP_SERVER_STATE_SIZE_ERR;
|
||||
}
|
||||
|
@ -354,10 +344,10 @@ scp_v0s_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session)
|
|||
}
|
||||
}
|
||||
|
||||
if (s_check_rem(c->in_s, 2))
|
||||
if (s_check_rem(in_s, 2))
|
||||
{
|
||||
/* reading client IP address */
|
||||
if (!in_string16(c->in_s, buf, "client IP"))
|
||||
if (!in_string16(in_s, buf, "client IP"))
|
||||
{
|
||||
return SCP_SERVER_STATE_SIZE_ERR;
|
||||
}
|
||||
|
@ -371,12 +361,11 @@ scp_v0s_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session)
|
|||
{
|
||||
scp_session_set_type(session, SCP_GW_AUTHENTICATION);
|
||||
/* reading username */
|
||||
if (!in_string16(c->in_s, buf, "username"))
|
||||
if (!in_string16(in_s, buf, "username"))
|
||||
{
|
||||
return SCP_SERVER_STATE_SIZE_ERR;
|
||||
}
|
||||
|
||||
/* g_writeln("Received user name: %s",buf); */
|
||||
if (0 != scp_session_set_username(session, buf))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "connection aborted: error setting username");
|
||||
|
@ -384,12 +373,11 @@ scp_v0s_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session)
|
|||
}
|
||||
|
||||
/* reading password */
|
||||
if (!in_string16(c->in_s, buf, "passwd"))
|
||||
if (!in_string16(in_s, buf, "passwd"))
|
||||
{
|
||||
return SCP_SERVER_STATE_SIZE_ERR;
|
||||
}
|
||||
|
||||
/* g_writeln("Received password: %s",buf); */
|
||||
if (0 != scp_session_set_password(session, buf))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "connection aborted: error setting password");
|
||||
|
@ -409,77 +397,52 @@ scp_v0s_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session)
|
|||
/* server API */
|
||||
/******************************************************************************/
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v0s_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s, int skipVchk)
|
||||
scp_v0s_accept(struct trans *atrans, struct SCP_SESSION **s)
|
||||
{
|
||||
enum SCP_SERVER_STATES_E result = SCP_SERVER_STATE_OK;
|
||||
struct SCP_SESSION *session = NULL;
|
||||
tui32 version = 0;
|
||||
|
||||
if (!skipVchk)
|
||||
{
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "starting connection");
|
||||
|
||||
if (0 == scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
|
||||
{
|
||||
c->in_s->end = c->in_s->data + 8;
|
||||
in_uint32_be(c->in_s, version);
|
||||
|
||||
if (version != 0)
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "connection aborted: version error");
|
||||
result = SCP_SERVER_STATE_VERSION_ERR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "connection aborted: network error");
|
||||
result = SCP_SERVER_STATE_NETWORK_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
if (result == SCP_SERVER_STATE_OK)
|
||||
{
|
||||
session = scp_session_create();
|
||||
struct SCP_SESSION *session = scp_session_create();
|
||||
if (NULL == session)
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "connection aborted: no memory");
|
||||
LOG(LOG_LEVEL_ERROR, "SCPV0 connection aborted: network error");
|
||||
result = SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = scp_v0s_init_session(c, session);
|
||||
result = scp_v0s_init_session(atrans, session);
|
||||
if (result != SCP_SERVER_STATE_OK)
|
||||
{
|
||||
scp_session_destroy(session);
|
||||
session = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(*s) = session;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v0s_allow_connection(struct SCP_CONNECTION *c, SCP_DISPLAY d, const tui8 *guid)
|
||||
scp_v0s_allow_connection(struct trans *atrans, SCP_DISPLAY d, const tui8 *guid)
|
||||
{
|
||||
int msg_size;
|
||||
struct stream *out_s;
|
||||
|
||||
out_s = trans_get_out_s(atrans, 0);
|
||||
msg_size = guid == 0 ? 14 : 14 + 16;
|
||||
out_uint32_be(c->out_s, 0); /* version */
|
||||
out_uint32_be(c->out_s, msg_size); /* size */
|
||||
out_uint16_be(c->out_s, 3); /* cmd */
|
||||
out_uint16_be(c->out_s, 1); /* data */
|
||||
out_uint16_be(c->out_s, d); /* data */
|
||||
out_uint32_be(out_s, 0); /* version */
|
||||
out_uint32_be(out_s, msg_size); /* size */
|
||||
out_uint16_be(out_s, 3); /* cmd */
|
||||
out_uint16_be(out_s, 1); /* data */
|
||||
out_uint16_be(out_s, d); /* data */
|
||||
if (msg_size > 14)
|
||||
{
|
||||
out_uint8a(c->out_s, guid, 16);
|
||||
out_uint8a(out_s, guid, 16);
|
||||
}
|
||||
s_mark_end(c->out_s);
|
||||
|
||||
if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data))
|
||||
s_mark_end(out_s);
|
||||
if (0 != trans_write_copy(atrans))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "connection aborted: network error");
|
||||
return SCP_SERVER_STATE_NETWORK_ERR;
|
||||
|
@ -491,16 +454,18 @@ scp_v0s_allow_connection(struct SCP_CONNECTION *c, SCP_DISPLAY d, const tui8 *gu
|
|||
|
||||
/******************************************************************************/
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v0s_deny_connection(struct SCP_CONNECTION *c)
|
||||
scp_v0s_deny_connection(struct trans *atrans)
|
||||
{
|
||||
out_uint32_be(c->out_s, 0); /* version */
|
||||
out_uint32_be(c->out_s, 14); /* size */
|
||||
out_uint16_be(c->out_s, 3); /* cmd */
|
||||
out_uint16_be(c->out_s, 0); /* data = 0 - means NOT ok*/
|
||||
out_uint16_be(c->out_s, 0); /* reserved for display number*/
|
||||
s_mark_end(c->out_s);
|
||||
struct stream *out_s;
|
||||
|
||||
if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data))
|
||||
out_s = trans_get_out_s(atrans, 0);
|
||||
out_uint32_be(out_s, 0); /* version */
|
||||
out_uint32_be(out_s, 14); /* size */
|
||||
out_uint16_be(out_s, 3); /* cmd */
|
||||
out_uint16_be(out_s, 0); /* data = 0 - means NOT ok*/
|
||||
out_uint16_be(out_s, 0); /* reserved for display number*/
|
||||
s_mark_end(out_s);
|
||||
if (0 != trans_write_copy(atrans))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "connection aborted: network error");
|
||||
return SCP_SERVER_STATE_NETWORK_ERR;
|
||||
|
@ -512,18 +477,19 @@ scp_v0s_deny_connection(struct SCP_CONNECTION *c)
|
|||
|
||||
/******************************************************************************/
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v0s_replyauthentication(struct SCP_CONNECTION *c, unsigned short int value)
|
||||
scp_v0s_replyauthentication(struct trans *atrans, unsigned short int value)
|
||||
{
|
||||
out_uint32_be(c->out_s, 0); /* version */
|
||||
out_uint32_be(c->out_s, 14); /* size */
|
||||
/* cmd SCP_GW_AUTHENTICATION means authentication reply */
|
||||
out_uint16_be(c->out_s, SCP_GW_AUTHENTICATION);
|
||||
out_uint16_be(c->out_s, value); /* reply code */
|
||||
out_uint16_be(c->out_s, 0); /* dummy data */
|
||||
s_mark_end(c->out_s);
|
||||
struct stream *out_s;
|
||||
|
||||
/* g_writeln("Total number of bytes that will be sent %d",c->out_s->end - c->out_s->data);*/
|
||||
if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data))
|
||||
out_s = trans_get_out_s(atrans, 0);
|
||||
out_uint32_be(out_s, 0); /* version */
|
||||
out_uint32_be(out_s, 14); /* size */
|
||||
/* cmd SCP_GW_AUTHENTICATION means authentication reply */
|
||||
out_uint16_be(out_s, SCP_GW_AUTHENTICATION);
|
||||
out_uint16_be(out_s, value); /* reply code */
|
||||
out_uint16_be(out_s, 0); /* dummy data */
|
||||
s_mark_end(out_s);
|
||||
if (0 != trans_write_copy(atrans))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "connection aborted: network error");
|
||||
return SCP_SERVER_STATE_NETWORK_ERR;
|
||||
|
|
|
@ -45,40 +45,38 @@ scp_v0c_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s);
|
|||
/**
|
||||
*
|
||||
* @brief processes the stream using scp version 0
|
||||
* @param c connection descriptor
|
||||
* @param atrans connection trans
|
||||
* @param s session descriptor
|
||||
* @param skipVchk if set to !0 skips the version control (to be used after
|
||||
* scp_vXs_accept() )
|
||||
*
|
||||
*/
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v0s_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s, int skipVchk);
|
||||
scp_v0s_accept(struct trans *atrans, struct SCP_SESSION **s);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief allows the connection to TS, returning the display port
|
||||
* @param c connection descriptor
|
||||
* @param atrans connection trans
|
||||
*
|
||||
*/
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v0s_allow_connection(struct SCP_CONNECTION *c, SCP_DISPLAY d, const tui8 *guid);
|
||||
scp_v0s_allow_connection(struct trans *atrans, SCP_DISPLAY d, const tui8 *guid);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief denies the connection to TS
|
||||
* @param c connection descriptor
|
||||
* @param atrans connection trans
|
||||
*
|
||||
*/
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v0s_deny_connection(struct SCP_CONNECTION *c);
|
||||
scp_v0s_deny_connection(struct trans *atrans);
|
||||
|
||||
/**
|
||||
* @brief send reply to an authentication request
|
||||
* @param c connection descriptor
|
||||
* @param atrans connection trans
|
||||
* @param value the reply code 0 means ok
|
||||
* @return
|
||||
*/
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v0s_replyauthentication(struct SCP_CONNECTION *c, unsigned short int value);
|
||||
scp_v0s_replyauthentication(struct trans *atrans, unsigned short int value);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -317,6 +317,186 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION *c, struct SCP_SES
|
|||
return result;
|
||||
}
|
||||
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_accept_msg(struct trans *atrans, struct SCP_SESSION **s)
|
||||
{
|
||||
struct SCP_SESSION *session;
|
||||
tui32 size;
|
||||
tui16 cmdset;
|
||||
tui16 cmd;
|
||||
tui8 sz;
|
||||
char buf[257];
|
||||
struct stream *in_s;
|
||||
|
||||
in_s = atrans->in_s;
|
||||
|
||||
if (!s_check_rem(in_s, 6))
|
||||
{
|
||||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
|
||||
in_uint8s(in_s, 4); /* size */
|
||||
|
||||
/* reading command set */
|
||||
in_uint16_be(in_s, cmdset);
|
||||
|
||||
/* if we are starting a management session */
|
||||
if (cmdset == SCP_COMMAND_SET_MANAGE)
|
||||
{
|
||||
log_message(LOG_LEVEL_DEBUG, "[v1s:%d] requested management connection", __LINE__);
|
||||
/* should return SCP_SERVER_STATE_START_MANAGE */
|
||||
return scp_v1s_mng_accept_msg(atrans, s);
|
||||
}
|
||||
|
||||
/* if we started with resource sharing... */
|
||||
if (cmdset == SCP_COMMAND_SET_RSR)
|
||||
{
|
||||
log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
|
||||
return SCP_SERVER_STATE_SEQUENCE_ERR;
|
||||
}
|
||||
|
||||
if (!s_check_rem(in_s, 27))
|
||||
{
|
||||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
|
||||
/* reading command */
|
||||
in_uint16_be(in_s, cmd);
|
||||
|
||||
if (cmd != 1)
|
||||
{
|
||||
log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
|
||||
return SCP_SERVER_STATE_SEQUENCE_ERR;
|
||||
}
|
||||
|
||||
session = scp_session_create();
|
||||
|
||||
if (0 == session)
|
||||
{
|
||||
log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error (malloc returned NULL)", __LINE__);
|
||||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
|
||||
scp_session_set_version(session, 1);
|
||||
|
||||
in_uint8(in_s, sz);
|
||||
|
||||
if ((sz != SCP_SESSION_TYPE_XVNC) && (sz != SCP_SESSION_TYPE_XRDP))
|
||||
{
|
||||
scp_session_destroy(session);
|
||||
log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: unknown session type", __LINE__);
|
||||
return SCP_SERVER_STATE_SESSION_TYPE_ERR;
|
||||
}
|
||||
|
||||
scp_session_set_type(session, sz);
|
||||
|
||||
in_uint16_be(in_s, cmd);
|
||||
scp_session_set_height(session, cmd);
|
||||
in_uint16_be(in_s, cmd);
|
||||
scp_session_set_width(session, cmd);
|
||||
in_uint8(in_s, sz);
|
||||
if (0 != scp_session_set_bpp(session, sz))
|
||||
{
|
||||
scp_session_destroy(session);
|
||||
log_message(LOG_LEVEL_WARNING,
|
||||
"[v1s:%d] connection aborted: unsupported bpp: %d",
|
||||
__LINE__, sz);
|
||||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
in_uint8(in_s, sz);
|
||||
scp_session_set_rsr(session, sz);
|
||||
in_uint8a(in_s, buf, 17);
|
||||
buf[17] = '\0';
|
||||
scp_session_set_locale(session, buf);
|
||||
|
||||
in_uint8(in_s, sz);
|
||||
|
||||
if (sz == SCP_ADDRESS_TYPE_IPV4)
|
||||
{
|
||||
if (!s_check_rem(in_s, 4))
|
||||
{
|
||||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
in_uint32_be(in_s, size);
|
||||
scp_session_set_addr(session, sz, &size);
|
||||
}
|
||||
else if (sz == SCP_ADDRESS_TYPE_IPV6)
|
||||
{
|
||||
if (!s_check_rem(in_s, 16))
|
||||
{
|
||||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
in_uint8a(in_s, buf, 16);
|
||||
scp_session_set_addr(session, sz, buf);
|
||||
}
|
||||
|
||||
buf[256] = '\0';
|
||||
/* reading hostname */
|
||||
if (!s_check_rem(in_s, 1))
|
||||
{
|
||||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
in_uint8(in_s, sz);
|
||||
if (!s_check_rem(in_s, sz))
|
||||
{
|
||||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
buf[sz] = '\0';
|
||||
in_uint8a(in_s, buf, sz);
|
||||
|
||||
if (0 != scp_session_set_hostname(session, buf))
|
||||
{
|
||||
scp_session_destroy(session);
|
||||
log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
|
||||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
|
||||
/* reading username */
|
||||
if (!s_check_rem(in_s, 1))
|
||||
{
|
||||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
in_uint8(in_s, sz);
|
||||
if (!s_check_rem(in_s, sz))
|
||||
{
|
||||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
buf[sz] = '\0';
|
||||
in_uint8a(in_s, buf, sz);
|
||||
|
||||
if (0 != scp_session_set_username(session, buf))
|
||||
{
|
||||
scp_session_destroy(session);
|
||||
log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
|
||||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
|
||||
/* reading password */
|
||||
if (!s_check_rem(in_s, 1))
|
||||
{
|
||||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
in_uint8(in_s, sz);
|
||||
if (!s_check_rem(in_s, sz))
|
||||
{
|
||||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
buf[sz] = '\0';
|
||||
in_uint8a(in_s, buf, sz);
|
||||
|
||||
if (0 != scp_session_set_password(session, buf))
|
||||
{
|
||||
scp_session_destroy(session);
|
||||
log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
|
||||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
|
||||
/* returning the struct */
|
||||
(*s) = session;
|
||||
|
||||
return SCP_SERVER_STATE_OK;
|
||||
}
|
||||
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_deny_connection(struct SCP_CONNECTION *c, const char *reason)
|
||||
{
|
||||
|
|
|
@ -44,6 +44,18 @@
|
|||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s, int skipVchk);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief processes the stream using scp version 1
|
||||
* @param trans connection trans
|
||||
* @param s pointer to session descriptor pointer
|
||||
*
|
||||
* this function places in *s the address of a newly allocated SCP_SESSION structure
|
||||
* that should be free()d
|
||||
*/
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_accept_msg(struct trans *atrans, struct SCP_SESSION **s);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief denies connection to sesman
|
||||
|
|
|
@ -212,6 +212,129 @@ scp_v1s_mng_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s)
|
|||
return result;
|
||||
}
|
||||
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_mng_accept_msg(struct trans *atrans, struct SCP_SESSION **s)
|
||||
{
|
||||
struct SCP_SESSION *session;
|
||||
tui32 ipaddr;
|
||||
tui16 cmd;
|
||||
tui8 sz;
|
||||
char buf[257];
|
||||
struct stream *in_s;
|
||||
|
||||
in_s = atrans->in_s;
|
||||
|
||||
/* reading command */
|
||||
if (!s_check_rem(in_s, 2))
|
||||
{
|
||||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
in_uint16_be(in_s, cmd);
|
||||
|
||||
if (cmd != 1) /* manager login */
|
||||
{
|
||||
return SCP_SERVER_STATE_SEQUENCE_ERR;
|
||||
}
|
||||
|
||||
session = scp_session_create();
|
||||
|
||||
if (0 == session)
|
||||
{
|
||||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
|
||||
scp_session_set_version(session, 1);
|
||||
scp_session_set_type(session, SCP_SESSION_TYPE_MANAGE);
|
||||
|
||||
/* reading username */
|
||||
if (!s_check_rem(in_s, 1))
|
||||
{
|
||||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
in_uint8(in_s, sz);
|
||||
if (!s_check_rem(in_s, sz))
|
||||
{
|
||||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
buf[sz] = '\0';
|
||||
in_uint8a(in_s, buf, sz);
|
||||
|
||||
if (0 != scp_session_set_username(session, buf))
|
||||
{
|
||||
scp_session_destroy(session);
|
||||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
|
||||
/* reading password */
|
||||
if (!s_check_rem(in_s, 1))
|
||||
{
|
||||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
in_uint8(in_s, sz);
|
||||
if (!s_check_rem(in_s, sz))
|
||||
{
|
||||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
buf[sz] = '\0';
|
||||
in_uint8a(in_s, buf, sz);
|
||||
|
||||
if (0 != scp_session_set_password(session, buf))
|
||||
{
|
||||
scp_session_destroy(session);
|
||||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
|
||||
/* reading remote address */
|
||||
if (!s_check_rem(in_s, 1))
|
||||
{
|
||||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
in_uint8(in_s, sz);
|
||||
|
||||
if (sz == SCP_ADDRESS_TYPE_IPV4)
|
||||
{
|
||||
if (!s_check_rem(in_s, 4))
|
||||
{
|
||||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
in_uint32_be(in_s, ipaddr);
|
||||
scp_session_set_addr(session, sz, &ipaddr);
|
||||
}
|
||||
else if (sz == SCP_ADDRESS_TYPE_IPV6)
|
||||
{
|
||||
if (!s_check_rem(in_s, 16))
|
||||
{
|
||||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
in_uint8a(in_s, buf, 16);
|
||||
scp_session_set_addr(session, sz, buf);
|
||||
}
|
||||
|
||||
/* reading hostname */
|
||||
if (!s_check_rem(in_s, 1))
|
||||
{
|
||||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
in_uint8(in_s, sz);
|
||||
if (!s_check_rem(in_s, sz))
|
||||
{
|
||||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
buf[sz] = '\0';
|
||||
in_uint8a(in_s, buf, sz);
|
||||
|
||||
if (0 != scp_session_set_hostname(session, buf))
|
||||
{
|
||||
scp_session_destroy(session);
|
||||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
|
||||
/* returning the struct */
|
||||
(*s) = session;
|
||||
|
||||
return SCP_SERVER_STATE_START_MANAGE;
|
||||
}
|
||||
|
||||
/* 002 */
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_mng_allow_connection(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
|
|
|
@ -42,6 +42,18 @@
|
|||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_mng_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief processes the stream using scp version 1
|
||||
* @param atrans connection descriptor
|
||||
* @param s pointer to session descriptor pointer
|
||||
*
|
||||
* this function places in *s the address of a newly allocated SCP_SESSION structure
|
||||
* that should be free()d
|
||||
*/
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_mng_accept_msg(struct trans *atrans, struct SCP_SESSION **s);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief allows connection to sesman
|
||||
|
|
|
@ -30,28 +30,26 @@
|
|||
|
||||
#include "libscp_vX.h"
|
||||
|
||||
/* server API */
|
||||
enum SCP_SERVER_STATES_E scp_vXs_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s)
|
||||
/******************************************************************************/
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_vXs_accept(struct trans *atrans, struct SCP_SESSION **s)
|
||||
{
|
||||
tui32 version;
|
||||
struct stream *in_s;
|
||||
int version;
|
||||
|
||||
/* reading version and packet size */
|
||||
if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
|
||||
in_s = atrans->in_s;
|
||||
if (!s_check_rem(in_s, 4))
|
||||
{
|
||||
return SCP_SERVER_STATE_NETWORK_ERR;
|
||||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
c->in_s->end = c->in_s->data + 8;
|
||||
|
||||
in_uint32_be(c->in_s, version);
|
||||
|
||||
in_uint32_be(in_s, version);
|
||||
if (version == 0)
|
||||
{
|
||||
return scp_v0s_accept(c, s, 1);
|
||||
return scp_v0s_accept(atrans, s);
|
||||
}
|
||||
else if (version == 1)
|
||||
{
|
||||
return scp_v1s_accept(c, s, 1);
|
||||
return scp_v1s_accept_msg(atrans, s);
|
||||
}
|
||||
|
||||
return SCP_SERVER_STATE_VERSION_ERR;
|
||||
}
|
||||
|
|
|
@ -36,12 +36,13 @@
|
|||
/**
|
||||
*
|
||||
* @brief version neutral server accept function
|
||||
* @param c connection descriptor
|
||||
* @param atrans connection trans
|
||||
* @param s session descriptor pointer address.
|
||||
* it will return a newly allocated descriptor.
|
||||
* It this memory needs to be g_free()d
|
||||
*
|
||||
*/
|
||||
enum SCP_SERVER_STATES_E scp_vXs_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s);
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_vXs_accept(struct trans *atrans, struct SCP_SESSION **s);
|
||||
|
||||
#endif
|
||||
|
|
40
sesman/scp.c
40
sesman/scp.c
|
@ -36,44 +36,32 @@
|
|||
extern struct config_sesman *g_cfg; /* in sesman.c */
|
||||
|
||||
/******************************************************************************/
|
||||
void *
|
||||
scp_process_start(void *sck)
|
||||
int
|
||||
scp_process(struct trans *atrans)
|
||||
{
|
||||
struct SCP_CONNECTION scon;
|
||||
struct SCP_SESSION *sdata = NULL;
|
||||
struct SCP_SESSION *sdata;
|
||||
|
||||
scon.in_sck = (int)(tintptr)sck;
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "started scp thread on socket %d", scon.in_sck);
|
||||
|
||||
make_stream(scon.in_s);
|
||||
make_stream(scon.out_s);
|
||||
|
||||
init_stream(scon.in_s, SCP_MAX_MESSAGE_SIZE);
|
||||
init_stream(scon.out_s, SCP_MAX_MESSAGE_SIZE);
|
||||
|
||||
switch (scp_vXs_accept(&scon, &(sdata)))
|
||||
sdata = NULL;
|
||||
switch (scp_vXs_accept(atrans, &sdata))
|
||||
{
|
||||
case SCP_SERVER_STATE_OK:
|
||||
|
||||
if (sdata->version == 0)
|
||||
{
|
||||
/* starts processing an scp v0 connection */
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "accept ok, go on with scp v0");
|
||||
scp_v0_process(&scon, sdata);
|
||||
scp_v0_process(atrans, sdata);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "accept ok, go on with scp v1");
|
||||
/*LOG_DEVEL(LOG_LEVEL_DEBUG, "user: %s\npass: %s",sdata->username, sdata->password);*/
|
||||
scp_v1_process(&scon, sdata);
|
||||
scp_v1_process_msg(atrans, sdata);
|
||||
}
|
||||
|
||||
break;
|
||||
case SCP_SERVER_STATE_START_MANAGE:
|
||||
/* starting a management session */
|
||||
LOG(LOG_LEVEL_WARNING,
|
||||
LOG(LOG_LEVEL_INFO,
|
||||
"starting a sesman management session...");
|
||||
scp_v1_mng_process(&scon, sdata);
|
||||
scp_v1_mng_process_msg(t, sdata);
|
||||
break;
|
||||
case SCP_SERVER_STATE_VERSION_ERR:
|
||||
case SCP_SERVER_STATE_SIZE_ERR:
|
||||
|
@ -97,14 +85,6 @@ scp_process_start(void *sck)
|
|||
LOG(LOG_LEVEL_ALWAYS, "unknown return from scp_vXs_accept()");
|
||||
break;
|
||||
}
|
||||
|
||||
free_stream(scon.in_s);
|
||||
free_stream(scon.out_s);
|
||||
|
||||
if (sdata)
|
||||
{
|
||||
scp_session_destroy(sdata);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,10 +36,10 @@
|
|||
* @brief Starts a an scp protocol thread.
|
||||
* Starts a an scp protocol thread.
|
||||
* But does only version control....
|
||||
* @param socket the connection socket
|
||||
* @param atrans the connection trans
|
||||
*
|
||||
*/
|
||||
void *
|
||||
scp_process_start(void *sck);
|
||||
int
|
||||
scp_process(struct trans *atrans);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -34,7 +34,7 @@ extern struct config_sesman *g_cfg; /* in sesman.c */
|
|||
|
||||
/******************************************************************************/
|
||||
void
|
||||
scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
scp_v0_process(struct trans *atrans, struct SCP_SESSION *s)
|
||||
{
|
||||
int display = 0;
|
||||
tbus data;
|
||||
|
@ -53,15 +53,15 @@ scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
|||
if (1 == access_login_allowed(s->username))
|
||||
{
|
||||
/* the user is member of the correct groups. */
|
||||
scp_v0s_replyauthentication(c, errorcode);
|
||||
scp_v0s_replyauthentication(atrans, errorcode);
|
||||
LOG(LOG_LEVEL_INFO, "Access permitted for user: %s",
|
||||
s->username);
|
||||
/* g_writeln("Connection allowed"); */
|
||||
}
|
||||
else
|
||||
{
|
||||
scp_v0s_replyauthentication(c, 32 + 3); /* all first 32 are reserved for PAM errors */
|
||||
LOG(LOG_LEVEL_INFO, "Username okey but group problem for "
|
||||
scp_v0s_replyauthentication(atrans, 32 + 3); /* all first 32 are reserved for PAM errors */
|
||||
LOG(LOG_LEVEL_INFO, "Username okay but group problem for "
|
||||
"user: %s", s->username);
|
||||
/* g_writeln("user password ok, but group problem"); */
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
|||
/* g_writeln("username or password error"); */
|
||||
LOG(LOG_LEVEL_INFO, "Username or password error for user: %s",
|
||||
s->username);
|
||||
scp_v0s_replyauthentication(c, errorcode);
|
||||
scp_v0s_replyauthentication(atrans, errorcode);
|
||||
}
|
||||
}
|
||||
else if (data)
|
||||
|
@ -123,18 +123,18 @@ scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
|||
if (SCP_SESSION_TYPE_XVNC == s->type)
|
||||
{
|
||||
LOG( LOG_LEVEL_INFO, "starting Xvnc session...");
|
||||
display = session_start(data, SESMAN_SESSION_TYPE_XVNC, c, s);
|
||||
display = session_start(data, SESMAN_SESSION_TYPE_XVNC, s);
|
||||
}
|
||||
else if (SCP_SESSION_TYPE_XRDP == s->type)
|
||||
{
|
||||
LOG(LOG_LEVEL_INFO, "starting X11rdp session...");
|
||||
display = session_start(data, SESMAN_SESSION_TYPE_XRDP, c, s);
|
||||
display = session_start(data, SESMAN_SESSION_TYPE_XRDP, s);
|
||||
}
|
||||
else if (SCP_SESSION_TYPE_XORG == s->type)
|
||||
{
|
||||
/* type is SCP_SESSION_TYPE_XORG */
|
||||
LOG(LOG_LEVEL_INFO, "starting Xorg session...");
|
||||
display = session_start(data, SESMAN_SESSION_TYPE_XORG, c, s);
|
||||
display = session_start(data, SESMAN_SESSION_TYPE_XORG, s);
|
||||
}
|
||||
/* if the session started up ok, auth_end will be called on
|
||||
sig child */
|
||||
|
@ -148,18 +148,18 @@ scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
|||
|
||||
if (display == 0)
|
||||
{
|
||||
scp_v0s_deny_connection(c);
|
||||
scp_v0s_deny_connection(atrans);
|
||||
}
|
||||
else
|
||||
{
|
||||
scp_v0s_allow_connection(c, display, s->guid);
|
||||
scp_v0s_allow_connection(atrans, display, s->guid);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(LOG_LEVEL_INFO, "Username or password error for user: %s",
|
||||
s->username);
|
||||
scp_v0s_deny_connection(c);
|
||||
scp_v0s_deny_connection(atrans);
|
||||
}
|
||||
if (do_auth_end)
|
||||
{
|
||||
|
|
|
@ -29,15 +29,7 @@
|
|||
|
||||
#include "libscp.h"
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief processes the stream using scp version 0
|
||||
* @param in_sck connection socket
|
||||
* @param in_s input stream
|
||||
* @param out_s output stream
|
||||
*
|
||||
*/
|
||||
void
|
||||
scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s);
|
||||
scp_v0_process(struct trans *atrans, struct SCP_SESSION *s);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -127,17 +127,17 @@ scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
|||
if (SCP_SESSION_TYPE_XVNC == s->type)
|
||||
{
|
||||
LOG(LOG_LEVEL_INFO, "starting Xvnc session...");
|
||||
display = session_start(data, SESMAN_SESSION_TYPE_XVNC, c, s);
|
||||
display = session_start(data, SESMAN_SESSION_TYPE_XVNC, s);
|
||||
}
|
||||
else if (SCP_SESSION_TYPE_XRDP == s->type)
|
||||
{
|
||||
LOG(LOG_LEVEL_INFO, "starting X11rdp session...");
|
||||
display = session_start(data, SESMAN_SESSION_TYPE_XRDP, c, s);
|
||||
display = session_start(data, SESMAN_SESSION_TYPE_XRDP, s);
|
||||
}
|
||||
else if (SCP_SESSION_TYPE_XORG == s->type)
|
||||
{
|
||||
LOG(LOG_LEVEL_INFO, "starting Xorg session...");
|
||||
display = session_start(data, SESMAN_SESSION_TYPE_XORG, c, s);
|
||||
display = session_start(data, SESMAN_SESSION_TYPE_XORG, s);
|
||||
}
|
||||
/* if the session started up ok, auth_end will be called on
|
||||
sig child */
|
||||
|
@ -215,6 +215,13 @@ scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
|||
g_free(slist);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void
|
||||
scp_v1_process_msg(struct trans *atrans, struct SCP_SESSION *s)
|
||||
{
|
||||
// JAY TODO
|
||||
}
|
||||
|
||||
static void parseCommonStates(enum SCP_SERVER_STATES_E e, const char *f)
|
||||
{
|
||||
switch (e)
|
||||
|
|
|
@ -38,4 +38,7 @@
|
|||
void
|
||||
scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s);
|
||||
|
||||
void
|
||||
scp_v1_process_msg(struct trans *atrans, struct SCP_SESSION *s);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -104,6 +104,12 @@ scp_v1_mng_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
|||
auth_end(data);
|
||||
}
|
||||
|
||||
void
|
||||
scp_v1_mng_process_msg(struct trans *atrans, struct SCP_SESSION *s)
|
||||
{
|
||||
// JAY TODO
|
||||
}
|
||||
|
||||
static void parseCommonStates(enum SCP_SERVER_STATES_E e, const char *f)
|
||||
{
|
||||
switch (e)
|
||||
|
|
|
@ -38,4 +38,7 @@
|
|||
void
|
||||
scp_v1_mng_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s);
|
||||
|
||||
void
|
||||
scp_v1_mng_process_msg(struct trans *atrans, struct SCP_SESSION *s);
|
||||
|
||||
#endif
|
||||
|
|
221
sesman/sesman.c
221
sesman/sesman.c
|
@ -44,13 +44,15 @@ struct sesman_startup_params
|
|||
int dump_config;
|
||||
};
|
||||
|
||||
int g_sck;
|
||||
int g_pid;
|
||||
unsigned char g_fixedkey[8] = { 23, 82, 107, 6, 35, 78, 88, 7 };
|
||||
struct config_sesman *g_cfg; /* defined in config.h */
|
||||
|
||||
tintptr g_term_event = 0;
|
||||
|
||||
static struct trans *g_list_trans = NULL;
|
||||
static struct list *g_con_list = NULL;
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief looks for a case-insensitive match of a string in a list
|
||||
|
@ -187,6 +189,82 @@ static int sesman_listen_test(struct config_sesman *cfg)
|
|||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
int
|
||||
sesman_close_all(void)
|
||||
{
|
||||
int index;
|
||||
struct trans *con_trans;
|
||||
|
||||
log_message(LOG_LEVEL_DEBUG, "sesman_close_all:");
|
||||
trans_delete(g_list_trans);
|
||||
for (index = 0; index < g_con_list->count; index++)
|
||||
{
|
||||
con_trans = (struct trans *) list_get_item(g_con_list, index);
|
||||
trans_delete(con_trans);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
static int
|
||||
sesman_data_in(struct trans *self)
|
||||
{
|
||||
int version;
|
||||
int size;
|
||||
|
||||
if (self->extra_flags == 0)
|
||||
{
|
||||
in_uint32_be(self->in_s, version);
|
||||
in_uint32_be(self->in_s, size);
|
||||
if (size > self->in_s->size)
|
||||
{
|
||||
log_message(LOG_LEVEL_ERROR, "sesman_data_in: bad message size");
|
||||
return 1;
|
||||
}
|
||||
self->header_size = size;
|
||||
self->extra_flags = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* prcess message */
|
||||
self->in_s->p = self->in_s->data;
|
||||
if (scp_process(self) != 0)
|
||||
{
|
||||
log_message(LOG_LEVEL_ERROR, "sesman_data_in: scp_process_msg "
|
||||
"failed");
|
||||
return 1;
|
||||
}
|
||||
/* reset for next message */
|
||||
self->header_size = 8;
|
||||
self->extra_flags = 0;
|
||||
init_stream(self->in_s, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
static int
|
||||
sesman_listen_conn_in(struct trans *self, struct trans *new_self)
|
||||
{
|
||||
if (g_con_list->count < 16)
|
||||
{
|
||||
new_self->header_size = 8;
|
||||
new_self->trans_data_in = sesman_data_in;
|
||||
new_self->no_stream_init_on_data_in = 1;
|
||||
new_self->extra_flags = 0;
|
||||
list_add_item(g_con_list, (intptr_t) new_self);
|
||||
}
|
||||
else
|
||||
{
|
||||
log_message(LOG_LEVEL_ERROR, "sesman_data_in: error, too many "
|
||||
"connections, rejecting");
|
||||
trans_delete(new_self);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
|
@ -196,44 +274,80 @@ static int sesman_listen_test(struct config_sesman *cfg)
|
|||
static int
|
||||
sesman_main_loop(void)
|
||||
{
|
||||
int in_sck;
|
||||
int error;
|
||||
int robjs_count;
|
||||
int wobjs_count;
|
||||
int cont;
|
||||
int rv = 0;
|
||||
tbus sck_obj;
|
||||
tbus robjs[8];
|
||||
int timeout;
|
||||
int index;
|
||||
intptr_t robjs[32];
|
||||
intptr_t wobjs[32];
|
||||
struct trans *con_trans;
|
||||
|
||||
g_sck = g_tcp_socket();
|
||||
if (g_sck < 0)
|
||||
g_con_list = list_create();
|
||||
if (g_con_list == NULL)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "error opening socket, g_tcp_socket() failed...");
|
||||
log_message(LOG_LEVEL_ERROR, "sesman_main_loop: list_create failed");
|
||||
return 1;
|
||||
}
|
||||
g_list_trans = trans_create(TRANS_MODE_TCP, 8192, 8192);
|
||||
if (g_list_trans == NULL)
|
||||
{
|
||||
log_message(LOG_LEVEL_ERROR, "sesman_main_loop: trans_create failed");
|
||||
list_delete(g_con_list);
|
||||
return 1;
|
||||
}
|
||||
|
||||
g_tcp_set_non_blocking(g_sck);
|
||||
error = scp_tcp_bind(g_sck, g_cfg->listen_address, g_cfg->listen_port);
|
||||
|
||||
if (error == 0)
|
||||
LOG(LOG_LEVEL_DEBUG, "sesman_main_loop: address %s port %s",
|
||||
g_cfg->listen_address, g_cfg->listen_port);
|
||||
error = trans_listen_address(g_list_trans, g_cfg->listen_port,
|
||||
g_cfg->listen_address);
|
||||
if (error != 0)
|
||||
{
|
||||
error = g_tcp_listen(g_sck);
|
||||
|
||||
if (error == 0)
|
||||
{
|
||||
LOG(LOG_LEVEL_INFO, "listening to port %s on %s",
|
||||
g_cfg->listen_port, g_cfg->listen_address);
|
||||
sck_obj = g_create_wait_obj_from_socket(g_sck, 0);
|
||||
log_message(LOG_LEVEL_ERROR, "sesman_main_loop: trans_listen_address "
|
||||
"failed");
|
||||
trans_delete(g_list_trans);
|
||||
list_delete(g_con_list);
|
||||
return 1;
|
||||
}
|
||||
g_list_trans->trans_conn_in = sesman_listen_conn_in;
|
||||
cont = 1;
|
||||
|
||||
while (cont)
|
||||
{
|
||||
/* build the wait obj list */
|
||||
timeout = -1;
|
||||
robjs_count = 0;
|
||||
robjs[robjs_count++] = sck_obj;
|
||||
robjs[robjs_count++] = g_term_event;
|
||||
wobjs_count = 0;
|
||||
for (index = 0; index < g_con_list->count; index++)
|
||||
{
|
||||
con_trans = (struct trans *) list_get_item(g_con_list, index);
|
||||
if (con_trans != NULL)
|
||||
{
|
||||
error = trans_get_wait_objs_rw(con_trans, robjs, &robjs_count,
|
||||
wobjs, &wobjs_count, &timeout);
|
||||
if (error != 0)
|
||||
{
|
||||
log_message(LOG_LEVEL_ERROR, "sesman_main_loop: "
|
||||
"trans_get_wait_objs_rw failed");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (error != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
error = trans_get_wait_objs_rw(g_list_trans, robjs, &robjs_count,
|
||||
wobjs, &wobjs_count, &timeout);
|
||||
if (error != 0)
|
||||
{
|
||||
log_message(LOG_LEVEL_ERROR, "sesman_main_loop: "
|
||||
"trans_get_wait_objs_rw failed");
|
||||
break;
|
||||
}
|
||||
|
||||
/* wait */
|
||||
if (g_obj_wait(robjs, robjs_count, 0, 0, -1) != 0)
|
||||
error = g_obj_wait(robjs, robjs_count, wobjs, wobjs_count, timeout);
|
||||
if (error != 0)
|
||||
{
|
||||
/* error, should not get here */
|
||||
g_sleep(100);
|
||||
|
@ -244,48 +358,39 @@ sesman_main_loop(void)
|
|||
break;
|
||||
}
|
||||
|
||||
if (g_is_wait_obj_set(sck_obj)) /* incoming connection */
|
||||
for (index = 0; index < g_con_list->count; index++)
|
||||
{
|
||||
in_sck = g_tcp_accept(g_sck);
|
||||
|
||||
if ((in_sck == -1) && g_tcp_last_error_would_block(g_sck))
|
||||
con_trans = (struct trans *) list_get_item(g_con_list, index);
|
||||
if (con_trans != NULL)
|
||||
{
|
||||
/* should not get here */
|
||||
g_sleep(100);
|
||||
error = trans_check_wait_objs(con_trans);
|
||||
if (error != 0)
|
||||
{
|
||||
log_message(LOG_LEVEL_ERROR, "sesman_main_loop: "
|
||||
"trans_check_wait_objs failed, removing trans");
|
||||
trans_delete(con_trans);
|
||||
list_remove_item(g_con_list, index);
|
||||
index--;
|
||||
continue;
|
||||
}
|
||||
else if (in_sck == -1)
|
||||
}
|
||||
}
|
||||
error = trans_check_wait_objs(g_list_trans);
|
||||
if (error != 0)
|
||||
{
|
||||
/* error, should not get here */
|
||||
log_message(LOG_LEVEL_ERROR, "sesman_main_loop: "
|
||||
"trans_check_wait_objs failed");
|
||||
break;
|
||||
}
|
||||
else
|
||||
}
|
||||
for (index = 0; index < g_con_list->count; index++)
|
||||
{
|
||||
/* we've got a connection, so we pass it to scp code */
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "new connection");
|
||||
scp_process_start((void *)(tintptr)in_sck);
|
||||
g_sck_close(in_sck);
|
||||
con_trans = (struct trans *) list_get_item(g_con_list, index);
|
||||
trans_delete(con_trans);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_delete_wait_obj_from_socket(sck_obj);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "listen error %d (%s)",
|
||||
g_get_errno(), g_get_strerror());
|
||||
rv = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "bind error on "
|
||||
"port '%s': %d (%s)", g_cfg->listen_port,
|
||||
g_get_errno(), g_get_strerror());
|
||||
rv = 1;
|
||||
}
|
||||
g_tcp_close(g_sck);
|
||||
return rv;
|
||||
list_delete(g_con_list);
|
||||
trans_delete(g_list_trans);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
@ -41,4 +41,7 @@
|
|||
|
||||
#include "libscp.h"
|
||||
|
||||
int
|
||||
sesman_close_all(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -49,7 +49,6 @@
|
|||
|
||||
extern unsigned char g_fixedkey[8];
|
||||
extern struct config_sesman *g_cfg; /* in sesman.c */
|
||||
extern int g_sck; /* in sesman.c */
|
||||
struct session_chain *g_sessions;
|
||||
int g_session_count;
|
||||
|
||||
|
@ -411,8 +410,7 @@ session_start_chansrv(char *username, int display)
|
|||
/******************************************************************************/
|
||||
/* called with the main thread */
|
||||
static int
|
||||
session_start_fork(tbus data, tui8 type, struct SCP_CONNECTION *c,
|
||||
struct SCP_SESSION *s)
|
||||
session_start_fork(tbus data, tui8 type, struct SCP_SESSION *s)
|
||||
{
|
||||
int display = 0;
|
||||
int pid = 0;
|
||||
|
@ -496,8 +494,7 @@ session_start_fork(tbus data, tui8 type, struct SCP_CONNECTION *c,
|
|||
display, g_getpid());
|
||||
auth_start_session(data, display);
|
||||
g_delete_wait_obj(g_term_event);
|
||||
g_tcp_close(g_sck);
|
||||
g_tcp_close(c->in_sck);
|
||||
sesman_close_all();
|
||||
g_sprintf(geometry, "%dx%d", s->width, s->height);
|
||||
g_sprintf(depth, "%d", s->bpp);
|
||||
g_sprintf(screen, ":%d", display);
|
||||
|
@ -1008,10 +1005,9 @@ session_reconnect_fork(int display, char *username, long data)
|
|||
/* called by a worker thread, ask the main thread to call session_sync_start
|
||||
and wait till done */
|
||||
int
|
||||
session_start(long data, tui8 type, struct SCP_CONNECTION *c,
|
||||
struct SCP_SESSION *s)
|
||||
session_start(long data, tui8 type, struct SCP_SESSION *s)
|
||||
{
|
||||
return session_start_fork(data, type, c, s);
|
||||
return session_start_fork(data, type, s);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
|
@ -105,8 +105,7 @@ session_get_bydata(const char *name, int width, int height, int bpp, int type,
|
|||
*
|
||||
*/
|
||||
int
|
||||
session_start(long data, tui8 type, struct SCP_CONNECTION *c,
|
||||
struct SCP_SESSION *s);
|
||||
session_start(long data, tui8 type, struct SCP_SESSION *s);
|
||||
|
||||
int
|
||||
session_reconnect(int display, char *username, long data);
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
|
||||
#include "sesman.h"
|
||||
|
||||
extern int g_sck;
|
||||
extern int g_pid;
|
||||
extern struct config_sesman *g_cfg; /* in sesman.c */
|
||||
extern tbus g_term_event;
|
||||
|
|
Loading…
Reference in New Issue