Merge pull request #1925 from matt335672/move_scp_to_trans
Move scp to standard transport (#1925)
This commit is contained in:
+2
-2
@@ -814,7 +814,7 @@ trans_connect(struct trans *self, const char *server, const char *port,
|
||||
* @return 0 on success, 1 on failure
|
||||
*/
|
||||
int
|
||||
trans_listen_address(struct trans *self, char *port, const char *address)
|
||||
trans_listen_address(struct trans *self, const char *port, const char *address)
|
||||
{
|
||||
if (self->sck != 0)
|
||||
{
|
||||
@@ -929,7 +929,7 @@ trans_listen_address(struct trans *self, char *port, const char *address)
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
trans_listen(struct trans *self, char *port)
|
||||
trans_listen(struct trans *self, const char *port)
|
||||
{
|
||||
return trans_listen_address(self, port, "0.0.0.0");
|
||||
}
|
||||
|
||||
+2
-2
@@ -148,9 +148,9 @@ int
|
||||
trans_connect(struct trans *self, const char *server, const char *port,
|
||||
int timeout);
|
||||
int
|
||||
trans_listen_address(struct trans *self, char *port, const char *address);
|
||||
trans_listen_address(struct trans *self, const char *port, const char *address);
|
||||
int
|
||||
trans_listen(struct trans *self, char *port);
|
||||
trans_listen(struct trans *self, const char *port);
|
||||
struct stream *
|
||||
trans_get_in_s(struct trans *self);
|
||||
struct stream *
|
||||
|
||||
+2
-1
@@ -143,7 +143,8 @@ env_set_user(const char *username, char **passwd_file, int display,
|
||||
g_sprintf(text, ":%d.0", display);
|
||||
g_setenv("DISPLAY", text, 1);
|
||||
g_setenv("XRDP_SESSION", "1", 1);
|
||||
/* XRDP_SOCKET_PATH should be set even here, chansrv uses this */
|
||||
/* XRDP_SOCKET_PATH should be set even here. It's used by
|
||||
* xorgxrdp and the pulseaudio plugin */
|
||||
g_setenv("XRDP_SOCKET_PATH", XRDP_SOCKET_PATH, 1);
|
||||
/* pulse sink socket */
|
||||
g_snprintf(text, sizeof(text) - 1, CHANSRV_PORT_OUT_BASE_STR, display);
|
||||
|
||||
@@ -29,7 +29,27 @@
|
||||
|
||||
#include "libscp_commands_mng.h"
|
||||
|
||||
#define SCP_CMD_LOGIN 0x0001
|
||||
#define SCP_CMD_CONN_ERROR 0xFFFF
|
||||
/* Message numbers
|
||||
* SCP_CMD_* are client to server, SCP_REPLY_* are server to client */
|
||||
|
||||
/* Login sequence */
|
||||
#define SCP_CMD_LOGIN 1
|
||||
#define SCP_REPLY_LOGIN_DENIED 2
|
||||
#define SCP_REPLY_REREQUEST_CREDS 3
|
||||
#define SCP_CMD_RESEND_CREDS 4
|
||||
#define SCP_REPLY_CHANGE_PASSWD 20
|
||||
#define SCP_REPLY_NEW_SESSION 30
|
||||
#define SCP_REPLY_USER_SESSIONS_EXIST 40
|
||||
|
||||
/* List sessions */
|
||||
#define SCP_CMD_GET_SESSION_LIST 41
|
||||
#define SCP_REPLY_SESSIONS_INFO 42
|
||||
#define SCP_CMD_SELECT_SESSION 43
|
||||
#define SCP_CMD_SELECT_SESSION_CANCEL 44
|
||||
|
||||
/* Other */
|
||||
#define SCP_CMD_FORCE_NEW_CONN 45
|
||||
#define SCP_REPLY_SESSION_RECONNECTED 46
|
||||
#define SCP_REPLY_CMD_CONN_ERROR 0xFFFF
|
||||
|
||||
#endif
|
||||
|
||||
@@ -32,32 +32,14 @@
|
||||
|
||||
//extern struct log_config* s_log;
|
||||
|
||||
struct SCP_CONNECTION *
|
||||
scp_connection_create(int sck)
|
||||
struct trans *
|
||||
scp_trans_create(int sck)
|
||||
{
|
||||
struct SCP_CONNECTION *conn;
|
||||
|
||||
conn = g_new(struct SCP_CONNECTION, 1);
|
||||
|
||||
if (0 == conn)
|
||||
struct trans *result = trans_create(TRANS_MODE_TCP, 8192, 8192);
|
||||
if (result != NULL)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "[connection:%d] connection create: malloc error", __LINE__);
|
||||
return 0;
|
||||
result->sck = sck;
|
||||
}
|
||||
|
||||
conn->in_sck = sck;
|
||||
make_stream(conn->in_s);
|
||||
init_stream(conn->in_s, 8196);
|
||||
make_stream(conn->out_s);
|
||||
init_stream(conn->out_s, 8196);
|
||||
|
||||
return conn;
|
||||
}
|
||||
|
||||
void
|
||||
scp_connection_destroy(struct SCP_CONNECTION *c)
|
||||
{
|
||||
free_stream(c->in_s);
|
||||
free_stream(c->out_s);
|
||||
g_free(c);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -31,22 +31,18 @@
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief creates a new connection
|
||||
* @brief creates a new SCP transport object
|
||||
* @param sck the connection socket
|
||||
*
|
||||
* @return a struct SCP_CONNECTION* object on success, NULL otherwise
|
||||
* This is a convenience function which calls trans_create() with the
|
||||
* correct parameters.
|
||||
*
|
||||
* Returned object can be freed with trans_delete()
|
||||
*
|
||||
* @return a struct trans* object on success, NULL otherwise
|
||||
*
|
||||
*/
|
||||
struct SCP_CONNECTION *
|
||||
scp_connection_create(int sck);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief destroys a struct SCP_CONNECTION* object
|
||||
* @param c the object to be destroyed
|
||||
*
|
||||
*/
|
||||
void
|
||||
scp_connection_destroy(struct SCP_CONNECTION *c);
|
||||
struct trans *
|
||||
scp_trans_create(int sck);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -78,14 +78,6 @@ scp_session_set_type(struct SCP_SESSION *s, tui8 type)
|
||||
|
||||
case SCP_SESSION_TYPE_MANAGE:
|
||||
s->type = SCP_SESSION_TYPE_MANAGE;
|
||||
s->mng = (struct SCP_MNG_DATA *)g_malloc(sizeof(struct SCP_MNG_DATA), 1);
|
||||
|
||||
if (NULL == s->mng)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "[session:%d] set_type: internal error", __LINE__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -439,14 +431,55 @@ scp_session_set_guid(struct SCP_SESSION *s, const tui8 *guid)
|
||||
void
|
||||
scp_session_destroy(struct SCP_SESSION *s)
|
||||
{
|
||||
g_free(s->username);
|
||||
g_free(s->password);
|
||||
g_free(s->hostname);
|
||||
g_free(s->domain);
|
||||
g_free(s->program);
|
||||
g_free(s->directory);
|
||||
g_free(s->client_ip);
|
||||
g_free(s->errstr);
|
||||
g_free(s->mng);
|
||||
g_free(s);
|
||||
if (s != NULL)
|
||||
{
|
||||
g_free(s->username);
|
||||
g_free(s->password);
|
||||
g_free(s->hostname);
|
||||
g_free(s->domain);
|
||||
g_free(s->program);
|
||||
g_free(s->directory);
|
||||
g_free(s->client_ip);
|
||||
g_free(s->errstr);
|
||||
g_free(s);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
struct SCP_SESSION *
|
||||
scp_session_clone(const struct SCP_SESSION *s)
|
||||
{
|
||||
struct SCP_SESSION *result = NULL;
|
||||
|
||||
if (s != NULL && (result = g_new(struct SCP_SESSION, 1)) != NULL)
|
||||
{
|
||||
/* Duplicate all the scalar variables */
|
||||
g_memcpy(result, s, sizeof(*s));
|
||||
|
||||
/* Now duplicate all the strings */
|
||||
result->username = g_strdup(s->username);
|
||||
result->password = g_strdup(s->password);
|
||||
result->hostname = g_strdup(s->hostname);
|
||||
result->errstr = g_strdup(s->errstr);
|
||||
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);
|
||||
|
||||
/* Did all the string copies succeed? */
|
||||
if ((s->username != NULL && result->username == NULL) ||
|
||||
(s->password != NULL && result->password == NULL) ||
|
||||
(s->hostname != NULL && result->hostname == NULL) ||
|
||||
(s->errstr != NULL && result->errstr == NULL) ||
|
||||
(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))
|
||||
{
|
||||
scp_session_destroy(result);
|
||||
result = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -40,6 +40,14 @@
|
||||
struct SCP_SESSION *
|
||||
scp_session_create(void);
|
||||
|
||||
/*
|
||||
* Makes a copy of a struct SCP_SESSION object
|
||||
* @param s Object to clone
|
||||
* @return a copy of s, or NULL if no memory
|
||||
*/
|
||||
struct SCP_SESSION *
|
||||
scp_session_clone(const struct SCP_SESSION *s);
|
||||
|
||||
int
|
||||
scp_session_set_type(struct SCP_SESSION *s, tui8 type);
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "parse.h"
|
||||
#include "arch.h"
|
||||
#include "log.h"
|
||||
#include "trans.h"
|
||||
|
||||
#define SCP_SID tui32
|
||||
#define SCP_DISPLAY tui16
|
||||
@@ -63,13 +64,6 @@
|
||||
exhaustion attempts (CVE-2020-4044) */
|
||||
#define SCP_MAX_MESSAGE_SIZE 8192
|
||||
|
||||
struct SCP_CONNECTION
|
||||
{
|
||||
int in_sck;
|
||||
struct stream *in_s;
|
||||
struct stream *out_s;
|
||||
};
|
||||
|
||||
struct SCP_SESSION
|
||||
{
|
||||
tui8 type;
|
||||
@@ -87,12 +81,16 @@ struct SCP_SESSION
|
||||
tui8 ipv6addr[16];
|
||||
SCP_DISPLAY display;
|
||||
char *errstr;
|
||||
struct SCP_MNG_DATA *mng;
|
||||
char *domain;
|
||||
char *program;
|
||||
char *directory;
|
||||
char *client_ip;
|
||||
tui8 guid[16];
|
||||
/* added for state */
|
||||
int current_cmd;
|
||||
int return_sid;
|
||||
int retries;
|
||||
int current_try;
|
||||
};
|
||||
|
||||
struct SCP_DISCONNECTED_SESSION
|
||||
|
||||
+73
-129
@@ -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
|
||||
@@ -226,55 +230,42 @@ scp_v0c_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
* @param [out] session pre-allocated session object
|
||||
* @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)
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v0s_accept(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;
|
||||
int session_type = -1;
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
scp_session_set_type(session, SCP_SESSION_TYPE_XVNC);
|
||||
session_type = SCP_SESSION_TYPE_XVNC;
|
||||
}
|
||||
else if (code == 10)
|
||||
{
|
||||
scp_session_set_type(session, SCP_SESSION_TYPE_XRDP);
|
||||
session_type = SCP_SESSION_TYPE_XRDP;
|
||||
}
|
||||
else if (code == 20)
|
||||
else
|
||||
{
|
||||
scp_session_set_type(session, SCP_SESSION_TYPE_XORG);
|
||||
session_type = SCP_SESSION_TYPE_XORG;
|
||||
}
|
||||
scp_session_set_type(session, session_type);
|
||||
|
||||
/* 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 +276,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 +287,22 @@ 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 (session_type == SCP_SESSION_TYPE_XORG && bpp != 24)
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING,
|
||||
"Setting bpp to 24 from %d for Xorg session", bpp);
|
||||
bpp = 24;
|
||||
}
|
||||
if (0 != scp_session_set_bpp(session, (tui8)bpp))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING,
|
||||
@@ -313,23 +310,24 @@ 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;
|
||||
}
|
||||
|
||||
if (buf[0] != '\0')
|
||||
{
|
||||
scp_session_set_domain(session, buf);
|
||||
}
|
||||
}
|
||||
|
||||
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 +338,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 +352,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 +369,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 +381,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");
|
||||
@@ -405,81 +401,26 @@ scp_v0s_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session)
|
||||
return SCP_SERVER_STATE_OK;
|
||||
}
|
||||
|
||||
|
||||
/* server API */
|
||||
/******************************************************************************/
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v0s_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s, int skipVchk)
|
||||
{
|
||||
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();
|
||||
if (NULL == session)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(*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 +432,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 +455,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;
|
||||
|
||||
+12
-10
@@ -29,6 +29,9 @@
|
||||
|
||||
#include "libscp.h"
|
||||
|
||||
/*TODO : Replace this (unused) function with something that can be used
|
||||
* by xrdp_mm.c and sesrun.c */
|
||||
#if 0
|
||||
/* client API */
|
||||
/**
|
||||
*
|
||||
@@ -40,45 +43,44 @@
|
||||
*/
|
||||
enum SCP_CLIENT_STATES_E
|
||||
scp_v0c_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s);
|
||||
#endif
|
||||
|
||||
/* server API */
|
||||
/**
|
||||
*
|
||||
* @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
|
||||
|
||||
+141
-135
@@ -35,18 +35,15 @@
|
||||
#include <stdio.h>
|
||||
|
||||
static enum SCP_CLIENT_STATES_E
|
||||
_scp_v1c_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s);
|
||||
_scp_v1c_check_response(struct trans *t, struct SCP_SESSION *s);
|
||||
|
||||
/* client API */
|
||||
/* 001 */
|
||||
enum SCP_CLIENT_STATES_E
|
||||
scp_v1c_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
scp_v1c_connect(struct trans *t, struct SCP_SESSION *s)
|
||||
{
|
||||
tui8 sz;
|
||||
tui32 size;
|
||||
|
||||
init_stream(c->out_s, c->out_s->size);
|
||||
init_stream(c->in_s, c->in_s->size);
|
||||
int size;
|
||||
struct stream *out_s = t->out_s;
|
||||
|
||||
size = (19 + 17 + 4 + g_strlen(s->hostname) + g_strlen(s->username) +
|
||||
g_strlen(s->password));
|
||||
@@ -60,95 +57,99 @@ scp_v1c_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
size = size + 16;
|
||||
}
|
||||
|
||||
init_stream(out_s, size);
|
||||
|
||||
/* sending request */
|
||||
|
||||
/* header */
|
||||
out_uint32_be(c->out_s, 1); /* version */
|
||||
out_uint32_be(c->out_s, size);
|
||||
out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT);
|
||||
out_uint16_be(c->out_s, 1);
|
||||
out_uint32_be(out_s, 1); /* version */
|
||||
out_uint32_be(out_s, size);
|
||||
out_uint16_be(out_s, SCP_COMMAND_SET_DEFAULT);
|
||||
out_uint16_be(out_s, SCP_CMD_LOGIN);
|
||||
|
||||
/* body */
|
||||
out_uint8(c->out_s, s->type);
|
||||
out_uint16_be(c->out_s, s->height);
|
||||
out_uint16_be(c->out_s, s->width);
|
||||
out_uint8(c->out_s, s->bpp);
|
||||
out_uint8(c->out_s, s->rsr);
|
||||
out_uint8p(c->out_s, s->locale, 17);
|
||||
out_uint8(c->out_s, s->addr_type);
|
||||
out_uint8(out_s, s->type);
|
||||
out_uint16_be(out_s, s->height);
|
||||
out_uint16_be(out_s, s->width);
|
||||
out_uint8(out_s, s->bpp);
|
||||
out_uint8(out_s, s->rsr);
|
||||
out_uint8p(out_s, s->locale, 17);
|
||||
out_uint8(out_s, s->addr_type);
|
||||
|
||||
if (s->addr_type == SCP_ADDRESS_TYPE_IPV4)
|
||||
{
|
||||
out_uint32_be(c->out_s, s->ipv4addr);
|
||||
out_uint32_be(out_s, s->ipv4addr);
|
||||
}
|
||||
else if (s->addr_type == SCP_ADDRESS_TYPE_IPV6)
|
||||
{
|
||||
out_uint8p(c->out_s, s->ipv6addr, 16);
|
||||
out_uint8p(out_s, s->ipv6addr, 16);
|
||||
}
|
||||
|
||||
sz = g_strlen(s->hostname);
|
||||
out_uint8(c->out_s, sz);
|
||||
out_uint8p(c->out_s, s->hostname, sz);
|
||||
out_uint8(out_s, sz);
|
||||
out_uint8p(out_s, s->hostname, sz);
|
||||
sz = g_strlen(s->username);
|
||||
out_uint8(c->out_s, sz);
|
||||
out_uint8p(c->out_s, s->username, sz);
|
||||
out_uint8(out_s, sz);
|
||||
out_uint8p(out_s, s->username, sz);
|
||||
sz = g_strlen(s->password);
|
||||
out_uint8(c->out_s, sz);
|
||||
out_uint8p(c->out_s, s->password, sz);
|
||||
out_uint8(out_s, sz);
|
||||
out_uint8p(out_s, s->password, sz);
|
||||
s_mark_end(out_s);
|
||||
|
||||
if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size))
|
||||
if (0 != trans_force_write(t))
|
||||
{
|
||||
return SCP_CLIENT_STATE_NETWORK_ERR;
|
||||
}
|
||||
|
||||
/* wait for response */
|
||||
return _scp_v1c_check_response(c, s);
|
||||
return _scp_v1c_check_response(t, s);
|
||||
}
|
||||
|
||||
/* 004 */
|
||||
enum SCP_CLIENT_STATES_E
|
||||
scp_v1c_resend_credentials(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
scp_v1c_resend_credentials(struct trans *t, struct SCP_SESSION *s)
|
||||
{
|
||||
struct stream *out_s = t->out_s;
|
||||
tui8 sz;
|
||||
tui32 size;
|
||||
|
||||
init_stream(c->out_s, c->out_s->size);
|
||||
init_stream(c->in_s, c->in_s->size);
|
||||
int size;
|
||||
|
||||
size = 12 + 2 + g_strlen(s->username) + g_strlen(s->password);
|
||||
|
||||
init_stream(out_s, size);
|
||||
|
||||
/* sending request */
|
||||
/* header */
|
||||
out_uint32_be(c->out_s, 1); /* version */
|
||||
out_uint32_be(c->out_s, size);
|
||||
out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT);
|
||||
out_uint16_be(c->out_s, 4);
|
||||
out_uint32_be(out_s, 1); /* version */
|
||||
out_uint32_be(out_s, size);
|
||||
out_uint16_be(out_s, SCP_COMMAND_SET_DEFAULT);
|
||||
out_uint16_be(out_s, SCP_CMD_RESEND_CREDS);
|
||||
|
||||
/* body */
|
||||
sz = g_strlen(s->username);
|
||||
out_uint8(c->out_s, sz);
|
||||
out_uint8p(c->out_s, s->username, sz);
|
||||
out_uint8(out_s, sz);
|
||||
out_uint8p(out_s, s->username, sz);
|
||||
sz = g_strlen(s->password);
|
||||
out_uint8(c->out_s, sz);
|
||||
out_uint8p(c->out_s, s->password, sz);
|
||||
out_uint8(out_s, sz);
|
||||
out_uint8p(out_s, s->password, sz);
|
||||
s_mark_end(out_s);
|
||||
|
||||
if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size))
|
||||
if (0 != trans_force_write(t))
|
||||
{
|
||||
return SCP_CLIENT_STATE_NETWORK_ERR;
|
||||
}
|
||||
|
||||
/* wait for response */
|
||||
return _scp_v1c_check_response(c, s);
|
||||
return _scp_v1c_check_response(t, s);
|
||||
}
|
||||
|
||||
/* 041 */
|
||||
enum SCP_CLIENT_STATES_E
|
||||
scp_v1c_get_session_list(struct SCP_CONNECTION *c, int *scount,
|
||||
scp_v1c_get_session_list(struct trans *t, int *scount,
|
||||
struct SCP_DISCONNECTED_SESSION **s)
|
||||
{
|
||||
struct stream *in_s = t->in_s;
|
||||
struct stream *out_s = t->out_s;
|
||||
tui32 version = 1;
|
||||
tui32 size = 12;
|
||||
tui16 cmd = 41;
|
||||
int size = 12;
|
||||
tui16 cmd = SCP_CMD_GET_SESSION_LIST;
|
||||
tui32 sescnt = 0; /* total session number */
|
||||
tui32 sestmp = 0; /* additional total session number */
|
||||
tui8 pktcnt = 0; /* packet session count */
|
||||
@@ -158,15 +159,16 @@ scp_v1c_get_session_list(struct SCP_CONNECTION *c, int *scount,
|
||||
int idx;
|
||||
struct SCP_DISCONNECTED_SESSION *ds = 0;
|
||||
|
||||
init_stream(c->out_s, c->out_s->size);
|
||||
init_stream(out_s, 64);
|
||||
|
||||
/* we request session list */
|
||||
out_uint32_be(c->out_s, version); /* version */
|
||||
out_uint32_be(c->out_s, size); /* size */
|
||||
out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */
|
||||
out_uint16_be(c->out_s, cmd); /* cmd */
|
||||
out_uint32_be(out_s, version); /* version */
|
||||
out_uint32_be(out_s, size); /* size */
|
||||
out_uint16_be(out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */
|
||||
out_uint16_be(out_s, cmd); /* cmd */
|
||||
s_mark_end(out_s);
|
||||
|
||||
if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size))
|
||||
if (0 != trans_force_write(t))
|
||||
{
|
||||
return SCP_CLIENT_STATE_NETWORK_ERR;
|
||||
}
|
||||
@@ -174,15 +176,15 @@ scp_v1c_get_session_list(struct SCP_CONNECTION *c, int *scount,
|
||||
do
|
||||
{
|
||||
/* then we wait for server response */
|
||||
init_stream(c->in_s, c->in_s->size);
|
||||
init_stream(in_s, 8);
|
||||
|
||||
if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
|
||||
if (0 != trans_force_read(t, 8))
|
||||
{
|
||||
g_free(ds);
|
||||
return SCP_CLIENT_STATE_NETWORK_ERR;
|
||||
}
|
||||
|
||||
in_uint32_be(c->in_s, version);
|
||||
in_uint32_be(t->in_s, version);
|
||||
|
||||
if (version != 1)
|
||||
{
|
||||
@@ -190,7 +192,7 @@ scp_v1c_get_session_list(struct SCP_CONNECTION *c, int *scount,
|
||||
return SCP_CLIENT_STATE_VERSION_ERR;
|
||||
}
|
||||
|
||||
in_uint32_be(c->in_s, size);
|
||||
in_uint32_be(t->in_s, size);
|
||||
|
||||
if (size < 12)
|
||||
{
|
||||
@@ -198,15 +200,15 @@ scp_v1c_get_session_list(struct SCP_CONNECTION *c, int *scount,
|
||||
return SCP_CLIENT_STATE_SIZE_ERR;
|
||||
}
|
||||
|
||||
init_stream(c->in_s, c->in_s->size);
|
||||
init_stream(t->in_s, size - 8);
|
||||
|
||||
if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8))
|
||||
if (0 != trans_force_read(t, size - 8))
|
||||
{
|
||||
g_free(ds);
|
||||
return SCP_CLIENT_STATE_NETWORK_ERR;
|
||||
}
|
||||
|
||||
in_uint16_be(c->in_s, cmd);
|
||||
in_uint16_be(in_s, cmd);
|
||||
|
||||
if (cmd != SCP_COMMAND_SET_DEFAULT)
|
||||
{
|
||||
@@ -214,9 +216,9 @@ scp_v1c_get_session_list(struct SCP_CONNECTION *c, int *scount,
|
||||
return SCP_CLIENT_STATE_SEQUENCE_ERR;
|
||||
}
|
||||
|
||||
in_uint16_be(c->in_s, cmd);
|
||||
in_uint16_be(in_s, cmd);
|
||||
|
||||
if (cmd != 42)
|
||||
if (cmd != SCP_REPLY_SESSIONS_INFO)
|
||||
{
|
||||
g_free(ds);
|
||||
return SCP_CLIENT_STATE_SEQUENCE_ERR;
|
||||
@@ -225,7 +227,7 @@ scp_v1c_get_session_list(struct SCP_CONNECTION *c, int *scount,
|
||||
if (firstpkt)
|
||||
{
|
||||
firstpkt = 0;
|
||||
in_uint32_be(c->in_s, sescnt);
|
||||
in_uint32_be(in_s, sescnt);
|
||||
sestmp = sescnt;
|
||||
|
||||
ds = g_new(struct SCP_DISCONNECTED_SESSION, sescnt);
|
||||
@@ -237,37 +239,37 @@ scp_v1c_get_session_list(struct SCP_CONNECTION *c, int *scount,
|
||||
}
|
||||
else
|
||||
{
|
||||
in_uint32_be(c->in_s, sestmp);
|
||||
in_uint32_be(in_s, sestmp);
|
||||
}
|
||||
|
||||
in_uint8(c->in_s, continued);
|
||||
in_uint8(c->in_s, pktcnt);
|
||||
in_uint8(in_s, continued);
|
||||
in_uint8(in_s, pktcnt);
|
||||
|
||||
for (idx = 0; idx < pktcnt; idx++)
|
||||
{
|
||||
in_uint32_be(c->in_s, (ds[totalcnt]).SID); /* session id */
|
||||
in_uint8(c->in_s, (ds[totalcnt]).type);
|
||||
in_uint16_be(c->in_s, (ds[totalcnt]).height);
|
||||
in_uint16_be(c->in_s, (ds[totalcnt]).width);
|
||||
in_uint8(c->in_s, (ds[totalcnt]).bpp);
|
||||
in_uint8(c->in_s, (ds[totalcnt]).idle_days);
|
||||
in_uint8(c->in_s, (ds[totalcnt]).idle_hours);
|
||||
in_uint8(c->in_s, (ds[totalcnt]).idle_minutes);
|
||||
in_uint32_be(in_s, (ds[totalcnt]).SID); /* session id */
|
||||
in_uint8(in_s, (ds[totalcnt]).type);
|
||||
in_uint16_be(in_s, (ds[totalcnt]).height);
|
||||
in_uint16_be(in_s, (ds[totalcnt]).width);
|
||||
in_uint8(in_s, (ds[totalcnt]).bpp);
|
||||
in_uint8(in_s, (ds[totalcnt]).idle_days);
|
||||
in_uint8(in_s, (ds[totalcnt]).idle_hours);
|
||||
in_uint8(in_s, (ds[totalcnt]).idle_minutes);
|
||||
|
||||
in_uint16_be(c->in_s, (ds[totalcnt]).conn_year);
|
||||
in_uint8(c->in_s, (ds[totalcnt]).conn_month);
|
||||
in_uint8(c->in_s, (ds[totalcnt]).conn_day);
|
||||
in_uint8(c->in_s, (ds[totalcnt]).conn_hour);
|
||||
in_uint8(c->in_s, (ds[totalcnt]).conn_minute);
|
||||
in_uint8(c->in_s, (ds[totalcnt]).addr_type);
|
||||
in_uint16_be(in_s, (ds[totalcnt]).conn_year);
|
||||
in_uint8(in_s, (ds[totalcnt]).conn_month);
|
||||
in_uint8(in_s, (ds[totalcnt]).conn_day);
|
||||
in_uint8(in_s, (ds[totalcnt]).conn_hour);
|
||||
in_uint8(in_s, (ds[totalcnt]).conn_minute);
|
||||
in_uint8(in_s, (ds[totalcnt]).addr_type);
|
||||
|
||||
if ((ds[totalcnt]).addr_type == SCP_ADDRESS_TYPE_IPV4)
|
||||
{
|
||||
in_uint32_be(c->in_s, (ds[totalcnt]).ipv4addr);
|
||||
in_uint32_be(in_s, (ds[totalcnt]).ipv4addr);
|
||||
}
|
||||
else if ((ds[totalcnt]).addr_type == SCP_ADDRESS_TYPE_IPV6)
|
||||
{
|
||||
in_uint8a(c->in_s, (ds[totalcnt]).ipv6addr, 16);
|
||||
in_uint8a(in_s, (ds[totalcnt]).ipv6addr, 16);
|
||||
}
|
||||
|
||||
totalcnt++;
|
||||
@@ -283,99 +285,102 @@ scp_v1c_get_session_list(struct SCP_CONNECTION *c, int *scount,
|
||||
return SCP_CLIENT_STATE_LIST_OK;
|
||||
}
|
||||
|
||||
/* 043 */
|
||||
enum SCP_CLIENT_STATES_E
|
||||
scp_v1c_select_session(struct SCP_CONNECTION *c, struct SCP_SESSION *s,
|
||||
scp_v1c_select_session(struct trans *t, struct SCP_SESSION *s,
|
||||
SCP_SID sid)
|
||||
{
|
||||
struct stream *in_s = t->in_s;
|
||||
struct stream *out_s = t->out_s;
|
||||
tui32 version = 1;
|
||||
tui32 size = 16;
|
||||
tui16 cmd = 43;
|
||||
int size = 16;
|
||||
tui16 cmd = SCP_CMD_SELECT_SESSION;
|
||||
|
||||
init_stream(c->out_s, c->out_s->size);
|
||||
init_stream(out_s, 64);
|
||||
|
||||
/* sending our selection */
|
||||
out_uint32_be(c->out_s, version); /* version */
|
||||
out_uint32_be(c->out_s, size); /* size */
|
||||
out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */
|
||||
out_uint16_be(c->out_s, cmd); /* cmd */
|
||||
out_uint32_be(out_s, version); /* version */
|
||||
out_uint32_be(out_s, size); /* size */
|
||||
out_uint16_be(out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */
|
||||
out_uint16_be(out_s, cmd); /* cmd */
|
||||
|
||||
out_uint32_be(c->out_s, sid);
|
||||
out_uint32_be(out_s, sid);
|
||||
s_mark_end(out_s);
|
||||
|
||||
if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size))
|
||||
if (0 != trans_force_write(t))
|
||||
{
|
||||
return SCP_CLIENT_STATE_NETWORK_ERR;
|
||||
}
|
||||
|
||||
/* waiting for response.... */
|
||||
init_stream(c->in_s, c->in_s->size);
|
||||
init_stream(in_s, 8);
|
||||
|
||||
if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
|
||||
if (0 != trans_force_read(t, 8))
|
||||
{
|
||||
return SCP_CLIENT_STATE_NETWORK_ERR;
|
||||
}
|
||||
|
||||
in_uint32_be(c->in_s, version);
|
||||
in_uint32_be(in_s, version);
|
||||
|
||||
if (version != 1)
|
||||
{
|
||||
return SCP_CLIENT_STATE_VERSION_ERR;
|
||||
}
|
||||
|
||||
in_uint32_be(c->in_s, size);
|
||||
in_uint32_be(in_s, size);
|
||||
|
||||
if (size < 12)
|
||||
{
|
||||
return SCP_CLIENT_STATE_SIZE_ERR;
|
||||
}
|
||||
|
||||
init_stream(c->in_s, c->in_s->size);
|
||||
init_stream(in_s, size - 8);
|
||||
|
||||
/* read the rest of the packet */
|
||||
if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8))
|
||||
if (0 != trans_force_read(t, size - 8))
|
||||
{
|
||||
return SCP_CLIENT_STATE_NETWORK_ERR;
|
||||
}
|
||||
|
||||
in_uint16_be(c->in_s, cmd);
|
||||
in_uint16_be(in_s, cmd);
|
||||
|
||||
if (cmd != SCP_COMMAND_SET_DEFAULT)
|
||||
{
|
||||
return SCP_CLIENT_STATE_SEQUENCE_ERR;
|
||||
}
|
||||
|
||||
in_uint16_be(c->in_s, cmd);
|
||||
in_uint16_be(in_s, cmd);
|
||||
|
||||
if (cmd != 46)
|
||||
if (cmd != SCP_REPLY_SESSION_RECONNECTED)
|
||||
{
|
||||
return SCP_CLIENT_STATE_SEQUENCE_ERR;
|
||||
}
|
||||
|
||||
/* session display */
|
||||
in_uint16_be(c->in_s, (s->display));
|
||||
in_uint16_be(in_s, (s->display));
|
||||
/*we don't need to return any data other than the display */
|
||||
/*because we already sent that */
|
||||
|
||||
return SCP_CLIENT_STATE_OK;
|
||||
}
|
||||
|
||||
/* 044 */
|
||||
enum SCP_CLIENT_STATES_E
|
||||
scp_v1c_select_session_cancel(struct SCP_CONNECTION *c)
|
||||
scp_v1c_select_session_cancel(struct trans *t)
|
||||
{
|
||||
struct stream *out_s = t->out_s;
|
||||
tui32 version = 1;
|
||||
tui32 size = 12;
|
||||
tui16 cmd = 44;
|
||||
tui16 cmd = SCP_CMD_SELECT_SESSION_CANCEL;
|
||||
|
||||
init_stream(c->out_s, c->out_s->size);
|
||||
init_stream(out_s, 64);
|
||||
|
||||
/* sending our selection */
|
||||
out_uint32_be(c->out_s, version); /* version */
|
||||
out_uint32_be(c->out_s, size); /* size */
|
||||
out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */
|
||||
out_uint16_be(c->out_s, cmd); /* cmd */
|
||||
out_uint32_be(out_s, version); /* version */
|
||||
out_uint32_be(out_s, size); /* size */
|
||||
out_uint16_be(out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */
|
||||
out_uint16_be(out_s, cmd); /* cmd */
|
||||
s_mark_end(out_s);
|
||||
|
||||
if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size))
|
||||
if (0 != trans_force_write(t))
|
||||
{
|
||||
return SCP_CLIENT_STATE_NETWORK_ERR;
|
||||
}
|
||||
@@ -384,49 +389,50 @@ scp_v1c_select_session_cancel(struct SCP_CONNECTION *c)
|
||||
}
|
||||
|
||||
static enum SCP_CLIENT_STATES_E
|
||||
_scp_v1c_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
_scp_v1c_check_response(struct trans *t, struct SCP_SESSION *s)
|
||||
{
|
||||
struct stream *in_s = t->in_s;
|
||||
tui32 version;
|
||||
tui32 size;
|
||||
int size;
|
||||
tui16 cmd;
|
||||
tui16 dim;
|
||||
|
||||
init_stream(c->in_s, c->in_s->size);
|
||||
init_stream(in_s, 64);
|
||||
|
||||
if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
|
||||
if (0 != trans_force_read(t, 8))
|
||||
{
|
||||
return SCP_CLIENT_STATE_NETWORK_ERR;
|
||||
}
|
||||
|
||||
in_uint32_be(c->in_s, version);
|
||||
in_uint32_be(in_s, version);
|
||||
|
||||
if (version != 1)
|
||||
{
|
||||
return SCP_CLIENT_STATE_VERSION_ERR;
|
||||
}
|
||||
|
||||
in_uint32_be(c->in_s, size);
|
||||
in_uint32_be(in_s, size);
|
||||
|
||||
init_stream(c->in_s, c->in_s->size);
|
||||
init_stream(in_s, size - 8);
|
||||
|
||||
/* read the rest of the packet */
|
||||
if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8))
|
||||
if (0 != trans_force_read(t, size - 8))
|
||||
{
|
||||
return SCP_CLIENT_STATE_NETWORK_ERR;
|
||||
}
|
||||
|
||||
in_uint16_be(c->in_s, cmd);
|
||||
in_uint16_be(in_s, cmd);
|
||||
|
||||
if (cmd != SCP_COMMAND_SET_DEFAULT)
|
||||
{
|
||||
return SCP_CLIENT_STATE_SEQUENCE_ERR;
|
||||
}
|
||||
|
||||
in_uint16_be(c->in_s, cmd);
|
||||
in_uint16_be(in_s, cmd);
|
||||
|
||||
if (cmd == 2) /* connection denied */
|
||||
if (cmd == SCP_REPLY_LOGIN_DENIED)
|
||||
{
|
||||
in_uint16_be(c->in_s, dim);
|
||||
in_uint16_be(in_s, dim);
|
||||
|
||||
if (s->errstr != 0)
|
||||
{
|
||||
@@ -440,14 +446,14 @@ _scp_v1c_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
return SCP_CLIENT_STATE_INTERNAL_ERR;
|
||||
}
|
||||
|
||||
in_uint8a(c->in_s, s->errstr, dim);
|
||||
in_uint8a(in_s, s->errstr, dim);
|
||||
(s->errstr)[dim] = '\0';
|
||||
|
||||
return SCP_CLIENT_STATE_CONNECTION_DENIED;
|
||||
}
|
||||
else if (cmd == 3) /* resend usr/pwd */
|
||||
else if (cmd == SCP_REPLY_REREQUEST_CREDS)
|
||||
{
|
||||
in_uint16_be(c->in_s, dim);
|
||||
in_uint16_be(in_s, dim);
|
||||
|
||||
if (s->errstr != 0)
|
||||
{
|
||||
@@ -461,14 +467,14 @@ _scp_v1c_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
return SCP_CLIENT_STATE_INTERNAL_ERR;
|
||||
}
|
||||
|
||||
in_uint8a(c->in_s, s->errstr, dim);
|
||||
in_uint8a(in_s, s->errstr, dim);
|
||||
(s->errstr)[dim] = '\0';
|
||||
|
||||
return SCP_CLIENT_STATE_RESEND_CREDENTIALS;
|
||||
}
|
||||
else if (cmd == 20) /* password change */
|
||||
else if (cmd == SCP_REPLY_CHANGE_PASSWD)
|
||||
{
|
||||
in_uint16_be(c->in_s, dim);
|
||||
in_uint16_be(in_s, dim);
|
||||
|
||||
if (s->errstr != 0)
|
||||
{
|
||||
@@ -482,14 +488,14 @@ _scp_v1c_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
return SCP_CLIENT_STATE_INTERNAL_ERR;
|
||||
}
|
||||
|
||||
in_uint8a(c->in_s, s->errstr, dim);
|
||||
in_uint8a(in_s, s->errstr, dim);
|
||||
(s->errstr)[dim] = '\0';
|
||||
|
||||
return SCP_CLIENT_STATE_PWD_CHANGE_REQ;
|
||||
}
|
||||
else if (cmd == 30) /* display */
|
||||
else if (cmd == SCP_REPLY_NEW_SESSION)
|
||||
{
|
||||
in_uint16_be(c->in_s, s->display);
|
||||
in_uint16_be(in_s, s->display);
|
||||
|
||||
return SCP_CLIENT_STATE_OK;
|
||||
}
|
||||
@@ -501,7 +507,7 @@ _scp_v1c_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
//{
|
||||
// return SCP_CLIENT_STATE_RECONNECT;
|
||||
//}
|
||||
else if (cmd == 40) /* session list */
|
||||
else if (cmd == SCP_REPLY_USER_SESSIONS_EXIST) /* session list */
|
||||
{
|
||||
return SCP_CLIENT_STATE_SESSION_LIST;
|
||||
}
|
||||
|
||||
@@ -32,32 +32,32 @@
|
||||
/* client API */
|
||||
/* 001 */
|
||||
enum SCP_CLIENT_STATES_E
|
||||
scp_v1c_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s);
|
||||
scp_v1c_connect(struct trans *t, struct SCP_SESSION *s);
|
||||
|
||||
/* 004 */
|
||||
enum SCP_CLIENT_STATES_E
|
||||
scp_v1c_resend_credentials(struct SCP_CONNECTION *c, struct SCP_SESSION *s);
|
||||
scp_v1c_resend_credentials(struct trans *t, struct SCP_SESSION *s);
|
||||
|
||||
/* 021 */
|
||||
enum SCP_CLIENT_STATES_E
|
||||
scp_v1c_pwd_change(struct SCP_CONNECTION *c, char *newpass);
|
||||
scp_v1c_pwd_change(struct trans *t, char *newpass);
|
||||
|
||||
/* 022 */
|
||||
enum SCP_CLIENT_STATES_E
|
||||
scp_v1c_pwd_change_cancel(struct SCP_CONNECTION *c);
|
||||
scp_v1c_pwd_change_cancel(struct trans *t);
|
||||
|
||||
/* 041 */
|
||||
enum SCP_CLIENT_STATES_E
|
||||
scp_v1c_get_session_list(struct SCP_CONNECTION *c, int *scount,
|
||||
scp_v1c_get_session_list(struct trans *t, int *scount,
|
||||
struct SCP_DISCONNECTED_SESSION **s);
|
||||
|
||||
/* 043 */
|
||||
enum SCP_CLIENT_STATES_E
|
||||
scp_v1c_select_session(struct SCP_CONNECTION *c, struct SCP_SESSION *s,
|
||||
scp_v1c_select_session(struct trans *t, struct SCP_SESSION *s,
|
||||
SCP_SID sid);
|
||||
|
||||
/* 044 */
|
||||
enum SCP_CLIENT_STATES_E
|
||||
scp_v1c_select_session_cancel(struct SCP_CONNECTION *c);
|
||||
scp_v1c_select_session_cancel(struct trans *t);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -37,18 +37,17 @@
|
||||
//extern struct log_config* s_log;
|
||||
|
||||
static enum SCP_CLIENT_STATES_E
|
||||
_scp_v1c_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s);
|
||||
_scp_v1c_mng_check_response(struct trans *t, struct SCP_SESSION *s);
|
||||
|
||||
/* client API */
|
||||
/* 001 */
|
||||
enum SCP_CLIENT_STATES_E
|
||||
scp_v1c_mng_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
scp_v1c_mng_connect(struct trans *t, struct SCP_SESSION *s)
|
||||
{
|
||||
tui8 sz;
|
||||
tui32 size;
|
||||
struct stream *out_s = t->out_s;
|
||||
|
||||
init_stream(c->out_s, c->out_s->size);
|
||||
init_stream(c->in_s, c->in_s->size);
|
||||
tui8 sz;
|
||||
int size;
|
||||
|
||||
size = (12 + 4 + g_strlen(s->hostname) + g_strlen(s->username) +
|
||||
g_strlen(s->password));
|
||||
@@ -62,56 +61,61 @@ scp_v1c_mng_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
size = size + 16;
|
||||
}
|
||||
|
||||
init_stream(out_s, size);
|
||||
|
||||
/* sending request */
|
||||
|
||||
/* header */
|
||||
out_uint32_be(c->out_s, 1); /* version */
|
||||
out_uint32_be(c->out_s, size);
|
||||
out_uint16_be(c->out_s, SCP_COMMAND_SET_MANAGE);
|
||||
out_uint16_be(c->out_s, SCP_CMD_MNG_LOGIN);
|
||||
out_uint32_be(out_s, 1); /* version */
|
||||
out_uint32_be(out_s, size);
|
||||
out_uint16_be(out_s, SCP_COMMAND_SET_MANAGE);
|
||||
out_uint16_be(out_s, SCP_CMD_MNG_LOGIN);
|
||||
|
||||
/* data */
|
||||
sz = g_strlen(s->username);
|
||||
out_uint8(c->out_s, sz);
|
||||
out_uint8p(c->out_s, s->username, sz);
|
||||
out_uint8(out_s, sz);
|
||||
out_uint8p(out_s, s->username, sz);
|
||||
sz = g_strlen(s->password);
|
||||
out_uint8(c->out_s, sz);
|
||||
out_uint8p(c->out_s, s->password, sz);
|
||||
out_uint8(out_s, sz);
|
||||
out_uint8p(out_s, s->password, sz);
|
||||
|
||||
/* address */
|
||||
out_uint8(c->out_s, s->addr_type);
|
||||
out_uint8(out_s, s->addr_type);
|
||||
|
||||
if (s->addr_type == SCP_ADDRESS_TYPE_IPV4)
|
||||
{
|
||||
out_uint32_be(c->out_s, s->ipv4addr);
|
||||
out_uint32_be(out_s, s->ipv4addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
out_uint8p(c->out_s, s->ipv6addr, 16);
|
||||
out_uint8p(out_s, s->ipv6addr, 16);
|
||||
}
|
||||
|
||||
/* hostname */
|
||||
sz = g_strlen(s->hostname);
|
||||
out_uint8(c->out_s, sz);
|
||||
out_uint8p(c->out_s, s->hostname, sz);
|
||||
out_uint8(out_s, sz);
|
||||
out_uint8p(out_s, s->hostname, sz);
|
||||
s_mark_end(out_s);
|
||||
|
||||
if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size))
|
||||
if (0 != trans_force_write(t))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
|
||||
return SCP_CLIENT_STATE_NETWORK_ERR;
|
||||
}
|
||||
|
||||
/* wait for response */
|
||||
return _scp_v1c_mng_check_response(c, s);
|
||||
return _scp_v1c_mng_check_response(t, s);
|
||||
}
|
||||
|
||||
/* 004 */
|
||||
enum SCP_CLIENT_STATES_E
|
||||
scp_v1c_mng_get_session_list(struct SCP_CONNECTION *c, int *scount,
|
||||
scp_v1c_mng_get_session_list(struct trans *t, int *scount,
|
||||
struct SCP_DISCONNECTED_SESSION **s)
|
||||
{
|
||||
struct stream *in_s = t->in_s;
|
||||
struct stream *out_s = t->out_s;
|
||||
tui32 version = 1;
|
||||
tui32 size = 12;
|
||||
int size = 12;
|
||||
tui16 cmd = SCP_CMD_MNG_LIST_REQ; /* request session list */
|
||||
tui32 sescnt = 0; /* total session number */
|
||||
tui32 sestmp = 0; /* additional total session number */
|
||||
@@ -123,15 +127,16 @@ scp_v1c_mng_get_session_list(struct SCP_CONNECTION *c, int *scount,
|
||||
struct SCP_DISCONNECTED_SESSION *ds = 0;
|
||||
// tui8 addr[16];
|
||||
|
||||
init_stream(c->out_s, c->out_s->size);
|
||||
init_stream(out_s, 64);
|
||||
|
||||
/* we request session list */
|
||||
out_uint32_be(c->out_s, version); /* version */
|
||||
out_uint32_be(c->out_s, size); /* size */
|
||||
out_uint16_be(c->out_s, SCP_COMMAND_SET_MANAGE); /* cmdset */
|
||||
out_uint16_be(c->out_s, cmd); /* cmd */
|
||||
out_uint32_be(out_s, version); /* version */
|
||||
out_uint32_be(out_s, size); /* size */
|
||||
out_uint16_be(out_s, SCP_COMMAND_SET_MANAGE); /* cmdset */
|
||||
out_uint16_be(out_s, cmd); /* cmd */
|
||||
s_mark_end(out_s);
|
||||
|
||||
if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size))
|
||||
if (0 != trans_force_write(t))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
|
||||
return SCP_CLIENT_STATE_NETWORK_ERR;
|
||||
@@ -140,16 +145,16 @@ scp_v1c_mng_get_session_list(struct SCP_CONNECTION *c, int *scount,
|
||||
do
|
||||
{
|
||||
/* then we wait for server response */
|
||||
init_stream(c->in_s, c->in_s->size);
|
||||
init_stream(in_s, 8);
|
||||
|
||||
if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
|
||||
if (0 != trans_force_read(t, 8))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
|
||||
g_free(ds);
|
||||
return SCP_CLIENT_STATE_NETWORK_ERR;
|
||||
}
|
||||
|
||||
in_uint32_be(c->in_s, version);
|
||||
in_uint32_be(in_s, version);
|
||||
|
||||
if (version != 1)
|
||||
{
|
||||
@@ -158,7 +163,7 @@ scp_v1c_mng_get_session_list(struct SCP_CONNECTION *c, int *scount,
|
||||
return SCP_CLIENT_STATE_VERSION_ERR;
|
||||
}
|
||||
|
||||
in_uint32_be(c->in_s, size);
|
||||
in_uint32_be(in_s, size);
|
||||
|
||||
if (size < 12)
|
||||
{
|
||||
@@ -167,16 +172,16 @@ scp_v1c_mng_get_session_list(struct SCP_CONNECTION *c, int *scount,
|
||||
return SCP_CLIENT_STATE_SIZE_ERR;
|
||||
}
|
||||
|
||||
init_stream(c->in_s, c->in_s->size);
|
||||
init_stream(in_s, size);
|
||||
|
||||
if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8))
|
||||
if (0 != trans_force_read(t, size - 8))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
|
||||
g_free(ds);
|
||||
return SCP_CLIENT_STATE_NETWORK_ERR;
|
||||
}
|
||||
|
||||
in_uint16_be(c->in_s, cmd);
|
||||
in_uint16_be(in_s, cmd);
|
||||
|
||||
if (cmd != SCP_COMMAND_SET_MANAGE)
|
||||
{
|
||||
@@ -185,7 +190,7 @@ scp_v1c_mng_get_session_list(struct SCP_CONNECTION *c, int *scount,
|
||||
return SCP_CLIENT_STATE_SEQUENCE_ERR;
|
||||
}
|
||||
|
||||
in_uint16_be(c->in_s, cmd);
|
||||
in_uint16_be(in_s, cmd);
|
||||
|
||||
if (cmd != SCP_CMD_MNG_LIST) /* session list */
|
||||
{
|
||||
@@ -197,7 +202,7 @@ scp_v1c_mng_get_session_list(struct SCP_CONNECTION *c, int *scount,
|
||||
if (firstpkt)
|
||||
{
|
||||
firstpkt = 0;
|
||||
in_uint32_be(c->in_s, sescnt);
|
||||
in_uint32_be(in_s, sescnt);
|
||||
sestmp = sescnt;
|
||||
|
||||
if (0 == sescnt)
|
||||
@@ -220,38 +225,38 @@ scp_v1c_mng_get_session_list(struct SCP_CONNECTION *c, int *scount,
|
||||
}
|
||||
else
|
||||
{
|
||||
in_uint32_be(c->in_s, sestmp);
|
||||
in_uint32_be(in_s, sestmp);
|
||||
}
|
||||
|
||||
in_uint8(c->in_s, continued);
|
||||
in_uint8(c->in_s, pktcnt);
|
||||
in_uint8(in_s, continued);
|
||||
in_uint8(in_s, pktcnt);
|
||||
|
||||
for (idx = 0; idx < pktcnt; idx++)
|
||||
{
|
||||
in_uint32_be(c->in_s, (ds[totalcnt]).SID); /* session id */
|
||||
in_uint8(c->in_s, (ds[totalcnt]).type);
|
||||
in_uint16_be(c->in_s, (ds[totalcnt]).height);
|
||||
in_uint16_be(c->in_s, (ds[totalcnt]).width);
|
||||
in_uint8(c->in_s, (ds[totalcnt]).bpp);
|
||||
in_uint8(c->in_s, (ds[totalcnt]).idle_days);
|
||||
in_uint8(c->in_s, (ds[totalcnt]).idle_hours);
|
||||
in_uint8(c->in_s, (ds[totalcnt]).idle_minutes);
|
||||
in_uint32_be(in_s, (ds[totalcnt]).SID); /* session id */
|
||||
in_uint8(in_s, (ds[totalcnt]).type);
|
||||
in_uint16_be(in_s, (ds[totalcnt]).height);
|
||||
in_uint16_be(in_s, (ds[totalcnt]).width);
|
||||
in_uint8(in_s, (ds[totalcnt]).bpp);
|
||||
in_uint8(in_s, (ds[totalcnt]).idle_days);
|
||||
in_uint8(in_s, (ds[totalcnt]).idle_hours);
|
||||
in_uint8(in_s, (ds[totalcnt]).idle_minutes);
|
||||
|
||||
in_uint16_be(c->in_s, (ds[totalcnt]).conn_year);
|
||||
in_uint8(c->in_s, (ds[totalcnt]).conn_month);
|
||||
in_uint8(c->in_s, (ds[totalcnt]).conn_day);
|
||||
in_uint8(c->in_s, (ds[totalcnt]).conn_hour);
|
||||
in_uint8(c->in_s, (ds[totalcnt]).conn_minute);
|
||||
in_uint8(c->in_s, (ds[totalcnt]).addr_type);
|
||||
in_uint16_be(in_s, (ds[totalcnt]).conn_year);
|
||||
in_uint8(in_s, (ds[totalcnt]).conn_month);
|
||||
in_uint8(in_s, (ds[totalcnt]).conn_day);
|
||||
in_uint8(in_s, (ds[totalcnt]).conn_hour);
|
||||
in_uint8(in_s, (ds[totalcnt]).conn_minute);
|
||||
in_uint8(in_s, (ds[totalcnt]).addr_type);
|
||||
|
||||
if ((ds[totalcnt]).addr_type == SCP_ADDRESS_TYPE_IPV4)
|
||||
{
|
||||
in_uint32_be(c->in_s, (ds[totalcnt]).ipv4addr);
|
||||
in_uint32_be(in_s, (ds[totalcnt]).ipv4addr);
|
||||
}
|
||||
|
||||
if ((ds[totalcnt]).addr_type == SCP_ADDRESS_TYPE_IPV6)
|
||||
{
|
||||
in_uint8a(c->in_s, (ds[totalcnt]).ipv6addr, 16);
|
||||
in_uint8a(in_s, (ds[totalcnt]).ipv6addr, 16);
|
||||
}
|
||||
|
||||
totalcnt++;
|
||||
@@ -362,23 +367,24 @@ scp_v1c_select_session_cancel(struct SCP_CONNECTION* c)
|
||||
}*/
|
||||
|
||||
static enum SCP_CLIENT_STATES_E
|
||||
_scp_v1c_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
_scp_v1c_mng_check_response(struct trans *t, struct SCP_SESSION *s)
|
||||
{
|
||||
struct stream *in_s = t->in_s;
|
||||
tui32 version;
|
||||
tui32 size;
|
||||
int size;
|
||||
tui16 cmd;
|
||||
tui8 dim;
|
||||
char buf[257];
|
||||
|
||||
init_stream(c->in_s, c->in_s->size);
|
||||
init_stream(in_s, 8);
|
||||
|
||||
if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
|
||||
if (0 != trans_force_read(t, 8))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
|
||||
return SCP_CLIENT_STATE_NETWORK_ERR;
|
||||
}
|
||||
|
||||
in_uint32_be(c->in_s, version);
|
||||
in_uint32_be(in_s, version);
|
||||
|
||||
if (version != 1)
|
||||
{
|
||||
@@ -386,18 +392,18 @@ _scp_v1c_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
return SCP_CLIENT_STATE_VERSION_ERR;
|
||||
}
|
||||
|
||||
in_uint32_be(c->in_s, size);
|
||||
in_uint32_be(in_s, size);
|
||||
|
||||
init_stream(c->in_s, c->in_s->size);
|
||||
init_stream(in_s, size - 8);
|
||||
|
||||
/* read the rest of the packet */
|
||||
if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8))
|
||||
if (0 != trans_force_read(t, size - 8))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
|
||||
return SCP_CLIENT_STATE_NETWORK_ERR;
|
||||
}
|
||||
|
||||
in_uint16_be(c->in_s, cmd);
|
||||
in_uint16_be(in_s, cmd);
|
||||
|
||||
if (cmd != SCP_COMMAND_SET_MANAGE)
|
||||
{
|
||||
@@ -405,7 +411,7 @@ _scp_v1c_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
return SCP_CLIENT_STATE_SEQUENCE_ERR;
|
||||
}
|
||||
|
||||
in_uint16_be(c->in_s, cmd);
|
||||
in_uint16_be(in_s, cmd);
|
||||
|
||||
if (cmd == SCP_CMD_MNG_LOGIN_ALLOW) /* connection ok */
|
||||
{
|
||||
@@ -414,9 +420,9 @@ _scp_v1c_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
}
|
||||
else if (cmd == SCP_CMD_MNG_LOGIN_DENY) /* connection denied */
|
||||
{
|
||||
in_uint8(c->in_s, dim);
|
||||
in_uint8(in_s, dim);
|
||||
buf[dim] = '\0';
|
||||
in_uint8a(c->in_s, buf, dim);
|
||||
in_uint8a(in_s, buf, dim);
|
||||
scp_session_set_errstr(s, buf);
|
||||
|
||||
LOG(LOG_LEVEL_INFO, "[v1c_mng:%d] connection denied: %s", __LINE__, s->errstr);
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
/* client API */
|
||||
/* 001 */
|
||||
enum SCP_CLIENT_STATES_E
|
||||
scp_v1c_mng_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s);
|
||||
scp_v1c_mng_connect(struct trans *t, struct SCP_SESSION *s);
|
||||
|
||||
/* 004 * /
|
||||
enum SCP_CLIENT_STATES_E
|
||||
@@ -49,7 +49,7 @@ scp_v1c_pwd_change_cancel(struct SCP_CONNECTION* c);
|
||||
|
||||
/* 041 */
|
||||
enum SCP_CLIENT_STATES_E
|
||||
scp_v1c_mng_get_session_list(struct SCP_CONNECTION *c, int *scount,
|
||||
scp_v1c_mng_get_session_list(struct trans *t, int *scount,
|
||||
struct SCP_DISCONNECTED_SESSION **s);
|
||||
|
||||
#endif
|
||||
|
||||
+271
-222
@@ -83,7 +83,6 @@ int in_string8(struct stream *s, char str[], const char *param, int line)
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/* server API */
|
||||
|
||||
/**
|
||||
* Initialises a V1 session object
|
||||
@@ -95,7 +94,7 @@ int in_string8(struct stream *s, char str[], const char *param, int line)
|
||||
* @return SCP_SERVER_STATE_OK for success
|
||||
*/
|
||||
static enum SCP_SERVER_STATES_E
|
||||
scp_v1s_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session)
|
||||
scp_v1s_init_session(struct trans *t, struct SCP_SESSION *session)
|
||||
{
|
||||
tui8 type;
|
||||
tui16 height;
|
||||
@@ -103,12 +102,13 @@ scp_v1s_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session)
|
||||
tui8 bpp;
|
||||
tui8 sz;
|
||||
char buf[256];
|
||||
struct stream *in_s = t->in_s;
|
||||
|
||||
scp_session_set_version(session, 1);
|
||||
|
||||
/* Check there's data for the session type, the height, the width, the
|
||||
* bpp, the resource sharing indicator and the locale */
|
||||
if (!s_check_rem(c->in_s, 1 + 2 + 2 + 1 + 1 + 17))
|
||||
if (!s_check_rem(in_s, 1 + 2 + 2 + 1 + 1 + 17))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING,
|
||||
"[v1s:%d] connection aborted: short packet",
|
||||
@@ -116,7 +116,7 @@ scp_v1s_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session)
|
||||
return SCP_SERVER_STATE_SIZE_ERR;
|
||||
}
|
||||
|
||||
in_uint8(c->in_s, type);
|
||||
in_uint8(in_s, type);
|
||||
|
||||
if ((type != SCP_SESSION_TYPE_XVNC) && (type != SCP_SESSION_TYPE_XRDP))
|
||||
{
|
||||
@@ -126,11 +126,11 @@ scp_v1s_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session)
|
||||
|
||||
scp_session_set_type(session, type);
|
||||
|
||||
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, width);
|
||||
in_uint16_be(in_s, width);
|
||||
scp_session_set_width(session, width);
|
||||
in_uint8(c->in_s, bpp);
|
||||
in_uint8(in_s, bpp);
|
||||
if (0 != scp_session_set_bpp(session, bpp))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING,
|
||||
@@ -138,14 +138,14 @@ scp_v1s_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session)
|
||||
__LINE__, bpp);
|
||||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
in_uint8(c->in_s, sz);
|
||||
in_uint8(in_s, sz);
|
||||
scp_session_set_rsr(session, sz);
|
||||
in_uint8a(c->in_s, buf, 17);
|
||||
in_uint8a(in_s, buf, 17);
|
||||
buf[17] = '\0';
|
||||
scp_session_set_locale(session, buf);
|
||||
|
||||
/* Check there's enough data left for at least an IPv4 address (+len) */
|
||||
if (!s_check_rem(c->in_s, 1 + 4))
|
||||
if (!s_check_rem(in_s, 1 + 4))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING,
|
||||
"[v1s:%d] connection aborted: IP addr len missing",
|
||||
@@ -153,29 +153,29 @@ scp_v1s_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session)
|
||||
return SCP_SERVER_STATE_SIZE_ERR;
|
||||
}
|
||||
|
||||
in_uint8(c->in_s, sz);
|
||||
in_uint8(in_s, sz);
|
||||
|
||||
if (sz == SCP_ADDRESS_TYPE_IPV4)
|
||||
{
|
||||
tui32 ipv4;
|
||||
in_uint32_be(c->in_s, ipv4);
|
||||
in_uint32_be(in_s, ipv4);
|
||||
scp_session_set_addr(session, sz, &ipv4);
|
||||
}
|
||||
else if (sz == SCP_ADDRESS_TYPE_IPV6)
|
||||
{
|
||||
if (!s_check_rem(c->in_s, 16))
|
||||
if (!s_check_rem(in_s, 16))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING,
|
||||
"[v1s:%d] connection aborted: IP addr missing",
|
||||
__LINE__);
|
||||
return SCP_SERVER_STATE_SIZE_ERR;
|
||||
}
|
||||
in_uint8a(c->in_s, buf, 16);
|
||||
in_uint8a(in_s, buf, 16);
|
||||
scp_session_set_addr(session, sz, buf);
|
||||
}
|
||||
|
||||
/* reading hostname */
|
||||
if (!in_string8(c->in_s, buf, "hostname", __LINE__))
|
||||
if (!in_string8(in_s, buf, "hostname", __LINE__))
|
||||
{
|
||||
return SCP_SERVER_STATE_SIZE_ERR;
|
||||
}
|
||||
@@ -187,7 +187,7 @@ scp_v1s_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session)
|
||||
}
|
||||
|
||||
/* reading username */
|
||||
if (!in_string8(c->in_s, buf, "username", __LINE__))
|
||||
if (!in_string8(in_s, buf, "username", __LINE__))
|
||||
{
|
||||
return SCP_SERVER_STATE_SIZE_ERR;
|
||||
}
|
||||
@@ -199,7 +199,7 @@ scp_v1s_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session)
|
||||
}
|
||||
|
||||
/* reading password */
|
||||
if (!in_string8(c->in_s, buf, "passwd", __LINE__))
|
||||
if (!in_string8(in_s, buf, "passwd", __LINE__))
|
||||
{
|
||||
return SCP_SERVER_STATE_SIZE_ERR;
|
||||
}
|
||||
@@ -214,38 +214,16 @@ scp_v1s_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session)
|
||||
}
|
||||
|
||||
/* server API */
|
||||
enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s, int skipVchk)
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_accept(struct trans *t, struct SCP_SESSION *s)
|
||||
{
|
||||
enum SCP_SERVER_STATES_E result;
|
||||
struct SCP_SESSION *session;
|
||||
tui32 version;
|
||||
int size;
|
||||
tui32 size;
|
||||
tui16 cmdset;
|
||||
tui16 cmd;
|
||||
struct stream *in_s = t->in_s;
|
||||
enum SCP_SERVER_STATES_E result;
|
||||
|
||||
(*s) = NULL;
|
||||
|
||||
if (!skipVchk)
|
||||
{
|
||||
|
||||
if (0 == scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
|
||||
{
|
||||
in_uint32_be(c->in_s, version);
|
||||
|
||||
if (version != 1)
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__);
|
||||
return SCP_SERVER_STATE_VERSION_ERR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
|
||||
return SCP_SERVER_STATE_NETWORK_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
in_uint32_be(c->in_s, size);
|
||||
in_uint32_be(in_s, size);
|
||||
|
||||
/* Check the message is big enough for the header, the command set, and
|
||||
* the command (but not too big) */
|
||||
@@ -255,25 +233,15 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION *c, struct SCP_SES
|
||||
return SCP_SERVER_STATE_SIZE_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, "[v1s:%d] connection aborted: network error", __LINE__);
|
||||
return SCP_SERVER_STATE_NETWORK_ERR;
|
||||
}
|
||||
|
||||
c->in_s->end = c->in_s->data + (size - 8);
|
||||
|
||||
/* reading command set */
|
||||
in_uint16_be(c->in_s, cmdset);
|
||||
in_uint16_be(in_s, cmdset);
|
||||
|
||||
/* if we are starting a management session */
|
||||
if (cmdset == SCP_COMMAND_SET_MANAGE)
|
||||
{
|
||||
LOG(LOG_LEVEL_DEBUG, "[v1s:%d] requested management connection", __LINE__);
|
||||
/* should return SCP_SERVER_STATE_START_MANAGE */
|
||||
return scp_v1s_mng_accept(c, s);
|
||||
return scp_v1s_mng_accept(t, s);
|
||||
}
|
||||
|
||||
/* if we started with resource sharing... */
|
||||
@@ -284,258 +252,190 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION *c, struct SCP_SES
|
||||
}
|
||||
|
||||
/* reading command */
|
||||
in_uint16_be(c->in_s, cmd);
|
||||
in_uint16_be(in_s, cmd);
|
||||
|
||||
if (cmd != 1)
|
||||
switch (cmd)
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
|
||||
return SCP_SERVER_STATE_SEQUENCE_ERR;
|
||||
}
|
||||
case SCP_CMD_LOGIN:
|
||||
s->current_cmd = cmd;
|
||||
result = scp_v1s_init_session(t, s);
|
||||
break;
|
||||
|
||||
session = scp_session_create();
|
||||
case SCP_CMD_RESEND_CREDS:
|
||||
result = scp_v1s_accept_password_reply(t, s);
|
||||
s->current_cmd = SCP_CMD_LOGIN; /* Caller re-parses credentials */
|
||||
break;
|
||||
|
||||
if (NULL == session)
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING,
|
||||
"[v1s:%d] connection aborted: internal error "
|
||||
"(malloc returned NULL)", __LINE__);
|
||||
result = SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
default:
|
||||
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence "
|
||||
"error. Unrecognised cmd %d", __LINE__, cmd);
|
||||
result = SCP_SERVER_STATE_SEQUENCE_ERR;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = scp_v1s_init_session(c, session);
|
||||
if (result != SCP_SERVER_STATE_OK)
|
||||
{
|
||||
scp_session_destroy(session);
|
||||
session = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* returning the struct */
|
||||
(*s) = session;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_deny_connection(struct SCP_CONNECTION *c, const char *reason)
|
||||
scp_v1s_deny_connection(struct trans *t, const char *reason)
|
||||
{
|
||||
struct stream *out_s;
|
||||
int rlen;
|
||||
|
||||
init_stream(c->out_s, c->out_s->size);
|
||||
|
||||
/* forcing message not to exceed 64k */
|
||||
rlen = g_strlen(reason);
|
||||
|
||||
if (rlen > 65535)
|
||||
{
|
||||
rlen = 65535;
|
||||
}
|
||||
|
||||
out_uint32_be(c->out_s, 1);
|
||||
/* packet size: 4 + 4 + 2 + 2 + 2 + strlen(reason)*/
|
||||
out_s = trans_get_out_s(t, rlen + 14);
|
||||
out_uint32_be(out_s, 1); /* version */
|
||||
/* packet size: 4 + 4 + 2 + 2 + 2 + strlen(reason) */
|
||||
/* version + size + cmdset + cmd + msglen + msg */
|
||||
out_uint32_be(c->out_s, rlen + 14);
|
||||
out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT);
|
||||
out_uint16_be(c->out_s, 2);
|
||||
out_uint16_be(c->out_s, rlen);
|
||||
out_uint8p(c->out_s, reason, rlen);
|
||||
|
||||
if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, rlen + 14))
|
||||
out_uint32_be(out_s, rlen + 14);
|
||||
out_uint16_be(out_s, SCP_COMMAND_SET_DEFAULT);
|
||||
out_uint16_be(out_s, SCP_REPLY_LOGIN_DENIED);
|
||||
out_uint16_be(out_s, rlen);
|
||||
out_uint8p(out_s, reason, rlen);
|
||||
s_mark_end(out_s);
|
||||
if (0 != trans_force_write(t))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
|
||||
return SCP_SERVER_STATE_NETWORK_ERR;
|
||||
}
|
||||
|
||||
return SCP_SERVER_STATE_END;
|
||||
}
|
||||
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_request_password(struct SCP_CONNECTION *c, struct SCP_SESSION *s,
|
||||
scp_v1s_request_password(struct trans *t, struct SCP_SESSION *s,
|
||||
const char *reason)
|
||||
{
|
||||
tui32 version;
|
||||
int size;
|
||||
tui16 cmdset;
|
||||
tui16 cmd;
|
||||
struct stream *out_s;
|
||||
int rlen;
|
||||
char buf[256];
|
||||
|
||||
init_stream(c->in_s, c->in_s->size);
|
||||
init_stream(c->out_s, c->out_s->size);
|
||||
|
||||
/* forcing message not to exceed 64k */
|
||||
rlen = g_strlen(reason);
|
||||
|
||||
if (rlen > 65535)
|
||||
{
|
||||
rlen = 65535;
|
||||
}
|
||||
|
||||
/* send password request */
|
||||
version = 1;
|
||||
cmd = 3;
|
||||
|
||||
out_uint32_be(c->out_s, version); /* version */
|
||||
out_uint32_be(c->out_s, 14 + rlen); /* size */
|
||||
out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */
|
||||
out_uint16_be(c->out_s, cmd); /* cmd */
|
||||
|
||||
out_uint16_be(c->out_s, rlen);
|
||||
out_uint8p(c->out_s, reason, rlen);
|
||||
|
||||
if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, 14 + rlen))
|
||||
out_s = trans_get_out_s(t, rlen + 14);
|
||||
out_uint32_be(out_s, 1); /* version */
|
||||
/* packet size: 4 + 4 + 2 + 2 + 2 + strlen(reason) */
|
||||
/* version + size + cmdset + cmd + msglen + msg */
|
||||
out_uint32_be(out_s, rlen + 14);
|
||||
out_uint16_be(out_s, SCP_COMMAND_SET_DEFAULT);
|
||||
out_uint16_be(out_s, SCP_REPLY_REREQUEST_CREDS);
|
||||
out_uint16_be(out_s, rlen);
|
||||
out_uint8p(out_s, reason, rlen);
|
||||
s_mark_end(out_s);
|
||||
if (0 != trans_force_write(t))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
|
||||
return SCP_SERVER_STATE_NETWORK_ERR;
|
||||
}
|
||||
|
||||
/* receive password & username */
|
||||
if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
|
||||
return SCP_SERVER_STATE_NETWORK_ERR;
|
||||
}
|
||||
return SCP_SERVER_STATE_OK;
|
||||
}
|
||||
|
||||
in_uint32_be(c->in_s, version);
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_accept_password_reply(struct trans *t, struct SCP_SESSION *s)
|
||||
{
|
||||
struct stream *in_s;
|
||||
char buf[257];
|
||||
|
||||
if (version != 1)
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__);
|
||||
return SCP_SERVER_STATE_VERSION_ERR;
|
||||
}
|
||||
|
||||
in_uint32_be(c->in_s, size);
|
||||
|
||||
/* Check the message is big enough for the header, the command set, and
|
||||
* the command (but not too big) */
|
||||
if (size < (8 + 2 + 2) || size > SCP_MAX_MESSAGE_SIZE)
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING,
|
||||
"[v1s:%d] connection aborted: size error",
|
||||
__LINE__);
|
||||
return SCP_SERVER_STATE_SIZE_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, "[v1s:%d] connection aborted: network error", __LINE__);
|
||||
return SCP_SERVER_STATE_NETWORK_ERR;
|
||||
}
|
||||
|
||||
c->in_s->end = c->in_s->data + (size - 8);
|
||||
|
||||
in_uint16_be(c->in_s, cmdset);
|
||||
|
||||
if (cmdset != SCP_COMMAND_SET_DEFAULT)
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
|
||||
return SCP_SERVER_STATE_SEQUENCE_ERR;
|
||||
}
|
||||
|
||||
in_uint16_be(c->in_s, cmd);
|
||||
|
||||
if (cmd != 4)
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
|
||||
return SCP_SERVER_STATE_SEQUENCE_ERR;
|
||||
}
|
||||
in_s = t->in_s;
|
||||
buf[256] = '\0';
|
||||
|
||||
/* reading username */
|
||||
if (!in_string8(c->in_s, buf, "username", __LINE__))
|
||||
if (!in_string8(in_s, buf, "username", __LINE__))
|
||||
{
|
||||
return SCP_SERVER_STATE_SIZE_ERR;
|
||||
}
|
||||
|
||||
if (0 != scp_session_set_username(s, buf))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
|
||||
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error",
|
||||
__LINE__);
|
||||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
|
||||
/* reading password */
|
||||
if (!in_string8(c->in_s, buf, "passwd", __LINE__))
|
||||
if (!in_string8(in_s, buf, "passwd", __LINE__))
|
||||
{
|
||||
return SCP_SERVER_STATE_SIZE_ERR;
|
||||
}
|
||||
|
||||
if (0 != scp_session_set_password(s, buf))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
|
||||
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error",
|
||||
__LINE__);
|
||||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
|
||||
return SCP_SERVER_STATE_OK;
|
||||
}
|
||||
|
||||
/* 020 */
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_request_pwd_change(struct SCP_CONNECTION *c, char *reason, char *npw)
|
||||
scp_v1s_request_pwd_change(struct trans *t, char *reason, char *npw)
|
||||
{
|
||||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
|
||||
/* 023 */
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_pwd_change_error(struct SCP_CONNECTION *c, char *error, int retry, char *npw)
|
||||
scp_v1s_pwd_change_error(struct trans *t, char *error, int retry, char *npw)
|
||||
{
|
||||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
|
||||
/* 030 */
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_connect_new_session(struct SCP_CONNECTION *c, SCP_DISPLAY d)
|
||||
scp_v1s_connect_new_session(struct trans *t, SCP_DISPLAY d)
|
||||
{
|
||||
/* send password request */
|
||||
tui32 version = 1;
|
||||
tui32 size = 14;
|
||||
tui16 cmd = 30;
|
||||
struct stream *out_s;
|
||||
|
||||
init_stream(c->out_s, c->out_s->size);
|
||||
|
||||
out_uint32_be(c->out_s, version); /* version */
|
||||
out_uint32_be(c->out_s, size); /* size */
|
||||
out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */
|
||||
out_uint16_be(c->out_s, cmd); /* cmd */
|
||||
|
||||
out_uint16_be(c->out_s, d); /* display */
|
||||
|
||||
if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, 14))
|
||||
out_s = trans_get_out_s(t, 14);
|
||||
out_uint32_be(out_s, 1); /* version */
|
||||
/* packet size: 4 + 4 + 2 + 2 + 2 */
|
||||
/* version + size + cmdset + cmd + msglen + msg */
|
||||
out_uint32_be(out_s, 14);
|
||||
out_uint16_be(out_s, SCP_COMMAND_SET_DEFAULT);
|
||||
out_uint16_be(out_s, SCP_REPLY_NEW_SESSION);
|
||||
out_uint16_be(out_s, d);
|
||||
s_mark_end(out_s);
|
||||
if (0 != trans_force_write(t))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
|
||||
return SCP_SERVER_STATE_NETWORK_ERR;
|
||||
}
|
||||
|
||||
return SCP_SERVER_STATE_OK;
|
||||
}
|
||||
|
||||
/* 032 */
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_connection_error(struct SCP_CONNECTION *c, const char *error)
|
||||
scp_v1s_connection_error(struct trans *t, const char *error)
|
||||
{
|
||||
struct stream *out_s;
|
||||
tui16 len;
|
||||
|
||||
len = g_strlen(error);
|
||||
init_stream(c->out_s, c->out_s->size);
|
||||
|
||||
out_uint32_be(c->out_s, 1);
|
||||
if (len > 8192 - 12)
|
||||
{
|
||||
len = 8192 - 12;
|
||||
}
|
||||
out_s = trans_get_out_s(t, 12 + len);
|
||||
out_uint32_be(out_s, 1); /* version */
|
||||
/* packet size: 4 + 4 + 2 + 2 + len */
|
||||
/* version + size + cmdset + cmd */
|
||||
out_uint32_be(c->out_s, (12 + len));
|
||||
out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT);
|
||||
out_uint16_be(c->out_s, SCP_CMD_CONN_ERROR);
|
||||
|
||||
if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, (12 + len)))
|
||||
out_uint32_be(out_s, 12 + len);
|
||||
out_uint16_be(out_s, SCP_COMMAND_SET_DEFAULT);
|
||||
out_uint16_be(out_s, SCP_REPLY_CMD_CONN_ERROR);
|
||||
out_uint8a(out_s, error, len);
|
||||
s_mark_end(out_s);
|
||||
if (0 != trans_force_write(t))
|
||||
{
|
||||
return SCP_SERVER_STATE_NETWORK_ERR;
|
||||
}
|
||||
|
||||
return SCP_SERVER_STATE_END;
|
||||
}
|
||||
|
||||
/* 040 */
|
||||
#if 0
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_list_sessions(struct SCP_CONNECTION *c, int sescnt, struct SCP_DISCONNECTED_SESSION *ds, SCP_SID *sid)
|
||||
{
|
||||
@@ -802,26 +702,175 @@ scp_v1s_list_sessions(struct SCP_CONNECTION *c, int sescnt, struct SCP_DISCONNEC
|
||||
|
||||
return SCP_SERVER_STATE_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 046 was: 031 struct SCP_DISCONNECTED_SESSION* ds, */
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_reconnect_session(struct SCP_CONNECTION *c, SCP_DISPLAY d)
|
||||
scp_v1s_list_sessions40(struct trans *t)
|
||||
{
|
||||
tui32 version = 1;
|
||||
tui32 size = 14;
|
||||
tui16 cmd = 46;
|
||||
struct stream *out_s;
|
||||
|
||||
out_s = trans_get_out_s(t, 12);
|
||||
/* send a notice that we have some disconnected sessions */
|
||||
out_uint32_be(out_s, 1); /* version */
|
||||
out_uint32_be(out_s, 12); /* size */
|
||||
out_uint16_be(out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */
|
||||
out_uint16_be(out_s, SCP_REPLY_USER_SESSIONS_EXIST);/* cmd */
|
||||
s_mark_end(out_s);
|
||||
if (0 != trans_force_write(t))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
|
||||
return SCP_SERVER_STATE_NETWORK_ERR;
|
||||
}
|
||||
return SCP_SERVER_STATE_OK;
|
||||
}
|
||||
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_list_sessions42(struct trans *t, int sescnt, struct SCP_DISCONNECTED_SESSION *ds)
|
||||
{
|
||||
int pktcnt;
|
||||
int idx;
|
||||
int sidx;
|
||||
int pidx;
|
||||
int size;
|
||||
struct stream *out_s;
|
||||
struct SCP_DISCONNECTED_SESSION *cds;
|
||||
|
||||
/* calculating the number of packets to send */
|
||||
pktcnt = sescnt / SCP_SERVER_MAX_LIST_SIZE;
|
||||
if ((sescnt % SCP_SERVER_MAX_LIST_SIZE) != 0)
|
||||
{
|
||||
pktcnt++;
|
||||
}
|
||||
|
||||
for (idx = 0; idx < pktcnt; idx++)
|
||||
{
|
||||
out_s = trans_get_out_s(t, 8192);
|
||||
|
||||
/* size: ver+size+cmdset+cmd+sescnt+continue+count */
|
||||
size = 4 + 4 + 2 + 2 + 4 + 1 + 1;
|
||||
|
||||
/* header */
|
||||
s_push_layer(out_s, channel_hdr, 8);
|
||||
out_uint16_be(out_s, SCP_COMMAND_SET_DEFAULT);
|
||||
out_uint16_be(out_s, SCP_REPLY_SESSIONS_INFO);
|
||||
|
||||
/* session count */
|
||||
out_uint32_be(out_s, sescnt);
|
||||
|
||||
/* setting the continue flag */
|
||||
if ((idx + 1) * SCP_SERVER_MAX_LIST_SIZE >= sescnt)
|
||||
{
|
||||
out_uint8(out_s, 0);
|
||||
/* setting session count for this packet */
|
||||
pidx = sescnt - (idx * SCP_SERVER_MAX_LIST_SIZE);
|
||||
out_uint8(out_s, pidx);
|
||||
}
|
||||
else
|
||||
{
|
||||
out_uint8(out_s, 1);
|
||||
/* setting session count for this packet */
|
||||
pidx = SCP_SERVER_MAX_LIST_SIZE;
|
||||
out_uint8(out_s, pidx);
|
||||
}
|
||||
|
||||
/* adding session descriptors */
|
||||
for (sidx = 0; sidx < pidx; sidx++)
|
||||
{
|
||||
/* shortcut to the current session to send */
|
||||
cds = ds + (idx * SCP_SERVER_MAX_LIST_SIZE) + sidx;
|
||||
|
||||
/* session data */
|
||||
out_uint32_be(out_s, cds->SID); /* session id */
|
||||
out_uint8(out_s, cds->type);
|
||||
out_uint16_be(out_s, cds->height);
|
||||
out_uint16_be(out_s, cds->width);
|
||||
out_uint8(out_s, cds->bpp);
|
||||
out_uint8(out_s, cds->idle_days);
|
||||
out_uint8(out_s, cds->idle_hours);
|
||||
out_uint8(out_s, cds->idle_minutes);
|
||||
size += 13;
|
||||
|
||||
out_uint16_be(out_s, cds->conn_year);
|
||||
out_uint8(out_s, cds->conn_month);
|
||||
out_uint8(out_s, cds->conn_day);
|
||||
out_uint8(out_s, cds->conn_hour);
|
||||
out_uint8(out_s, cds->conn_minute);
|
||||
out_uint8(out_s, cds->addr_type);
|
||||
size += 7;
|
||||
|
||||
if (cds->addr_type == SCP_ADDRESS_TYPE_IPV4)
|
||||
{
|
||||
in_uint32_be(out_s, cds->ipv4addr);
|
||||
size += 4;
|
||||
}
|
||||
else if (cds->addr_type == SCP_ADDRESS_TYPE_IPV6)
|
||||
{
|
||||
in_uint8a(out_s, cds->ipv6addr, 16);
|
||||
size += 16;
|
||||
}
|
||||
}
|
||||
s_mark_end(out_s);
|
||||
s_pop_layer(out_s, channel_hdr);
|
||||
out_uint32_be(out_s, 1); /* version */
|
||||
out_uint32_be(out_s, size);
|
||||
|
||||
if (0 != trans_force_write(t))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
|
||||
return SCP_SERVER_STATE_NETWORK_ERR;
|
||||
}
|
||||
}
|
||||
return SCP_SERVER_STATE_OK;
|
||||
}
|
||||
|
||||
// TODO
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_accept_list_sessions_reply(int cmd, struct trans *t)
|
||||
{
|
||||
struct SCP_SESSION *s;
|
||||
struct stream *in_s;
|
||||
|
||||
s = (struct SCP_SESSION *) (t->callback_data);
|
||||
if (s == NULL)
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
|
||||
return SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
s->current_cmd = cmd;
|
||||
in_s = t->in_s;
|
||||
switch (cmd)
|
||||
{
|
||||
case SCP_CMD_GET_SESSION_LIST:
|
||||
break;
|
||||
case SCP_CMD_SELECT_SESSION:
|
||||
in_uint32_be(in_s, s->return_sid);
|
||||
break;
|
||||
case SCP_CMD_SELECT_SESSION_CANCEL:
|
||||
break;
|
||||
case SCP_CMD_FORCE_NEW_CONN:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return SCP_SERVER_STATE_OK;
|
||||
}
|
||||
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_reconnect_session(struct trans *t, SCP_DISPLAY d)
|
||||
{
|
||||
struct stream *out_s;
|
||||
|
||||
/* ok, we send session data and display */
|
||||
init_stream(c->out_s, c->out_s->size);
|
||||
|
||||
out_s = trans_get_out_s(t, 14);
|
||||
/* header */
|
||||
out_uint32_be(c->out_s, version);
|
||||
out_uint32_be(c->out_s, size);
|
||||
out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT);
|
||||
out_uint16_be(c->out_s, cmd);
|
||||
|
||||
out_uint32_be(out_s, 1); /* version */
|
||||
out_uint32_be(out_s, 14); /* size */
|
||||
out_uint16_be(out_s, SCP_COMMAND_SET_DEFAULT);
|
||||
out_uint16_be(out_s, SCP_REPLY_SESSION_RECONNECTED); /* cmd */
|
||||
/* session data */
|
||||
out_uint16_be(c->out_s, d); /* session display */
|
||||
out_uint16_be(out_s, d); /* session display */
|
||||
s_mark_end(out_s);
|
||||
|
||||
/*out_uint8(c->out_s, ds->type);
|
||||
out_uint16_be(c->out_s, ds->height);
|
||||
out_uint16_be(c->out_s, ds->width);
|
||||
@@ -831,7 +880,7 @@ scp_v1s_reconnect_session(struct SCP_CONNECTION *c, SCP_DISPLAY d)
|
||||
out_uint8(c->out_s, ds->idle_minutes);*/
|
||||
/* these last three are not really needed... */
|
||||
|
||||
if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size))
|
||||
if (0 != trans_force_write(t))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
|
||||
return SCP_SERVER_STATE_NETWORK_ERR;
|
||||
|
||||
+23
-11
@@ -33,16 +33,14 @@
|
||||
/**
|
||||
*
|
||||
* @brief processes the stream using scp version 1
|
||||
* @param c connection descriptor
|
||||
* @param trans connection trans
|
||||
* @param s pointer to session descriptor pointer
|
||||
* @param skipVchk if set to !0 skips the version control (to be used after
|
||||
* scp_vXs_accept() )
|
||||
*
|
||||
* 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(struct SCP_CONNECTION *c, struct SCP_SESSION **s, int skipVchk);
|
||||
scp_v1s_accept(struct trans *t, struct SCP_SESSION *s);
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -53,35 +51,49 @@ scp_v1s_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s, int skipVchk);
|
||||
*/
|
||||
/* 002 */
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_deny_connection(struct SCP_CONNECTION *c, const char *reason);
|
||||
scp_v1s_deny_connection(struct trans *t, const char *reason);
|
||||
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_request_password(struct SCP_CONNECTION *c, struct SCP_SESSION *s,
|
||||
scp_v1s_request_password(struct trans *t, struct SCP_SESSION *s,
|
||||
const char *reason);
|
||||
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_accept_password_reply(struct trans *t, struct SCP_SESSION *s);
|
||||
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_accept_list_sessions_reply(int cmd, struct trans *t);
|
||||
|
||||
/* 020 */
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_request_pwd_change(struct SCP_CONNECTION *c, char *reason, char *npw);
|
||||
scp_v1s_request_pwd_change(struct trans *t, char *reason, char *npw);
|
||||
|
||||
/* 023 */
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_pwd_change_error(struct SCP_CONNECTION *c, char *error, int retry, char *npw);
|
||||
scp_v1s_pwd_change_error(struct trans *t, char *error, int retry, char *npw);
|
||||
|
||||
/* 030 */
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_connect_new_session(struct SCP_CONNECTION *c, SCP_DISPLAY d);
|
||||
scp_v1s_connect_new_session(struct trans *t, SCP_DISPLAY d);
|
||||
|
||||
/* 032 */
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_connection_error(struct SCP_CONNECTION *c, const char *error);
|
||||
scp_v1s_connection_error(struct trans *t, const char *error);
|
||||
|
||||
/* 040 */
|
||||
#if 0
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_list_sessions(struct SCP_CONNECTION *c, int sescnt,
|
||||
struct SCP_DISCONNECTED_SESSION *ds, SCP_SID *sid);
|
||||
#endif
|
||||
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_list_sessions40(struct trans *t);
|
||||
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_list_sessions42(struct trans *t, int sescnt, struct SCP_DISCONNECTED_SESSION *ds);
|
||||
|
||||
/* 046 was: 031 struct SCP_DISCONNECTED_SESSION* ds, */
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_reconnect_session(struct SCP_CONNECTION *c, SCP_DISPLAY d);
|
||||
scp_v1s_reconnect_session(struct trans *t, SCP_DISPLAY d);
|
||||
|
||||
#endif
|
||||
|
||||
+85
-102
@@ -37,7 +37,7 @@
|
||||
//extern struct log_config* s_log;
|
||||
|
||||
static enum SCP_SERVER_STATES_E
|
||||
_scp_v1s_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s);
|
||||
_scp_v1s_mng_check_response(struct trans *t, struct SCP_SESSION *s);
|
||||
|
||||
/**
|
||||
* Reads a uint8 followed by a string into a buffer
|
||||
@@ -86,6 +86,7 @@ int in_string8(struct stream *s, char str[], const char *param, int line)
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialises a V1 management session object
|
||||
*
|
||||
@@ -96,23 +97,25 @@ int in_string8(struct stream *s, char str[], const char *param, int line)
|
||||
* @param [out] session pre-allocated session object
|
||||
* @return SCP_SERVER_STATE_START_MANAGE for success
|
||||
*/
|
||||
static enum SCP_SERVER_STATES_E
|
||||
scp_v1s_mng_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session)
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_mng_accept(struct trans *atrans, struct SCP_SESSION *session)
|
||||
{
|
||||
tui32 ipaddr;
|
||||
tui16 cmd;
|
||||
tui8 sz;
|
||||
char buf[256];
|
||||
struct stream *in_s = atrans->in_s;
|
||||
|
||||
scp_session_set_version(session, 1);
|
||||
scp_session_set_type(session, SCP_SESSION_TYPE_MANAGE);
|
||||
|
||||
/* reading command */
|
||||
if (!s_check_rem(c->in_s, 2))
|
||||
if (!s_check_rem(in_s, 2))
|
||||
{
|
||||
/* Caller should have checked this */
|
||||
return SCP_SERVER_STATE_SIZE_ERR;
|
||||
}
|
||||
in_uint16_be(c->in_s, cmd);
|
||||
in_uint16_be(in_s, cmd);
|
||||
|
||||
if (cmd != 1) /* manager login */
|
||||
{
|
||||
@@ -120,7 +123,7 @@ scp_v1s_mng_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session)
|
||||
}
|
||||
|
||||
/* reading username */
|
||||
if (!in_string8(c->in_s, buf, "username", __LINE__))
|
||||
if (!in_string8(in_s, buf, "username", __LINE__))
|
||||
{
|
||||
return SCP_SERVER_STATE_SIZE_ERR;
|
||||
}
|
||||
@@ -131,7 +134,7 @@ scp_v1s_mng_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session)
|
||||
}
|
||||
|
||||
/* reading password */
|
||||
if (!in_string8(c->in_s, buf, "passwd", __LINE__))
|
||||
if (!in_string8(in_s, buf, "passwd", __LINE__))
|
||||
{
|
||||
return SCP_SERVER_STATE_SIZE_ERR;
|
||||
}
|
||||
@@ -143,7 +146,7 @@ scp_v1s_mng_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session)
|
||||
|
||||
/* reading remote address
|
||||
* Check there's enough data left for at least an IPv4 address (+len) */
|
||||
if (!s_check_rem(c->in_s, 1 + 4))
|
||||
if (!s_check_rem(in_s, 1 + 4))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING,
|
||||
"[v1s_mng:%d] connection aborted: IP addr len missing",
|
||||
@@ -151,27 +154,27 @@ scp_v1s_mng_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session)
|
||||
return SCP_SERVER_STATE_SIZE_ERR;
|
||||
}
|
||||
|
||||
in_uint8(c->in_s, sz);
|
||||
in_uint8(in_s, sz);
|
||||
if (sz == SCP_ADDRESS_TYPE_IPV4)
|
||||
{
|
||||
in_uint32_be(c->in_s, ipaddr);
|
||||
in_uint32_be(in_s, ipaddr);
|
||||
scp_session_set_addr(session, sz, &ipaddr);
|
||||
}
|
||||
else if (sz == SCP_ADDRESS_TYPE_IPV6)
|
||||
{
|
||||
if (!s_check_rem(c->in_s, 16))
|
||||
if (!s_check_rem(in_s, 16))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING,
|
||||
"[v1s_mng:%d] connection aborted: IP addr missing",
|
||||
__LINE__);
|
||||
return SCP_SERVER_STATE_SIZE_ERR;
|
||||
}
|
||||
in_uint8a(c->in_s, buf, 16);
|
||||
in_uint8a(in_s, buf, 16);
|
||||
scp_session_set_addr(session, sz, buf);
|
||||
}
|
||||
|
||||
/* reading hostname */
|
||||
if (!in_string8(c->in_s, buf, "hostname", __LINE__))
|
||||
if (!in_string8(in_s, buf, "hostname", __LINE__))
|
||||
{
|
||||
return SCP_SERVER_STATE_SIZE_ERR;
|
||||
}
|
||||
@@ -184,81 +187,58 @@ scp_v1s_mng_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session)
|
||||
return SCP_SERVER_STATE_START_MANAGE;
|
||||
}
|
||||
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_mng_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s)
|
||||
{
|
||||
enum SCP_SERVER_STATES_E result;
|
||||
struct SCP_SESSION *session;
|
||||
|
||||
session = scp_session_create();
|
||||
if (NULL == session)
|
||||
{
|
||||
result = SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
}
|
||||
else
|
||||
{
|
||||
scp_session_set_type(session, SCP_SESSION_TYPE_MANAGE);
|
||||
|
||||
result = scp_v1s_mng_init_session(c, session);
|
||||
if (result != SCP_SERVER_STATE_START_MANAGE)
|
||||
{
|
||||
scp_session_destroy(session);
|
||||
session = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
(*s) = session;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* 002 */
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_mng_allow_connection(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
scp_v1s_mng_allow_connection(struct trans *t, struct SCP_SESSION *s)
|
||||
{
|
||||
init_stream(c->out_s, c->out_s->size);
|
||||
struct stream *out_s = t->out_s;
|
||||
init_stream(out_s, 64);
|
||||
|
||||
out_uint32_be(c->out_s, 1);
|
||||
out_uint32_be(out_s, 1);
|
||||
/* packet size: 4 + 4 + 2 + 2 */
|
||||
/* version + size + cmdset + cmd */
|
||||
out_uint32_be(c->out_s, 12);
|
||||
out_uint16_be(c->out_s, SCP_COMMAND_SET_MANAGE);
|
||||
out_uint16_be(c->out_s, SCP_CMD_MNG_LOGIN_ALLOW);
|
||||
out_uint32_be(out_s, 12);
|
||||
out_uint16_be(out_s, SCP_COMMAND_SET_MANAGE);
|
||||
out_uint16_be(out_s, SCP_CMD_MNG_LOGIN_ALLOW);
|
||||
s_mark_end(out_s);
|
||||
|
||||
if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, 12))
|
||||
if (0 != trans_force_write(t))
|
||||
{
|
||||
return SCP_SERVER_STATE_NETWORK_ERR;
|
||||
}
|
||||
|
||||
return _scp_v1s_mng_check_response(c, s);
|
||||
return _scp_v1s_mng_check_response(t, s);
|
||||
}
|
||||
|
||||
/* 003 */
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_mng_deny_connection(struct SCP_CONNECTION *c, const char *reason)
|
||||
scp_v1s_mng_deny_connection(struct trans *t, const char *reason)
|
||||
{
|
||||
int rlen;
|
||||
|
||||
init_stream(c->out_s, c->out_s->size);
|
||||
struct stream *out_s = t->out_s;
|
||||
|
||||
/* forcing message not to exceed 64k */
|
||||
rlen = g_strlen(reason);
|
||||
|
||||
if (rlen > 65535)
|
||||
if (rlen > 65535 - 64)
|
||||
{
|
||||
rlen = 65535;
|
||||
rlen = 65535 - 64;
|
||||
}
|
||||
|
||||
out_uint32_be(c->out_s, 1);
|
||||
init_stream(out_s, rlen + 64);
|
||||
|
||||
out_uint32_be(out_s, 1);
|
||||
/* packet size: 4 + 4 + 2 + 2 + 2 + strlen(reason)*/
|
||||
/* version + size + cmdset + cmd + msglen + msg */
|
||||
out_uint32_be(c->out_s, rlen + 14);
|
||||
out_uint16_be(c->out_s, SCP_COMMAND_SET_MANAGE);
|
||||
out_uint16_be(c->out_s, SCP_CMD_MNG_LOGIN_DENY);
|
||||
out_uint16_be(c->out_s, rlen);
|
||||
out_uint8p(c->out_s, reason, rlen);
|
||||
out_uint32_be(out_s, rlen + 14);
|
||||
out_uint16_be(out_s, SCP_COMMAND_SET_MANAGE);
|
||||
out_uint16_be(out_s, SCP_CMD_MNG_LOGIN_DENY);
|
||||
out_uint16_be(out_s, rlen);
|
||||
out_uint8p(out_s, reason, rlen);
|
||||
s_mark_end(out_s);
|
||||
|
||||
if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, rlen + 14))
|
||||
if (0 != trans_force_write(t))
|
||||
{
|
||||
return SCP_SERVER_STATE_NETWORK_ERR;
|
||||
}
|
||||
@@ -268,7 +248,7 @@ scp_v1s_mng_deny_connection(struct SCP_CONNECTION *c, const char *reason)
|
||||
|
||||
/* 006 */
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_mng_list_sessions(struct SCP_CONNECTION *c, struct SCP_SESSION *s,
|
||||
scp_v1s_mng_list_sessions(struct trans *t, struct SCP_SESSION *s,
|
||||
int sescnt, struct SCP_DISCONNECTED_SESSION *ds)
|
||||
{
|
||||
tui32 version = 1;
|
||||
@@ -280,6 +260,8 @@ scp_v1s_mng_list_sessions(struct SCP_CONNECTION *c, struct SCP_SESSION *s,
|
||||
int pidx;
|
||||
struct SCP_DISCONNECTED_SESSION *cds;
|
||||
|
||||
struct stream *out_s = t->out_s;
|
||||
|
||||
/* calculating the number of packets to send */
|
||||
if (sescnt == 0)
|
||||
{
|
||||
@@ -298,33 +280,33 @@ scp_v1s_mng_list_sessions(struct SCP_CONNECTION *c, struct SCP_SESSION *s,
|
||||
for (idx = 0; idx < pktcnt; idx++)
|
||||
{
|
||||
/* ok, we send session session list */
|
||||
init_stream(c->out_s, c->out_s->size);
|
||||
init_stream(out_s, 64 + (SCP_SERVER_MAX_LIST_SIZE * 40));
|
||||
|
||||
/* size: ver+size+cmdset+cmd+sescnt+continue+count */
|
||||
size = 4 + 4 + 2 + 2 + 4 + 1 + 1;
|
||||
|
||||
/* header */
|
||||
s_push_layer(c->out_s, channel_hdr, 8);
|
||||
out_uint16_be(c->out_s, SCP_COMMAND_SET_MANAGE);
|
||||
out_uint16_be(c->out_s, cmd);
|
||||
s_push_layer(out_s, channel_hdr, 8);
|
||||
out_uint16_be(out_s, SCP_COMMAND_SET_MANAGE);
|
||||
out_uint16_be(out_s, cmd);
|
||||
|
||||
/* session count */
|
||||
out_uint32_be(c->out_s, sescnt);
|
||||
out_uint32_be(out_s, sescnt);
|
||||
|
||||
/* setting the continue flag */
|
||||
if ((idx + 1)*SCP_SERVER_MAX_LIST_SIZE >= sescnt)
|
||||
{
|
||||
out_uint8(c->out_s, 0);
|
||||
out_uint8(out_s, 0);
|
||||
/* setting session count for this packet */
|
||||
pidx = sescnt - (idx * SCP_SERVER_MAX_LIST_SIZE);
|
||||
out_uint8(c->out_s, pidx);
|
||||
out_uint8(out_s, pidx);
|
||||
}
|
||||
else
|
||||
{
|
||||
out_uint8(c->out_s, 1);
|
||||
out_uint8(out_s, 1);
|
||||
/* setting session count for this packet */
|
||||
pidx = SCP_SERVER_MAX_LIST_SIZE;
|
||||
out_uint8(c->out_s, pidx);
|
||||
out_uint8(out_s, pidx);
|
||||
}
|
||||
|
||||
/* adding session descriptors */
|
||||
@@ -334,52 +316,53 @@ scp_v1s_mng_list_sessions(struct SCP_CONNECTION *c, struct SCP_SESSION *s,
|
||||
cds = ds + ((idx) * SCP_SERVER_MAX_LIST_SIZE) + sidx;
|
||||
|
||||
/* session data */
|
||||
out_uint32_be(c->out_s, cds->SID); /* session id */
|
||||
out_uint8(c->out_s, cds->type);
|
||||
out_uint16_be(c->out_s, cds->height);
|
||||
out_uint16_be(c->out_s, cds->width);
|
||||
out_uint8(c->out_s, cds->bpp);
|
||||
out_uint8(c->out_s, cds->idle_days);
|
||||
out_uint8(c->out_s, cds->idle_hours);
|
||||
out_uint8(c->out_s, cds->idle_minutes);
|
||||
out_uint32_be(out_s, cds->SID); /* session id */
|
||||
out_uint8(out_s, cds->type);
|
||||
out_uint16_be(out_s, cds->height);
|
||||
out_uint16_be(out_s, cds->width);
|
||||
out_uint8(out_s, cds->bpp);
|
||||
out_uint8(out_s, cds->idle_days);
|
||||
out_uint8(out_s, cds->idle_hours);
|
||||
out_uint8(out_s, cds->idle_minutes);
|
||||
size += 13;
|
||||
|
||||
out_uint16_be(c->out_s, cds->conn_year);
|
||||
out_uint8(c->out_s, cds->conn_month);
|
||||
out_uint8(c->out_s, cds->conn_day);
|
||||
out_uint8(c->out_s, cds->conn_hour);
|
||||
out_uint8(c->out_s, cds->conn_minute);
|
||||
out_uint8(c->out_s, cds->addr_type);
|
||||
out_uint16_be(out_s, cds->conn_year);
|
||||
out_uint8(out_s, cds->conn_month);
|
||||
out_uint8(out_s, cds->conn_day);
|
||||
out_uint8(out_s, cds->conn_hour);
|
||||
out_uint8(out_s, cds->conn_minute);
|
||||
out_uint8(out_s, cds->addr_type);
|
||||
size += 7;
|
||||
|
||||
if (cds->addr_type == SCP_ADDRESS_TYPE_IPV4)
|
||||
{
|
||||
in_uint32_be(c->out_s, cds->ipv4addr);
|
||||
out_uint32_be(out_s, cds->ipv4addr);
|
||||
size += 4;
|
||||
}
|
||||
else if (cds->addr_type == SCP_ADDRESS_TYPE_IPV6)
|
||||
{
|
||||
in_uint8a(c->out_s, cds->ipv6addr, 16);
|
||||
out_uint8a(out_s, cds->ipv6addr, 16);
|
||||
size += 16;
|
||||
}
|
||||
}
|
||||
|
||||
s_pop_layer(c->out_s, channel_hdr);
|
||||
out_uint32_be(c->out_s, version);
|
||||
out_uint32_be(c->out_s, size);
|
||||
s_mark_end(out_s);
|
||||
s_pop_layer(out_s, channel_hdr);
|
||||
out_uint32_be(out_s, version);
|
||||
out_uint32_be(out_s, size);
|
||||
|
||||
if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size))
|
||||
if (0 != trans_force_write(t))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__);
|
||||
return SCP_SERVER_STATE_NETWORK_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
return _scp_v1s_mng_check_response(c, s);
|
||||
return _scp_v1s_mng_check_response(t, s);
|
||||
}
|
||||
|
||||
static enum SCP_SERVER_STATES_E
|
||||
_scp_v1s_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
_scp_v1s_mng_check_response(struct trans *t, struct SCP_SESSION *s)
|
||||
{
|
||||
tui32 version;
|
||||
int size;
|
||||
@@ -387,15 +370,17 @@ _scp_v1s_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
// tui8 dim;
|
||||
// char buf[257];
|
||||
|
||||
init_stream(c->in_s, c->in_s->size);
|
||||
struct stream *in_s = t->in_s;
|
||||
|
||||
if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
|
||||
init_stream(in_s, 64);
|
||||
|
||||
if (0 != trans_force_read(t, 8))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__);
|
||||
return SCP_SERVER_STATE_NETWORK_ERR;
|
||||
}
|
||||
|
||||
in_uint32_be(c->in_s, version);
|
||||
in_uint32_be(in_s, version);
|
||||
|
||||
if (version != 1)
|
||||
{
|
||||
@@ -403,7 +388,7 @@ _scp_v1s_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
return SCP_SERVER_STATE_VERSION_ERR;
|
||||
}
|
||||
|
||||
in_uint32_be(c->in_s, size);
|
||||
in_uint32_be(in_s, size);
|
||||
|
||||
/* Check the message is big enough for the header, the command set, and
|
||||
* the command (but not too big) */
|
||||
@@ -413,18 +398,16 @@ _scp_v1s_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
return SCP_SERVER_STATE_SIZE_ERR;
|
||||
}
|
||||
|
||||
init_stream(c->in_s, size - 8);
|
||||
init_stream(in_s, size - 8);
|
||||
|
||||
/* read the rest of the packet */
|
||||
if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8))
|
||||
if (0 != trans_force_read(t, size - 8))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__);
|
||||
return SCP_SERVER_STATE_NETWORK_ERR;
|
||||
}
|
||||
|
||||
c->in_s->end = c->in_s->data + (size - 8);
|
||||
|
||||
in_uint16_be(c->in_s, cmd);
|
||||
in_uint16_be(in_s, cmd);
|
||||
|
||||
if (cmd != SCP_COMMAND_SET_MANAGE)
|
||||
{
|
||||
@@ -432,7 +415,7 @@ _scp_v1s_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
return SCP_SERVER_STATE_SEQUENCE_ERR;
|
||||
}
|
||||
|
||||
in_uint16_be(c->in_s, cmd);
|
||||
in_uint16_be(in_s, cmd);
|
||||
|
||||
if (cmd == SCP_CMD_MNG_LIST_REQ) /* request session list */
|
||||
{
|
||||
|
||||
@@ -33,14 +33,11 @@
|
||||
/**
|
||||
*
|
||||
* @brief processes the stream using scp version 1
|
||||
* @param c 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
|
||||
* @param atrans connection descriptor
|
||||
* @param s session descriptor pointer
|
||||
*/
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_mng_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s);
|
||||
scp_v1s_mng_accept(struct trans *atrans, struct SCP_SESSION *s);
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -50,7 +47,7 @@ scp_v1s_mng_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s);
|
||||
*/
|
||||
/* 002 */
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_mng_allow_connection(struct SCP_CONNECTION *c, struct SCP_SESSION *s);
|
||||
scp_v1s_mng_allow_connection(struct trans *atrans, struct SCP_SESSION *s);
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -61,7 +58,7 @@ scp_v1s_mng_allow_connection(struct SCP_CONNECTION *c, struct SCP_SESSION *s);
|
||||
*/
|
||||
/* 003 */
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_mng_deny_connection(struct SCP_CONNECTION *c, const char *reason);
|
||||
scp_v1s_mng_deny_connection(struct trans *atrans, const char *reason);
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -71,7 +68,7 @@ scp_v1s_mng_deny_connection(struct SCP_CONNECTION *c, const char *reason);
|
||||
*/
|
||||
/* 006 */
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1s_mng_list_sessions(struct SCP_CONNECTION *c, struct SCP_SESSION *s,
|
||||
scp_v1s_mng_list_sessions(struct trans *atrans, struct SCP_SESSION *s,
|
||||
int sescnt, struct SCP_DISCONNECTED_SESSION *ds);
|
||||
// SCP_SID* sid);
|
||||
|
||||
|
||||
+11
-13
@@ -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(atrans, s);
|
||||
}
|
||||
|
||||
return SCP_SERVER_STATE_VERSION_ERR;
|
||||
}
|
||||
|
||||
@@ -36,12 +36,11 @@
|
||||
/**
|
||||
*
|
||||
* @brief version neutral server accept function
|
||||
* @param c connection descriptor
|
||||
* @param s session descriptor pointer address.
|
||||
* it will return a newly allocated descriptor.
|
||||
* It this memory needs to be g_free()d
|
||||
* @param atrans connection trans
|
||||
* @param s session descriptor
|
||||
*
|
||||
*/
|
||||
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
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
************************************************************
|
||||
** Notes on the current version of the SCP protocol used **
|
||||
** to communicate with sesman **
|
||||
** **
|
||||
** This information is for internal documentational use **
|
||||
** only. It may be incomplete. The SCP protocol is **
|
||||
** internal, and may change for even minor releases. **
|
||||
************************************************************
|
||||
|
||||
|
||||
message header
|
||||
version 4 - version, 0 or 1
|
||||
size 4 - size of PDU including header
|
||||
cmdset 2 - 0
|
||||
|
||||
version 0
|
||||
cmdset 2 bytes
|
||||
0 - Xvnc client to server
|
||||
3 - response to 0, 10, or 20 server to client
|
||||
4 - SCP_GW_AUTHENTICATION client to server
|
||||
10 - X11rdp client to server
|
||||
20 - Xorg client to server
|
||||
|
||||
version 1
|
||||
cmdset 2 bytes
|
||||
0 - SCP_COMMAND_SET_DEFAULT
|
||||
1 - SCP_COMMAND_SET_MANAGE
|
||||
2 - SCP_COMMAND_SET_RSR
|
||||
|
||||
SCP_COMMAND_SET_DEFAULT
|
||||
cmd 2 bytes
|
||||
1 - main client to server
|
||||
3 - password request server to client
|
||||
4 - password reply client to server
|
||||
30 - connect new session
|
||||
40 - list all sessions server to client
|
||||
41 - list all sessions response client to server
|
||||
42 - list all sessions server to client
|
||||
43 - list all sessions response client to server
|
||||
44 - list all sessions response client to server
|
||||
45 - client to server
|
||||
46 - reconnect session
|
||||
0xFFFF - SCP_CMD_CONN_ERROR
|
||||
|
||||
SCP_COMMAND_SET_MANAGE
|
||||
cmd 2 bytes
|
||||
1 - manager login
|
||||
2 - SCP_CMD_MNG_LOGIN_ALLOW
|
||||
|
||||
v0
|
||||
scp_process scp.c
|
||||
scp_vXs_accept libscp_vX.c
|
||||
scp_v0s_accept libscp_v0.c
|
||||
scp_v0_process scp_v0.c
|
||||
session_start session.c
|
||||
|
||||
v1
|
||||
scp_process scp.c
|
||||
scp_vXs_accept libscp_vX.c
|
||||
scp_v1s_accept libscp_v1s.c
|
||||
scp_v1s_mng_accept libscp_v1s_mng.c
|
||||
scp_v1_process scp_v1.c
|
||||
scp_v1s_request_password libscp_v1s.c
|
||||
or
|
||||
scp_v1_mng_process scp_v1_mng.c
|
||||
|
||||
+11
-31
@@ -36,44 +36,30 @@
|
||||
extern struct config_sesman *g_cfg; /* in sesman.c */
|
||||
|
||||
/******************************************************************************/
|
||||
void *
|
||||
scp_process_start(void *sck)
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_process(struct trans *t, struct SCP_SESSION *sdata)
|
||||
{
|
||||
struct SCP_CONNECTION scon;
|
||||
struct SCP_SESSION *sdata = NULL;
|
||||
|
||||
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)))
|
||||
enum SCP_SERVER_STATES_E result = scp_vXs_accept(t, sdata);
|
||||
switch (result)
|
||||
{
|
||||
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);
|
||||
result = scp_v0_process(t, 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);
|
||||
result = scp_v1_process(t, 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);
|
||||
result = scp_v1_mng_process_msg(t, sdata);
|
||||
break;
|
||||
case SCP_SERVER_STATE_VERSION_ERR:
|
||||
case SCP_SERVER_STATE_SIZE_ERR:
|
||||
@@ -95,16 +81,10 @@ scp_process_start(void *sck)
|
||||
break;
|
||||
default:
|
||||
LOG(LOG_LEVEL_ALWAYS, "unknown return from scp_vXs_accept()");
|
||||
result = SCP_SERVER_STATE_INTERNAL_ERR;
|
||||
break;
|
||||
}
|
||||
|
||||
free_stream(scon.in_s);
|
||||
free_stream(scon.out_s);
|
||||
|
||||
if (sdata)
|
||||
{
|
||||
scp_session_destroy(sdata);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -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);
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_process(struct trans *t, struct SCP_SESSION *s);
|
||||
|
||||
#endif
|
||||
|
||||
+13
-12
@@ -33,8 +33,8 @@
|
||||
extern struct config_sesman *g_cfg; /* in sesman.c */
|
||||
|
||||
/******************************************************************************/
|
||||
void
|
||||
scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v0_process(struct trans *t, 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(t, 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(t, 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(t, 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,21 +148,22 @@ scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
|
||||
if (display == 0)
|
||||
{
|
||||
scp_v0s_deny_connection(c);
|
||||
scp_v0s_deny_connection(t);
|
||||
}
|
||||
else
|
||||
{
|
||||
scp_v0s_allow_connection(c, display, s->guid);
|
||||
scp_v0s_allow_connection(t, 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(t);
|
||||
}
|
||||
if (do_auth_end)
|
||||
{
|
||||
auth_end(data);
|
||||
}
|
||||
return SCP_SERVER_STATE_END;
|
||||
}
|
||||
|
||||
+2
-10
@@ -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);
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v0_process(struct trans *t, struct SCP_SESSION *s);
|
||||
|
||||
#endif
|
||||
|
||||
+163
-108
@@ -35,79 +35,72 @@
|
||||
|
||||
extern struct config_sesman *g_cfg; /* in sesman.c */
|
||||
|
||||
static void parseCommonStates(enum SCP_SERVER_STATES_E e, const char *f);
|
||||
static void
|
||||
parseCommonStates(enum SCP_SERVER_STATES_E e, const char *f);
|
||||
|
||||
/******************************************************************************/
|
||||
void
|
||||
scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
static enum SCP_SERVER_STATES_E
|
||||
scp_v1_process1(struct trans *t, struct SCP_SESSION *s)
|
||||
{
|
||||
long data;
|
||||
int display = 0;
|
||||
int retries;
|
||||
int current_try;
|
||||
int scount;
|
||||
long data;
|
||||
enum SCP_SERVER_STATES_E e;
|
||||
struct SCP_DISCONNECTED_SESSION *slist;
|
||||
struct session_item *sitem;
|
||||
int scount;
|
||||
SCP_SID sid;
|
||||
bool_t do_auth_end = 1;
|
||||
|
||||
retries = g_cfg->sec.login_retry;
|
||||
current_try = retries;
|
||||
|
||||
data = auth_userpass(s->username, s->password, NULL);
|
||||
/*LOG_DEVEL(LOG_LEVEL_DEBUG, "user: %s\npass: %s", s->username, s->password);*/
|
||||
|
||||
while ((!data) && ((retries == 0) || (current_try > 0)))
|
||||
if (s->retries == 0)
|
||||
{
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "data %ld - retry %d - currenttry %d - expr %d",
|
||||
data, retries, current_try,
|
||||
((!data) && ((retries == 0) || (current_try > 0))));
|
||||
|
||||
e = scp_v1s_request_password(c, s, "Wrong username and/or password");
|
||||
|
||||
switch (e)
|
||||
{
|
||||
case SCP_SERVER_STATE_OK:
|
||||
/* all ok, we got new username and password */
|
||||
data = auth_userpass(s->username, s->password, NULL);
|
||||
|
||||
/* one try less */
|
||||
if (current_try > 0)
|
||||
{
|
||||
current_try--;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
/* we check the other errors */
|
||||
parseCommonStates(e, "scp_v1s_list_sessions()");
|
||||
return;
|
||||
//break;
|
||||
}
|
||||
/* First time in */
|
||||
s->retries = g_cfg->sec.login_retry;
|
||||
s->current_try = s->retries;
|
||||
}
|
||||
|
||||
if (!data)
|
||||
data = auth_userpass(s->username, s->password, NULL);
|
||||
if (data == 0)
|
||||
{
|
||||
scp_v1s_deny_connection(c, "Login failed");
|
||||
LOG( LOG_LEVEL_INFO,
|
||||
"Login failed for user %s. Connection terminated", s->username);
|
||||
return;
|
||||
if ((s->retries == 0) || (s->current_try > 0))
|
||||
{
|
||||
e = scp_v1s_request_password(t, s, "Wrong username and/or "
|
||||
"password");
|
||||
switch (e)
|
||||
{
|
||||
case SCP_SERVER_STATE_OK:
|
||||
/* one try less */
|
||||
if (s->current_try > 0)
|
||||
{
|
||||
s->current_try--;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* we check the other errors */
|
||||
parseCommonStates(e, "scp_v1s_list_sessions()");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/* testing if login is allowed*/
|
||||
if (0 == access_login_allowed(s->username))
|
||||
{
|
||||
scp_v1s_deny_connection(c, "Access to Terminal Server not allowed.");
|
||||
LOG(LOG_LEVEL_INFO,
|
||||
"User %s not allowed on TS. Connection terminated", s->username);
|
||||
return;
|
||||
scp_v1s_deny_connection(t, "Access to Terminal Server not allowed.");
|
||||
LOG(LOG_LEVEL_INFO, "User %s not allowed on TS. "
|
||||
"Connection terminated", s->username);
|
||||
return SCP_SERVER_STATE_END;
|
||||
}
|
||||
|
||||
//check if we need password change
|
||||
|
||||
/* list disconnected sessions */
|
||||
slist = session_get_byuser(s->username, &scount, SESMAN_SESSION_STATUS_DISCONNECTED);
|
||||
slist = session_get_byuser(s->username, &scount,
|
||||
SESMAN_SESSION_STATUS_DISCONNECTED);
|
||||
|
||||
if (scount == 0)
|
||||
{
|
||||
@@ -117,32 +110,34 @@ scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
|
||||
if (0 != s->client_ip)
|
||||
{
|
||||
LOG(LOG_LEVEL_INFO, "++ created session (access granted): username %s, ip %s", s->username, s->client_ip);
|
||||
LOG(LOG_LEVEL_INFO, "++ created session (access granted): "
|
||||
"username %s, ip %s", s->username, s->client_ip);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(LOG_LEVEL_INFO, "++ created session (access granted): username %s", s->username);
|
||||
LOG(LOG_LEVEL_INFO, "++ created session (access granted): "
|
||||
"username %s", s->username);
|
||||
}
|
||||
|
||||
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 */
|
||||
do_auth_end = display == 0;
|
||||
e = scp_v1s_connect_new_session(c, display);
|
||||
e = scp_v1s_connect_new_session(t, display);
|
||||
switch (e)
|
||||
{
|
||||
case SCP_SERVER_STATE_OK:
|
||||
@@ -156,55 +151,7 @@ scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* one or more disconnected sessions - listing */
|
||||
e = scp_v1s_list_sessions(c, scount, slist, &sid);
|
||||
|
||||
switch (e)
|
||||
{
|
||||
/*case SCP_SERVER_STATE_FORCE_NEW:*/
|
||||
/* we should check for MaxSessions */
|
||||
case SCP_SERVER_STATE_SELECTION_CANCEL:
|
||||
LOG( LOG_LEVEL_INFO, "Connection cancelled after session listing");
|
||||
break;
|
||||
case SCP_SERVER_STATE_OK:
|
||||
/* ok, reconnecting... */
|
||||
sitem = session_get_bypid(sid);
|
||||
|
||||
if (0 == sitem)
|
||||
{
|
||||
e = scp_v1s_connection_error(c, "Internal error");
|
||||
LOG(LOG_LEVEL_INFO, "Cannot find session item on the chain");
|
||||
}
|
||||
else
|
||||
{
|
||||
display = sitem->display;
|
||||
/*e=scp_v1s_reconnect_session(c, sitem, display);*/
|
||||
e = scp_v1s_reconnect_session(c, display);
|
||||
|
||||
if (0 != 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->client_ip);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(LOG_LEVEL_INFO, "++ reconnected session: username %s, display :%d.0, session_pid %d", s->username, display, sitem->pid);
|
||||
}
|
||||
|
||||
g_free(sitem);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
/* we check the other errors */
|
||||
parseCommonStates(e, "scp_v1s_list_sessions()");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* resource management */
|
||||
if ((e == SCP_SERVER_STATE_OK) && (s->rsr))
|
||||
{
|
||||
/* here goes scp resource sharing code */
|
||||
e = scp_v1s_list_sessions40(t);
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
@@ -213,9 +160,117 @@ scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
auth_end(data);
|
||||
}
|
||||
g_free(slist);
|
||||
return SCP_SERVER_STATE_OK;
|
||||
}
|
||||
|
||||
static void parseCommonStates(enum SCP_SERVER_STATES_E e, const char *f)
|
||||
/******************************************************************************/
|
||||
static enum SCP_SERVER_STATES_E
|
||||
scp_v1_process4(struct trans *t, struct SCP_SESSION *s)
|
||||
{
|
||||
return SCP_SERVER_STATE_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
static enum SCP_SERVER_STATES_E
|
||||
scp_v1_process41(struct trans *t, struct SCP_SESSION *s)
|
||||
{
|
||||
int scount;
|
||||
enum SCP_SERVER_STATES_E e;
|
||||
struct SCP_DISCONNECTED_SESSION *slist;
|
||||
|
||||
/* list disconnected sessions */
|
||||
slist = session_get_byuser(s->username, &scount,
|
||||
SESMAN_SESSION_STATUS_DISCONNECTED);
|
||||
|
||||
if (scount == 0)
|
||||
{
|
||||
/* */
|
||||
return SCP_SERVER_STATE_END;
|
||||
}
|
||||
|
||||
e = scp_v1s_list_sessions42(t, scount, slist);
|
||||
if (SCP_SERVER_STATE_OK != e)
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "scp_v1s_list_sessions42 failed");
|
||||
}
|
||||
|
||||
return SCP_SERVER_STATE_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
static enum SCP_SERVER_STATES_E
|
||||
scp_v1_process43(struct trans *t, struct SCP_SESSION *s)
|
||||
{
|
||||
struct session_item *sitem;
|
||||
enum SCP_SERVER_STATES_E e;
|
||||
int display;
|
||||
|
||||
sitem = session_get_bypid(s->return_sid);
|
||||
if (0 == sitem)
|
||||
{
|
||||
e = scp_v1s_connection_error(t, "Internal error");
|
||||
LOG(LOG_LEVEL_INFO, "No session exists with PID %d", s->return_sid);
|
||||
}
|
||||
else
|
||||
{
|
||||
display = sitem->display;
|
||||
e = scp_v1s_reconnect_session(t, display);
|
||||
if (SCP_SERVER_STATE_OK != e)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "scp_v1s_reconnect_session failed");
|
||||
}
|
||||
if (0 != 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->client_ip);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(LOG_LEVEL_INFO, "++ reconnected session: username %s, display :%d.0, session_pid %d", s->username, display, sitem->pid);
|
||||
}
|
||||
g_free(sitem);
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
static enum SCP_SERVER_STATES_E
|
||||
scp_v1_process44(struct trans *t, struct SCP_SESSION *s)
|
||||
{
|
||||
return SCP_SERVER_STATE_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
static enum SCP_SERVER_STATES_E
|
||||
scp_v1_process45(struct trans *t, struct SCP_SESSION *s)
|
||||
{
|
||||
return SCP_SERVER_STATE_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1_process(struct trans *t, struct SCP_SESSION *s)
|
||||
{
|
||||
; /* astyle 3.1 needs this, or the switch is badly formatted */
|
||||
switch (s->current_cmd)
|
||||
{
|
||||
case SCP_CMD_LOGIN:
|
||||
return scp_v1_process1(t, s);
|
||||
case SCP_CMD_RESEND_CREDS:
|
||||
return scp_v1_process4(t, s);
|
||||
case SCP_CMD_GET_SESSION_LIST:
|
||||
return scp_v1_process41(t, s);
|
||||
case SCP_CMD_SELECT_SESSION:
|
||||
return scp_v1_process43(t, s);
|
||||
case SCP_CMD_SELECT_SESSION_CANCEL:
|
||||
return scp_v1_process44(t, s);
|
||||
case SCP_CMD_FORCE_NEW_CONN:
|
||||
return scp_v1_process45(t, s);
|
||||
}
|
||||
return SCP_SERVER_STATE_END;
|
||||
}
|
||||
|
||||
static void
|
||||
parseCommonStates(enum SCP_SERVER_STATES_E e, const char *f)
|
||||
{
|
||||
switch (e)
|
||||
{
|
||||
|
||||
+2
-2
@@ -35,7 +35,7 @@
|
||||
* @param out_s output stream
|
||||
*
|
||||
*/
|
||||
void
|
||||
scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s);
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1_process(struct trans *t, struct SCP_SESSION *s);
|
||||
|
||||
#endif
|
||||
|
||||
+9
-8
@@ -37,8 +37,8 @@ extern struct config_sesman *g_cfg; /* in sesman.c */
|
||||
static void parseCommonStates(enum SCP_SERVER_STATES_E e, const char *f);
|
||||
|
||||
/******************************************************************************/
|
||||
void
|
||||
scp_v1_mng_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1_mng_process_msg(struct trans *atrans, struct SCP_SESSION *s)
|
||||
{
|
||||
long data;
|
||||
enum SCP_SERVER_STATES_E e;
|
||||
@@ -51,24 +51,24 @@ scp_v1_mng_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
|
||||
if (!data)
|
||||
{
|
||||
scp_v1s_mng_deny_connection(c, "Login failed");
|
||||
scp_v1s_mng_deny_connection(atrans, "Login failed");
|
||||
LOG(LOG_LEVEL_INFO,
|
||||
"[MNG] Login failed for user %s. Connection terminated", s->username);
|
||||
auth_end(data);
|
||||
return;
|
||||
return SCP_SERVER_STATE_END;
|
||||
}
|
||||
|
||||
/* testing if login is allowed */
|
||||
if (0 == access_login_mng_allowed(s->username))
|
||||
{
|
||||
scp_v1s_mng_deny_connection(c, "Access to Terminal Server not allowed.");
|
||||
scp_v1s_mng_deny_connection(atrans, "Access to Terminal Server not allowed.");
|
||||
LOG(LOG_LEVEL_INFO,
|
||||
"[MNG] User %s not allowed on TS. Connection terminated", s->username);
|
||||
auth_end(data);
|
||||
return;
|
||||
return SCP_SERVER_STATE_END;
|
||||
}
|
||||
|
||||
e = scp_v1s_mng_allow_connection(c, s);
|
||||
e = scp_v1s_mng_allow_connection(atrans, s);
|
||||
|
||||
end = 1;
|
||||
|
||||
@@ -89,7 +89,7 @@ scp_v1_mng_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
LOG(LOG_LEVEL_INFO, "No sessions on Terminal Server");
|
||||
}
|
||||
|
||||
e = scp_v1s_mng_list_sessions(c, s, scount, slist);
|
||||
e = scp_v1s_mng_list_sessions(atrans, s, scount, slist);
|
||||
g_free(slist);
|
||||
break;
|
||||
default:
|
||||
@@ -102,6 +102,7 @@ scp_v1_mng_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
|
||||
/* cleanup */
|
||||
auth_end(data);
|
||||
return SCP_SERVER_STATE_END;
|
||||
}
|
||||
|
||||
static void parseCommonStates(enum SCP_SERVER_STATES_E e, const char *f)
|
||||
|
||||
+4
-5
@@ -30,12 +30,11 @@
|
||||
/**
|
||||
*
|
||||
* @brief processes the stream using scp version 1
|
||||
* @param in_sck connection socket
|
||||
* @param in_s input stream
|
||||
* @param out_s output stream
|
||||
* @param atrans incoming transport
|
||||
* @param s incoming session details
|
||||
*
|
||||
*/
|
||||
void
|
||||
scp_v1_mng_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s);
|
||||
enum SCP_SERVER_STATES_E
|
||||
scp_v1_mng_process_msg(struct trans *atrans, struct SCP_SESSION *s);
|
||||
|
||||
#endif
|
||||
|
||||
+246
-67
@@ -34,6 +34,14 @@
|
||||
#include "xrdp_configure_options.h"
|
||||
#include "string_calls.h"
|
||||
|
||||
/**
|
||||
* Maximum number of short-lived connections to sesman
|
||||
*
|
||||
* At the moment, all connections to sesman are short-lived. This may change
|
||||
* in the future
|
||||
*/
|
||||
#define MAX_SHORT_LIVED_CONNECTIONS 16
|
||||
|
||||
struct sesman_startup_params
|
||||
{
|
||||
const char *sesman_ini;
|
||||
@@ -44,13 +52,24 @@ 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;
|
||||
|
||||
/**
|
||||
* Items stored on the g_con_list
|
||||
*/
|
||||
struct sesman_con
|
||||
{
|
||||
struct trans *t;
|
||||
struct SCP_SESSION *s;
|
||||
};
|
||||
|
||||
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
|
||||
@@ -78,6 +97,54 @@ static int nocase_matches(const char *candidate, ...)
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates a sesman_con struct
|
||||
*
|
||||
* @param trans Pointer to newly-allocated transport
|
||||
* @return struct sesman_con pointer
|
||||
*/
|
||||
static struct sesman_con *
|
||||
alloc_connection(struct trans *t)
|
||||
{
|
||||
struct sesman_con *result;
|
||||
struct SCP_SESSION *s;
|
||||
|
||||
if ((result = g_new(struct sesman_con, 1)) != NULL)
|
||||
{
|
||||
if ((s = scp_session_create()) != NULL)
|
||||
{
|
||||
result->t = t;
|
||||
result->s = s;
|
||||
/* Ensure we can find the connection easily from a callback */
|
||||
t->callback_data = (void *)result;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_free(result);
|
||||
result = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a sesman_con struct, freeing resources
|
||||
*
|
||||
* After this call, the passed-in pointer is invalid and must not be
|
||||
* referenced.
|
||||
*
|
||||
* @param sc struct to de-allocate
|
||||
*/
|
||||
static void
|
||||
delete_connection(struct sesman_con *sc)
|
||||
{
|
||||
trans_delete(sc->t);
|
||||
scp_session_destroy(sc->s);
|
||||
g_free(sc);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
@@ -187,6 +254,90 @@ static int sesman_listen_test(struct config_sesman *cfg)
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
int
|
||||
sesman_close_all(void)
|
||||
{
|
||||
int index;
|
||||
struct sesman_con *sc;
|
||||
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "sesman_close_all:");
|
||||
trans_delete(g_list_trans);
|
||||
for (index = 0; index < g_con_list->count; index++)
|
||||
{
|
||||
sc = (struct sesman_con *) list_get_item(g_con_list, index);
|
||||
delete_connection(sc);
|
||||
}
|
||||
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(LOG_LEVEL_ERROR, "sesman_data_in: bad message size");
|
||||
return 1;
|
||||
}
|
||||
self->header_size = size;
|
||||
self->extra_flags = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* process message */
|
||||
struct sesman_con *sc = (struct sesman_con *)self->callback_data;
|
||||
self->in_s->p = self->in_s->data;
|
||||
if (scp_process(self, sc->s) != SCP_SERVER_STATE_OK)
|
||||
{
|
||||
LOG(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); /* Reset input stream pointers */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
static int
|
||||
sesman_listen_conn_in(struct trans *self, struct trans *new_self)
|
||||
{
|
||||
struct sesman_con *sc;
|
||||
if (g_con_list->count >= MAX_SHORT_LIVED_CONNECTIONS)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "sesman_data_in: error, too many "
|
||||
"connections, rejecting");
|
||||
trans_delete(new_self);
|
||||
}
|
||||
else if ((sc = alloc_connection(new_self)) == NULL)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "sesman_data_in: No memory to allocate "
|
||||
"new connection");
|
||||
trans_delete(new_self);
|
||||
}
|
||||
else
|
||||
{
|
||||
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) sc);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
*
|
||||
@@ -196,96 +347,124 @@ 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 sesman_con *scon;
|
||||
|
||||
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(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(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_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)
|
||||
scon = (struct sesman_con *)list_get_item(g_con_list, index);
|
||||
if (scon != 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(scon->t,
|
||||
robjs, &robjs_count,
|
||||
wobjs, &wobjs_count, &timeout);
|
||||
if (error != 0)
|
||||
{
|
||||
LOG(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(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++)
|
||||
{
|
||||
scon = (struct sesman_con *)list_get_item(g_con_list, index);
|
||||
if (scon != NULL)
|
||||
{
|
||||
error = trans_check_wait_objs(scon->t);
|
||||
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(LOG_LEVEL_ERROR, "sesman_main_loop: "
|
||||
"trans_check_wait_objs failed, removing trans");
|
||||
delete_connection(scon);
|
||||
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(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;
|
||||
scon = (struct sesman_con *) list_get_item(g_con_list, index);
|
||||
delete_connection(scon);
|
||||
}
|
||||
g_tcp_close(g_sck);
|
||||
return rv;
|
||||
list_delete(g_con_list);
|
||||
trans_delete(g_list_trans);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
@@ -41,4 +41,16 @@
|
||||
|
||||
#include "libscp.h"
|
||||
|
||||
/*
|
||||
* Close all file descriptors used by sesman.
|
||||
*
|
||||
* This is generally used after forking, to make sure the
|
||||
* file descriptors used by the main process are not disturbed
|
||||
*
|
||||
* This call will also release all trans and SCP_SESSION objects
|
||||
* held by sesman
|
||||
*/
|
||||
int
|
||||
sesman_close_all(void);
|
||||
|
||||
#endif
|
||||
|
||||
+13
-8
@@ -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;
|
||||
@@ -494,10 +492,18 @@ session_start_fork(tbus data, tui8 type, struct SCP_CONNECTION *c,
|
||||
LOG(LOG_LEVEL_INFO,
|
||||
"[session start] (display %d): calling auth_start_session from pid %d",
|
||||
display, g_getpid());
|
||||
|
||||
/* Clone the session object, as the passed-in copy will be
|
||||
* deleted by sesman_close_all() */
|
||||
if ((s = scp_session_clone(s)) == NULL)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR,
|
||||
"Failed to clone the session data - out of memory");
|
||||
g_exit(1);
|
||||
}
|
||||
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 +1014,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);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
+1
-2
@@ -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;
|
||||
|
||||
+13
-14
@@ -38,8 +38,8 @@ char cmnd[257];
|
||||
char serv[257];
|
||||
char port[257];
|
||||
|
||||
void cmndList(struct SCP_CONNECTION *c);
|
||||
void cmndKill(struct SCP_CONNECTION *c, struct SCP_SESSION *s);
|
||||
void cmndList(struct trans *t);
|
||||
void cmndKill(struct trans *t, struct SCP_SESSION *s);
|
||||
void cmndHelp(void);
|
||||
|
||||
int inputSession(struct SCP_SESSION *s);
|
||||
@@ -48,7 +48,7 @@ unsigned int menuSelect(unsigned int choices);
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct SCP_SESSION *s;
|
||||
struct SCP_CONNECTION *c;
|
||||
struct trans *t;
|
||||
enum SCP_CLIENT_STATES_E e;
|
||||
//int end;
|
||||
int idx;
|
||||
@@ -136,13 +136,13 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
s = scp_session_create();
|
||||
c = scp_connection_create(sock);
|
||||
t = scp_trans_create(sock);
|
||||
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "Connecting to %s:%s with user %s (%s)", serv, port, user, pass);
|
||||
|
||||
if (0 != g_tcp_connect(sock, serv, port))
|
||||
if (0 != trans_connect(t, serv, port, 3000))
|
||||
{
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "g_tcp_connect() error");
|
||||
LOG(LOG_LEVEL_ERROR, "trans_connect() error");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ int main(int argc, char **argv)
|
||||
scp_session_set_username(s, user);
|
||||
scp_session_set_password(s, pass);
|
||||
|
||||
e = scp_v1c_mng_connect(c, s);
|
||||
e = scp_v1c_mng_connect(t, s);
|
||||
|
||||
if (SCP_CLIENT_STATE_OK != e)
|
||||
{
|
||||
@@ -160,16 +160,15 @@ int main(int argc, char **argv)
|
||||
|
||||
if (0 == g_strncmp(cmnd, "list", 5))
|
||||
{
|
||||
cmndList(c);
|
||||
cmndList(t);
|
||||
}
|
||||
else if (0 == g_strncmp(cmnd, "kill:", 5))
|
||||
{
|
||||
cmndKill(c, s);
|
||||
cmndKill(t, s);
|
||||
}
|
||||
|
||||
g_tcp_close(sock);
|
||||
scp_session_destroy(s);
|
||||
scp_connection_destroy(c);
|
||||
trans_delete(t);
|
||||
log_end();
|
||||
|
||||
return 0;
|
||||
@@ -203,14 +202,14 @@ print_session(const struct SCP_DISCONNECTED_SESSION *s)
|
||||
s->conn_minute);
|
||||
}
|
||||
|
||||
void cmndList(struct SCP_CONNECTION *c)
|
||||
void cmndList(struct trans *t)
|
||||
{
|
||||
struct SCP_DISCONNECTED_SESSION *dsl;
|
||||
enum SCP_CLIENT_STATES_E e;
|
||||
int scnt;
|
||||
int idx;
|
||||
|
||||
e = scp_v1c_mng_get_session_list(c, &scnt, &dsl);
|
||||
e = scp_v1c_mng_get_session_list(t, &scnt, &dsl);
|
||||
|
||||
if (e != SCP_CLIENT_STATE_LIST_OK)
|
||||
{
|
||||
@@ -233,7 +232,7 @@ void cmndList(struct SCP_CONNECTION *c)
|
||||
g_free(dsl);
|
||||
}
|
||||
|
||||
void cmndKill(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
|
||||
void cmndKill(struct trans *t, struct SCP_SESSION *s)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -504,6 +504,7 @@ handle_scpv0_auth_reply(int sck)
|
||||
int data;
|
||||
int display;
|
||||
|
||||
in_s->end = in_s->data + 8;
|
||||
in_uint32_be(in_s, version);
|
||||
in_uint32_be(in_s, size);
|
||||
if (version == 0 && size >= 14)
|
||||
|
||||
+14
-17
@@ -37,22 +37,21 @@ int main(int argc, char **argv)
|
||||
{
|
||||
char buf[256];
|
||||
struct SCP_SESSION *s;
|
||||
struct SCP_CONNECTION *c;
|
||||
struct trans *t;
|
||||
/*struct SCP_DISCONNECTED_SESSION ds;*/
|
||||
struct SCP_DISCONNECTED_SESSION *dsl;
|
||||
enum SCP_CLIENT_STATES_E e;
|
||||
struct log_config log;
|
||||
struct log_config *logging;
|
||||
int end;
|
||||
int scnt;
|
||||
int idx;
|
||||
int sel;
|
||||
int sock;
|
||||
|
||||
log.enable_syslog = 0;
|
||||
log.log_level = LOG_LEVEL_DEBUG;
|
||||
log.program_name = "sestest";
|
||||
log.log_file = g_strdup("sestest.log");
|
||||
log_start_from_param(&log);
|
||||
logging = log_config_init_for_console(LOG_LEVEL_INFO, NULL);
|
||||
log_start_from_param(logging);
|
||||
log_config_free(logging);
|
||||
|
||||
scp_init();
|
||||
|
||||
sock = g_tcp_socket();
|
||||
@@ -62,9 +61,9 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
s = scp_session_create();
|
||||
c = scp_connection_create(sock);
|
||||
t = scp_trans_create(sock);
|
||||
|
||||
if (0 != g_tcp_connect(sock, "localhost", "3350"))
|
||||
if (0 != trans_connect(t, "localhost", "3350", 3000))
|
||||
{
|
||||
g_printf("error connecting");
|
||||
return 1;
|
||||
@@ -105,7 +104,7 @@ int main(int argc, char **argv)
|
||||
s.errstr=0;*/
|
||||
|
||||
end = 0;
|
||||
e = scp_v1c_connect(c, s);
|
||||
e = scp_v1c_connect(t, s);
|
||||
|
||||
while (!end)
|
||||
{
|
||||
@@ -117,7 +116,7 @@ int main(int argc, char **argv)
|
||||
break;
|
||||
case SCP_CLIENT_STATE_SESSION_LIST:
|
||||
g_printf("OK : session list needed\n");
|
||||
e = scp_v1c_get_session_list(c, &scnt, &dsl);
|
||||
e = scp_v1c_get_session_list(t, &scnt, &dsl);
|
||||
break;
|
||||
case SCP_CLIENT_STATE_LIST_OK:
|
||||
g_printf("OK : selecting a session:\n");
|
||||
@@ -131,7 +130,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
sel = menuSelect(scnt);
|
||||
e = scp_v1c_select_session(c, s, dsl[sel - 1].SID);
|
||||
e = scp_v1c_select_session(t, s, dsl[sel - 1].SID);
|
||||
g_printf("\n return: %d \n", e);
|
||||
break;
|
||||
case SCP_CLIENT_STATE_RESEND_CREDENTIALS:
|
||||
@@ -152,7 +151,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
scp_session_set_password(s, buf);
|
||||
e = scp_v1c_resend_credentials(c, s);
|
||||
e = scp_v1c_resend_credentials(t, s);
|
||||
break;
|
||||
case SCP_CLIENT_STATE_CONNECTION_DENIED:
|
||||
g_printf("ERR: connection denied: %s\n", s->errstr);
|
||||
@@ -173,11 +172,9 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
g_tcp_close(sock);
|
||||
scp_session_destroy(s);
|
||||
scp_connection_destroy(c);
|
||||
/*free_stream(c.in_s);
|
||||
free_stream(c.out_s);*/
|
||||
trans_delete(t);
|
||||
log_end();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user