more work on scp v1

ulab-original
ilsimo 18 years ago
parent 5260d224dc
commit ae9faad218

@ -36,7 +36,7 @@
#include "arch.h" #include "arch.h"
#include "log.h" #include "log.h"
//#warning sesman requires its own tcp streaming functions for threading safety //sesman requires its own tcp streaming functions for threading safety
#include "tcp.h" #include "tcp.h"
#define SCP_SID uint32_t #define SCP_SID uint32_t
@ -58,6 +58,8 @@
#define SCP_COMMAND_SET_MANAGE 0x0001 #define SCP_COMMAND_SET_MANAGE 0x0001
#define SCP_COMMAND_SET_RSR 0x0002 #define SCP_COMMAND_SET_RSR 0x0002
#define SCP_SERVER_MAX_LIST_SIZE 100
#define free_session(s) {g_free((s)->username); g_free((s)->password); g_free((s)->hostname); g_free(s);} #define free_session(s) {g_free((s)->username); g_free((s)->password); g_free((s)->hostname); g_free(s);}
struct SCP_CONNECTION struct SCP_CONNECTION
@ -89,13 +91,13 @@ struct SCP_SESSION
struct SCP_DISCONNECTED_SESSION struct SCP_DISCONNECTED_SESSION
{ {
uint32_t SID; uint32_t SID;
unsigned char type; uint8_t type;
uint16_t height; uint16_t height;
uint16_t width; uint16_t width;
unsigned char bpp; uint8_t bpp;
unsigned char idle_days; uint8_t idle_days;
unsigned char idle_hours; uint8_t idle_hours;
unsigned char idle_minutes; uint8_t idle_minutes;
}; };
enum SCP_CLIENT_STATES_E enum SCP_CLIENT_STATES_E
@ -104,12 +106,16 @@ enum SCP_CLIENT_STATES_E
SCP_CLIENT_STATE_NETWORK_ERR, SCP_CLIENT_STATE_NETWORK_ERR,
SCP_CLIENT_STATE_VERSION_ERR, SCP_CLIENT_STATE_VERSION_ERR,
SCP_CLIENT_STATE_SEQUENCE_ERR, SCP_CLIENT_STATE_SEQUENCE_ERR,
SCP_CLIENT_STATE_SIZE_ERR,
SCP_CLIENT_STATE_INTERNAL_ERR, SCP_CLIENT_STATE_INTERNAL_ERR,
SCP_CLIENT_STATE_SESSION_LIST, SCP_CLIENT_STATE_SESSION_LIST,
SCP_CLIENT_STATE_LIST_OK,
SCP_CLIENT_STATE_RESEND_CREDENTIALS, SCP_CLIENT_STATE_RESEND_CREDENTIALS,
SCP_CLIENT_STATE_CONNECTION_DENIED, SCP_CLIENT_STATE_CONNECTION_DENIED,
SCP_CLIENT_STATE_PWD_CHANGE_REQ, SCP_CLIENT_STATE_PWD_CHANGE_REQ,
SCP_CLIENT_STATE_RECONNECT SCP_CLIENT_STATE_RECONNECT_SINGLE,
SCP_CLIENT_STATE_SELECTION_CANCEL,
SCP_CLIENT_STATE_END
}; };
enum SCP_SERVER_STATES_E enum SCP_SERVER_STATES_E
@ -121,6 +127,8 @@ enum SCP_SERVER_STATES_E
SCP_SERVER_STATE_INTERNAL_ERR, SCP_SERVER_STATE_INTERNAL_ERR,
SCP_SERVER_STATE_SESSION_TYPE_ERR, SCP_SERVER_STATE_SESSION_TYPE_ERR,
SCP_SERVER_STATE_SIZE_ERR, SCP_SERVER_STATE_SIZE_ERR,
SCP_SERVER_STATE_SELECTION_CANCEL,
/*SCP_SERVER_STATE_FORCE_NEW,*/
SCP_SERVER_STATE_START_MANAGE, SCP_SERVER_STATE_START_MANAGE,
SCP_SERVER_STATE_END SCP_SERVER_STATE_END
}; };

