diff --git a/sesman/libscp/libscp_session.c b/sesman/libscp/libscp_session.c index 99629f31..baace5d1 100644 --- a/sesman/libscp/libscp_session.c +++ b/sesman/libscp/libscp_session.c @@ -78,14 +78,6 @@ scp_session_set_type(struct SCP_SESSION *s, tui8 type) case SCP_SESSION_TYPE_MANAGE: s->type = SCP_SESSION_TYPE_MANAGE; - s->mng = (struct SCP_MNG_DATA *)g_malloc(sizeof(struct SCP_MNG_DATA), 1); - - if (NULL == s->mng) - { - LOG(LOG_LEVEL_ERROR, "[session:%d] set_type: internal error", __LINE__); - return 1; - } - break; default: @@ -439,14 +431,55 @@ scp_session_set_guid(struct SCP_SESSION *s, const tui8 *guid) void scp_session_destroy(struct SCP_SESSION *s) { - g_free(s->username); - g_free(s->password); - g_free(s->hostname); - g_free(s->domain); - g_free(s->program); - g_free(s->directory); - g_free(s->client_ip); - g_free(s->errstr); - g_free(s->mng); - g_free(s); + if (s != NULL) + { + g_free(s->username); + g_free(s->password); + g_free(s->hostname); + g_free(s->domain); + g_free(s->program); + g_free(s->directory); + g_free(s->client_ip); + g_free(s->errstr); + g_free(s); + } +} + +/*******************************************************************/ +struct SCP_SESSION * +scp_session_clone(const struct SCP_SESSION *s) +{ + struct SCP_SESSION *result = NULL; + + if (s != NULL && (result = g_new(struct SCP_SESSION, 1)) != NULL) + { + /* Duplicate all the scalar variables */ + g_memcpy(result, s, sizeof(*s)); + + /* Now duplicate all the strings */ + result->username = g_strdup(s->username); + result->password = g_strdup(s->password); + result->hostname = g_strdup(s->hostname); + result->errstr = g_strdup(s->errstr); + result->domain = g_strdup(s->domain); + result->program = g_strdup(s->program); + result->directory = g_strdup(s->directory); + result->client_ip = g_strdup(s->client_ip); + + /* Did all the string copies succeed? */ + if ((s->username != NULL && result->username == NULL) || + (s->password != NULL && result->password == NULL) || + (s->hostname != NULL && result->hostname == NULL) || + (s->errstr != NULL && result->errstr == NULL) || + (s->domain != NULL && result->domain == NULL) || + (s->program != NULL && result->program == NULL) || + (s->directory != NULL && result->directory == NULL) || + (s->client_ip != NULL && result->client_ip == NULL)) + { + scp_session_destroy(result); + result = NULL; + } + } + + return result; } diff --git a/sesman/libscp/libscp_session.h b/sesman/libscp/libscp_session.h index b702f1cc..227f34e5 100644 --- a/sesman/libscp/libscp_session.h +++ b/sesman/libscp/libscp_session.h @@ -40,6 +40,14 @@ struct SCP_SESSION * scp_session_create(void); +/* + * Makes a copy of a struct SCP_SESSION object + * @param s Object to clone + * @return a copy of s, or NULL if no memory + */ +struct SCP_SESSION * +scp_session_clone(const struct SCP_SESSION *s); + int scp_session_set_type(struct SCP_SESSION *s, tui8 type); diff --git a/sesman/libscp/libscp_types.h b/sesman/libscp/libscp_types.h index 41fbc640..fcfbfa51 100644 --- a/sesman/libscp/libscp_types.h +++ b/sesman/libscp/libscp_types.h @@ -81,7 +81,6 @@ struct SCP_SESSION tui8 ipv6addr[16]; SCP_DISPLAY display; char *errstr; - struct SCP_MNG_DATA *mng; char *domain; char *program; char *directory; diff --git a/sesman/libscp/libscp_v0.c b/sesman/libscp/libscp_v0.c index 84206443..e996e52c 100644 --- a/sesman/libscp/libscp_v0.c +++ b/sesman/libscp/libscp_v0.c @@ -230,8 +230,8 @@ scp_v0c_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s) * @param [out] session pre-allocated session object * @return SCP_SERVER_STATE_OK for success */ -static enum SCP_SERVER_STATES_E -scp_v0s_init_session(struct trans *atrans, struct SCP_SESSION *session) +enum SCP_SERVER_STATES_E +scp_v0s_accept(struct trans *atrans, struct SCP_SESSION *session) { tui16 height; tui16 width; @@ -239,7 +239,7 @@ scp_v0s_init_session(struct trans *atrans, struct SCP_SESSION *session) tui32 code = 0; char buf[STRING16_MAX_LEN + 1]; struct stream *in_s = atrans->in_s; - + int session_type = -1; scp_session_set_version(session, 0); if (!s_check_rem(in_s, 6)) @@ -252,16 +252,17 @@ scp_v0s_init_session(struct trans *atrans, struct SCP_SESSION *session) { if (code == 0) { - scp_session_set_type(session, SCP_SESSION_TYPE_XVNC); + session_type = SCP_SESSION_TYPE_XVNC; } else if (code == 10) { - scp_session_set_type(session, SCP_SESSION_TYPE_XRDP); + session_type = SCP_SESSION_TYPE_XRDP; } - else if (code == 20) + else { - scp_session_set_type(session, SCP_SESSION_TYPE_XORG); + session_type = SCP_SESSION_TYPE_XORG; } + scp_session_set_type(session, session_type); /* reading username */ if (!in_string16(in_s, buf, "username")) @@ -296,6 +297,12 @@ scp_v0s_init_session(struct trans *atrans, struct SCP_SESSION *session) in_uint16_be(in_s, height); scp_session_set_height(session, height); in_uint16_be(in_s, bpp); + if (session_type == SCP_SESSION_TYPE_XORG && bpp != 24) + { + LOG(LOG_LEVEL_WARNING, + "Setting bpp to 24 from %d for Xorg session", bpp); + bpp = 24; + } if (0 != scp_session_set_bpp(session, (tui8)bpp)) { LOG(LOG_LEVEL_WARNING, @@ -394,36 +401,6 @@ scp_v0s_init_session(struct trans *atrans, struct SCP_SESSION *session) return SCP_SERVER_STATE_OK; } - -/* server API */ -/******************************************************************************/ -enum SCP_SERVER_STATES_E -scp_v0s_accept(struct trans *atrans, struct SCP_SESSION **s) -{ - enum SCP_SERVER_STATES_E result = SCP_SERVER_STATE_OK; - - struct SCP_SESSION *session = scp_session_create(); - if (NULL == session) - { - LOG(LOG_LEVEL_ERROR, "SCPV0 connection aborted: network error"); - result = SCP_SERVER_STATE_INTERNAL_ERR; - } - else - { - result = scp_v0s_init_session(atrans, session); - if (result != SCP_SERVER_STATE_OK) - { - scp_session_destroy(session); - session = NULL; - } - } - - (*s) = session; - - return result; -} - - /******************************************************************************/ enum SCP_SERVER_STATES_E scp_v0s_allow_connection(struct trans *atrans, SCP_DISPLAY d, const tui8 *guid) diff --git a/sesman/libscp/libscp_v0.h b/sesman/libscp/libscp_v0.h index 0048ae43..946af06f 100644 --- a/sesman/libscp/libscp_v0.h +++ b/sesman/libscp/libscp_v0.h @@ -54,7 +54,7 @@ scp_v0c_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s); * */ enum SCP_SERVER_STATES_E -scp_v0s_accept(struct trans *atrans, struct SCP_SESSION **s); +scp_v0s_accept(struct trans *atrans, struct SCP_SESSION *s); /** * diff --git a/sesman/libscp/libscp_v1c_mng.c b/sesman/libscp/libscp_v1c_mng.c index 12efe846..a120237e 100644 --- a/sesman/libscp/libscp_v1c_mng.c +++ b/sesman/libscp/libscp_v1c_mng.c @@ -95,6 +95,7 @@ scp_v1c_mng_connect(struct trans *t, struct SCP_SESSION *s) sz = g_strlen(s->hostname); out_uint8(out_s, sz); out_uint8p(out_s, s->hostname, sz); + s_mark_end(out_s); if (0 != trans_force_write(t)) { diff --git a/sesman/libscp/libscp_v1s.c b/sesman/libscp/libscp_v1s.c index 6b0cb094..8445445d 100644 --- a/sesman/libscp/libscp_v1s.c +++ b/sesman/libscp/libscp_v1s.c @@ -83,7 +83,6 @@ int in_string8(struct stream *s, char str[], const char *param, int line) } return result; } -/* server API */ /** * Initialises a V1 session object @@ -216,16 +215,13 @@ scp_v1s_init_session(struct trans *t, struct SCP_SESSION *session) /* server API */ enum SCP_SERVER_STATES_E -scp_v1s_accept(struct trans *t, struct SCP_SESSION **s) +scp_v1s_accept(struct trans *t, struct SCP_SESSION *s) { - enum SCP_SERVER_STATES_E result; tui32 size; tui16 cmdset; tui16 cmd; - struct SCP_SESSION *session; struct stream *in_s = t->in_s; - - (*s) = NULL; + enum SCP_SERVER_STATES_E result; in_uint32_be(in_s, size); @@ -258,33 +254,23 @@ scp_v1s_accept(struct trans *t, struct SCP_SESSION **s) /* reading command */ in_uint16_be(in_s, cmd); - if (cmd != 1) + switch (cmd) { - LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); - return SCP_SERVER_STATE_SEQUENCE_ERR; - } + case 1: + s->current_cmd = cmd; + result = scp_v1s_init_session(t, s); + break; - session = scp_session_create(); + case 4: + result = scp_v1s_accept_password_reply(t, s); + s->current_cmd = 1; /* Caller re-parses credentials */ + break; - if (NULL == session) - { - LOG(LOG_LEVEL_WARNING, - "[v1s:%d] connection aborted: internal error " - "(malloc returned NULL)", __LINE__); - result = SCP_SERVER_STATE_INTERNAL_ERR; + default: + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence " + "error. Unrecognised cmd %d", __LINE__, cmd); + result = SCP_SERVER_STATE_SEQUENCE_ERR; } - else - { - result = scp_v1s_init_session(t, session); - if (result != SCP_SERVER_STATE_OK) - { - scp_session_destroy(session); - session = NULL; - } - } - - /* returning the struct */ - (*s) = session; return result; } @@ -311,7 +297,7 @@ scp_v1s_deny_connection(struct trans *t, const char *reason) out_uint16_be(out_s, rlen); out_uint8p(out_s, reason, rlen); s_mark_end(out_s); - if (0 != trans_write_copy(t)) + if (0 != trans_force_write(t)) { LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; @@ -342,28 +328,21 @@ scp_v1s_request_password(struct trans *t, struct SCP_SESSION *s, out_uint16_be(out_s, rlen); out_uint8p(out_s, reason, rlen); s_mark_end(out_s); - if (0 != trans_write_copy(t)) + if (0 != trans_force_write(t)) { LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } + return SCP_SERVER_STATE_OK; } enum SCP_SERVER_STATES_E -scp_v1s_accept_password_reply(int cmd, struct trans *t) +scp_v1s_accept_password_reply(struct trans *t, struct SCP_SESSION *s) { struct stream *in_s; char buf[257]; - struct SCP_SESSION *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; buf[256] = '\0'; @@ -424,7 +403,7 @@ scp_v1s_connect_new_session(struct trans *t, SCP_DISPLAY d) out_uint16_be(out_s, 30); out_uint16_be(out_s, d); s_mark_end(out_s); - if (0 != trans_write_copy(t)) + if (0 != trans_force_write(t)) { LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; @@ -453,7 +432,7 @@ scp_v1s_connection_error(struct trans *t, const char *error) 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)) + if (0 != trans_force_write(t)) { return SCP_SERVER_STATE_NETWORK_ERR; } @@ -742,7 +721,7 @@ scp_v1s_list_sessions40(struct trans *t) 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)) + if (0 != trans_force_write(t)) { LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; @@ -840,7 +819,7 @@ scp_v1s_list_sessions42(struct trans *t, int sescnt, struct SCP_DISCONNECTED_SES out_uint32_be(out_s, 1); /* version */ out_uint32_be(out_s, size); - if (0 != trans_write_copy(t)) + if (0 != trans_force_write(t)) { LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; @@ -907,7 +886,7 @@ scp_v1s_reconnect_session(struct trans *t, SCP_DISPLAY d) out_uint8(c->out_s, ds->idle_minutes);*/ /* these last three are not really needed... */ - if (0 != trans_write_copy(t)) + if (0 != trans_force_write(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 30e56203..f9efefa5 100644 --- a/sesman/libscp/libscp_v1s.h +++ b/sesman/libscp/libscp_v1s.h @@ -40,7 +40,7 @@ * that should be free()d */ enum SCP_SERVER_STATES_E -scp_v1s_accept(struct trans *t, struct SCP_SESSION **s); +scp_v1s_accept(struct trans *t, struct SCP_SESSION *s); /** * @@ -58,7 +58,7 @@ 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); +scp_v1s_accept_password_reply(struct trans *t, struct SCP_SESSION *s); enum SCP_SERVER_STATES_E scp_v1s_accept_list_sessions_reply(int cmd, struct trans *t); diff --git a/sesman/libscp/libscp_v1s_mng.c b/sesman/libscp/libscp_v1s_mng.c index a5ae4398..5469cde3 100644 --- a/sesman/libscp/libscp_v1s_mng.c +++ b/sesman/libscp/libscp_v1s_mng.c @@ -97,8 +97,8 @@ int in_string8(struct stream *s, char str[], const char *param, int line) * @param [out] session pre-allocated session object * @return SCP_SERVER_STATE_START_MANAGE for success */ -static enum SCP_SERVER_STATES_E -scp_v1s_mng_init_session(struct trans *atrans, struct SCP_SESSION *session) +enum SCP_SERVER_STATES_E +scp_v1s_mng_accept(struct trans *atrans, struct SCP_SESSION *session) { tui32 ipaddr; tui16 cmd; @@ -187,34 +187,6 @@ scp_v1s_mng_init_session(struct trans *atrans, struct SCP_SESSION *session) return SCP_SERVER_STATE_START_MANAGE; } -enum SCP_SERVER_STATES_E -scp_v1s_mng_accept(struct trans *atrans, struct SCP_SESSION **s) -{ - enum SCP_SERVER_STATES_E result; - struct SCP_SESSION *session; - - session = scp_session_create(); - if (NULL == session) - { - result = SCP_SERVER_STATE_INTERNAL_ERR; - } - else - { - scp_session_set_type(session, SCP_SESSION_TYPE_MANAGE); - - result = scp_v1s_mng_init_session(atrans, session); - if (result != SCP_SERVER_STATE_START_MANAGE) - { - scp_session_destroy(session); - session = NULL; - } - } - - (*s) = session; - - return result; -} - /* 002 */ enum SCP_SERVER_STATES_E scp_v1s_mng_allow_connection(struct trans *t, struct SCP_SESSION *s) @@ -230,7 +202,7 @@ scp_v1s_mng_allow_connection(struct trans *t, struct SCP_SESSION *s) out_uint16_be(out_s, SCP_CMD_MNG_LOGIN_ALLOW); s_mark_end(out_s); - if (0 != trans_write_copy(t)) + if (0 != trans_force_write(t)) { return SCP_SERVER_STATE_NETWORK_ERR; } @@ -266,7 +238,7 @@ scp_v1s_mng_deny_connection(struct trans *t, const char *reason) out_uint8p(out_s, reason, rlen); s_mark_end(out_s); - if (0 != trans_write_copy(t)) + if (0 != trans_force_write(t)) { return SCP_SERVER_STATE_NETWORK_ERR; } @@ -364,12 +336,12 @@ scp_v1s_mng_list_sessions(struct trans *t, struct SCP_SESSION *s, if (cds->addr_type == SCP_ADDRESS_TYPE_IPV4) { - in_uint32_be(out_s, cds->ipv4addr); + out_uint32_be(out_s, cds->ipv4addr); size += 4; } else if (cds->addr_type == SCP_ADDRESS_TYPE_IPV6) { - in_uint8a(out_s, cds->ipv6addr, 16); + out_uint8a(out_s, cds->ipv6addr, 16); size += 16; } } diff --git a/sesman/libscp/libscp_v1s_mng.h b/sesman/libscp/libscp_v1s_mng.h index 6f9483c0..f6e884c6 100644 --- a/sesman/libscp/libscp_v1s_mng.h +++ b/sesman/libscp/libscp_v1s_mng.h @@ -34,13 +34,10 @@ * * @brief processes the stream using scp version 1 * @param atrans connection descriptor - * @param s pointer to session descriptor pointer - * - * this function places in *s the address of a newly allocated SCP_SESSION structure - * that should be free()d + * @param s session descriptor pointer */ enum SCP_SERVER_STATES_E -scp_v1s_mng_accept(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 29156c0f..d643cc18 100644 --- a/sesman/libscp/libscp_vX.c +++ b/sesman/libscp/libscp_vX.c @@ -32,7 +32,7 @@ /******************************************************************************/ enum SCP_SERVER_STATES_E -scp_vXs_accept(struct trans *atrans, struct SCP_SESSION **s) +scp_vXs_accept(struct trans *atrans, struct SCP_SESSION *s) { struct stream *in_s; int version; diff --git a/sesman/libscp/libscp_vX.h b/sesman/libscp/libscp_vX.h index 6c7e8170..47fb99cc 100644 --- a/sesman/libscp/libscp_vX.h +++ b/sesman/libscp/libscp_vX.h @@ -37,12 +37,10 @@ * * @brief version neutral server accept function * @param atrans connection trans - * @param s session descriptor pointer address. - * it will return a newly allocated descriptor. - * It this memory needs to be g_free()d + * @param s session descriptor * */ enum SCP_SERVER_STATES_E -scp_vXs_accept(struct trans *atrans, struct SCP_SESSION **s); +scp_vXs_accept(struct trans *atrans, struct SCP_SESSION *s); #endif diff --git a/sesman/scp.c b/sesman/scp.c index 774d71fa..36cf4045 100644 --- a/sesman/scp.c +++ b/sesman/scp.c @@ -37,13 +37,9 @@ extern struct config_sesman *g_cfg; /* in sesman.c */ /******************************************************************************/ enum SCP_SERVER_STATES_E -scp_process(struct trans *t) +scp_process(struct trans *t, struct SCP_SESSION *sdata) { - enum SCP_SERVER_STATES_E result; - struct SCP_SESSION *sdata; - - sdata = NULL; - result = scp_vXs_accept(t, &sdata); + enum SCP_SERVER_STATES_E result = scp_vXs_accept(t, sdata); switch (result) { case SCP_SERVER_STATE_OK: @@ -88,6 +84,7 @@ scp_process(struct trans *t) result = SCP_SERVER_STATE_INTERNAL_ERR; break; } + return result; } diff --git a/sesman/scp.h b/sesman/scp.h index 089a5183..088da5fd 100644 --- a/sesman/scp.h +++ b/sesman/scp.h @@ -40,6 +40,6 @@ * */ enum SCP_SERVER_STATES_E -scp_process(struct trans *t); +scp_process(struct trans *t, struct SCP_SESSION *s); #endif diff --git a/sesman/scp_v1.c b/sesman/scp_v1.c index ea1f2933..9def2e9e 100644 --- a/sesman/scp_v1.c +++ b/sesman/scp_v1.c @@ -49,8 +49,12 @@ scp_v1_process1(struct trans *t, struct SCP_SESSION *s) struct SCP_DISCONNECTED_SESSION *slist; bool_t do_auth_end = 1; - s->retries = g_cfg->sec.login_retry; - s->current_try = s->retries; + if (s->retries == 0) + { + /* First time in */ + s->retries = g_cfg->sec.login_retry; + s->current_try = s->retries; + } data = auth_userpass(s->username, s->password, NULL); if (data == 0) { @@ -246,10 +250,11 @@ scp_v1_process45(struct trans *t, struct SCP_SESSION *s) enum SCP_SERVER_STATES_E scp_v1_process(struct trans *t, struct SCP_SESSION *s) { + ; /* astyle 3.1 needs this, or the switch is badly formatted */ switch (s->current_cmd) { case 1: - return scp_v1_process1(t, s); + return scp_v1_process1(t, s); case 4: return scp_v1_process4(t, s); case 41: diff --git a/sesman/sesman.c b/sesman/sesman.c index f55b7a1b..3567e6c0 100644 --- a/sesman/sesman.c +++ b/sesman/sesman.c @@ -50,6 +50,15 @@ struct config_sesman *g_cfg; /* defined in config.h */ tintptr g_term_event = 0; +/** + * Items stored on the g_con_list + */ +struct sesman_con +{ + struct trans *t; + struct SCP_SESSION *s; +}; + static struct trans *g_list_trans = NULL; static struct list *g_con_list = NULL; @@ -80,6 +89,54 @@ static int nocase_matches(const char *candidate, ...) return result; } +/** + * Allocates a sesman_con struct + * + * @param trans Pointer to newly-allocated transport + * @return struct sesman_con pointer + */ +static struct sesman_con * +alloc_connection(struct trans *t) +{ + struct sesman_con *result; + struct SCP_SESSION *s; + + if ((result = g_new(struct sesman_con, 1)) != NULL) + { + if ((s = scp_session_create()) != NULL) + { + result->t = t; + result->s = s; + /* Ensure we can find the connection easily from a callback */ + t->callback_data = (void *)result; + } + else + { + g_free(result); + result = NULL; + } + } + + return result; +} + +/** + * Deletes a sesman_con struct, freeing resources + * + * After this call, the passed-in pointer is invalid and must not be + * referenced. + * + * @param sc struct to de-allocate + */ +static void +delete_connection(struct sesman_con *sc) +{ + trans_delete(sc->t); + scp_session_destroy(sc->s); + g_free(sc); +} + + /*****************************************************************************/ /** * @@ -195,14 +252,14 @@ int sesman_close_all(void) { int index; - struct trans *con_trans; + struct sesman_con *sc; LOG_DEVEL(LOG_LEVEL_TRACE, "sesman_close_all:"); trans_delete(g_list_trans); for (index = 0; index < g_con_list->count; index++) { - con_trans = (struct trans *) list_get_item(g_con_list, index); - trans_delete(con_trans); + sc = (struct sesman_con *) list_get_item(g_con_list, index); + delete_connection(sc); } return 0; } @@ -228,9 +285,10 @@ sesman_data_in(struct trans *self) } else { - /* prcess message */ + /* process message */ + struct sesman_con *sc = (struct sesman_con *)self->callback_data; self->in_s->p = self->in_s->data; - if (scp_process(self) != SCP_SERVER_STATE_OK) + if (scp_process(self, sc->s) != SCP_SERVER_STATE_OK) { LOG(LOG_LEVEL_ERROR, "sesman_data_in: scp_process_msg failed"); return 1; @@ -247,20 +305,28 @@ sesman_data_in(struct trans *self) static int sesman_listen_conn_in(struct trans *self, struct trans *new_self) { - if (g_con_list->count < 16) - { - new_self->header_size = 8; - new_self->trans_data_in = sesman_data_in; - new_self->no_stream_init_on_data_in = 1; - new_self->extra_flags = 0; - list_add_item(g_con_list, (intptr_t) new_self); - } - else + struct sesman_con *sc; + if (g_con_list->count >= 16) { LOG(LOG_LEVEL_ERROR, "sesman_data_in: error, too many " "connections, rejecting"); trans_delete(new_self); } + else if ((sc = alloc_connection(new_self)) == NULL) + { + LOG(LOG_LEVEL_ERROR, "sesman_data_in: No memory to allocate " + "new connection"); + trans_delete(new_self); + } + else + { + new_self->header_size = 8; + new_self->trans_data_in = sesman_data_in; + new_self->no_stream_init_on_data_in = 1; + new_self->extra_flags = 0; + list_add_item(g_con_list, (intptr_t) sc); + } + return 0; } @@ -281,7 +347,7 @@ sesman_main_loop(void) int index; intptr_t robjs[32]; intptr_t wobjs[32]; - struct trans *con_trans; + struct sesman_con *scon; g_con_list = list_create(); if (g_con_list == NULL) @@ -319,10 +385,11 @@ sesman_main_loop(void) wobjs_count = 0; for (index = 0; index < g_con_list->count; index++) { - con_trans = (struct trans *) list_get_item(g_con_list, index); - if (con_trans != NULL) + scon = (struct sesman_con *)list_get_item(g_con_list, index); + if (scon != NULL) { - error = trans_get_wait_objs_rw(con_trans, robjs, &robjs_count, + error = trans_get_wait_objs_rw(scon->t, + robjs, &robjs_count, wobjs, &wobjs_count, &timeout); if (error != 0) { @@ -359,15 +426,15 @@ sesman_main_loop(void) for (index = 0; index < g_con_list->count; index++) { - con_trans = (struct trans *) list_get_item(g_con_list, index); - if (con_trans != NULL) + scon = (struct sesman_con *)list_get_item(g_con_list, index); + if (scon != NULL) { - error = trans_check_wait_objs(con_trans); + error = trans_check_wait_objs(scon->t); if (error != 0) { LOG(LOG_LEVEL_ERROR, "sesman_main_loop: " "trans_check_wait_objs failed, removing trans"); - trans_delete(con_trans); + delete_connection(scon); list_remove_item(g_con_list, index); index--; continue; @@ -384,8 +451,8 @@ sesman_main_loop(void) } for (index = 0; index < g_con_list->count; index++) { - con_trans = (struct trans *) list_get_item(g_con_list, index); - trans_delete(con_trans); + scon = (struct sesman_con *) list_get_item(g_con_list, index); + delete_connection(scon); } list_delete(g_con_list); trans_delete(g_list_trans); diff --git a/sesman/sesman.h b/sesman/sesman.h index c7b3913c..ebffff47 100644 --- a/sesman/sesman.h +++ b/sesman/sesman.h @@ -41,6 +41,15 @@ #include "libscp.h" +/* + * Close all file descriptors used by sesman. + * + * This is generally used after forking, to make sure the + * file descriptors used by the main process are not disturbed + * + * This call will also release all trans and SCP_SESSION objects + * held by sesman + */ int sesman_close_all(void); diff --git a/sesman/session.c b/sesman/session.c index 97dd1f13..a2968e1b 100644 --- a/sesman/session.c +++ b/sesman/session.c @@ -492,6 +492,15 @@ session_start_fork(tbus data, tui8 type, struct SCP_SESSION *s) LOG(LOG_LEVEL_INFO, "[session start] (display %d): calling auth_start_session from pid %d", display, g_getpid()); + + /* Clone the session object, as the passed-in copy will be + * deleted by sesman_close_all() */ + if ((s = scp_session_clone(s)) == NULL) + { + LOG(LOG_LEVEL_ERROR, + "Failed to clone the session data - out of memory"); + g_exit(1); + } auth_start_session(data, display); g_delete_wait_obj(g_term_event); sesman_close_all(); diff --git a/sesman/tools/sesadmin.c b/sesman/tools/sesadmin.c index 0db30bb4..8ff654a9 100644 --- a/sesman/tools/sesadmin.c +++ b/sesman/tools/sesadmin.c @@ -140,9 +140,9 @@ int main(int argc, char **argv) LOG_DEVEL(LOG_LEVEL_DEBUG, "Connecting to %s:%s with user %s (%s)", serv, port, user, pass); - if (0 != g_tcp_connect(sock, serv, port)) + if (0 != trans_connect(t, serv, port, 3000)) { - LOG_DEVEL(LOG_LEVEL_DEBUG, "g_tcp_connect() error"); + LOG(LOG_LEVEL_ERROR, "trans_connect() error"); return 1; } @@ -167,7 +167,6 @@ int main(int argc, char **argv) cmndKill(t, s); } - g_tcp_close(sock); scp_session_destroy(s); trans_delete(t); log_end(); diff --git a/sesman/tools/sesrun.c b/sesman/tools/sesrun.c index bbcaa37d..30dde82e 100644 --- a/sesman/tools/sesrun.c +++ b/sesman/tools/sesrun.c @@ -504,6 +504,7 @@ handle_scpv0_auth_reply(int sck) int data; int display; + in_s->end = in_s->data + 8; in_uint32_be(in_s, version); in_uint32_be(in_s, size); if (version == 0 && size >= 14) diff --git a/sesman/tools/sestest.c b/sesman/tools/sestest.c index 43045b29..d4fb561f 100644 --- a/sesman/tools/sestest.c +++ b/sesman/tools/sestest.c @@ -41,18 +41,17 @@ int main(int argc, char **argv) /*struct SCP_DISCONNECTED_SESSION ds;*/ struct SCP_DISCONNECTED_SESSION *dsl; enum SCP_CLIENT_STATES_E e; - struct log_config log; + struct log_config *logging; int end; int scnt; int idx; int sel; int sock; - log.enable_syslog = 0; - log.log_level = LOG_LEVEL_DEBUG; - log.program_name = "sestest"; - log.log_file = g_strdup("sestest.log"); - log_start_from_param(&log); + logging = log_config_init_for_console(LOG_LEVEL_INFO, NULL); + log_start_from_param(logging); + log_config_free(logging); + scp_init(); sock = g_tcp_socket(); @@ -64,7 +63,7 @@ int main(int argc, char **argv) s = scp_session_create(); t = scp_trans_create(sock); - if (0 != g_tcp_connect(sock, "localhost", "3350")) + if (0 != trans_connect(t, "localhost", "3350", 3000)) { g_printf("error connecting"); return 1; @@ -173,11 +172,9 @@ int main(int argc, char **argv) } } - g_tcp_close(sock); scp_session_destroy(s); trans_delete(t); - /*free_stream(c.in_s); - free_stream(c.out_s);*/ + log_end(); return 0; }