sesman: work on moving sesman to trans, v0 scp working

This commit is contained in:
Jay Sorg 2020-06-10 01:20:27 -07:00 committed by matt335672
parent 7e95576849
commit 738e346f81
22 changed files with 648 additions and 264 deletions

View File

@ -31,6 +31,7 @@
#include "parse.h"
#include "arch.h"
#include "log.h"
#include "trans.h"
#define SCP_SID tui32
#define SCP_DISPLAY tui16

View File

@ -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,50 +397,23 @@ 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)
struct SCP_SESSION *session = scp_session_create();
if (NULL == session)
{
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;
}
LOG(LOG_LEVEL_ERROR, "SCPV0 connection aborted: network error");
result = SCP_SERVER_STATE_INTERNAL_ERR;
}
if (result == SCP_SERVER_STATE_OK)
else
{
session = scp_session_create();
if (NULL == session)
result = scp_v0s_init_session(atrans, session);
if (result != SCP_SERVER_STATE_OK)
{
LOG(LOG_LEVEL_WARNING, "connection aborted: no memory");
result = SCP_SERVER_STATE_INTERNAL_ERR;
}
else
{
result = scp_v0s_init_session(c, session);
if (result != SCP_SERVER_STATE_OK)
{
scp_session_destroy(session);
session = NULL;
}
scp_session_destroy(session);
session = NULL;
}
}
@ -461,25 +422,27 @@ scp_v0s_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s, int skipVchk)
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;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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,96 +274,123 @@ 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_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)
{
timeout = -1;
robjs_count = 0;
robjs[robjs_count++] = g_term_event;
wobjs_count = 0;
for (index = 0; index < g_con_list->count; index++)
{
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);
cont = 1;
while (cont)
con_trans = (struct trans *) list_get_item(g_con_list, index);
if (con_trans != NULL)
{
/* build the wait obj list */
robjs_count = 0;
robjs[robjs_count++] = sck_obj;
robjs[robjs_count++] = g_term_event;
/* wait */
if (g_obj_wait(robjs, robjs_count, 0, 0, -1) != 0)
{
/* error, should not get here */
g_sleep(100);
}
if (g_is_wait_obj_set(g_term_event)) /* term */
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;
}
if (g_is_wait_obj_set(sck_obj)) /* incoming connection */
error = g_obj_wait(robjs, robjs_count, wobjs, wobjs_count, timeout);
if (error != 0)
{
/* error, should not get here */
g_sleep(100);
}
if (g_is_wait_obj_set(g_term_event)) /* term */
{
break;
}
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_check_wait_objs(con_trans);
if (error != 0)
{
in_sck = g_tcp_accept(g_sck);
if ((in_sck == -1) && g_tcp_last_error_would_block(g_sck))
{
/* should not get here */
g_sleep(100);
}
else if (in_sck == -1)
{
/* error, should not get here */
break;
}
else
{
/* 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);
}
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;
}
}
g_delete_wait_obj_from_socket(sck_obj);
}
else
error = trans_check_wait_objs(g_list_trans);
if (error != 0)
{
LOG(LOG_LEVEL_ERROR, "listen error %d (%s)",
g_get_errno(), g_get_strerror());
rv = 1;
log_message(LOG_LEVEL_ERROR, "sesman_main_loop: "
"trans_check_wait_objs failed");
break;
}
}
else
for (index = 0; index < g_con_list->count; index++)
{
LOG(LOG_LEVEL_ERROR, "bind error on "
"port '%s': %d (%s)", g_cfg->listen_port,
g_get_errno(), g_get_strerror());
rv = 1;
con_trans = (struct trans *) list_get_item(g_con_list, index);
trans_delete(con_trans);
}
g_tcp_close(g_sck);
return rv;
list_delete(g_con_list);
trans_delete(g_list_trans);
return 0;
}
/*****************************************************************************/

View File

@ -41,4 +41,7 @@
#include "libscp.h"
int
sesman_close_all(void);
#endif

View File

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

View File

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

View File

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