diff --git a/sesman/libscp/libscp_types.h b/sesman/libscp/libscp_types.h index 6b20f792..51a175eb 100644 --- a/sesman/libscp/libscp_types.h +++ b/sesman/libscp/libscp_types.h @@ -94,6 +94,11 @@ struct SCP_SESSION 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 diff --git a/sesman/libscp/libscp_v0.c b/sesman/libscp/libscp_v0.c index 9c609086..84206443 100644 --- a/sesman/libscp/libscp_v0.c +++ b/sesman/libscp/libscp_v0.c @@ -244,7 +244,7 @@ scp_v0s_init_session(struct trans *atrans, struct SCP_SESSION *session) if (!s_check_rem(in_s, 6)) { - return SCP_SERVER_STATE_INTERNAL_ERR; + return SCP_SERVER_STATE_SIZE_ERR; } in_uint8s(in_s, 4); /* size */ in_uint16_be(in_s, code); @@ -310,6 +310,7 @@ scp_v0s_init_session(struct trans *atrans, struct SCP_SESSION *session) { return SCP_SERVER_STATE_SIZE_ERR; } + if (buf[0] != '\0') { scp_session_set_domain(session, buf); diff --git a/sesman/libscp/libscp_v1s.c b/sesman/libscp/libscp_v1s.c index 9a21056a..6b0cb094 100644 --- a/sesman/libscp/libscp_v1s.c +++ b/sesman/libscp/libscp_v1s.c @@ -95,7 +95,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 +103,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 +117,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 +127,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 +139,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 +154,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 +188,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 +200,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 +215,19 @@ 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 SCP_SESSION *session; + struct stream *in_s = t->in_s; (*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 +237,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,7 +256,7 @@ 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) { @@ -303,7 +275,7 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION *c, struct SCP_SES } else { - result = scp_v1s_init_session(c, session); + result = scp_v1s_init_session(t, session); if (result != SCP_SERVER_STATE_OK) { scp_session_destroy(session); @@ -318,332 +290,105 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION *c, struct SCP_SES } enum SCP_SERVER_STATES_E -scp_v1s_accept_msg(struct trans *atrans, struct SCP_SESSION **s) -{ - struct SCP_SESSION *session; - tui32 size; - tui16 cmdset; - tui16 cmd; - tui8 sz; - char buf[257]; - struct stream *in_s; - - in_s = atrans->in_s; - - if (!s_check_rem(in_s, 6)) - { - return SCP_SERVER_STATE_INTERNAL_ERR; - } - - in_uint8s(in_s, 4); /* size */ - - /* reading command set */ - in_uint16_be(in_s, cmdset); - - /* if we are starting a management session */ - if (cmdset == SCP_COMMAND_SET_MANAGE) - { - log_message(LOG_LEVEL_DEBUG, "[v1s:%d] requested management connection", __LINE__); - /* should return SCP_SERVER_STATE_START_MANAGE */ - return scp_v1s_mng_accept_msg(atrans, s); - } - - /* if we started with resource sharing... */ - if (cmdset == SCP_COMMAND_SET_RSR) - { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); - return SCP_SERVER_STATE_SEQUENCE_ERR; - } - - if (!s_check_rem(in_s, 27)) - { - return SCP_SERVER_STATE_INTERNAL_ERR; - } - - /* reading command */ - in_uint16_be(in_s, cmd); - - if (cmd != 1) - { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); - return SCP_SERVER_STATE_SEQUENCE_ERR; - } - - session = scp_session_create(); - - if (0 == session) - { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error (malloc returned NULL)", __LINE__); - return SCP_SERVER_STATE_INTERNAL_ERR; - } - - scp_session_set_version(session, 1); - - in_uint8(in_s, sz); - - if ((sz != SCP_SESSION_TYPE_XVNC) && (sz != SCP_SESSION_TYPE_XRDP)) - { - scp_session_destroy(session); - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: unknown session type", __LINE__); - return SCP_SERVER_STATE_SESSION_TYPE_ERR; - } - - scp_session_set_type(session, sz); - - in_uint16_be(in_s, cmd); - scp_session_set_height(session, cmd); - in_uint16_be(in_s, cmd); - scp_session_set_width(session, cmd); - in_uint8(in_s, sz); - if (0 != scp_session_set_bpp(session, sz)) - { - scp_session_destroy(session); - log_message(LOG_LEVEL_WARNING, - "[v1s:%d] connection aborted: unsupported bpp: %d", - __LINE__, sz); - return SCP_SERVER_STATE_INTERNAL_ERR; - } - in_uint8(in_s, sz); - scp_session_set_rsr(session, sz); - in_uint8a(in_s, buf, 17); - buf[17] = '\0'; - scp_session_set_locale(session, buf); - - in_uint8(in_s, sz); - - if (sz == SCP_ADDRESS_TYPE_IPV4) - { - if (!s_check_rem(in_s, 4)) - { - return SCP_SERVER_STATE_INTERNAL_ERR; - } - in_uint32_be(in_s, size); - scp_session_set_addr(session, sz, &size); - } - else if (sz == SCP_ADDRESS_TYPE_IPV6) - { - if (!s_check_rem(in_s, 16)) - { - return SCP_SERVER_STATE_INTERNAL_ERR; - } - in_uint8a(in_s, buf, 16); - scp_session_set_addr(session, sz, buf); - } - - buf[256] = '\0'; - /* reading hostname */ - if (!s_check_rem(in_s, 1)) - { - return SCP_SERVER_STATE_INTERNAL_ERR; - } - in_uint8(in_s, sz); - if (!s_check_rem(in_s, sz)) - { - return SCP_SERVER_STATE_INTERNAL_ERR; - } - buf[sz] = '\0'; - in_uint8a(in_s, buf, sz); - - if (0 != scp_session_set_hostname(session, buf)) - { - scp_session_destroy(session); - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__); - return SCP_SERVER_STATE_INTERNAL_ERR; - } - - /* reading username */ - if (!s_check_rem(in_s, 1)) - { - return SCP_SERVER_STATE_INTERNAL_ERR; - } - in_uint8(in_s, sz); - if (!s_check_rem(in_s, sz)) - { - return SCP_SERVER_STATE_INTERNAL_ERR; - } - buf[sz] = '\0'; - in_uint8a(in_s, buf, sz); - - if (0 != scp_session_set_username(session, buf)) - { - scp_session_destroy(session); - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__); - return SCP_SERVER_STATE_INTERNAL_ERR; - } - - /* reading password */ - if (!s_check_rem(in_s, 1)) - { - return SCP_SERVER_STATE_INTERNAL_ERR; - } - in_uint8(in_s, sz); - if (!s_check_rem(in_s, sz)) - { - return SCP_SERVER_STATE_INTERNAL_ERR; - } - buf[sz] = '\0'; - in_uint8a(in_s, buf, sz); - - if (0 != scp_session_set_password(session, buf)) - { - scp_session_destroy(session); - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__); - return SCP_SERVER_STATE_INTERNAL_ERR; - } - - /* returning the struct */ - (*s) = session; - - return SCP_SERVER_STATE_OK; -} - -enum SCP_SERVER_STATES_E -scp_v1s_deny_connection(struct SCP_CONNECTION *c, const char *reason) +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, 2); + out_uint16_be(out_s, rlen); + out_uint8p(out_s, reason, rlen); + s_mark_end(out_s); + if (0 != trans_write_copy(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, 3); + out_uint16_be(out_s, rlen); + out_uint8p(out_s, reason, rlen); + s_mark_end(out_s); + if (0 != trans_write_copy(t)) { LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } + return SCP_SERVER_STATE_OK; +} - /* 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; - } +enum SCP_SERVER_STATES_E +scp_v1s_accept_password_reply(int cmd, struct trans *t) +{ + struct stream *in_s; + char buf[257]; + struct SCP_SESSION *s; - 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; - } - - 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; - } - - /* reading username */ - if (!in_string8(c->in_s, buf, "username", __LINE__)) - { - return SCP_SERVER_STATE_SIZE_ERR; - } - - if (0 != scp_session_set_username(s, buf)) + 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; + buf[256] = '\0'; + + /* reading username */ + 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__); + 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; } @@ -652,70 +397,71 @@ scp_v1s_request_password(struct SCP_CONNECTION *c, struct SCP_SESSION *s, /* 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, 30); + out_uint16_be(out_s, d); + s_mark_end(out_s); + if (0 != trans_write_copy(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_CMD_CONN_ERROR); + out_uint8a(out_s, error, len); + s_mark_end(out_s); + if (0 != trans_write_copy(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) { @@ -982,26 +728,176 @@ scp_v1s_list_sessions(struct SCP_CONNECTION *c, int sescnt, struct SCP_DISCONNEC return SCP_SERVER_STATE_OK; } +#endif + +enum SCP_SERVER_STATES_E +scp_v1s_list_sessions40(struct trans *t) +{ + 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, 40); /* cmd */ + s_mark_end(out_s); + if (0 != trans_write_copy(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, 42); + + /* 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_write_copy(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 41: + break; + case 43: + in_uint32_be(in_s, s->return_sid); + break; + case 44: + break; + case 45: + break; + default: + break; + } + 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) +scp_v1s_reconnect_session(struct trans *t, SCP_DISPLAY d) { - tui32 version = 1; - tui32 size = 14; - tui16 cmd = 46; + 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, 46); /* 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); @@ -1011,7 +907,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_write_copy(t)) { LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; diff --git a/sesman/libscp/libscp_v1s.h b/sesman/libscp/libscp_v1s.h index db7ef11a..ed0cecf3 100644 --- a/sesman/libscp/libscp_v1s.h +++ b/sesman/libscp/libscp_v1s.h @@ -30,20 +30,6 @@ #include "libscp.h" /* server API */ -/** - * - * @brief processes the stream using scp version 1 - * @param c connection descriptor - * @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); - /** * * @brief processes the stream using scp version 1 @@ -54,7 +40,7 @@ scp_v1s_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s, int skipVchk); * that should be free()d */ enum SCP_SERVER_STATES_E -scp_v1s_accept_msg(struct trans *atrans, struct SCP_SESSION **s); +scp_v1s_accept(struct trans *t, struct SCP_SESSION **s); /** * @@ -65,35 +51,47 @@ scp_v1s_accept_msg(struct trans *atrans, struct SCP_SESSION **s); */ /* 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(int cmd, struct trans *t); + +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 */ enum SCP_SERVER_STATES_E scp_v1s_list_sessions(struct SCP_CONNECTION *c, int sescnt, struct SCP_DISCONNECTED_SESSION *ds, SCP_SID *sid); +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 diff --git a/sesman/libscp/libscp_v1s_mng.c b/sesman/libscp/libscp_v1s_mng.c index 1f886af9..021273c0 100644 --- a/sesman/libscp/libscp_v1s_mng.c +++ b/sesman/libscp/libscp_v1s_mng.c @@ -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 * @@ -97,22 +98,24 @@ int in_string8(struct stream *s, char str[], const char *param, int line) * @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) +scp_v1s_mng_init_session(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; } @@ -185,7 +188,7 @@ scp_v1s_mng_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session) } 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) { enum SCP_SERVER_STATES_E result; struct SCP_SESSION *session; @@ -199,7 +202,7 @@ scp_v1s_mng_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s) { scp_session_set_type(session, SCP_SESSION_TYPE_MANAGE); - result = scp_v1s_mng_init_session(c, session); + result = scp_v1s_mng_init_session(atrans, session); if (result != SCP_SERVER_STATE_START_MANAGE) { scp_session_destroy(session); @@ -212,129 +215,6 @@ scp_v1s_mng_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s) return result; } -enum SCP_SERVER_STATES_E -scp_v1s_mng_accept_msg(struct trans *atrans, struct SCP_SESSION **s) -{ - struct SCP_SESSION *session; - tui32 ipaddr; - tui16 cmd; - tui8 sz; - char buf[257]; - struct stream *in_s; - - in_s = atrans->in_s; - - /* reading command */ - if (!s_check_rem(in_s, 2)) - { - return SCP_SERVER_STATE_INTERNAL_ERR; - } - in_uint16_be(in_s, cmd); - - if (cmd != 1) /* manager login */ - { - return SCP_SERVER_STATE_SEQUENCE_ERR; - } - - session = scp_session_create(); - - if (0 == session) - { - return SCP_SERVER_STATE_INTERNAL_ERR; - } - - scp_session_set_version(session, 1); - scp_session_set_type(session, SCP_SESSION_TYPE_MANAGE); - - /* reading username */ - if (!s_check_rem(in_s, 1)) - { - return SCP_SERVER_STATE_INTERNAL_ERR; - } - in_uint8(in_s, sz); - if (!s_check_rem(in_s, sz)) - { - return SCP_SERVER_STATE_INTERNAL_ERR; - } - buf[sz] = '\0'; - in_uint8a(in_s, buf, sz); - - if (0 != scp_session_set_username(session, buf)) - { - scp_session_destroy(session); - return SCP_SERVER_STATE_INTERNAL_ERR; - } - - /* reading password */ - if (!s_check_rem(in_s, 1)) - { - return SCP_SERVER_STATE_INTERNAL_ERR; - } - in_uint8(in_s, sz); - if (!s_check_rem(in_s, sz)) - { - return SCP_SERVER_STATE_INTERNAL_ERR; - } - buf[sz] = '\0'; - in_uint8a(in_s, buf, sz); - - if (0 != scp_session_set_password(session, buf)) - { - scp_session_destroy(session); - return SCP_SERVER_STATE_INTERNAL_ERR; - } - - /* reading remote address */ - if (!s_check_rem(in_s, 1)) - { - return SCP_SERVER_STATE_INTERNAL_ERR; - } - in_uint8(in_s, sz); - - if (sz == SCP_ADDRESS_TYPE_IPV4) - { - if (!s_check_rem(in_s, 4)) - { - return SCP_SERVER_STATE_INTERNAL_ERR; - } - in_uint32_be(in_s, ipaddr); - scp_session_set_addr(session, sz, &ipaddr); - } - else if (sz == SCP_ADDRESS_TYPE_IPV6) - { - if (!s_check_rem(in_s, 16)) - { - return SCP_SERVER_STATE_INTERNAL_ERR; - } - in_uint8a(in_s, buf, 16); - scp_session_set_addr(session, sz, buf); - } - - /* reading hostname */ - if (!s_check_rem(in_s, 1)) - { - return SCP_SERVER_STATE_INTERNAL_ERR; - } - in_uint8(in_s, sz); - if (!s_check_rem(in_s, sz)) - { - return SCP_SERVER_STATE_INTERNAL_ERR; - } - buf[sz] = '\0'; - in_uint8a(in_s, buf, sz); - - if (0 != scp_session_set_hostname(session, buf)) - { - scp_session_destroy(session); - return SCP_SERVER_STATE_INTERNAL_ERR; - } - - /* returning the struct */ - (*s) = session; - - return SCP_SERVER_STATE_START_MANAGE; -} - /* 002 */ enum SCP_SERVER_STATES_E scp_v1s_mng_allow_connection(struct SCP_CONNECTION *c, struct SCP_SESSION *s) diff --git a/sesman/libscp/libscp_v1s_mng.h b/sesman/libscp/libscp_v1s_mng.h index 2c805141..f8563d03 100644 --- a/sesman/libscp/libscp_v1s_mng.h +++ b/sesman/libscp/libscp_v1s_mng.h @@ -30,18 +30,6 @@ #include "libscp.h" /* server API */ -/** - * - * @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 - */ -enum SCP_SERVER_STATES_E -scp_v1s_mng_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s); - /** * * @brief processes the stream using scp version 1 @@ -52,7 +40,7 @@ scp_v1s_mng_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s); * that should be free()d */ enum SCP_SERVER_STATES_E -scp_v1s_mng_accept_msg(struct trans *atrans, struct SCP_SESSION **s); +scp_v1s_mng_accept(struct trans *atrans, struct SCP_SESSION **s); /** * diff --git a/sesman/libscp/libscp_vX.c b/sesman/libscp/libscp_vX.c index 815e4664..29156c0f 100644 --- a/sesman/libscp/libscp_vX.c +++ b/sesman/libscp/libscp_vX.c @@ -49,7 +49,7 @@ scp_vXs_accept(struct trans *atrans, struct SCP_SESSION **s) } else if (version == 1) { - return scp_v1s_accept_msg(atrans, s); + return scp_v1s_accept(atrans, s); } return SCP_SERVER_STATE_VERSION_ERR; } diff --git a/sesman/notes.txt b/sesman/notes.txt new file mode 100644 index 00000000..edb351ce --- /dev/null +++ b/sesman/notes.txt @@ -0,0 +1,58 @@ + + +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 + diff --git a/sesman/scp.c b/sesman/scp.c index 5c9c07ef..d5803d66 100644 --- a/sesman/scp.c +++ b/sesman/scp.c @@ -36,25 +36,25 @@ extern struct config_sesman *g_cfg; /* in sesman.c */ /******************************************************************************/ -int -scp_process(struct trans *atrans) +enum SCP_SERVER_STATES_E +scp_process(struct trans *t) { struct SCP_SESSION *sdata; sdata = NULL; - switch (scp_vXs_accept(atrans, &sdata)) + switch (scp_vXs_accept(t, &sdata)) { case SCP_SERVER_STATE_OK: if (sdata->version == 0) { /* starts processing an scp v0 connection */ LOG_DEVEL(LOG_LEVEL_DEBUG, "accept ok, go on with scp v0"); - scp_v0_process(atrans, sdata); + scp_v0_process(t, sdata); } else { LOG_DEVEL(LOG_LEVEL_DEBUG, "accept ok, go on with scp v1"); - scp_v1_process_msg(atrans, sdata); + scp_v1_process(t, sdata); } break; case SCP_SERVER_STATE_START_MANAGE: diff --git a/sesman/scp.h b/sesman/scp.h index 40c732f7..089a5183 100644 --- a/sesman/scp.h +++ b/sesman/scp.h @@ -39,7 +39,7 @@ * @param atrans the connection trans * */ -int -scp_process(struct trans *atrans); +enum SCP_SERVER_STATES_E +scp_process(struct trans *t); #endif diff --git a/sesman/scp_v0.c b/sesman/scp_v0.c index 9c2d1867..d040280e 100644 --- a/sesman/scp_v0.c +++ b/sesman/scp_v0.c @@ -33,8 +33,8 @@ extern struct config_sesman *g_cfg; /* in sesman.c */ /******************************************************************************/ -void -scp_v0_process(struct trans *atrans, 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,14 +53,14 @@ scp_v0_process(struct trans *atrans, struct SCP_SESSION *s) if (1 == access_login_allowed(s->username)) { /* the user is member of the correct groups. */ - scp_v0s_replyauthentication(atrans, 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(atrans, 32 + 3); /* all first 32 are reserved for PAM errors */ + 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 trans *atrans, 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(atrans, errorcode); + scp_v0s_replyauthentication(t, errorcode); } } else if (data) @@ -148,21 +148,22 @@ scp_v0_process(struct trans *atrans, struct SCP_SESSION *s) if (display == 0) { - scp_v0s_deny_connection(atrans); + scp_v0s_deny_connection(t); } else { - scp_v0s_allow_connection(atrans, 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(atrans); + scp_v0s_deny_connection(t); } if (do_auth_end) { auth_end(data); } + return SCP_SERVER_STATE_END; } diff --git a/sesman/scp_v0.h b/sesman/scp_v0.h index cc62da36..17d4a36e 100644 --- a/sesman/scp_v0.h +++ b/sesman/scp_v0.h @@ -29,7 +29,7 @@ #include "libscp.h" -void -scp_v0_process(struct trans *atrans, struct SCP_SESSION *s); +enum SCP_SERVER_STATES_E +scp_v0_process(struct trans *t, struct SCP_SESSION *s); #endif diff --git a/sesman/scp_v1.c b/sesman/scp_v1.c index d6327f18..36780442 100644 --- a/sesman/scp_v1.c +++ b/sesman/scp_v1.c @@ -35,79 +35,68 @@ 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; - + s->retries = g_cfg->sec.login_retry; + s->current_try = s->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 (data == 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) + if ((s->retries == 0) || (s->current_try > 0)) { - 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; + 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; + } } - } - - if (!data) - { - scp_v1s_deny_connection(c, "Login failed"); - LOG( LOG_LEVEL_INFO, - "Login failed for user %s. Connection terminated", s->username); - return; + else + { + scp_v1s_deny_connection(t, "Login failed"); + LOG(LOG_LEVEL_INFO, "Login failed for user %s. " + "Connection terminated", s->username); + return 1; + } + return 0; } /* 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 0; } //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,11 +106,13 @@ 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) @@ -142,7 +133,7 @@ scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *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 +147,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,16 +156,116 @@ scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s) auth_end(data); } g_free(slist); + return 0; } /******************************************************************************/ -void -scp_v1_process_msg(struct trans *atrans, struct SCP_SESSION *s) +static enum SCP_SERVER_STATES_E +scp_v1_process4(struct trans *t, struct SCP_SESSION *s) { - // JAY TODO + return 0; } -static void parseCommonStates(enum SCP_SERVER_STATES_E e, const char *f) +/******************************************************************************/ +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 1; + } + + e = scp_v1s_list_sessions42(t, scount, slist); + if (SCP_SERVER_STATE_OK != e) + { + LOG(LOG_LEVEL_ERROR, "scp_v1s_list_sessions42 failed"); + } + + return 0; +} + +/******************************************************************************/ +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, "Cannot find session item on the chain"); + } + 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) +{ + switch (s->current_cmd) + { + case 1: + return scp_v1_process1(t, s); + case 4: + return scp_v1_process4(t, s); + case 41: + return scp_v1_process41(t, s); + case 43: + return scp_v1_process43(t, s); + case 44: + return scp_v1_process44(t, s); + case 45: + 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) { diff --git a/sesman/scp_v1.h b/sesman/scp_v1.h index 972ce066..4c509cd3 100644 --- a/sesman/scp_v1.h +++ b/sesman/scp_v1.h @@ -35,10 +35,7 @@ * @param out_s output stream * */ -void -scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s); - -void -scp_v1_process_msg(struct trans *atrans, struct SCP_SESSION *s); +enum SCP_SERVER_STATES_E +scp_v1_process(struct trans *t, struct SCP_SESSION *s); #endif diff --git a/sesman/sesman.c b/sesman/sesman.c index d0929969..a0d2620c 100644 --- a/sesman/sesman.c +++ b/sesman/sesman.c @@ -197,7 +197,7 @@ sesman_close_all(void) int index; struct trans *con_trans; - log_message(LOG_LEVEL_DEBUG, "sesman_close_all:"); + LOG_DEVEL(LOG_LEVEL_TRACE, "sesman_close_all:"); trans_delete(g_list_trans); for (index = 0; index < g_con_list->count; index++) { @@ -220,7 +220,7 @@ sesman_data_in(struct trans *self) in_uint32_be(self->in_s, size); if (size > self->in_s->size) { - log_message(LOG_LEVEL_ERROR, "sesman_data_in: bad message size"); + LOG(LOG_LEVEL_ERROR, "sesman_data_in: bad message size"); return 1; } self->header_size = size; @@ -232,8 +232,7 @@ sesman_data_in(struct trans *self) self->in_s->p = self->in_s->data; if (scp_process(self) != 0) { - log_message(LOG_LEVEL_ERROR, "sesman_data_in: scp_process_msg " - "failed"); + LOG(LOG_LEVEL_ERROR, "sesman_data_in: scp_process_msg failed"); return 1; } /* reset for next message */ @@ -258,8 +257,8 @@ sesman_listen_conn_in(struct trans *self, struct trans *new_self) } else { - log_message(LOG_LEVEL_ERROR, "sesman_data_in: error, too many " - "connections, rejecting"); + LOG(LOG_LEVEL_ERROR, "sesman_data_in: error, too many " + "connections, rejecting"); trans_delete(new_self); } return 0; @@ -287,13 +286,13 @@ sesman_main_loop(void) g_con_list = list_create(); if (g_con_list == NULL) { - log_message(LOG_LEVEL_ERROR, "sesman_main_loop: list_create 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_message(LOG_LEVEL_ERROR, "sesman_main_loop: trans_create failed"); + LOG(LOG_LEVEL_ERROR, "sesman_main_loop: trans_create failed"); list_delete(g_con_list); return 1; } @@ -304,8 +303,8 @@ sesman_main_loop(void) g_cfg->listen_address); if (error != 0) { - log_message(LOG_LEVEL_ERROR, "sesman_main_loop: trans_listen_address " - "failed"); + LOG(LOG_LEVEL_ERROR, "sesman_main_loop: trans_listen_address " + "failed"); trans_delete(g_list_trans); list_delete(g_con_list); return 1; @@ -327,8 +326,8 @@ sesman_main_loop(void) wobjs, &wobjs_count, &timeout); if (error != 0) { - log_message(LOG_LEVEL_ERROR, "sesman_main_loop: " - "trans_get_wait_objs_rw failed"); + LOG(LOG_LEVEL_ERROR, "sesman_main_loop: " + "trans_get_wait_objs_rw failed"); break; } } @@ -341,8 +340,8 @@ sesman_main_loop(void) wobjs, &wobjs_count, &timeout); if (error != 0) { - log_message(LOG_LEVEL_ERROR, "sesman_main_loop: " - "trans_get_wait_objs_rw failed"); + LOG(LOG_LEVEL_ERROR, "sesman_main_loop: " + "trans_get_wait_objs_rw failed"); break; } @@ -366,8 +365,8 @@ sesman_main_loop(void) error = trans_check_wait_objs(con_trans); if (error != 0) { - log_message(LOG_LEVEL_ERROR, "sesman_main_loop: " - "trans_check_wait_objs failed, removing trans"); + LOG(LOG_LEVEL_ERROR, "sesman_main_loop: " + "trans_check_wait_objs failed, removing trans"); trans_delete(con_trans); list_remove_item(g_con_list, index); index--; @@ -378,8 +377,8 @@ sesman_main_loop(void) error = trans_check_wait_objs(g_list_trans); if (error != 0) { - log_message(LOG_LEVEL_ERROR, "sesman_main_loop: " - "trans_check_wait_objs failed"); + LOG(LOG_LEVEL_ERROR, "sesman_main_loop: " + "trans_check_wait_objs failed"); break; } }