@ -27,6 +27,9 @@
#include "libscp_v1c.h" #include "libscp_v1c.h"
#include <stdlib.h>
#include <stdio.h>
static enum SCP_CLIENT_STATES_E _scp_v1c_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s); static enum SCP_CLIENT_STATES_E _scp_v1c_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s);
/* client API */ /* client API */
@ -138,11 +141,208 @@ enum SCP_CLIENT_STATES_E scp_v1c_resend_credentials(struct SCP_CONNECTION* c, st
/* 021 */ enum SCP_CLIENT_STATES_E scp_v1c_pwd_change(struct SCP_CONNECTION* c, char* newpass); /* 021 */ enum SCP_CLIENT_STATES_E scp_v1c_pwd_change(struct SCP_CONNECTION* c, char* newpass);
/* 022 */ enum SCP_CLIENT_STATES_E scp_v1c_pwd_change_cancel(struct SCP_CONNECTION* c); /* 022 */ enum SCP_CLIENT_STATES_E scp_v1c_pwd_change_cancel(struct SCP_CONNECTION* c);
/* ... */ enum SCP_CLIENT_STATES_E scp_v1c_get_session_list(struct SCP_CONNECTION* c, int* scount, struct SCP_DISCONNECTED_SESSION** s); /* 041 */
/* 041 */ enum SCP_CLIENT_STATES_E scp_v1c_select_session(struct SCP_CONNECTION* c, SCP_SID sid); enum SCP_CLIENT_STATES_E
/* 042 */ enum SCP_CLIENT_STATES_E scp_v1c_select_session_cancel(struct SCP_CONNECTION* c); scp_v1c_get_session_list(struct SCP_CONNECTION* c, int* scount, struct SCP_DISCONNECTED_SESSION** s)
{
uint32_t version=1;
uint32_t size=12;
uint16_t cmd=41;
uint32_t sescnt=0; /* total session number */
uint32_t sestmp=0; /* additional total session number */
uint8_t pktcnt=0; /* packet session count */
uint32_t totalcnt=0; /* session counter */
uint8_t continued=0; /* continue flag */
int firstpkt=1; /* "first packet" flag */
int idx;
struct SCP_DISCONNECTED_SESSION* ds=0;
init_stream(c->out_s, c->out_s->size);
/* 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 */
if (0!=tcp_force_send(c->in_sck, c->out_s->data, size))
{
return SCP_CLIENT_STATE_NETWORK_ERR;
}
do
{
/* then we wait for server response */
init_stream(c->in_s, c->in_s->size);
if (0!=tcp_force_recv(c->in_sck, c->in_s->data, 8))
{
return SCP_CLIENT_STATE_NETWORK_ERR;
}
in_uint32_be(c->in_s, version);
if (version!=1)
{
return SCP_CLIENT_STATE_VERSION_ERR;
}
in_uint32_be(c->in_s, size);
if (size<12)
{
return SCP_CLIENT_STATE_SIZE_ERR;
}
init_stream(c->in_s, c->in_s->size);
if (0!=tcp_force_recv(c->in_sck, c->in_s->data, size-8))
{
return SCP_CLIENT_STATE_NETWORK_ERR;
}
in_uint16_be(c->in_s, cmd);
if (cmd!=SCP_COMMAND_SET_DEFAULT)
{
return SCP_CLIENT_STATE_SEQUENCE_ERR;
}
in_uint16_be(c->in_s, cmd);
if (cmd!=42)
{
return SCP_CLIENT_STATE_SEQUENCE_ERR;
}
if (firstpkt)
{
firstpkt = 0;
in_uint32_be(c->in_s, sescnt);
sestmp = sescnt;
ds = g_malloc(sizeof(struct SCP_DISCONNECTED_SESSION)*sescnt, 0);
if (ds == 0)
{
return SCP_CLIENT_STATE_INTERNAL_ERR;
}
}
else
{
in_uint32_be(c->in_s, sestmp);
}
in_uint8(c->in_s, continued);
in_uint8(c->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);
totalcnt++;
}
}
while (continued);
printf("fine\n");
/* return data... */
(*scount) = sescnt;
(*s) = ds;
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_SID sid)
{
uint32_t version = 1;
uint32_t size = 16;
uint16_t cmd = 43;
init_stream(c->out_s, c->out_s->size);
/* 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(c->out_s, sid);
if (0!=tcp_force_send(c->in_sck, c->out_s->data, size))
{
return SCP_CLIENT_STATE_NETWORK_ERR;
}
/* 03x */ enum SCP_CLIENT_STATES_E scp_v1c_retrieve_session(struct SCP_CONNECTION* c, struct SCP_SESSION* s, struct SCP_DISCONNECTED_SESSION* ds); /* waiting for response.... */
init_stream(c->in_s, c->in_s->size);
if (0!=tcp_force_recv(c->in_sck, c->in_s->data, 8))
{
return SCP_CLIENT_STATE_NETWORK_ERR;
}
in_uint32_be(c->in_s, version);
if (version!=1)
{
return SCP_CLIENT_STATE_VERSION_ERR;
}
in_uint32_be(c->in_s, size);
if (size<12)
{
return SCP_CLIENT_STATE_SIZE_ERR;
}
init_stream(c->in_s, c->in_s->size);
/* read the rest of the packet */
if (0!=tcp_force_recv(c->in_sck, c->in_s->data, size-8))
{
return SCP_CLIENT_STATE_NETWORK_ERR;
}
in_uint16_be(c->in_s, cmd);
if (cmd != SCP_COMMAND_SET_DEFAULT)
{
return SCP_CLIENT_STATE_SEQUENCE_ERR;
}
in_uint16_be(c->in_s, cmd);
if (cmd != 46)
{
return SCP_CLIENT_STATE_SEQUENCE_ERR;
}
/* session display */
in_uint16_be(c->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)
{
uint32_t version = 1;
uint32_t size = 12;
uint16_t cmd = 44;
init_stream(c->out_s, c->out_s->size);
/* 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 */
if (0!=tcp_force_send(c->in_sck, c->out_s->data, size))
{
return SCP_CLIENT_STATE_NETWORK_ERR;
}
return SCP_CLIENT_STATE_END;
}
static enum SCP_CLIENT_STATES_E _scp_v1c_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s) static enum SCP_CLIENT_STATES_E _scp_v1c_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
{ {
@ -236,10 +436,14 @@ static enum SCP_CLIENT_STATES_E _scp_v1c_check_response(struct SCP_CONNECTION* c
return SCP_CLIENT_STATE_OK; return SCP_CLIENT_STATE_OK;
} }
else if (cmd==32) /* display of a disconnected session */ //else if (cmd==31) /* there's a disconnected session */
{ //{
return SCP_CLIENT_STATE_RECONNECT; // return SCP_CLIENT_STATE_RECONNECT_SINGLE;
} //}
//else if (cmd==33) /* display of a disconnected session */
//{
// return SCP_CLIENT_STATE_RECONNECT;
//}
else if (cmd==40) /* session list */ else if (cmd==40) /* session list */
{ {
return SCP_CLIENT_STATE_SESSION_LIST; return SCP_CLIENT_STATE_SESSION_LIST;

@ -31,14 +31,34 @@
#include "libscp_types.h" #include "libscp_types.h"
/* client API */ /* client API */
/* 001 */ enum SCP_CLIENT_STATES_E scp_v1c_connect(struct SCP_CONNECTION* c, struct SCP_SESSION* s); /* 001 */
/* 004 */ enum SCP_CLIENT_STATES_E scp_v1c_resend_credentials(struct SCP_CONNECTION* c, struct SCP_SESSION* s); enum SCP_CLIENT_STATES_E
scp_v1c_connect(struct SCP_CONNECTION* c, struct SCP_SESSION* s);
/* 021 */ enum SCP_CLIENT_STATES_E scp_v1c_pwd_change(struct SCP_CONNECTION* c, char* newpass); /* 004 */
/* 022 */ enum SCP_CLIENT_STATES_E scp_v1c_pwd_change_cancel(struct SCP_CONNECTION* c); enum SCP_CLIENT_STATES_E
scp_v1c_resend_credentials(struct SCP_CONNECTION* c, struct SCP_SESSION* s);
/* ... */ enum SCP_CLIENT_STATES_E scp_v1c_get_session_list(struct SCP_CONNECTION* c, int* scount, struct SCP_DISCONNECTED_SESSION** s); /* 021 */
/* 041 */ enum SCP_CLIENT_STATES_E scp_v1c_select_session(struct SCP_CONNECTION* c, SCP_SID sid); enum SCP_CLIENT_STATES_E
/* 042 */ enum SCP_CLIENT_STATES_E scp_v1c_select_session_cancel(struct SCP_CONNECTION* c); scp_v1c_pwd_change(struct SCP_CONNECTION* c, char* newpass);
/* 022 */
enum SCP_CLIENT_STATES_E
scp_v1c_pwd_change_cancel(struct SCP_CONNECTION* c);
/* 041 */
enum SCP_CLIENT_STATES_E
scp_v1c_get_session_list(struct SCP_CONNECTION* c, 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_SID sid);
/* 044 */
enum SCP_CLIENT_STATES_E
scp_v1c_select_session_cancel(struct SCP_CONNECTION* c);
#endif #endif

@ -62,7 +62,6 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SES
} }
in_uint32_be(c->in_s, size); in_uint32_be(c->in_s, size);
LOG_DBG("size: %d",size);
if (size<12) if (size<12)
{ {
return SCP_SERVER_STATE_SIZE_ERR; return SCP_SERVER_STATE_SIZE_ERR;
@ -76,7 +75,6 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SES
/* reading command set */ /* reading command set */
in_uint16_be(c->in_s, cmdset); in_uint16_be(c->in_s, cmdset);
LOG_DBG("command set: %d",cmdset);
/* if we are starting a management session */ /* if we are starting a management session */
if (cmdset==SCP_COMMAND_SET_MANAGE) if (cmdset==SCP_COMMAND_SET_MANAGE)
@ -92,7 +90,6 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SES
/* reading command */ /* reading command */
in_uint16_be(c->in_s, cmd); in_uint16_be(c->in_s, cmd);
LOG_DBG("command: %d",cmd);
if (cmd != 1) if (cmd != 1)
{ {
return SCP_SERVER_STATE_SEQUENCE_ERR; return SCP_SERVER_STATE_SEQUENCE_ERR;
@ -119,8 +116,6 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SES
in_uint8a(c->in_s, session->locale, 17); in_uint8a(c->in_s, session->locale, 17);
session->locale[17]='\0'; session->locale[17]='\0';
LOG_DBG("locale: %s\n", session->locale);
in_uint8(c->in_s, session->addr_type); in_uint8(c->in_s, session->addr_type);
if (session->addr_type==SCP_ADDRESS_TYPE_IPV4) if (session->addr_type==SCP_ADDRESS_TYPE_IPV4)
{ {
@ -131,11 +126,8 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SES
#warning how to handle ipv6 addresses? #warning how to handle ipv6 addresses?
} }
LOG_DBG("rest: %d\n",(unsigned char)*((c->in_s->p)+2));
/* reading hostname */ /* reading hostname */
in_uint8(c->in_s, sz); in_uint8(c->in_s, sz);
LOG_DBG("size read: %d", sz);
session->hostname=g_malloc(sz+1,1); session->hostname=g_malloc(sz+1,1);
if (0==session->hostname) if (0==session->hostname)
{ {
@ -159,7 +151,6 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SES
/* reading password */ /* reading password */
in_uint8(c->in_s, sz); in_uint8(c->in_s, sz);
LOG_DBG("size read: %d", sz);
session->password=g_malloc(sz+1,1); session->password=g_malloc(sz+1,1);
if (0==session->password) if (0==session->password)
{ {
@ -171,8 +162,6 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SES
session->password[sz]='\0'; session->password[sz]='\0';
in_uint8a(c->in_s, session->password, sz); in_uint8a(c->in_s, session->password, sz);
LOG_DBG("password: %s - size: %d - pointer: %x", session->password, sz, session->password);
/* returning the struct */ /* returning the struct */
(*s)=session; (*s)=session;
@ -260,14 +249,12 @@ scp_v1s_request_password(struct SCP_CONNECTION* c, struct SCP_SESSION* s, char*
in_uint32_be(c->in_s, version); in_uint32_be(c->in_s, version);
if (version!=1) if (version!=1)
{ {
LOG_DBG("version: %d",version);
return SCP_SERVER_STATE_VERSION_ERR; return SCP_SERVER_STATE_VERSION_ERR;
} }
in_uint32_be(c->in_s, size); in_uint32_be(c->in_s, size);
if (size<12) if (size<12)
{ {
LOG_DBG("size: %d",size);
return SCP_SERVER_STATE_SIZE_ERR; return SCP_SERVER_STATE_SIZE_ERR;
} }
@ -277,9 +264,17 @@ scp_v1s_request_password(struct SCP_CONNECTION* c, struct SCP_SESSION* s, char*
return SCP_SERVER_STATE_NETWORK_ERR; return SCP_SERVER_STATE_NETWORK_ERR;
} }
#warning check cmd seq
in_uint16_be(c->in_s, cmdset); in_uint16_be(c->in_s, cmdset);
if (cmdset != SCP_COMMAND_SET_DEFAULT)
{
return SCP_SERVER_STATE_SEQUENCE_ERR;
}
in_uint16_be(c->in_s, cmd); in_uint16_be(c->in_s, cmd);
if (cmd != 4)
{
return SCP_SERVER_STATE_SEQUENCE_ERR;
}
/* reading username */ /* reading username */
in_uint8(c->in_s, sz); in_uint8(c->in_s, sz);
@ -351,17 +346,28 @@ scp_v1s_connect_new_session(struct SCP_CONNECTION* c, SCP_DISPLAY d)
return SCP_SERVER_STATE_OK; return SCP_SERVER_STATE_OK;
} }
/* 031 */ /* 032 */
enum SCP_SERVER_STATES_E
scp_v1s_connection_error(struct SCP_CONNECTION* c, char* error)
{
return SCP_SERVER_STATE_INTERNAL_ERR;
return SCP_SERVER_STATE_END;
}
/* 040 */
enum SCP_SERVER_STATES_E enum SCP_SERVER_STATES_E
scp_v1s_reconnect_session(struct SCP_CONNECTION* c, struct SCP_DISCONNECTED_SESSION* ds, scp_v1s_list_sessions(struct SCP_CONNECTION* c, int sescnt, struct SCP_DISCONNECTED_SESSION* ds, SCP_SID* sid)
SCP_DISPLAY d)
{ {
uint32_t version=1; uint32_t version=1;
uint32_t size=12; uint32_t size=12;
uint16_t cmd=32; uint16_t cmd=40;
#warning FIXME check this command code int pktcnt;
int idx;
/* first we send a notice that we're reconnecting to an existing session */ int sidx;
int pidx;
struct SCP_DISCONNECTED_SESSION* cds;
/* first we send a notice that we have some disconnected sessions */
init_stream(c->out_s, c->out_s->size); init_stream(c->out_s, c->out_s->size);
out_uint32_be(c->out_s, version); /* version */ out_uint32_be(c->out_s, version); /* version */
@ -369,7 +375,7 @@ scp_v1s_reconnect_session(struct SCP_CONNECTION* c, struct SCP_DISCONNECTED_SESS
out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */ 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, cmd); /* cmd */
if (0!=tcp_force_send(c->in_sck, c->out_s->data, 14)) if (0!=tcp_force_send(c->in_sck, c->out_s->data, size))
{ {
return SCP_SERVER_STATE_NETWORK_ERR; return SCP_SERVER_STATE_NETWORK_ERR;
} }
@ -377,6 +383,7 @@ scp_v1s_reconnect_session(struct SCP_CONNECTION* c, struct SCP_DISCONNECTED_SESS
/* then we wait for client ack */ /* then we wait for client ack */
#warning maybe this message could say if the session should be resized on #warning maybe this message could say if the session should be resized on
#warning server side or client side #warning server side or client side
init_stream(c->in_s, c->in_s->size);
if (0!=tcp_force_recv(c->in_sck, c->in_s->data, 8)) if (0!=tcp_force_recv(c->in_sck, c->in_s->data, 8))
{ {
return SCP_SERVER_STATE_NETWORK_ERR; return SCP_SERVER_STATE_NETWORK_ERR;
@ -407,21 +414,164 @@ scp_v1s_reconnect_session(struct SCP_CONNECTION* c, struct SCP_DISCONNECTED_SESS
} }
in_uint16_be(c->in_s, cmd); in_uint16_be(c->in_s, cmd);
#warning FIXME check this command code if (cmd != 41)
if (cmd != 33)
{ {
return SCP_SERVER_STATE_SEQUENCE_ERR; return SCP_SERVER_STATE_SEQUENCE_ERR;
} }
/* ok, we send session data and display */ /* 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++)
{
/* ok, we send session session list */
init_stream(c->out_s, c->out_s->size); init_stream(c->out_s, c->out_s->size);
/* size */ /* size: ver+size+cmdset+cmd+sescnt+continue+count */
size=4+4+2+2+ \ size=4+4+2+2+4+1+1;
2+1+2+2+1+1+1+1;
/* header */
cmd=42;
s_push_layer(c->out_s, channel_hdr, 8);
out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT);
out_uint16_be(c->out_s, cmd);
/* session count */
out_uint32_be(c->out_s, sescnt);
/* setting the continue flag */
if ((idx+1)*SCP_SERVER_MAX_LIST_SIZE >= sescnt)
{
out_uint8(c->out_s, 0);
/* setting session count for this packet */
pidx=sescnt-(idx*SCP_SERVER_MAX_LIST_SIZE);
out_uint8(c->out_s, pidx);
}
else
{
out_uint8(c->out_s, 1);
/* setting session count for this packet */
pidx=SCP_SERVER_MAX_LIST_SIZE;
out_uint8(c->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(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);
size = size + 13;
}
s_pop_layer(c->out_s, channel_hdr);
out_uint32_be(c->out_s, version);
out_uint32_be(c->out_s, size);
if (0!=tcp_force_send(c->in_sck, c->out_s->data, size))
{
return SCP_SERVER_STATE_NETWORK_ERR;
}
}
/* we get the response */
init_stream(c->in_s, c->in_s->size);
if (0!=tcp_force_recv(c->in_sck, c->in_s->data, (8)))
{
return SCP_SERVER_STATE_NETWORK_ERR;
}
in_uint32_be(c->in_s, version);
if (version!=1)
{
return SCP_SERVER_STATE_VERSION_ERR;
}
in_uint32_be(c->in_s, size);
if (size<12)
{
return SCP_SERVER_STATE_SIZE_ERR;
}
/* rest of the packet */
init_stream(c->in_s, c->in_s->size);
if (0!=tcp_force_recv(c->in_sck, c->in_s->data, (size-8)))
{
return SCP_SERVER_STATE_NETWORK_ERR;
}
in_uint16_be(c->in_s, cmd);
if (cmd != SCP_COMMAND_SET_DEFAULT)
{
return SCP_SERVER_STATE_SEQUENCE_ERR;
}
in_uint16_be(c->in_s, cmd);
if (cmd == 43)
{
/* select session */
in_uint32_be(c->in_s, (*sid));
/* checking sid value */
for (idx=0; idx<sescnt; idx++)
{
/* the sid is valid */
if (ds[idx].SID==(*sid))
{
/* ok, session selected */
return SCP_SERVER_STATE_OK;
}
}
/* if we got here, the requested sid wasn't one from the list we sent */
/* we should kill the connection */
return SCP_CLIENT_STATE_INTERNAL_ERR;
}
else if (cmd == 44)
{
/* cancel connection */
return SCP_SERVER_STATE_SELECTION_CANCEL;
}
// else if (cmd == 45)
// {
// /* force new connection */
// return SCP_SERVER_STATE_FORCE_NEW;
// }
else
{
/* wrong response */
return SCP_SERVER_STATE_SEQUENCE_ERR;
}
return SCP_SERVER_STATE_OK;
}
/* 046 was: 031 struct SCP_DISCONNECTED_SESSION* ds, */
enum SCP_SERVER_STATES_E
scp_v1s_reconnect_session(struct SCP_CONNECTION* c, SCP_DISPLAY d)
{
uint32_t version = 1;
uint32_t size = 14;
uint16_t cmd = 46;
/* ok, we send session data and display */
init_stream(c->out_s, c->out_s->size);
/* header */ /* header */
cmd=31;
out_uint32_be(c->out_s, version); out_uint32_be(c->out_s, version);
out_uint32_be(c->out_s, size); out_uint32_be(c->out_s, size);
out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT);
@ -429,13 +579,13 @@ scp_v1s_reconnect_session(struct SCP_CONNECTION* c, struct SCP_DISCONNECTED_SESS
/* session data */ /* session data */
out_uint16_be(c->out_s, d); /* session display */ out_uint16_be(c->out_s, d); /* session display */
out_uint8(c->out_s, ds->type); /*out_uint8(c->out_s, ds->type);
out_uint16_be(c->out_s, ds->height); out_uint16_be(c->out_s, ds->height);
out_uint16_be(c->out_s, ds->width); out_uint16_be(c->out_s, ds->width);
out_uint8(c->out_s, ds->bpp); out_uint8(c->out_s, ds->bpp);
out_uint8(c->out_s, ds->idle_days); out_uint8(c->out_s, ds->idle_days);
out_uint8(c->out_s, ds->idle_hours); out_uint8(c->out_s, ds->idle_hours);
out_uint8(c->out_s, ds->idle_minutes); out_uint8(c->out_s, ds->idle_minutes);*/
/* these last three are not really needed... */ /* these last three are not really needed... */
if (0!=tcp_force_send(c->in_sck, c->out_s->data, size)) if (0!=tcp_force_send(c->in_sck, c->out_s->data, size))
@ -446,19 +596,4 @@ scp_v1s_reconnect_session(struct SCP_CONNECTION* c, struct SCP_DISCONNECTED_SESS
return SCP_SERVER_STATE_OK; return SCP_SERVER_STATE_OK;
} }
/* 032 */
enum SCP_SERVER_STATES_E
scp_v1s_connection_error(struct SCP_CONNECTION* c, char* error)
{
return SCP_SERVER_STATE_INTERNAL_ERR;
return SCP_SERVER_STATE_END;
}
/* 040 */
enum SCP_SERVER_STATES_E
scp_v1s_list_sessions(struct SCP_CONNECTION* c, int sescnt, struct SCP_DISCONNECTED_SESSION* ds, SCP_SID* sid)
{
return SCP_SERVER_STATE_INTERNAL_ERR;
}
#endif #endif

@ -50,6 +50,7 @@ scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk);
* @brief denies connection to sesman * @brief denies connection to sesman
* @param c connection descriptor * @param c connection descriptor
* @param reason pointer to a string containinge the reason for denying connection * @param reason pointer to a string containinge the reason for denying connection
*
*/ */
/* 002 */ /* 002 */
enum SCP_SERVER_STATES_E enum SCP_SERVER_STATES_E
@ -70,18 +71,17 @@ scp_v1s_pwd_change_error(struct SCP_CONNECTION* c, char* error, int retry, char*
enum SCP_SERVER_STATES_E enum SCP_SERVER_STATES_E
scp_v1s_connect_new_session(struct SCP_CONNECTION* c, SCP_DISPLAY d); scp_v1s_connect_new_session(struct SCP_CONNECTION* c, SCP_DISPLAY d);
/* 031 */
enum SCP_SERVER_STATES_E
scp_v1s_reconnect_session(struct SCP_CONNECTION* c, struct SCP_DISCONNECTED_SESSION* ds,
SCP_DISPLAY d);
/* 032 */ /* 032 */
enum SCP_SERVER_STATES_E enum SCP_SERVER_STATES_E
scp_v1s_connection_error(struct SCP_CONNECTION* c, char* error); scp_v1s_connection_error(struct SCP_CONNECTION* c, char* error);
/* 040 */ /* 040 */
enum SCP_SERVER_STATES_E enum SCP_SERVER_STATES_E
scp_v1s_list_sessions(struct SCP_CONNECTION* c, int sescnt, struct SCP_DISCONNECTED_SESSION* ds, scp_v1s_list_sessions(struct SCP_CONNECTION* c, int sescnt,
SCP_SID* sid); struct SCP_DISCONNECTED_SESSION* ds, SCP_SID* sid);
/* 046 was: 031 struct SCP_DISCONNECTED_SESSION* ds, */
enum SCP_SERVER_STATES_E
scp_v1s_reconnect_session(struct SCP_CONNECTION* c, SCP_DISPLAY d);
#endif #endif

@ -32,6 +32,8 @@
extern struct config_sesman g_cfg; extern struct config_sesman g_cfg;
static void parseCommonStates(enum SCP_SERVER_STATES_E e, char* f);
/******************************************************************************/ /******************************************************************************/
void DEFAULT_CC void DEFAULT_CC
scp_v1_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s) scp_v1_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
@ -50,14 +52,13 @@ scp_v1_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
current_try = retries; current_try = retries;
data = auth_userpass(s->username, s->password); data = auth_userpass(s->username, s->password);
LOG_DBG("user: %s\npass: %s", s->username, s->password); /*LOG_DBG("user: %s\npass: %s", s->username, s->password);*/
while ((!data) && ((retries == 0) || (current_try > 0))) while ((!data) && ((retries == 0) || (current_try > 0)))
{ {
LOG_DBG("data %d - retry %d - currenttry %d - expr %d", data, retries, LOG_DBG("data %d - retry %d - currenttry %d - expr %d", data, retries, current_try, ((!data) && ((retries==0) || (current_try>0))));
current_try, ((!data) && ((retries == 0) || (current_try > 0))));
e = scp_v1s_request_password(c, s, "Wrong username and/or password"); e=scp_v1s_request_password(c,s,"Wrong username and/or password");
switch (e) switch (e)
{ {
@ -70,30 +71,12 @@ scp_v1_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
current_try--; current_try--;
} }
break; break;
case SCP_SERVER_STATE_VERSION_ERR:
LOG_DBG("version error", 0)
case SCP_SERVER_STATE_SIZE_ERR:
/* an unknown scp version was requested, so we shut down the */
/* connection (and log the fact) */
log_message(LOG_LEVEL_WARNING,
"protocol violation. connection closed.");
return;
case SCP_SERVER_STATE_NETWORK_ERR:
log_message(LOG_LEVEL_WARNING, "libscp network error.");
return;
case SCP_SERVER_STATE_SEQUENCE_ERR:
log_message(LOG_LEVEL_WARNING, "libscp sequence error.");
return;
case SCP_SERVER_STATE_INTERNAL_ERR:
/* internal error occurred (eg. malloc() error, ecc.) */
log_message(LOG_LEVEL_ERROR, "libscp internal error occurred.");
return;
default: default:
/* dummy: scp_v1s_request_password won't generate any other */ /* we check the other errors */
/* error other than the ones before */ parseCommonStates(e, "scp_v1s_list_sessions()");
log_message(LOG_LEVEL_ALWAYS, free_session(s);
"unknown return from scp_v1s_request_password()");
return; return;
//break;
} }
} }
@ -123,7 +106,6 @@ scp_v1_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
if (scount == 0) if (scount == 0)
{ {
#warning FIXME we should check for MaxSessions
/* no disconnected sessions - start a new one */ /* no disconnected sessions - start a new one */
log_message(LOG_LEVEL_INFO, "granted TS access to user %s", s->username); log_message(LOG_LEVEL_INFO, "granted TS access to user %s", s->username);
if (SCP_SESSION_TYPE_XVNC == s->type) if (SCP_SESSION_TYPE_XVNC == s->type)
@ -145,42 +127,48 @@ scp_v1_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
case SCP_SERVER_STATE_OK: case SCP_SERVER_STATE_OK:
/* all ok, we got new username and password */ /* all ok, we got new username and password */
break; break;
case SCP_SERVER_STATE_NETWORK_ERR:
log_message(LOG_LEVEL_WARNING, "libscp network error.");
return;
default: default:
return; /* we check the other errors */
parseCommonStates(e, "scp_v1s_connect_new_session()");
break;
} }
} }
else if (scount == 1) else
{ {
/* there's only one session - returning that */
sitem = session_get_bypid(slist->SID);
#warning FIXME session_get_by*() should return a malloc()ated struct #warning FIXME session_get_by*() should return a malloc()ated struct
#warning FIXME or at least lock the chain #warning FIXME or at least lock the chain
if (0 == sitem) /* one or more disconnected sessions - listing */
e = scp_v1s_list_sessions(c, scount, slist, &sid);
switch (e)
{ {
e = scp_v1s_connection_error(c, "Internal error"); /*case SCP_SERVER_STATE_FORCE_NEW:*/
/* we should check for MaxSessions */
case SCP_SERVER_STATE_SELECTION_CANCEL:
log_message(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_message(LOG_LEVEL_INFO, "Cannot find session item on the chain"); log_message(LOG_LEVEL_INFO, "Cannot find session item on the chain");
} }
else else
{ {
display = sitem->display; display=sitem->display;
e = scp_v1s_reconnect_session(c, slist, display); /*e=scp_v1s_reconnect_session(c, sitem, display);*/
log_message(LOG_LEVEL_INFO, e=scp_v1s_reconnect_session(c, display);
"User %s reconnected to session %d on port %d", log_message(LOG_LEVEL_INFO, "User %s reconnected to session %d on port %d", \
s->username, sitem->pid, display); s->username, sitem->pid, display);
} }
g_free(slist); break;
default:
/* we check the other errors */
parseCommonStates(e, "scp_v1s_list_sessions()");
break;
} }
else
{
/* 2 or more disconnected sessions - listing */
//max session x packet = 100 => pkt size = 1300 (13x100)
e = scp_v1s_list_sessions(c, scount, slist, &sid);
//CHECK RETURN
g_free(slist); g_free(slist);
} }
@ -195,3 +183,32 @@ scp_v1_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
auth_end(data); auth_end(data);
} }
static void parseCommonStates(enum SCP_SERVER_STATES_E e, char* f)
{
switch (e)
{
case SCP_SERVER_STATE_VERSION_ERR:
LOG_DBG("version error", 0)
case SCP_SERVER_STATE_SIZE_ERR:
/* an unknown scp version was requested, so we shut down the */
/* connection (and log the fact) */
log_message(LOG_LEVEL_WARNING,
"protocol violation. connection closed.");
break;
case SCP_SERVER_STATE_NETWORK_ERR:
log_message(LOG_LEVEL_WARNING, "libscp network error.");
break;
case SCP_SERVER_STATE_SEQUENCE_ERR:
log_message(LOG_LEVEL_WARNING, "libscp sequence error.");
break;
case SCP_SERVER_STATE_INTERNAL_ERR:
/* internal error occurred (eg. malloc() error, ecc.) */
log_message(LOG_LEVEL_ERROR, "libscp internal error occurred.");
break;
default:
/* dummy: scp_v1s_request_password won't generate any other */
/* error other than the ones before */
log_message(LOG_LEVEL_ALWAYS, "unknown return from %s", f);
break;
}
}

@ -6,8 +6,9 @@ SESTESTOBJ = sestest.o tcp.o \
DEFINES = -DLIBSCP_CLIENT DEFINES = -DLIBSCP_CLIENT
CFLAGS = -Wall -O2 -I../../common -I../ -I/usr/include/nptl $(DEFINES) CFLAGS = -Wall -O2 -I../../common -I../ -I/usr/include/nptl $(DEFINES)
LDFLAGS = -L /usr/gnu/lib -I/usr/include/nptl -L/usr/lib/nptl -lpthread -ldl $(DEFINES) #LDFLAGS = -L /usr/gnu/lib -I/usr/include/nptl -L/usr/lib/nptl -lpthread -ldl $(DEFINES)
C_OS_FLAGS = $(CFLAGS) -c LDFLAGS = -L /usr/gnu/lib -ldl $(DEFINES)
C_OS_FLAGS = $(CFLAGS) -c -g
CC = gcc CC = gcc
all: sestest all: sestest
@ -37,4 +38,4 @@ clean:
rm $(SESTESTOBJ) sestest rm $(SESTESTOBJ) sestest
install: install:
#install:wq #install

@ -14,8 +14,13 @@ int main(int argc, char** argv)
{ {
struct SCP_SESSION s; struct SCP_SESSION s;
struct SCP_CONNECTION c; struct SCP_CONNECTION c;
/*struct SCP_DISCONNECTED_SESSION ds;*/
struct SCP_DISCONNECTED_SESSION* dsl;
enum SCP_CLIENT_STATES_E e; enum SCP_CLIENT_STATES_E e;
int end; int end;
int scnt;
int idx;
int sel;
make_stream(c.in_s); make_stream(c.in_s);
init_stream(c.in_s, 8192); init_stream(c.in_s, 8192);
@ -68,11 +73,23 @@ int main(int argc, char** argv)
switch (e) switch (e)
{ {
case SCP_CLIENT_STATE_OK: case SCP_CLIENT_STATE_OK:
g_printf("OK : display is %d\n", (int)s.display); g_printf("OK : display is %d\n", (short int)s.display);
end=1; end=1;
break; break;
case SCP_CLIENT_STATE_SESSION_LIST: case SCP_CLIENT_STATE_SESSION_LIST:
g_printf("OK : session list needed\n"); g_printf("OK : session list needed\n");
e=scp_v1c_get_session_list(&c, &scnt, &dsl);
printf("Sessions: %d\n", scnt);
for (idx=0; idx <scnt; idx++)
{
printf("Session \t%d - %d - %dx%dx%d - %d %d %d\n", (dsl[idx]).SID, (dsl[idx]).type, (dsl[idx]).height, (dsl[idx]).width, (dsl[idx]).bpp, (dsl[idx]).idle_days, (dsl[idx]).idle_hours, (dsl[idx]).idle_minutes);
}
break;
case SCP_CLIENT_STATE_LIST_OK:
g_printf("OK : selecting a session:\n");
sel = menuSelect(scnt);
e=scp_v1c_select_session(&c, &s, dsl[sel-1].SID);
g_printf("\n return: %d \n", e);
break; break;
case SCP_CLIENT_STATE_RESEND_CREDENTIALS: case SCP_CLIENT_STATE_RESEND_CREDENTIALS:
g_printf("ERR: resend credentials - %s\n", s.errstr); g_printf("ERR: resend credentials - %s\n", s.errstr);
@ -89,6 +106,12 @@ int main(int argc, char** argv)
case SCP_CLIENT_STATE_PWD_CHANGE_REQ: case SCP_CLIENT_STATE_PWD_CHANGE_REQ:
g_printf("OK : password change required\n"); g_printf("OK : password change required\n");
break; break;
/*case SCP_CLIENT_STATE_RECONNECT_SINGLE:
g_printf("OK : reconnect to 1 disconnected session\n");
e=scp_v1c_retrieve_session(&c, &s, &ds);
g_printf("Session Type: %d on %d\n", ds.type, s.display);
g_printf("Session Screen: %dx%dx%d\n", ds.height, ds.width, ds.bpp);*/
break;
default: default:
g_printf("protocol error: %d\n", e); g_printf("protocol error: %d\n", e);
end=1; end=1;

Loading…
Cancel
Save