/* 046 was: 031 struct SCP_DISCONNECTED_SESSION* ds, */ enum SCP_SERVER_STATES_E scp_v1s_reconnect_session(struct SCP_CONNECTION* c, SCP_DISPLAY d) { tui32 version = 1; tui32 size = 14; tui16 cmd = 46; /* ok, we send session data and display */ init_stream(c->out_s, c->out_s->size); /* 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); /* session data */ out_uint16_be(c->out_s, d); /* session display */ /*out_uint8(c->out_s, ds->type); out_uint16_be(c->out_s, ds->height); out_uint16_be(c->out_s, ds->width); out_uint8(c->out_s, ds->bpp); out_uint8(c->out_s, ds->idle_days); out_uint8(c->out_s, ds->idle_hours); 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)) { log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } return SCP_SERVER_STATE_OK; }
/* 003 */ enum SCP_SERVER_STATES_E scp_v1s_mng_deny_connection(struct SCP_CONNECTION *c, char *reason) { 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)*/ /* 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); if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, rlen + 14)) { return SCP_SERVER_STATE_NETWORK_ERR; } return SCP_SERVER_STATE_END; }
/* 004 */ enum SCP_CLIENT_STATES_E scp_v1c_resend_credentials(struct SCP_CONNECTION *c, 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); size = 12 + 2 + g_strlen(s->username) + g_strlen(s->password); /* 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); /* body */ sz = g_strlen(s->username); out_uint8(c->out_s, sz); out_uint8p(c->out_s, s->username, sz); sz = g_strlen(s->password); out_uint8(c->out_s, sz); out_uint8p(c->out_s, s->password, sz); if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size)) { return SCP_CLIENT_STATE_NETWORK_ERR; } /* wait for response */ return _scp_v1c_check_response(c, s); }
enum SCP_SERVER_STATES_E scp_v1s_deny_connection(struct SCP_CONNECTION* c, char* reason) { 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)*/ /* 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)) { log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } return SCP_SERVER_STATE_END; }
/* 030 */ enum SCP_SERVER_STATES_E scp_v1s_connect_new_session(struct SCP_CONNECTION* c, SCP_DISPLAY d) { /* send password request */ tui32 version=1; tui32 size=14; tui16 cmd=30; 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)) { log_message(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_v0s_deny_connection(struct SCP_CONNECTION *c) { 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); if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data)) { log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } LOG_DBG("[v0:%d] connection terminated (denied)", __LINE__); return SCP_SERVER_STATE_OK; }
enum SCP_SERVER_STATES_E scp_v0s_allow_connection(struct SCP_CONNECTION *c, SCP_DISPLAY d) { 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, 1); /* data */ out_uint16_be(c->out_s, d); /* data */ 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)) { log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } LOG_DBG("[v0:%d] connection terminated (allowed)", __LINE__); return SCP_SERVER_STATE_OK; }
/* 002 */ enum SCP_SERVER_STATES_E scp_v1s_mng_allow_connection(struct SCP_CONNECTION *c, struct SCP_SESSION *s) { init_stream(c->out_s, c->out_s->size); out_uint32_be(c->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); if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, 12)) { return SCP_SERVER_STATE_NETWORK_ERR; } return _scp_v1s_mng_check_response(c, s); }
enum SCP_SERVER_STATES_E scp_v0s_replyauthentication(struct SCP_CONNECTION *c, 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); /* 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)) { /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); */ return SCP_SERVER_STATE_NETWORK_ERR; } /* until syslog merge LOG_DBG(s_log, "[v0:%d] connection terminated (scp_v0s_deny_authentication)", __LINE__);*/ return SCP_SERVER_STATE_OK; }
/* 032 */ enum SCP_SERVER_STATES_E scp_v1s_connection_error(struct SCP_CONNECTION* c, char* error) { tui16 len; len = g_strlen(error); init_stream(c->out_s,c->out_s->size); out_uint32_be(c->out_s, 1); /* 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))) { return SCP_SERVER_STATE_NETWORK_ERR; } return SCP_SERVER_STATE_END; }
/* 001 */ enum SCP_CLIENT_STATES_E scp_v1c_mng_connect(struct SCP_CONNECTION *c, 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); size = 12 + 4 + g_strlen(s->hostname) + g_strlen(s->username) + g_strlen(s->password); if (s->addr_type == SCP_ADDRESS_TYPE_IPV4) { size = size + 4; } else { size = size + 16; } /* 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); /* data */ sz = g_strlen(s->username); out_uint8(c->out_s, sz); out_uint8p(c->out_s, s->username, sz); sz = g_strlen(s->password); out_uint8(c->out_s, sz); out_uint8p(c->out_s, s->password, sz); /* address */ out_uint8(c->out_s, s->addr_type); if (s->addr_type == SCP_ADDRESS_TYPE_IPV4) { out_uint32_be(c->out_s, s->ipv4addr); } else { out_uint8p(c->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); if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size)) { log_message(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); }
/* 004 */ enum SCP_CLIENT_STATES_E scp_v1c_mng_get_session_list(struct SCP_CONNECTION *c, int *scount, struct SCP_DISCONNECTED_SESSION **s) { tui32 version = 1; tui32 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 */ tui8 pktcnt = 0; /* packet session count */ tui32 totalcnt = 0; /* session counter */ tui8 continued = 0; /* continue flag */ int firstpkt = 1; /* "first packet" flag */ int idx; struct SCP_DISCONNECTED_SESSION *ds = 0; // tui8 addr[16]; 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_MANAGE); /* cmdset */ out_uint16_be(c->out_s, cmd); /* cmd */ if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size)) { log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__); return SCP_CLIENT_STATE_NETWORK_ERR; } do { /* then we wait for server response */ init_stream(c->in_s, c->in_s->size); if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) { log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__); return SCP_CLIENT_STATE_NETWORK_ERR; } in_uint32_be(c->in_s, version); if (version != 1) { log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: version error", __LINE__); return SCP_CLIENT_STATE_VERSION_ERR; } in_uint32_be(c->in_s, size); if (size < 12) { log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: size error", __LINE__); return SCP_CLIENT_STATE_SIZE_ERR; } init_stream(c->in_s, c->in_s->size); if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8)) { log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__); return SCP_CLIENT_STATE_NETWORK_ERR; } in_uint16_be(c->in_s, cmd); if (cmd != SCP_COMMAND_SET_MANAGE) { log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__); return SCP_CLIENT_STATE_SEQUENCE_ERR; } in_uint16_be(c->in_s, cmd); if (cmd != SCP_CMD_MNG_LIST) /* session list */ { log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__); return SCP_CLIENT_STATE_SEQUENCE_ERR; } if (firstpkt) { firstpkt = 0; in_uint32_be(c->in_s, sescnt); sestmp = sescnt; if (0 == sescnt) { /* return data... */ (*scount) = sescnt; (*s) = NULL; LOG_DBG("[v1c_mng] end list - no session on TS"); return SCP_CLIENT_STATE_LIST_OK; } ds = g_malloc(sizeof(struct SCP_DISCONNECTED_SESSION) * sescnt, 0); if (ds == 0) { log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: internal error", __LINE__); 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); 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); if ((ds[totalcnt]).addr_type == SCP_ADDRESS_TYPE_IPV4) { in_uint32_be(c->in_s, (ds[totalcnt]).ipv4addr); } if ((ds[totalcnt]).addr_type == SCP_ADDRESS_TYPE_IPV6) { in_uint8a(c->in_s, (ds[totalcnt]).ipv6addr, 16); } totalcnt++; } } while (continued); /* return data... */ (*scount) = sescnt; (*s) = ds; LOG_DBG("[v1c_mng] end list"); return SCP_CLIENT_STATE_LIST_OK; }
/* 001 */ enum SCP_CLIENT_STATES_E scp_v1c_connect(struct SCP_CONNECTION *c, 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); size = 19 + 17 + 4 + g_strlen(s->hostname) + g_strlen(s->username) + g_strlen(s->password); if (s->addr_type == SCP_ADDRESS_TYPE_IPV4) { size = size + 4; } else { size = size + 16; } /* 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); /* 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); if (s->addr_type == SCP_ADDRESS_TYPE_IPV4) { out_uint32_be(c->out_s, s->ipv4addr); } else if (s->addr_type == SCP_ADDRESS_TYPE_IPV6) { out_uint8p(c->out_s, s->ipv6addr, 16); } sz = g_strlen(s->hostname); out_uint8(c->out_s, sz); out_uint8p(c->out_s, s->hostname, sz); sz = g_strlen(s->username); out_uint8(c->out_s, sz); out_uint8p(c->out_s, s->username, sz); sz = g_strlen(s->password); out_uint8(c->out_s, sz); out_uint8p(c->out_s, s->password, sz); if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size)) { return SCP_CLIENT_STATE_NETWORK_ERR; } /* wait for response */ return _scp_v1c_check_response(c, s); }
/* 041 */ enum SCP_CLIENT_STATES_E scp_v1c_get_session_list(struct SCP_CONNECTION *c, int *scount, struct SCP_DISCONNECTED_SESSION **s) { tui32 version = 1; tui32 size = 12; tui16 cmd = 41; tui32 sescnt = 0; /* total session number */ tui32 sestmp = 0; /* additional total session number */ tui8 pktcnt = 0; /* packet session count */ tui32 totalcnt = 0; /* session counter */ tui8 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 != scp_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 != scp_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 != scp_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_new(struct SCP_DISCONNECTED_SESSION, sescnt); 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); 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); if ((ds[totalcnt]).addr_type == SCP_ADDRESS_TYPE_IPV4) { in_uint32_be(c->in_s, (ds[totalcnt]).ipv4addr); } else if ((ds[totalcnt]).addr_type == SCP_ADDRESS_TYPE_IPV6) { in_uint8a(c->in_s, (ds[totalcnt]).ipv6addr, 16); } totalcnt++; } }
/* 006 */ enum SCP_SERVER_STATES_E scp_v1s_mng_list_sessions(struct SCP_CONNECTION *c, struct SCP_SESSION *s, int sescnt, struct SCP_DISCONNECTED_SESSION *ds) { tui32 version = 1; tui32 size = 12; tui16 cmd = SCP_CMD_MNG_LIST; int pktcnt; int idx; int sidx; int pidx; 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++) { /* ok, we send session session list */ init_stream(c->out_s, c->out_s->size); /* 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); /* 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 += 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); size += 7; if (cds->addr_type == SCP_ADDRESS_TYPE_IPV4) { in_uint32_be(c->out_s, cds->ipv4addr); size += 4; } else if (cds->addr_type == SCP_ADDRESS_TYPE_IPV6) { in_uint8a(c->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); if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size)) { log_message(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); }
enum SCP_CLIENT_STATES_E scp_v0c_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s) { tui32 version; tui32 size; tui16 sz; init_stream(c->in_s, c->in_s->size); init_stream(c->out_s, c->in_s->size); LOG_DBG("[v0:%d] starting connection", __LINE__); g_tcp_set_non_blocking(c->in_sck); g_tcp_set_no_delay(c->in_sck); s_push_layer(c->out_s, channel_hdr, 8); /* code */ if (s->type == SCP_SESSION_TYPE_XVNC) { out_uint16_be(c->out_s, 0); } else if (s->type == SCP_SESSION_TYPE_XRDP) { out_uint16_be(c->out_s, 10); } else if (s->type == SCP_SESSION_TYPE_XORG) { out_uint16_be(c->out_s, 20); } else { log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); return SCP_CLIENT_STATE_INTERNAL_ERR; } sz = g_strlen(s->username); out_uint16_be(c->out_s, sz); out_uint8a(c->out_s, s->username, sz); sz = g_strlen(s->password); out_uint16_be(c->out_s, sz); out_uint8a(c->out_s, s->password, sz); out_uint16_be(c->out_s, s->width); out_uint16_be(c->out_s, s->height); out_uint16_be(c->out_s, s->bpp); s_mark_end(c->out_s); s_pop_layer(c->out_s, channel_hdr); /* version */ out_uint32_be(c->out_s, 0); /* size */ out_uint32_be(c->out_s, 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)) { log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); return SCP_CLIENT_STATE_NETWORK_ERR; } if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) { log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); return SCP_CLIENT_STATE_NETWORK_ERR; } in_uint32_be(c->in_s, version); if (0 != version) { log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: version error", __LINE__); return SCP_CLIENT_STATE_VERSION_ERR; } in_uint32_be(c->in_s, size); if (size < 14) { log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: packet size error", __LINE__); return SCP_CLIENT_STATE_SIZE_ERR; } /* getting payload */ init_stream(c->in_s, c->in_s->size); if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8)) { log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); return SCP_CLIENT_STATE_NETWORK_ERR; } /* check code */ in_uint16_be(c->in_s, sz); if (3 != sz) { log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: sequence error", __LINE__); return SCP_CLIENT_STATE_SEQUENCE_ERR; } /* message payload */ in_uint16_be(c->in_s, sz); if (1 != sz) { log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: connection denied", __LINE__); return SCP_CLIENT_STATE_CONNECTION_DENIED; } in_uint16_be(c->in_s, sz); s->display = sz; LOG_DBG("[v0:%d] connection terminated", __LINE__); return SCP_CLIENT_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) { tui32 version=1; tui32 size=12; tui16 cmd=40; int pktcnt; int idx; 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); 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!=scp_tcp_force_send(c->in_sck, c->out_s->data, size)) { log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } /* then we wait for client ack */ #warning maybe this message could say if the session should be resized on #warning server side or client side init_stream(c->in_s, c->in_s->size); if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) { log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } in_uint32_be(c->in_s, version); if (version!=1) { log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__); return SCP_SERVER_STATE_VERSION_ERR; } in_uint32_be(c->in_s, size); if (size<12) { log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__); return SCP_SERVER_STATE_SIZE_ERR; } init_stream(c->in_s, c->in_s->size); if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, (size-8))) { log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } in_uint16_be(c->in_s, cmd); if (cmd != SCP_COMMAND_SET_DEFAULT) { log_message(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 != 41) { log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); return SCP_SERVER_STATE_SEQUENCE_ERR; } /* 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); /* size: ver+size+cmdset+cmd+sescnt+continue+count */ size=4+4+2+2+4+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 += 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); size += 7; if (cds->addr_type == SCP_ADDRESS_TYPE_IPV4) { in_uint32_be(c->out_s, cds->ipv4addr); size += 4; } else if (cds->addr_type == SCP_ADDRESS_TYPE_IPV6) { in_uint8a(c->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); if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size)) { log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } } /* we get the response */ init_stream(c->in_s, c->in_s->size); if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, (8))) { log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } in_uint32_be(c->in_s, version); if (version != 1) { log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__); return SCP_SERVER_STATE_VERSION_ERR; } in_uint32_be(c->in_s, size); if (size < 12) { log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__); return SCP_SERVER_STATE_SIZE_ERR; } /* rest of the packet */ init_stream(c->in_s, c->in_s->size); if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, (size-8))) { log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } in_uint16_be(c->in_s, cmd); if (cmd != SCP_COMMAND_SET_DEFAULT) { log_message(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 == 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 */ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error (no such session in list)", __LINE__); 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 */ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); return SCP_SERVER_STATE_SEQUENCE_ERR; } return SCP_SERVER_STATE_OK; }
enum SCP_SERVER_STATES_E scp_v1s_request_password(struct SCP_CONNECTION* c, struct SCP_SESSION* s, char* reason) { tui8 sz; tui32 version; tui32 size; tui16 cmdset; tui16 cmd; int rlen; char buf[257]; 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)) { log_message(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_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } in_uint32_be(c->in_s, version); if (version!=1) { log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__); return SCP_SERVER_STATE_VERSION_ERR; } in_uint32_be(c->in_s, size); if (size<12) { log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__); return SCP_SERVER_STATE_SIZE_ERR; } init_stream(c->in_s, c->in_s->size); if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, (size-8))) { log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } in_uint16_be(c->in_s, cmdset); if (cmdset != SCP_COMMAND_SET_DEFAULT) { log_message(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_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); return SCP_SERVER_STATE_SEQUENCE_ERR; } buf[256] = '\0'; /* reading username */ in_uint8(c->in_s, sz); buf[sz] = '\0'; in_uint8a(c->in_s, buf, sz); if (0 != scp_session_set_username(s, buf)) { scp_session_destroy(s); log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__); return SCP_SERVER_STATE_INTERNAL_ERR; } /* reading password */ in_uint8(c->in_s, sz); buf[sz]='\0'; in_uint8a(c->in_s, buf, sz); if (0 != scp_session_set_password(s, buf)) { scp_session_destroy(s); log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__); return SCP_SERVER_STATE_INTERNAL_ERR; } return SCP_SERVER_STATE_OK; }