diff options
author | Laxmikant Rashinkar <LK.Rashinkar@gmail.com> | 2012-09-19 20:51:34 -0700 |
---|---|---|
committer | Laxmikant Rashinkar <LK.Rashinkar@gmail.com> | 2012-09-19 20:51:34 -0700 |
commit | 1123323fda6d128fb98b0427e0ea5f6a2dc9e632 (patch) | |
tree | 3407a3771a069f812554312ce7c36db625139cc2 /sesman | |
parent | 3cedfae76a2351bc8b1e5bd2ee33bbf8630dbacf (diff) | |
download | xrdp-proprietary-1123323fda6d128fb98b0427e0ea5f6a2dc9e632.tar.gz xrdp-proprietary-1123323fda6d128fb98b0427e0ea5f6a2dc9e632.zip |
o moved from GNU General Public License to Apache License, Version 2.0
o applied new coding standards to all .c files
o moved some files around
Diffstat (limited to 'sesman')
70 files changed, 10210 insertions, 9506 deletions
diff --git a/sesman/access.c b/sesman/access.c index 0037de3f..00c9c381 100644 --- a/sesman/access.c +++ b/sesman/access.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -27,102 +26,102 @@ #include "sesman.h" -extern struct config_sesman* g_cfg; /* in sesman.c */ +extern struct config_sesman *g_cfg; /* in sesman.c */ /******************************************************************************/ int DEFAULT_CC -access_login_allowed(char* user) +access_login_allowed(char *user) { - int gid; - int ok; + int gid; + int ok; + + if ((0 == g_strncmp(user, "root", 5)) && (0 == g_cfg->sec.allow_root)) + { + log_message(LOG_LEVEL_WARNING, + "ROOT login attempted, but root login is disabled"); + return 0; + } + + if (0 == g_cfg->sec.ts_users_enable) + { + LOG_DBG("Terminal Server Users group is disabled, allowing authentication", + 1); + return 1; + } + + if (0 != g_getuser_info(user, &gid, 0, 0, 0, 0)) + { + log_message(LOG_LEVEL_ERROR, "Cannot read user info! - login denied"); + return 0; + } + + if (g_cfg->sec.ts_users == gid) + { + LOG_DBG("ts_users is user's primary group"); + return 1; + } + + if (0 != g_check_user_in_group(user, g_cfg->sec.ts_users, &ok)) + { + log_message(LOG_LEVEL_ERROR, "Cannot read group info! - login denied"); + return 0; + } + + if (ok) + { + return 1; + } + + log_message(LOG_LEVEL_INFO, "login denied for user %s", user); - if ((0 == g_strncmp(user, "root", 5)) && (0 == g_cfg->sec.allow_root)) - { - log_message(LOG_LEVEL_WARNING, - "ROOT login attempted, but root login is disabled"); return 0; - } - - if (0 == g_cfg->sec.ts_users_enable) - { - LOG_DBG("Terminal Server Users group is disabled, allowing authentication", - 1); - return 1; - } - - if (0 != g_getuser_info(user, &gid, 0, 0, 0, 0)) - { - log_message(LOG_LEVEL_ERROR, "Cannot read user info! - login denied"); - return 0; - } - - if (g_cfg->sec.ts_users == gid) - { - LOG_DBG("ts_users is user's primary group"); - return 1; - } - - if (0 != g_check_user_in_group(user, g_cfg->sec.ts_users, &ok)) - { - log_message(LOG_LEVEL_ERROR, "Cannot read group info! - login denied"); - return 0; - } - - if (ok) - { - return 1; - } - - log_message(LOG_LEVEL_INFO, "login denied for user %s", user); - - return 0; } /******************************************************************************/ int DEFAULT_CC -access_login_mng_allowed(char* user) +access_login_mng_allowed(char *user) { - int gid; - int ok; + int gid; + int ok; + + if ((0 == g_strncmp(user, "root", 5)) && (0 == g_cfg->sec.allow_root)) + { + log_message(LOG_LEVEL_WARNING, + "[MNG] ROOT login attempted, but root login is disabled"); + return 0; + } + + if (0 == g_cfg->sec.ts_admins_enable) + { + LOG_DBG("[MNG] Terminal Server Admin group is disabled," + "allowing authentication", 1); + return 1; + } + + if (0 != g_getuser_info(user, &gid, 0, 0, 0, 0)) + { + log_message(LOG_LEVEL_ERROR, "[MNG] Cannot read user info! - login denied"); + return 0; + } + + if (g_cfg->sec.ts_admins == gid) + { + LOG_DBG("[MNG] ts_users is user's primary group"); + return 1; + } + + if (0 != g_check_user_in_group(user, g_cfg->sec.ts_admins, &ok)) + { + log_message(LOG_LEVEL_ERROR, "[MNG] Cannot read group info! - login denied"); + return 0; + } + + if (ok) + { + return 1; + } + + log_message(LOG_LEVEL_INFO, "[MNG] login denied for user %s", user); - if ((0 == g_strncmp(user, "root", 5)) && (0 == g_cfg->sec.allow_root)) - { - log_message(LOG_LEVEL_WARNING, - "[MNG] ROOT login attempted, but root login is disabled"); - return 0; - } - - if (0 == g_cfg->sec.ts_admins_enable) - { - LOG_DBG("[MNG] Terminal Server Admin group is disabled," - "allowing authentication",1); - return 1; - } - - if (0 != g_getuser_info(user, &gid, 0, 0, 0, 0)) - { - log_message(LOG_LEVEL_ERROR, "[MNG] Cannot read user info! - login denied"); return 0; - } - - if (g_cfg->sec.ts_admins == gid) - { - LOG_DBG("[MNG] ts_users is user's primary group"); - return 1; - } - - if (0 != g_check_user_in_group(user, g_cfg->sec.ts_admins, &ok)) - { - log_message(LOG_LEVEL_ERROR, "[MNG] Cannot read group info! - login denied"); - return 0; - } - - if (ok) - { - return 1; - } - - log_message(LOG_LEVEL_INFO, "[MNG] login denied for user %s", user); - - return 0; } diff --git a/sesman/access.h b/sesman/access.h index bad20540..d53c65ad 100644 --- a/sesman/access.h +++ b/sesman/access.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * diff --git a/sesman/auth.h b/sesman/auth.h index a6c5e7fa..09bec2e9 100644 --- a/sesman/auth.h +++ b/sesman/auth.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c index 10a42ef9..0f69f1f6 100644 --- a/sesman/chansrv/chansrv.c +++ b/sesman/chansrv/chansrv.c @@ -32,10 +32,10 @@ #include "rail.h" #include "xcommon.h" -static struct trans* g_lis_trans = 0; -static struct trans* g_con_trans = 0; -static struct trans* g_api_lis_trans = 0; -static struct trans* g_api_con_trans = 0; +static struct trans *g_lis_trans = 0; +static struct trans *g_con_trans = 0; +static struct trans *g_api_lis_trans = 0; +static struct trans *g_api_con_trans = 0; static struct chan_item g_chan_items[32]; static int g_num_chan_items = 0; static int g_cliprdr_index = -1; @@ -54,7 +54,7 @@ int g_rdpsnd_chan_id = -1; /* rdpsnd */ int g_rdpdr_chan_id = -1; /* rdpdr */ int g_rail_chan_id = -1; /* rail */ -char* g_exec_name; +char *g_exec_name; tbus g_exec_event; tbus g_exec_mutex; tbus g_exec_sem; @@ -63,97 +63,109 @@ int g_exec_pid = 0; /* data in struct trans::callback_data */ struct xrdp_api_data { - int chan_id; - char header[64]; - int flags; + int chan_id; + char header[64]; + int flags; }; /*****************************************************************************/ /* add data to chan_item, on its way to the client */ /* returns error */ static int APP_CC -add_data_to_chan_item(struct chan_item* chan_item, char* data, int size) +add_data_to_chan_item(struct chan_item *chan_item, char *data, int size) { - struct stream* s; - struct chan_out_data* cod; - - make_stream(s); - init_stream(s, size); - g_memcpy(s->data, data, size); - s->end = s->data + size; - cod = (struct chan_out_data*)g_malloc(sizeof(struct chan_out_data), 1); - cod->s = s; - if (chan_item->tail == 0) - { - chan_item->tail = cod; - chan_item->head = cod; - } - else - { - chan_item->tail->next = cod; - chan_item->tail = cod; - } - return 0; + struct stream *s; + struct chan_out_data *cod; + + make_stream(s); + init_stream(s, size); + g_memcpy(s->data, data, size); + s->end = s->data + size; + cod = (struct chan_out_data *)g_malloc(sizeof(struct chan_out_data), 1); + cod->s = s; + + if (chan_item->tail == 0) + { + chan_item->tail = cod; + chan_item->head = cod; + } + else + { + chan_item->tail->next = cod; + chan_item->tail = cod; + } + + return 0; } /*****************************************************************************/ /* returns error */ static int APP_CC -send_data_from_chan_item(struct chan_item* chan_item) +send_data_from_chan_item(struct chan_item *chan_item) { - struct stream* s; - struct chan_out_data* cod; - int bytes_left; - int size; - int chan_flags; - int error; - - if (chan_item->head == 0) - { - return 0; - } - cod = chan_item->head; - bytes_left = (int)(cod->s->end - cod->s->p); - size = MIN(1600, bytes_left); - chan_flags = 0; - if (cod->s->p == cod->s->data) - { - chan_flags |= 1; /* first */ - } - if (cod->s->p + size >= cod->s->end) - { - chan_flags |= 2; /* last */ - } - s = trans_get_out_s(g_con_trans, 8192); - out_uint32_le(s, 0); /* version */ - out_uint32_le(s, 8 + 8 + 2 + 2 + 2 + 4 + size); /* size */ - out_uint32_le(s, 8); /* msg id */ - out_uint32_le(s, 8 + 2 + 2 + 2 + 4 + size); /* size */ - out_uint16_le(s, chan_item->id); - out_uint16_le(s, chan_flags); - out_uint16_le(s, size); - out_uint32_le(s, cod->s->size); - out_uint8a(s, cod->s->p, size); - s_mark_end(s); - LOGM((LOG_LEVEL_DEBUG, "chansrv::send_channel_data: -- " - "size %d chan_flags 0x%8.8x", size, chan_flags)); - error = trans_force_write(g_con_trans); - if (error != 0) - { - return 1; - } - cod->s->p += size; - if (cod->s->p >= cod->s->end) - { - free_stream(cod->s); - chan_item->head = chan_item->head->next; + struct stream *s; + struct chan_out_data *cod; + int bytes_left; + int size; + int chan_flags; + int error; + if (chan_item->head == 0) { - chan_item->tail = 0; + return 0; + } + + cod = chan_item->head; + bytes_left = (int)(cod->s->end - cod->s->p); + size = MIN(1600, bytes_left); + chan_flags = 0; + + if (cod->s->p == cod->s->data) + { + chan_flags |= 1; /* first */ } - g_free(cod); - } - return 0; + + if (cod->s->p + size >= cod->s->end) + { + chan_flags |= 2; /* last */ + } + + s = trans_get_out_s(g_con_trans, 8192); + out_uint32_le(s, 0); /* version */ + out_uint32_le(s, 8 + 8 + 2 + 2 + 2 + 4 + size); /* size */ + out_uint32_le(s, 8); /* msg id */ + out_uint32_le(s, 8 + 2 + 2 + 2 + 4 + size); /* size */ + out_uint16_le(s, chan_item->id); + out_uint16_le(s, chan_flags); + out_uint16_le(s, size); + out_uint32_le(s, cod->s->size); + out_uint8a(s, cod->s->p, size); + s_mark_end(s); + LOGM((LOG_LEVEL_DEBUG, "chansrv::send_channel_data: -- " + "size %d chan_flags 0x%8.8x", size, chan_flags)); + error = trans_force_write(g_con_trans); + + if (error != 0) + { + return 1; + } + + cod->s->p += size; + + if (cod->s->p >= cod->s->end) + { + free_stream(cod->s); + chan_item->head = chan_item->head->next; + + if (chan_item->head == 0) + { + chan_item->tail = 0; + } + + g_free(cod); + } + + return 0; } /*****************************************************************************/ @@ -161,40 +173,44 @@ send_data_from_chan_item(struct chan_item* chan_item) static int APP_CC check_chan_items(void) { - int index; + int index; - for (index = 0; index < g_num_chan_items; index++) - { - if (g_chan_items[index].head != 0) + for (index = 0; index < g_num_chan_items; index++) { - send_data_from_chan_item(g_chan_items + index); + if (g_chan_items[index].head != 0) + { + send_data_from_chan_item(g_chan_items + index); + } } - } - return 0; + + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -send_channel_data(int chan_id, char* data, int size) +send_channel_data(int chan_id, char *data, int size) { - int index; + int index; - LOGM((LOG_LEVEL_DEBUG, "chansrv::send_channel_data: size %d", size)); - if (chan_id == -1) - { - return 1; - } - for (index = 0; index < g_num_chan_items; index++) - { - if (g_chan_items[index].id == chan_id) + LOGM((LOG_LEVEL_DEBUG, "chansrv::send_channel_data: size %d", size)); + + if (chan_id == -1) { - add_data_to_chan_item(g_chan_items + index, data, size); - check_chan_items(); - return 0; + return 1; } - } - return 1; + + for (index = 0; index < g_num_chan_items; index++) + { + if (g_chan_items[index].id == chan_id) + { + add_data_to_chan_item(g_chan_items + index, data, size); + check_chan_items(); + return 0; + } + } + + return 1; } /*****************************************************************************/ @@ -202,20 +218,22 @@ send_channel_data(int chan_id, char* data, int size) static int APP_CC send_init_response_message(void) { - struct stream * s = (struct stream *)NULL; + struct stream *s = (struct stream *)NULL; - LOGM((LOG_LEVEL_INFO, "send_init_response_message:")); - s = trans_get_out_s(g_con_trans, 8192); - if (s == 0) - { - return 1; - } - out_uint32_le(s, 0); /* version */ - out_uint32_le(s, 8 + 8); /* size */ - out_uint32_le(s, 2); /* msg id */ - out_uint32_le(s, 8); /* size */ - s_mark_end(s); - return trans_force_write(g_con_trans); + LOGM((LOG_LEVEL_INFO, "send_init_response_message:")); + s = trans_get_out_s(g_con_trans, 8192); + + if (s == 0) + { + return 1; + } + + out_uint32_le(s, 0); /* version */ + out_uint32_le(s, 8 + 8); /* size */ + out_uint32_le(s, 2); /* msg id */ + out_uint32_le(s, 8); /* size */ + s_mark_end(s); + return trans_force_write(g_con_trans); } /*****************************************************************************/ @@ -223,20 +241,22 @@ send_init_response_message(void) static int APP_CC send_channel_setup_response_message(void) { - struct stream * s = (struct stream *)NULL; + struct stream *s = (struct stream *)NULL; - LOGM((LOG_LEVEL_DEBUG, "send_channel_setup_response_message:")); - s = trans_get_out_s(g_con_trans, 8192); - if (s == 0) - { - return 1; - } - out_uint32_le(s, 0); /* version */ - out_uint32_le(s, 8 + 8); /* size */ - out_uint32_le(s, 4); /* msg id */ - out_uint32_le(s, 8); /* size */ - s_mark_end(s); - return trans_force_write(g_con_trans); + LOGM((LOG_LEVEL_DEBUG, "send_channel_setup_response_message:")); + s = trans_get_out_s(g_con_trans, 8192); + + if (s == 0) + { + return 1; + } + + out_uint32_le(s, 0); /* version */ + out_uint32_le(s, 8 + 8); /* size */ + out_uint32_le(s, 4); /* msg id */ + out_uint32_le(s, 8); /* size */ + s_mark_end(s); + return trans_force_write(g_con_trans); } /*****************************************************************************/ @@ -244,176 +264,192 @@ send_channel_setup_response_message(void) static int APP_CC send_channel_data_response_message(void) { - struct stream * s = (struct stream *)NULL; + struct stream *s = (struct stream *)NULL; - LOGM((LOG_LEVEL_DEBUG, "send_channel_data_response_message:")); - s = trans_get_out_s(g_con_trans, 8192); - if (s == 0) - { - return 1; - } - out_uint32_le(s, 0); /* version */ - out_uint32_le(s, 8 + 8); /* size */ - out_uint32_le(s, 6); /* msg id */ - out_uint32_le(s, 8); /* size */ - s_mark_end(s); - return trans_force_write(g_con_trans); + LOGM((LOG_LEVEL_DEBUG, "send_channel_data_response_message:")); + s = trans_get_out_s(g_con_trans, 8192); + + if (s == 0) + { + return 1; + } + + out_uint32_le(s, 0); /* version */ + out_uint32_le(s, 8 + 8); /* size */ + out_uint32_le(s, 6); /* msg id */ + out_uint32_le(s, 8); /* size */ + s_mark_end(s); + return trans_force_write(g_con_trans); } /*****************************************************************************/ /* returns error */ static int APP_CC -process_message_init(struct stream* s) +process_message_init(struct stream *s) { - LOGM((LOG_LEVEL_DEBUG, "process_message_init:")); - return send_init_response_message(); + LOGM((LOG_LEVEL_DEBUG, "process_message_init:")); + return send_init_response_message(); } /*****************************************************************************/ /* returns error */ static int APP_CC -process_message_channel_setup(struct stream* s) +process_message_channel_setup(struct stream *s) { - int num_chans; - int index; - int rv; - struct chan_item* ci; - - g_num_chan_items = 0; - g_cliprdr_index = -1; - g_rdpsnd_index = -1; - g_rdpdr_index = -1; - g_rail_index = -1; - g_cliprdr_chan_id = -1; - g_rdpsnd_chan_id = -1; - g_rdpdr_chan_id = -1; - g_rail_chan_id = -1; - LOGM((LOG_LEVEL_DEBUG, "process_message_channel_setup:")); - in_uint16_le(s, num_chans); - LOGM((LOG_LEVEL_DEBUG, "process_message_channel_setup: num_chans %d", - num_chans)); - for (index = 0; index < num_chans; index++) - { - ci = &(g_chan_items[g_num_chan_items]); - g_memset(ci->name, 0, sizeof(ci->name)); - in_uint8a(s, ci->name, 8); - in_uint16_le(s, ci->id); - in_uint16_le(s, ci->flags); - LOGM((LOG_LEVEL_DEBUG, "process_message_channel_setup: chan name '%s' " - "id %d flags %8.8x", ci->name, ci->id, ci->flags)); - if (g_strcasecmp(ci->name, "cliprdr") == 0) + int num_chans; + int index; + int rv; + struct chan_item *ci; + + g_num_chan_items = 0; + g_cliprdr_index = -1; + g_rdpsnd_index = -1; + g_rdpdr_index = -1; + g_rail_index = -1; + g_cliprdr_chan_id = -1; + g_rdpsnd_chan_id = -1; + g_rdpdr_chan_id = -1; + g_rail_chan_id = -1; + LOGM((LOG_LEVEL_DEBUG, "process_message_channel_setup:")); + in_uint16_le(s, num_chans); + LOGM((LOG_LEVEL_DEBUG, "process_message_channel_setup: num_chans %d", + num_chans)); + + for (index = 0; index < num_chans; index++) { - g_cliprdr_index = g_num_chan_items; - g_cliprdr_chan_id = ci->id; + ci = &(g_chan_items[g_num_chan_items]); + g_memset(ci->name, 0, sizeof(ci->name)); + in_uint8a(s, ci->name, 8); + in_uint16_le(s, ci->id); + in_uint16_le(s, ci->flags); + LOGM((LOG_LEVEL_DEBUG, "process_message_channel_setup: chan name '%s' " + "id %d flags %8.8x", ci->name, ci->id, ci->flags)); + + if (g_strcasecmp(ci->name, "cliprdr") == 0) + { + g_cliprdr_index = g_num_chan_items; + g_cliprdr_chan_id = ci->id; + } + else if (g_strcasecmp(ci->name, "rdpsnd") == 0) + { + g_rdpsnd_index = g_num_chan_items; + g_rdpsnd_chan_id = ci->id; + } + else if (g_strcasecmp(ci->name, "rdpdr") == 0) + { + g_rdpdr_index = g_num_chan_items; + g_rdpdr_chan_id = ci->id; + } + else if (g_strcasecmp(ci->name, "rail") == 0) + { + g_rail_index = g_num_chan_items; + g_rail_chan_id = ci->id; + } + else + { + LOG(10, ("other %s", ci->name)); + } + + g_num_chan_items++; } - else if (g_strcasecmp(ci->name, "rdpsnd") == 0) + + rv = send_channel_setup_response_message(); + + if (g_cliprdr_index >= 0) { - g_rdpsnd_index = g_num_chan_items; - g_rdpsnd_chan_id = ci->id; + clipboard_init(); } - else if (g_strcasecmp(ci->name, "rdpdr") == 0) + + if (g_rdpsnd_index >= 0) { - g_rdpdr_index = g_num_chan_items; - g_rdpdr_chan_id = ci->id; + sound_init(); } - else if (g_strcasecmp(ci->name, "rail") == 0) + + if (g_rdpdr_index >= 0) { - g_rail_index = g_num_chan_items; - g_rail_chan_id = ci->id; + dev_redir_init(); } - else + + if (g_rail_index >= 0) { - LOG(10, ("other %s", ci->name)); + rail_init(); } - g_num_chan_items++; - } - rv = send_channel_setup_response_message(); - if (g_cliprdr_index >= 0) - { - clipboard_init(); - } - if (g_rdpsnd_index >= 0) - { - sound_init(); - } - if (g_rdpdr_index >= 0) - { - dev_redir_init(); - } - if (g_rail_index >= 0) - { - rail_init(); - } - return rv; + + return rv; } /*****************************************************************************/ /* returns error */ static int APP_CC -process_message_channel_data(struct stream* s) +process_message_channel_data(struct stream *s) { - int chan_id = 0; - int chan_flags = 0; - int rv = 0; - int length = 0; - int total_length = 0; - struct stream* ls; - - in_uint16_le(s, chan_id); - in_uint16_le(s, chan_flags); - in_uint16_le(s, length); - in_uint32_le(s, total_length); - LOGM((LOG_LEVEL_DEBUG,"process_message_channel_data: chan_id %d " - "chan_flags %d", chan_id, chan_flags)); - LOG(10, ("process_message_channel_data")); - rv = send_channel_data_response_message(); - if (rv == 0) - { - if (chan_id == g_cliprdr_chan_id) - { - rv = clipboard_data_in(s, chan_id, chan_flags, length, total_length); - } - else if (chan_id == g_rdpsnd_chan_id) - { - rv = sound_data_in(s, chan_id, chan_flags, length, total_length); - } - else if (chan_id == g_rdpdr_chan_id) - { - rv = dev_redir_data_in(s, chan_id, chan_flags, length, total_length); - } - else if (chan_id == g_rail_chan_id) - { - rv = rail_data_in(s, chan_id, chan_flags, length, total_length); - } - else if (chan_id == ((struct xrdp_api_data*) - (g_api_con_trans->callback_data))->chan_id) + int chan_id = 0; + int chan_flags = 0; + int rv = 0; + int length = 0; + int total_length = 0; + struct stream *ls; + + in_uint16_le(s, chan_id); + in_uint16_le(s, chan_flags); + in_uint16_le(s, length); + in_uint32_le(s, total_length); + LOGM((LOG_LEVEL_DEBUG, "process_message_channel_data: chan_id %d " + "chan_flags %d", chan_id, chan_flags)); + LOG(10, ("process_message_channel_data")); + rv = send_channel_data_response_message(); + + if (rv == 0) { - LOG(10, ("process_message_channel_data length %d total_length %d " - "chan_flags 0x%8.8x", length, total_length, chan_flags)); - ls = g_api_con_trans->out_s; - if (chan_flags & 1) /* first */ - { - init_stream(ls, total_length); - } - out_uint8a(ls, s->p, length); - if (chan_flags & 2) /* last */ - { - s_mark_end(ls); - trans_force_write(g_api_con_trans); - } + if (chan_id == g_cliprdr_chan_id) + { + rv = clipboard_data_in(s, chan_id, chan_flags, length, total_length); + } + else if (chan_id == g_rdpsnd_chan_id) + { + rv = sound_data_in(s, chan_id, chan_flags, length, total_length); + } + else if (chan_id == g_rdpdr_chan_id) + { + rv = dev_redir_data_in(s, chan_id, chan_flags, length, total_length); + } + else if (chan_id == g_rail_chan_id) + { + rv = rail_data_in(s, chan_id, chan_flags, length, total_length); + } + else if (chan_id == ((struct xrdp_api_data *) + (g_api_con_trans->callback_data))->chan_id) + { + LOG(10, ("process_message_channel_data length %d total_length %d " + "chan_flags 0x%8.8x", length, total_length, chan_flags)); + ls = g_api_con_trans->out_s; + + if (chan_flags & 1) /* first */ + { + init_stream(ls, total_length); + } + + out_uint8a(ls, s->p, length); + + if (chan_flags & 2) /* last */ + { + s_mark_end(ls); + trans_force_write(g_api_con_trans); + } + } } - } - return rv; + + return rv; } /*****************************************************************************/ /* returns error */ static int APP_CC -process_message_channel_data_response(struct stream* s) +process_message_channel_data_response(struct stream *s) { - LOG(10, ("process_message_channel_data_response:")); - check_chan_items(); - return 0; + LOG(10, ("process_message_channel_data_response:")); + check_chan_items(); + return 0; } /*****************************************************************************/ @@ -421,680 +457,752 @@ process_message_channel_data_response(struct stream* s) static int APP_CC process_message(void) { - struct stream * s = (struct stream *)NULL; - int size = 0; - int id = 0; - int rv = 0; - char* next_msg = (char *)NULL; - - if (g_con_trans == 0) - { - return 1; - } - s = trans_get_in_s(g_con_trans); - if (s == 0) - { - return 1; - } - rv = 0; - while (s_check_rem(s, 8)) - { - next_msg = s->p; - in_uint32_le(s, id); - in_uint32_le(s, size); - next_msg += size; - switch (id) + struct stream *s = (struct stream *)NULL; + int size = 0; + int id = 0; + int rv = 0; + char *next_msg = (char *)NULL; + + if (g_con_trans == 0) { - case 1: /* init */ - rv = process_message_init(s); - break; - case 3: /* channel setup */ - rv = process_message_channel_setup(s); - break; - case 5: /* channel data */ - rv = process_message_channel_data(s); - break; - case 7: /* channel data response */ - rv = process_message_channel_data_response(s); - break; - default: - LOGM((LOG_LEVEL_ERROR, "process_message: error in process_message ", - "unknown msg %d", id)); - break; + return 1; } - if (rv != 0) + + s = trans_get_in_s(g_con_trans); + + if (s == 0) { - break; + return 1; + } + + rv = 0; + + while (s_check_rem(s, 8)) + { + next_msg = s->p; + in_uint32_le(s, id); + in_uint32_le(s, size); + next_msg += size; + + switch (id) + { + case 1: /* init */ + rv = process_message_init(s); + break; + case 3: /* channel setup */ + rv = process_message_channel_setup(s); + break; + case 5: /* channel data */ + rv = process_message_channel_data(s); + break; + case 7: /* channel data response */ + rv = process_message_channel_data_response(s); + break; + default: + LOGM((LOG_LEVEL_ERROR, "process_message: error in process_message ", + "unknown msg %d", id)); + break; + } + + if (rv != 0) + { + break; + } + + s->p = next_msg; } - s->p = next_msg; - } - return rv; + + return rv; } /*****************************************************************************/ /* returns error */ int DEFAULT_CC -my_trans_data_in(struct trans* trans) +my_trans_data_in(struct trans *trans) { - struct stream * s = (struct stream *)NULL; - int id = 0; - int size = 0; - int error = 0; + struct stream *s = (struct stream *)NULL; + int id = 0; + int size = 0; + int error = 0; - if (trans == 0) - { - return 0; - } - if (trans != g_con_trans) - { - return 1; - } - LOGM((LOG_LEVEL_DEBUG, "my_trans_data_in:")); - s = trans_get_in_s(trans); - in_uint32_le(s, id); - in_uint32_le(s, size); - error = trans_force_read(trans, size - 8); - if (error == 0) - { - /* here, the entire message block is read in, process it */ - error = process_message(); - } - return error; + if (trans == 0) + { + return 0; + } + + if (trans != g_con_trans) + { + return 1; + } + + LOGM((LOG_LEVEL_DEBUG, "my_trans_data_in:")); + s = trans_get_in_s(trans); + in_uint32_le(s, id); + in_uint32_le(s, size); + error = trans_force_read(trans, size - 8); + + if (error == 0) + { + /* here, the entire message block is read in, process it */ + error = process_message(); + } + + return error; } /*****************************************************************************/ /* returns error */ int DEFAULT_CC -my_api_trans_data_in(struct trans* trans) +my_api_trans_data_in(struct trans *trans) { - struct stream* s; - int error; - struct xrdp_api_data* ad; + struct stream *s; + int error; + struct xrdp_api_data *ad; - LOG(10, ("my_api_trans_data_in:")); - if (trans == 0) - { - return 0; - } - if (trans != g_api_con_trans) - { - return 1; - } - LOGM((LOG_LEVEL_DEBUG, "my_api_trans_data_in:")); - s = trans_get_in_s(trans); - error = g_tcp_recv(trans->sck, s->data, 8192, 0); - if (error > 0) - { - LOG(10, ("my_api_trans_data_in: got data %d", error)); - ad = (struct xrdp_api_data*)(trans->callback_data); - if (send_channel_data(ad->chan_id, s->data, error) != 0) + LOG(10, ("my_api_trans_data_in:")); + + if (trans == 0) { - LOG(0, ("my_api_trans_data_in: send_channel_data failed")); + return 0; } - } - else - { - LOG(10, ("my_api_trans_data_in: g_tcp_recv failed, or disconnected")); - return 1; - } - return 0; + + if (trans != g_api_con_trans) + { + return 1; + } + + LOGM((LOG_LEVEL_DEBUG, "my_api_trans_data_in:")); + s = trans_get_in_s(trans); + error = g_tcp_recv(trans->sck, s->data, 8192, 0); + + if (error > 0) + { + LOG(10, ("my_api_trans_data_in: got data %d", error)); + ad = (struct xrdp_api_data *)(trans->callback_data); + + if (send_channel_data(ad->chan_id, s->data, error) != 0) + { + LOG(0, ("my_api_trans_data_in: send_channel_data failed")); + } + } + else + { + LOG(10, ("my_api_trans_data_in: g_tcp_recv failed, or disconnected")); + return 1; + } + + return 0; } /*****************************************************************************/ int DEFAULT_CC -my_trans_conn_in(struct trans* trans, struct trans* new_trans) +my_trans_conn_in(struct trans *trans, struct trans *new_trans) { - if (trans == 0) - { - return 1; - } - if (trans != g_lis_trans) - { - return 1; - } - if (g_con_trans != 0) /* if already set, error */ - { - return 1; - } - if (new_trans == 0) - { - return 1; - } - LOGM((LOG_LEVEL_DEBUG, "my_trans_conn_in:")); - g_con_trans = new_trans; - g_con_trans->trans_data_in = my_trans_data_in; - g_con_trans->header_size = 8; - /* stop listening */ - trans_delete(g_lis_trans); - g_lis_trans = 0; - return 0; + if (trans == 0) + { + return 1; + } + + if (trans != g_lis_trans) + { + return 1; + } + + if (g_con_trans != 0) /* if already set, error */ + { + return 1; + } + + if (new_trans == 0) + { + return 1; + } + + LOGM((LOG_LEVEL_DEBUG, "my_trans_conn_in:")); + g_con_trans = new_trans; + g_con_trans->trans_data_in = my_trans_data_in; + g_con_trans->header_size = 8; + /* stop listening */ + trans_delete(g_lis_trans); + g_lis_trans = 0; + return 0; } /*****************************************************************************/ int DEFAULT_CC -my_api_trans_conn_in(struct trans* trans, struct trans* new_trans) +my_api_trans_conn_in(struct trans *trans, struct trans *new_trans) { - struct xrdp_api_data* ad; - int error; - int index; - int found; - struct stream* s; - - if (trans == 0) - { - return 1; - } - if (trans != g_api_lis_trans) - { - return 1; - } - if (new_trans == 0) - { - return 1; - } - LOGM((LOG_LEVEL_DEBUG, "my_api_trans_conn_in:")); + struct xrdp_api_data *ad; + int error; + int index; + int found; + struct stream *s; - LOG(10, ("my_api_trans_conn_in: got incoming")); + if (trans == 0) + { + return 1; + } - s = trans_get_in_s(new_trans); - s->end = s->data; - error = trans_force_read(new_trans, 64); - if (error != 0) - { - LOG(0, ("my_api_trans_conn_in: trans_force_read failed")); - trans_delete(new_trans); - } - s->end = s->data; + if (trans != g_api_lis_trans) + { + return 1; + } + + if (new_trans == 0) + { + return 1; + } - ad = (struct xrdp_api_data*)g_malloc(sizeof(struct xrdp_api_data), 1); + LOGM((LOG_LEVEL_DEBUG, "my_api_trans_conn_in:")); + + LOG(10, ("my_api_trans_conn_in: got incoming")); + + s = trans_get_in_s(new_trans); + s->end = s->data; + error = trans_force_read(new_trans, 64); + + if (error != 0) + { + LOG(0, ("my_api_trans_conn_in: trans_force_read failed")); + trans_delete(new_trans); + } - g_memcpy(ad->header, s->data, 64); + s->end = s->data; - ad->flags = GGET_UINT32(ad->header, 16); + ad = (struct xrdp_api_data *)g_malloc(sizeof(struct xrdp_api_data), 1); + + g_memcpy(ad->header, s->data, 64); + + ad->flags = GGET_UINT32(ad->header, 16); - found = 0; - if (ad->flags | 1) /* WTS_CHANNEL_OPTION_DYNAMIC */ - { - /* TODO */ found = 0; - } - else - { - for (index = 0; index < g_num_chan_items; index++) + + if (ad->flags | 1) /* WTS_CHANNEL_OPTION_DYNAMIC */ + { + /* TODO */ + found = 0; + } + else + { + for (index = 0; index < g_num_chan_items; index++) + { + LOG(10, (" %s %s", ad->header, g_chan_items[index].name)); + + if (g_strcasecmp(ad->header, g_chan_items[index].name) == 0) + { + LOG(10, ("my_api_trans_conn_in: found it at %d", index)); + ad->chan_id = g_chan_items[index].id; + found = 1; + break; + } + } + } + + LOG(10, ("my_api_trans_conn_in: found %d", found)); + + if (!found) { - LOG(10, (" %s %s", ad->header, g_chan_items[index].name)); - if (g_strcasecmp(ad->header, g_chan_items[index].name) == 0) - { - LOG(10, ("my_api_trans_conn_in: found it at %d", index)); - ad->chan_id = g_chan_items[index].id; - found = 1; - break; - } + ad->chan_id = -1; } - } - LOG(10, ("my_api_trans_conn_in: found %d", found)); - if (!found) - { - ad->chan_id = -1; - } - new_trans->callback_data = ad; + new_trans->callback_data = ad; - trans_delete(g_api_con_trans); - g_api_con_trans = new_trans; - g_api_con_trans->trans_data_in = my_api_trans_data_in; - g_api_con_trans->header_size = 0; + trans_delete(g_api_con_trans); + g_api_con_trans = new_trans; + g_api_con_trans->trans_data_in = my_api_trans_data_in; + g_api_con_trans->header_size = 0; - return 0; + return 0; } /*****************************************************************************/ static int APP_CC setup_listen(void) { - char port[256]; - int error = 0; + char port[256]; + int error = 0; - if (g_lis_trans != 0) - { - trans_delete(g_lis_trans); - } - if (g_use_unix_socket) - { - g_lis_trans = trans_create(2, 8192, 8192); - g_snprintf(port, 255, "/tmp/.xrdp/xrdp_chansrv_socket_%d", - 7200 + g_display_num); - } - else - { - g_lis_trans = trans_create(1, 8192, 8192); - g_snprintf(port, 255, "%d", 7200 + g_display_num); - } - g_lis_trans->trans_conn_in = my_trans_conn_in; - error = trans_listen(g_lis_trans, port); - if (error != 0) - { - LOGM((LOG_LEVEL_ERROR, "setup_listen: trans_listen failed for port %s", - port)); - return 1; - } - return 0; + if (g_lis_trans != 0) + { + trans_delete(g_lis_trans); + } + + if (g_use_unix_socket) + { + g_lis_trans = trans_create(2, 8192, 8192); + g_snprintf(port, 255, "/tmp/.xrdp/xrdp_chansrv_socket_%d", + 7200 + g_display_num); + } + else + { + g_lis_trans = trans_create(1, 8192, 8192); + g_snprintf(port, 255, "%d", 7200 + g_display_num); + } + + g_lis_trans->trans_conn_in = my_trans_conn_in; + error = trans_listen(g_lis_trans, port); + + if (error != 0) + { + LOGM((LOG_LEVEL_ERROR, "setup_listen: trans_listen failed for port %s", + port)); + return 1; + } + + return 0; } /*****************************************************************************/ static int APP_CC setup_api_listen(void) { - char port[256]; - int error = 0; - - g_api_lis_trans = trans_create(2, 8192, 8192); - g_snprintf(port, 255, "/tmp/.xrdp/xrdpapi_%d", g_display_num); - g_api_lis_trans->trans_conn_in = my_api_trans_conn_in; - error = trans_listen(g_api_lis_trans, port); - if (error != 0) - { - LOGM((LOG_LEVEL_ERROR, "setup_api_listen: trans_listen failed for port %s", - port)); - return 1; - } - return 0; + char port[256]; + int error = 0; + + g_api_lis_trans = trans_create(2, 8192, 8192); + g_snprintf(port, 255, "/tmp/.xrdp/xrdpapi_%d", g_display_num); + g_api_lis_trans->trans_conn_in = my_api_trans_conn_in; + error = trans_listen(g_api_lis_trans, port); + + if (error != 0) + { + LOGM((LOG_LEVEL_ERROR, "setup_api_listen: trans_listen failed for port %s", + port)); + return 1; + } + + return 0; } /*****************************************************************************/ THREAD_RV THREAD_CC -channel_thread_loop(void* in_val) +channel_thread_loop(void *in_val) { - tbus objs[32]; - int num_objs; - int timeout; - int error; - THREAD_RV rv; - - LOGM((LOG_LEVEL_INFO, "channel_thread_loop: thread start")); - rv = 0; - setup_api_listen(); - error = setup_listen(); - if (error == 0) - { - timeout = -1; - num_objs = 0; - objs[num_objs] = g_term_event; - num_objs++; - trans_get_wait_objs(g_lis_trans, objs, &num_objs); - trans_get_wait_objs(g_api_lis_trans, objs, &num_objs); - while (g_obj_wait(objs, num_objs, 0, 0, timeout) == 0) + tbus objs[32]; + int num_objs; + int timeout; + int error; + THREAD_RV rv; + + LOGM((LOG_LEVEL_INFO, "channel_thread_loop: thread start")); + rv = 0; + setup_api_listen(); + error = setup_listen(); + + if (error == 0) { - if (g_is_wait_obj_set(g_term_event)) - { - LOGM((LOG_LEVEL_INFO, "channel_thread_loop: g_term_event set")); - clipboard_deinit(); - sound_deinit(); - dev_redir_deinit(); - rail_deinit(); - break; - } - if (g_lis_trans != 0) - { - if (trans_check_wait_objs(g_lis_trans) != 0) + timeout = -1; + num_objs = 0; + objs[num_objs] = g_term_event; + num_objs++; + trans_get_wait_objs(g_lis_trans, objs, &num_objs); + trans_get_wait_objs(g_api_lis_trans, objs, &num_objs); + + while (g_obj_wait(objs, num_objs, 0, 0, timeout) == 0) { - LOGM((LOG_LEVEL_INFO, "channel_thread_loop: " - "trans_check_wait_objs error")); + if (g_is_wait_obj_set(g_term_event)) + { + LOGM((LOG_LEVEL_INFO, "channel_thread_loop: g_term_event set")); + clipboard_deinit(); + sound_deinit(); + dev_redir_deinit(); + rail_deinit(); + break; + } + + if (g_lis_trans != 0) + { + if (trans_check_wait_objs(g_lis_trans) != 0) + { + LOGM((LOG_LEVEL_INFO, "channel_thread_loop: " + "trans_check_wait_objs error")); + } + } + + if (g_con_trans != 0) + { + if (trans_check_wait_objs(g_con_trans) != 0) + { + LOGM((LOG_LEVEL_INFO, "channel_thread_loop: " + "trans_check_wait_objs error resetting")); + clipboard_deinit(); + sound_deinit(); + dev_redir_deinit(); + rail_deinit(); + /* delete g_con_trans */ + trans_delete(g_con_trans); + g_con_trans = 0; + /* create new listener */ + error = setup_listen(); + + if (error != 0) + { + break; + } + } + } + + if (g_api_lis_trans != 0) + { + if (trans_check_wait_objs(g_api_lis_trans) != 0) + { + LOG(0, ("channel_thread_loop: trans_check_wait_objs failed")); + } + } + + LOG(10, ("0 %p", g_api_con_trans)); + + if (g_api_con_trans != 0) + { + LOG(10, ("1 %p %d", g_api_con_trans, g_tcp_can_recv(g_api_con_trans->sck, 0))); + + if (trans_check_wait_objs(g_api_con_trans) != 0) + { + LOG(10, ("channel_thread_loop: trans_check_wait_objs failed, " + "or disconnected")); + g_free(g_api_con_trans->callback_data); + trans_delete(g_api_con_trans); + g_api_con_trans = 0; + } + } + + xcommon_check_wait_objs(); + sound_check_wait_objs(); + dev_redir_check_wait_objs(); + timeout = -1; + num_objs = 0; + objs[num_objs] = g_term_event; + num_objs++; + trans_get_wait_objs(g_lis_trans, objs, &num_objs); + trans_get_wait_objs(g_con_trans, objs, &num_objs); + trans_get_wait_objs(g_api_lis_trans, objs, &num_objs); + trans_get_wait_objs(g_api_con_trans, objs, &num_objs); + xcommon_get_wait_objs(objs, &num_objs, &timeout); + sound_get_wait_objs(objs, &num_objs, &timeout); + dev_redir_get_wait_objs(objs, &num_objs, &timeout); } - } - if (g_con_trans != 0) - { - if (trans_check_wait_objs(g_con_trans) != 0) - { - LOGM((LOG_LEVEL_INFO, "channel_thread_loop: " - "trans_check_wait_objs error resetting")); - clipboard_deinit(); - sound_deinit(); - dev_redir_deinit(); - rail_deinit(); - /* delete g_con_trans */ - trans_delete(g_con_trans); - g_con_trans = 0; - /* create new listener */ - error = setup_listen(); - if (error != 0) - { - break; - } - } - } - if (g_api_lis_trans != 0) - { - if (trans_check_wait_objs(g_api_lis_trans) != 0) - { - LOG(0, ("channel_thread_loop: trans_check_wait_objs failed")); - } - } - - LOG(10, ("0 %p", g_api_con_trans)); - if (g_api_con_trans != 0) - { - LOG(10, ("1 %p %d", g_api_con_trans, g_tcp_can_recv(g_api_con_trans->sck, 0))); - if (trans_check_wait_objs(g_api_con_trans) != 0) - { - LOG(10, ("channel_thread_loop: trans_check_wait_objs failed, " - "or disconnected")); - g_free(g_api_con_trans->callback_data); - trans_delete(g_api_con_trans); - g_api_con_trans = 0; - } - } - - xcommon_check_wait_objs(); - sound_check_wait_objs(); - dev_redir_check_wait_objs(); - timeout = -1; - num_objs = 0; - objs[num_objs] = g_term_event; - num_objs++; - trans_get_wait_objs(g_lis_trans, objs, &num_objs); - trans_get_wait_objs(g_con_trans, objs, &num_objs); - trans_get_wait_objs(g_api_lis_trans, objs, &num_objs); - trans_get_wait_objs(g_api_con_trans, objs, &num_objs); - xcommon_get_wait_objs(objs, &num_objs, &timeout); - sound_get_wait_objs(objs, &num_objs, &timeout); - dev_redir_get_wait_objs(objs, &num_objs, &timeout); } - } - trans_delete(g_lis_trans); - g_lis_trans = 0; - trans_delete(g_con_trans); - g_con_trans = 0; - trans_delete(g_api_lis_trans); - g_api_lis_trans = 0; - trans_delete(g_api_con_trans); - g_api_con_trans = 0; - LOGM((LOG_LEVEL_INFO, "channel_thread_loop: thread stop")); - g_set_wait_obj(g_thread_done_event); - return rv; + + trans_delete(g_lis_trans); + g_lis_trans = 0; + trans_delete(g_con_trans); + g_con_trans = 0; + trans_delete(g_api_lis_trans); + g_api_lis_trans = 0; + trans_delete(g_api_con_trans); + g_api_con_trans = 0; + LOGM((LOG_LEVEL_INFO, "channel_thread_loop: thread stop")); + g_set_wait_obj(g_thread_done_event); + return rv; } /*****************************************************************************/ void DEFAULT_CC term_signal_handler(int sig) { - LOGM((LOG_LEVEL_INFO, "term_signal_handler: got signal %d", sig)); - g_set_wait_obj(g_term_event); + LOGM((LOG_LEVEL_INFO, "term_signal_handler: got signal %d", sig)); + g_set_wait_obj(g_term_event); } /*****************************************************************************/ void DEFAULT_CC nil_signal_handler(int sig) { - LOGM((LOG_LEVEL_INFO, "nil_signal_handler: got signal %d", sig)); + LOGM((LOG_LEVEL_INFO, "nil_signal_handler: got signal %d", sig)); } /*****************************************************************************/ void DEFAULT_CC child_signal_handler(int sig) { - int i1; + int i1; - LOG(10, ("child_signal_handler:")); - do - { - i1 = g_waitchild(); - if (i1 == g_exec_pid) + LOG(10, ("child_signal_handler:")); + + do { - LOG(0, ("child_signal_handler: found pid %d", i1)); - //shutdownx(); + i1 = g_waitchild(); + + if (i1 == g_exec_pid) + { + LOG(0, ("child_signal_handler: found pid %d", i1)); + //shutdownx(); + } + + LOG(10, (" %d", i1)); } - LOG(10, (" %d", i1)); - } while (i1 >= 0); + while (i1 >= 0); } /*****************************************************************************/ static int APP_CC -get_display_num_from_display(char* display_text) +get_display_num_from_display(char *display_text) { - int index; - int mode; - int host_index; - int disp_index; - int scre_index; - char host[256]; - char disp[256]; - char scre[256]; - - g_memset(host, 0, 256); - g_memset(disp, 0, 256); - g_memset(scre, 0, 256); - - index = 0; - host_index = 0; - disp_index = 0; - scre_index = 0; - mode = 0; - while (display_text[index] != 0) - { - if (display_text[index] == ':') - { - mode = 1; - } - else if (display_text[index] == '.') - { - mode = 2; - } - else if (mode == 0) - { - host[host_index] = display_text[index]; - host_index++; - } - else if (mode == 1) - { - disp[disp_index] = display_text[index]; - disp_index++; - } - else if (mode == 2) + int index; + int mode; + int host_index; + int disp_index; + int scre_index; + char host[256]; + char disp[256]; + char scre[256]; + + g_memset(host, 0, 256); + g_memset(disp, 0, 256); + g_memset(scre, 0, 256); + + index = 0; + host_index = 0; + disp_index = 0; + scre_index = 0; + mode = 0; + + while (display_text[index] != 0) { - scre[scre_index] = display_text[index]; - scre_index++; + if (display_text[index] == ':') + { + mode = 1; + } + else if (display_text[index] == '.') + { + mode = 2; + } + else if (mode == 0) + { + host[host_index] = display_text[index]; + host_index++; + } + else if (mode == 1) + { + disp[disp_index] = display_text[index]; + disp_index++; + } + else if (mode == 2) + { + scre[scre_index] = display_text[index]; + scre_index++; + } + + index++; } - index++; - } - host[host_index] = 0; - disp[disp_index] = 0; - scre[scre_index] = 0; - g_display_num = g_atoi(disp); - return 0; + + host[host_index] = 0; + disp[disp_index] = 0; + scre[scre_index] = 0; + g_display_num = g_atoi(disp); + return 0; } /*****************************************************************************/ int APP_CC main_cleanup(void) { - g_delete_wait_obj(g_term_event); - g_delete_wait_obj(g_thread_done_event); - g_delete_wait_obj(g_exec_event); - tc_mutex_delete(g_exec_mutex); - g_deinit(); /* os_calls */ - return 0; + g_delete_wait_obj(g_term_event); + g_delete_wait_obj(g_thread_done_event); + g_delete_wait_obj(g_exec_event); + tc_mutex_delete(g_exec_mutex); + g_deinit(); /* os_calls */ + return 0; } /*****************************************************************************/ static int APP_CC read_ini(void) { - char filename[256]; - struct list* names; - struct list* values; - char* name; - char* value; - int index; - - g_memset(filename,0,(sizeof(char) * 256)); - names = list_create(); - names->auto_free = 1; - values = list_create(); - values->auto_free = 1; - g_use_unix_socket = 0; - g_snprintf(filename, 255, "%s/sesman.ini", XRDP_CFG_PATH); - if (file_by_name_read_section(filename, "Globals", names, values) == 0) - { - for (index = 0; index < names->count; index++) + char filename[256]; + struct list *names; + struct list *values; + char *name; + char *value; + int index; + + g_memset(filename, 0, (sizeof(char) * 256)); + names = list_create(); + names->auto_free = 1; + values = list_create(); + values->auto_free = 1; + g_use_unix_socket = 0; + g_snprintf(filename, 255, "%s/sesman.ini", XRDP_CFG_PATH); + + if (file_by_name_read_section(filename, "Globals", names, values) == 0) { - name = (char*)list_get_item(names, index); - value = (char*)list_get_item(values, index); - if (g_strcasecmp(name, "ListenAddress") == 0) - { - if (g_strcasecmp(value, "127.0.0.1") == 0) + for (index = 0; index < names->count; index++) { - g_use_unix_socket = 1; + name = (char *)list_get_item(names, index); + value = (char *)list_get_item(values, index); + + if (g_strcasecmp(name, "ListenAddress") == 0) + { + if (g_strcasecmp(value, "127.0.0.1") == 0) + { + g_use_unix_socket = 1; + } + } } - } } - } - list_delete(names); - list_delete(values); - return 0; + + list_delete(names); + list_delete(values); + return 0; } /*****************************************************************************/ static int APP_CC run_exec(void) { - int pid; + int pid; - LOG(10, ("run_exec:")); - pid = g_fork(); - if (pid == 0) - { - trans_delete(g_con_trans); - g_close_wait_obj(g_term_event); - g_close_wait_obj(g_thread_done_event); - g_close_wait_obj(g_exec_event); - tc_mutex_delete(g_exec_mutex); - tc_sem_delete(g_exec_sem); - g_execlp3(g_exec_name, g_exec_name, 0); - g_exit(0); - } - g_exec_pid = pid; - tc_sem_inc(g_exec_sem); - - return 0; + LOG(10, ("run_exec:")); + pid = g_fork(); + + if (pid == 0) + { + trans_delete(g_con_trans); + g_close_wait_obj(g_term_event); + g_close_wait_obj(g_thread_done_event); + g_close_wait_obj(g_exec_event); + tc_mutex_delete(g_exec_mutex); + tc_sem_delete(g_exec_sem); + g_execlp3(g_exec_name, g_exec_name, 0); + g_exit(0); + } + + g_exec_pid = pid; + tc_sem_inc(g_exec_sem); + + return 0; } /*****************************************************************************/ int DEFAULT_CC -main(int argc, char** argv) +main(int argc, char **argv) { - tbus waiters[4]; - int pid = 0; - char text[256]; - char* home_text; - char* display_text; - char log_file[256]; - enum logReturns error; - struct log_config logconfig; - - g_init("xrdp-chansrv"); /* os_calls */ - - home_text = g_getenv("HOME"); - if (home_text == 0) - { - g_writeln("error reading HOME environment variable"); - g_deinit(); - return 1; - } - - read_ini(); - pid = g_getpid(); - - /* starting logging subsystem */ - g_memset(&logconfig, 0, sizeof(struct log_config)); - logconfig.program_name = "XRDP-Chansrv"; - g_snprintf(log_file, 255, "%s/xrdp-chansrv.log", home_text); - g_writeln("chansrv::main: using log file [%s]", log_file); - if (g_file_exist(log_file)) - { - g_file_delete(log_file); - } - logconfig.log_file = log_file; - logconfig.fd = -1; - logconfig.log_level = LOG_LEVEL_ERROR; - logconfig.enable_syslog = 0; - logconfig.syslog_level = 0; - error = log_start_from_param(&logconfig); - if (error != LOG_STARTUP_OK) - { - switch (error) + tbus waiters[4]; + int pid = 0; + char text[256]; + char *home_text; + char *display_text; + char log_file[256]; + enum logReturns error; + struct log_config logconfig; + + g_init("xrdp-chansrv"); /* os_calls */ + + home_text = g_getenv("HOME"); + + if (home_text == 0) { - case LOG_ERROR_MALLOC: - g_writeln("error on malloc. cannot start logging. quitting."); - break; - case LOG_ERROR_FILE_OPEN: - g_writeln("error opening log file [%s]. quitting.", - getLogFile(text, 255)); - break; - default: - g_writeln("log_start error"); - break; + g_writeln("error reading HOME environment variable"); + g_deinit(); + return 1; } - g_deinit(); - return 1; - } - LOGM((LOG_LEVEL_ALWAYS, "main: app started pid %d(0x%8.8x)", pid, pid)); - /* set up signal handler */ - g_signal_kill(term_signal_handler); /* SIGKILL */ - g_signal_terminate(term_signal_handler); /* SIGTERM */ - g_signal_user_interrupt(term_signal_handler); /* SIGINT */ - g_signal_pipe(nil_signal_handler); /* SIGPIPE */ - g_signal_child_stop(child_signal_handler); /* SIGCHLD */ - display_text = g_getenv("DISPLAY"); - LOGM((LOG_LEVEL_INFO, "main: DISPLAY env var set to %s", display_text)); - get_display_num_from_display(display_text); - if (g_display_num == 0) - { - LOGM((LOG_LEVEL_ERROR, "main: error, display is zero")); - g_deinit(); - return 1; - } - LOGM((LOG_LEVEL_INFO, "main: using DISPLAY %d", g_display_num)); - g_snprintf(text, 255, "xrdp_chansrv_%8.8x_main_term", pid); - g_term_event = g_create_wait_obj(text); - g_snprintf(text, 255, "xrdp_chansrv_%8.8x_thread_done", pid); - g_thread_done_event = g_create_wait_obj(text); - g_snprintf(text, 255, "xrdp_chansrv_%8.8x_exec", pid); - g_exec_event = g_create_wait_obj(text); - g_exec_mutex = tc_mutex_create(); - g_exec_sem = tc_sem_create(0); - tc_thread_create(channel_thread_loop, 0); - while (g_term_event > 0 && !g_is_wait_obj_set(g_term_event)) - { - waiters[0] = g_term_event; - waiters[1] = g_exec_event; - if (g_obj_wait(waiters, 2, 0, 0, 0) != 0) + + read_ini(); + pid = g_getpid(); + + /* starting logging subsystem */ + g_memset(&logconfig, 0, sizeof(struct log_config)); + logconfig.program_name = "XRDP-Chansrv"; + g_snprintf(log_file, 255, "%s/xrdp-chansrv.log", home_text); + g_writeln("chansrv::main: using log file [%s]", log_file); + + if (g_file_exist(log_file)) { - LOGM((LOG_LEVEL_ERROR, "main: error, g_obj_wait failed")); - break; + g_file_delete(log_file); } - if (g_is_wait_obj_set(g_term_event)) + + logconfig.log_file = log_file; + logconfig.fd = -1; + logconfig.log_level = LOG_LEVEL_ERROR; + logconfig.enable_syslog = 0; + logconfig.syslog_level = 0; + error = log_start_from_param(&logconfig); + + if (error != LOG_STARTUP_OK) + { + switch (error) + { + case LOG_ERROR_MALLOC: + g_writeln("error on malloc. cannot start logging. quitting."); + break; + case LOG_ERROR_FILE_OPEN: + g_writeln("error opening log file [%s]. quitting.", + getLogFile(text, 255)); + break; + default: + g_writeln("log_start error"); + break; + } + + g_deinit(); + return 1; + } + + LOGM((LOG_LEVEL_ALWAYS, "main: app started pid %d(0x%8.8x)", pid, pid)); + /* set up signal handler */ + g_signal_kill(term_signal_handler); /* SIGKILL */ + g_signal_terminate(term_signal_handler); /* SIGTERM */ + g_signal_user_interrupt(term_signal_handler); /* SIGINT */ + g_signal_pipe(nil_signal_handler); /* SIGPIPE */ + g_signal_child_stop(child_signal_handler); /* SIGCHLD */ + display_text = g_getenv("DISPLAY"); + LOGM((LOG_LEVEL_INFO, "main: DISPLAY env var set to %s", display_text)); + get_display_num_from_display(display_text); + + if (g_display_num == 0) { - break; + LOGM((LOG_LEVEL_ERROR, "main: error, display is zero")); + g_deinit(); + return 1; } - if (g_is_wait_obj_set(g_exec_event)) + + LOGM((LOG_LEVEL_INFO, "main: using DISPLAY %d", g_display_num)); + g_snprintf(text, 255, "xrdp_chansrv_%8.8x_main_term", pid); + g_term_event = g_create_wait_obj(text); + g_snprintf(text, 255, "xrdp_chansrv_%8.8x_thread_done", pid); + g_thread_done_event = g_create_wait_obj(text); + g_snprintf(text, 255, "xrdp_chansrv_%8.8x_exec", pid); + g_exec_event = g_create_wait_obj(text); + g_exec_mutex = tc_mutex_create(); + g_exec_sem = tc_sem_create(0); + tc_thread_create(channel_thread_loop, 0); + + while (g_term_event > 0 && !g_is_wait_obj_set(g_term_event)) { - g_reset_wait_obj(g_exec_event); - run_exec(); + waiters[0] = g_term_event; + waiters[1] = g_exec_event; + + if (g_obj_wait(waiters, 2, 0, 0, 0) != 0) + { + LOGM((LOG_LEVEL_ERROR, "main: error, g_obj_wait failed")); + break; + } + + if (g_is_wait_obj_set(g_term_event)) + { + break; + } + + if (g_is_wait_obj_set(g_exec_event)) + { + g_reset_wait_obj(g_exec_event); + run_exec(); + } } - } - while (g_thread_done_event > 0 && !g_is_wait_obj_set(g_thread_done_event)) - { - /* wait for thread to exit */ - if (g_obj_wait(&g_thread_done_event, 1, 0, 0, 0) != 0) + + while (g_thread_done_event > 0 && !g_is_wait_obj_set(g_thread_done_event)) { - LOGM((LOG_LEVEL_ERROR, "main: error, g_obj_wait failed")); - break; + /* wait for thread to exit */ + if (g_obj_wait(&g_thread_done_event, 1, 0, 0, 0) != 0) + { + LOGM((LOG_LEVEL_ERROR, "main: error, g_obj_wait failed")); + break; + } } - } - /* cleanup */ - main_cleanup(); - LOGM((LOG_LEVEL_INFO, "main: app exiting pid %d(0x%8.8x)", pid, pid)); - g_deinit(); - return 0; + + /* cleanup */ + main_cleanup(); + LOGM((LOG_LEVEL_INFO, "main: app exiting pid %d(0x%8.8x)", pid, pid)); + g_deinit(); + return 0; } diff --git a/sesman/chansrv/clipboard.c b/sesman/chansrv/clipboard.c index 3bea9704..1541170d 100644 --- a/sesman/chansrv/clipboard.c +++ b/sesman/chansrv/clipboard.c @@ -48,10 +48,10 @@ static char g_bmp_image_header[] = extern int g_cliprdr_chan_id; /* in chansrv.c */ -extern Display* g_display; /* in xcommon.c */ +extern Display *g_display; /* in xcommon.c */ extern int g_x_socket; /* in xcommon.c */ extern tbus g_x_wait_obj; /* in xcommon.c */ -extern Screen* g_screen; /* in xcommon.c */ +extern Screen *g_screen; /* in xcommon.c */ extern int g_screen_num; /* in xcommon.c */ int g_clip_up = 0; @@ -73,18 +73,18 @@ static Window g_wnd = 0; static int g_xfixes_event_base = 0; static int g_last_clip_size = 0; -static char* g_last_clip_data = 0; +static char *g_last_clip_data = 0; static Atom g_last_clip_type = 0; static int g_got_selection = 0; /* boolean */ static Time g_selection_time = 0; -static struct stream* g_ins = 0; +static struct stream *g_ins = 0; static XSelectionRequestEvent g_selection_request_event[16]; static int g_selection_request_event_count = 0; -static char* g_data_in = 0; +static char *g_data_in = 0; static int g_data_in_size = 0; static int g_data_in_time = 0; static int g_data_in_up_to_date = 0; @@ -98,7 +98,7 @@ static XSelectionRequestEvent g_saved_selection_req_event; static Atom g_incr_atom; static Atom g_incr_atom_type; static Atom g_incr_atom_target; -static char* g_incr_data = 0; +static char *g_incr_data = 0; static int g_incr_data_size = 0; static int g_incr_in_progress = 0; @@ -109,19 +109,22 @@ static int clipboard_format_id = CB_FORMAT_UNICODETEXT; static Time APP_CC clipboard_get_server_time(void) { - XEvent xevent; - unsigned char no_text[4]; - - /* append nothing */ - no_text[0] = 0; - XChangeProperty(g_display, g_wnd, g_get_time_atom, XA_STRING, 8, - PropModeAppend, no_text, 0); - /* wait for PropertyNotify */ - do - { - XMaskEvent(g_display, PropertyChangeMask, &xevent); - } while (xevent.type != PropertyNotify); - return xevent.xproperty.time; + XEvent xevent; + unsigned char no_text[4]; + + /* append nothing */ + no_text[0] = 0; + XChangeProperty(g_display, g_wnd, g_get_time_atom, XA_STRING, 8, + PropModeAppend, no_text, 0); + + /* wait for PropertyNotify */ + do + { + XMaskEvent(g_display, PropertyChangeMask, &xevent); + } + while (xevent.type != PropertyNotify); + + return xevent.xproperty.time; } /*****************************************************************************/ @@ -132,7 +135,7 @@ clipboard_get_server_time(void) static int APP_CC clipboard_get_local_time(void) { - return g_time3(); + return g_time3(); } /*****************************************************************************/ @@ -140,386 +143,416 @@ clipboard_get_local_time(void) int APP_CC clipboard_init(void) { - struct stream* s; - int size; - int rv; - int input_mask; - int dummy; - int ver_maj; - int ver_min; - Status st; - - LOGM((LOG_LEVEL_DEBUG, "xrdp-chansrv: in clipboard_init")); - if (g_clip_up) - { - return 0; - } - xcommon_init(); - clipboard_deinit(); - rv = 0; - if (rv == 0) - { - g_clipboard_atom = XInternAtom(g_display, "CLIPBOARD", False); - if (g_clipboard_atom == None) + struct stream *s; + int size; + int rv; + int input_mask; + int dummy; + int ver_maj; + int ver_min; + Status st; + + LOGM((LOG_LEVEL_DEBUG, "xrdp-chansrv: in clipboard_init")); + + if (g_clip_up) { - LOGM((LOG_LEVEL_ERROR, "clipboard_init: XInternAtom failed")); - rv = 3; + return 0; } - } - if (rv == 0) - { - if (!XFixesQueryExtension(g_display, &g_xfixes_event_base, &dummy)) + + xcommon_init(); + clipboard_deinit(); + rv = 0; + + if (rv == 0) { - LOGM((LOG_LEVEL_ERROR, "clipboard_init: no xfixes")); - rv = 5; + g_clipboard_atom = XInternAtom(g_display, "CLIPBOARD", False); + + if (g_clipboard_atom == None) + { + LOGM((LOG_LEVEL_ERROR, "clipboard_init: XInternAtom failed")); + rv = 3; + } } - } - if (rv == 0) - { - LOGM((LOG_LEVEL_DEBUG, "clipboard_init: g_xfixes_event_base %d", - g_xfixes_event_base)); - st = XFixesQueryVersion(g_display, &ver_maj, &ver_min); - LOGM((LOG_LEVEL_DEBUG, "clipboard_init st %d, maj %d min %d", st, - ver_maj, ver_min)); - g_clip_property_atom = XInternAtom(g_display, "XRDP_CLIP_PROPERTY_ATOM", - False); - g_get_time_atom = XInternAtom(g_display, "XRDP_GET_TIME_ATOM", - False); - g_timestamp_atom = XInternAtom(g_display, "TIMESTAMP", False); - g_targets_atom = XInternAtom(g_display, "TARGETS", False); - g_multiple_atom = XInternAtom(g_display, "MULTIPLE", False); - g_primary_atom = XInternAtom(g_display, "PRIMARY", False); - g_secondary_atom = XInternAtom(g_display, "SECONDARY", False); - g_utf8_atom = XInternAtom(g_display, "UTF8_STRING", False); - - g_image_bmp_atom = XInternAtom(g_display, "image/bmp", False); - g_incr_atom = XInternAtom(g_display, "INCR", False); - if (g_image_bmp_atom == None) + + if (rv == 0) { - LOGM((LOG_LEVEL_ERROR, "clipboard_init: g_image_bmp_atom was " - "not allocated")); + if (!XFixesQueryExtension(g_display, &g_xfixes_event_base, &dummy)) + { + LOGM((LOG_LEVEL_ERROR, "clipboard_init: no xfixes")); + rv = 5; + } } - g_wnd = XCreateSimpleWindow(g_display, RootWindowOfScreen(g_screen), - 0, 0, 4, 4, 0, 0, 0); - input_mask = StructureNotifyMask | PropertyChangeMask; - XSelectInput(g_display, g_wnd, input_mask); - //XMapWindow(g_display, g_wnd); - XFixesSelectSelectionInput(g_display, g_wnd, - g_clipboard_atom, - XFixesSetSelectionOwnerNotifyMask | - XFixesSelectionWindowDestroyNotifyMask | - XFixesSelectionClientCloseNotifyMask); - } - if (rv == 0) - { - make_stream(s); - init_stream(s, 8192); - out_uint16_le(s, 1); /* CLIPRDR_CONNECT */ - out_uint16_le(s, 0); /* status */ - out_uint32_le(s, 0); /* length */ - out_uint32_le(s, 0); /* extra 4 bytes ? */ - s_mark_end(s); - size = (int)(s->end - s->data); - LOGM((LOG_LEVEL_DEBUG, "clipboard_init: data out, sending " - "CLIPRDR_CONNECT (clip_msg_id = 1)")); - rv = send_channel_data(g_cliprdr_chan_id, s->data, size); - if (rv != 0) + if (rv == 0) { - LOGM((LOG_LEVEL_ERROR, "clipboard_init: send_channel_data failed " - "rv = %d", rv)); - rv = 4; + LOGM((LOG_LEVEL_DEBUG, "clipboard_init: g_xfixes_event_base %d", + g_xfixes_event_base)); + st = XFixesQueryVersion(g_display, &ver_maj, &ver_min); + LOGM((LOG_LEVEL_DEBUG, "clipboard_init st %d, maj %d min %d", st, + ver_maj, ver_min)); + g_clip_property_atom = XInternAtom(g_display, "XRDP_CLIP_PROPERTY_ATOM", + False); + g_get_time_atom = XInternAtom(g_display, "XRDP_GET_TIME_ATOM", + False); + g_timestamp_atom = XInternAtom(g_display, "TIMESTAMP", False); + g_targets_atom = XInternAtom(g_display, "TARGETS", False); + g_multiple_atom = XInternAtom(g_display, "MULTIPLE", False); + g_primary_atom = XInternAtom(g_display, "PRIMARY", False); + g_secondary_atom = XInternAtom(g_display, "SECONDARY", False); + g_utf8_atom = XInternAtom(g_display, "UTF8_STRING", False); + + g_image_bmp_atom = XInternAtom(g_display, "image/bmp", False); + g_incr_atom = XInternAtom(g_display, "INCR", False); + + if (g_image_bmp_atom == None) + { + LOGM((LOG_LEVEL_ERROR, "clipboard_init: g_image_bmp_atom was " + "not allocated")); + } + + g_wnd = XCreateSimpleWindow(g_display, RootWindowOfScreen(g_screen), + 0, 0, 4, 4, 0, 0, 0); + input_mask = StructureNotifyMask | PropertyChangeMask; + XSelectInput(g_display, g_wnd, input_mask); + //XMapWindow(g_display, g_wnd); + XFixesSelectSelectionInput(g_display, g_wnd, + g_clipboard_atom, + XFixesSetSelectionOwnerNotifyMask | + XFixesSelectionWindowDestroyNotifyMask | + XFixesSelectionClientCloseNotifyMask); } - free_stream(s); - } - if (rv == 0) - { - g_clip_up = 1; - make_stream(g_ins); - init_stream(g_ins, 8192); - } - else - { - LOGM((LOG_LEVEL_ERROR, "xrdp-chansrv: clipboard_init: error on exit")); - } - return rv; + + if (rv == 0) + { + make_stream(s); + init_stream(s, 8192); + out_uint16_le(s, 1); /* CLIPRDR_CONNECT */ + out_uint16_le(s, 0); /* status */ + out_uint32_le(s, 0); /* length */ + out_uint32_le(s, 0); /* extra 4 bytes ? */ + s_mark_end(s); + size = (int)(s->end - s->data); + LOGM((LOG_LEVEL_DEBUG, "clipboard_init: data out, sending " + "CLIPRDR_CONNECT (clip_msg_id = 1)")); + rv = send_channel_data(g_cliprdr_chan_id, s->data, size); + + if (rv != 0) + { + LOGM((LOG_LEVEL_ERROR, "clipboard_init: send_channel_data failed " + "rv = %d", rv)); + rv = 4; + } + + free_stream(s); + } + + if (rv == 0) + { + g_clip_up = 1; + make_stream(g_ins); + init_stream(g_ins, 8192); + } + else + { + LOGM((LOG_LEVEL_ERROR, "xrdp-chansrv: clipboard_init: error on exit")); + } + + return rv; } /*****************************************************************************/ int APP_CC clipboard_deinit(void) { - if (g_wnd != 0) - { - XDestroyWindow(g_display, g_wnd); - g_wnd = 0; - } - g_free(g_last_clip_data); - g_last_clip_data = 0; - g_last_clip_size = 0; - free_stream(g_ins); - g_ins = 0; - g_clip_up = 0; - return 0; + if (g_wnd != 0) + { + XDestroyWindow(g_display, g_wnd); + g_wnd = 0; + } + + g_free(g_last_clip_data); + g_last_clip_data = 0; + g_last_clip_size = 0; + free_stream(g_ins); + g_ins = 0; + g_clip_up = 0; + return 0; } /*****************************************************************************/ static int APP_CC clipboard_send_data_request(void) { - struct stream* s; - int size; - int rv; - - LOGM((LOG_LEVEL_DEBUG, "clipboard_send_data_request:")); - if (!g_got_format_announce) - { - LOGM((LOG_LEVEL_ERROR, "clipboard_send_data_request: error, " - "no format announce")); - return 0; - } - g_got_format_announce = 0; - make_stream(s); - init_stream(s, 8192); - out_uint16_le(s, 4); /* CLIPRDR_DATA_REQUEST */ - out_uint16_le(s, 0); /* status */ - out_uint32_le(s, 4); /* length */ - out_uint32_le(s, clipboard_format_id); - s_mark_end(s); - size = (int)(s->end - s->data); - LOGM((LOG_LEVEL_DEBUG,"clipboard_send_data_request: data out, sending " - "CLIPRDR_DATA_REQUEST (clip_msg_id = 4)")); - rv = send_channel_data(g_cliprdr_chan_id, s->data, size); - free_stream(s); - return rv; + struct stream *s; + int size; + int rv; + + LOGM((LOG_LEVEL_DEBUG, "clipboard_send_data_request:")); + + if (!g_got_format_announce) + { + LOGM((LOG_LEVEL_ERROR, "clipboard_send_data_request: error, " + "no format announce")); + return 0; + } + + g_got_format_announce = 0; + make_stream(s); + init_stream(s, 8192); + out_uint16_le(s, 4); /* CLIPRDR_DATA_REQUEST */ + out_uint16_le(s, 0); /* status */ + out_uint32_le(s, 4); /* length */ + out_uint32_le(s, clipboard_format_id); + s_mark_end(s); + size = (int)(s->end - s->data); + LOGM((LOG_LEVEL_DEBUG, "clipboard_send_data_request: data out, sending " + "CLIPRDR_DATA_REQUEST (clip_msg_id = 4)")); + rv = send_channel_data(g_cliprdr_chan_id, s->data, size); + free_stream(s); + return rv; } /*****************************************************************************/ static int APP_CC clipboard_send_format_ack(void) { - struct stream* s; - int size; - int rv; - - make_stream(s); - init_stream(s, 8192); - out_uint16_le(s, 3); /* CLIPRDR_FORMAT_ACK */ - out_uint16_le(s, 1); /* status */ - out_uint32_le(s, 0); /* length */ - out_uint32_le(s, 0); /* extra 4 bytes ? */ - s_mark_end(s); - size = (int)(s->end - s->data); - LOGM((LOG_LEVEL_DEBUG,"clipboard_send_format_ack: data out, sending " - "CLIPRDR_FORMAT_ACK (clip_msg_id = 3)")); - rv = send_channel_data(g_cliprdr_chan_id, s->data, size); - free_stream(s); - return rv; + struct stream *s; + int size; + int rv; + + make_stream(s); + init_stream(s, 8192); + out_uint16_le(s, 3); /* CLIPRDR_FORMAT_ACK */ + out_uint16_le(s, 1); /* status */ + out_uint32_le(s, 0); /* length */ + out_uint32_le(s, 0); /* extra 4 bytes ? */ + s_mark_end(s); + size = (int)(s->end - s->data); + LOGM((LOG_LEVEL_DEBUG, "clipboard_send_format_ack: data out, sending " + "CLIPRDR_FORMAT_ACK (clip_msg_id = 3)")); + rv = send_channel_data(g_cliprdr_chan_id, s->data, size); + free_stream(s); + return rv; } static char windows_native_format[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; /*****************************************************************************/ static int APP_CC -clipboard_send_format_announce(tui32 format_id, char* format_name) +clipboard_send_format_announce(tui32 format_id, char *format_name) { - struct stream* s; - int size; - int rv; - - make_stream(s); - init_stream(s, 8192); - out_uint16_le(s, 2); /* CLIPRDR_FORMAT_ANNOUNCE */ - out_uint16_le(s, 0); /* status */ - out_uint32_le(s, 4 + sizeof(windows_native_format)); /* length */ - out_uint32_le(s, format_id); - out_uint8p(s, windows_native_format, sizeof(windows_native_format)); - s_mark_end(s); - size = (int)(s->end - s->data); - LOGM((LOG_LEVEL_DEBUG,"clipboard_send_format_announce: data out, sending " - "CLIPRDR_FORMAT_ANNOUNCE (clip_msg_id = 2)")); - rv = send_channel_data(g_cliprdr_chan_id, s->data, size); - free_stream(s); - return rv; + struct stream *s; + int size; + int rv; + + make_stream(s); + init_stream(s, 8192); + out_uint16_le(s, 2); /* CLIPRDR_FORMAT_ANNOUNCE */ + out_uint16_le(s, 0); /* status */ + out_uint32_le(s, 4 + sizeof(windows_native_format)); /* length */ + out_uint32_le(s, format_id); + out_uint8p(s, windows_native_format, sizeof(windows_native_format)); + s_mark_end(s); + size = (int)(s->end - s->data); + LOGM((LOG_LEVEL_DEBUG, "clipboard_send_format_announce: data out, sending " + "CLIPRDR_FORMAT_ANNOUNCE (clip_msg_id = 2)")); + rv = send_channel_data(g_cliprdr_chan_id, s->data, size); + free_stream(s); + return rv; } /*****************************************************************************/ /* returns number of bytes written */ static int APP_CC -clipboard_out_unicode(struct stream* s, char* text, int num_chars) +clipboard_out_unicode(struct stream *s, char *text, int num_chars) { - int index; - int lnum_chars; - twchar* ltext; + int index; + int lnum_chars; + twchar *ltext; - if ((num_chars < 1) || (text == 0)) - { - return 0; - } - lnum_chars = g_mbstowcs(0, text, num_chars); - if (lnum_chars < 0) - { - return 0; - } - ltext = g_malloc((num_chars + 1) * sizeof(twchar), 1); - g_mbstowcs(ltext, text, num_chars); - index = 0; - while (index < num_chars) - { - out_uint16_le(s, ltext[index]); - index++; - } - g_free(ltext); - return index * 2; + if ((num_chars < 1) || (text == 0)) + { + return 0; + } + + lnum_chars = g_mbstowcs(0, text, num_chars); + + if (lnum_chars < 0) + { + return 0; + } + + ltext = g_malloc((num_chars + 1) * sizeof(twchar), 1); + g_mbstowcs(ltext, text, num_chars); + index = 0; + + while (index < num_chars) + { + out_uint16_le(s, ltext[index]); + index++; + } + + g_free(ltext); + return index * 2; } /*****************************************************************************/ static int APP_CC clipboard_send_data_response_for_image(void) { - struct stream* s; - int size; - int rv; - - LOG(10, ("clipboard_send_data_response_for_image: g_last_clip_size %d\n", - g_last_clip_size)); - make_stream(s); - init_stream(s, 64 + g_last_clip_size); - out_uint16_le(s, 5); /* CLIPRDR_DATA_RESPONSE */ - out_uint16_le(s, 1); /* status */ - out_uint32_le(s, g_last_clip_size); /* length */ - /* insert image data */ - if (g_last_clip_type == g_image_bmp_atom) - { - /* do not insert first header */ - out_uint8p(s, g_last_clip_data + 14, g_last_clip_size - 14); - } - out_uint16_le(s, 0); /* nil for string */ - out_uint32_le(s, 0); - out_uint32_le(s, 0); - out_uint32_le(s, 0); - s_mark_end(s); - size = (int)(s->end - s->data); - /* HANGING HERE WHEN IMAGE DATA IS TOO BIG!!!! */ - rv = send_channel_data(g_cliprdr_chan_id, s->data, size); - free_stream(s); - return rv; + struct stream *s; + int size; + int rv; + + LOG(10, ("clipboard_send_data_response_for_image: g_last_clip_size %d\n", + g_last_clip_size)); + make_stream(s); + init_stream(s, 64 + g_last_clip_size); + out_uint16_le(s, 5); /* CLIPRDR_DATA_RESPONSE */ + out_uint16_le(s, 1); /* status */ + out_uint32_le(s, g_last_clip_size); /* length */ + + /* insert image data */ + if (g_last_clip_type == g_image_bmp_atom) + { + /* do not insert first header */ + out_uint8p(s, g_last_clip_data + 14, g_last_clip_size - 14); + } + + out_uint16_le(s, 0); /* nil for string */ + out_uint32_le(s, 0); + out_uint32_le(s, 0); + out_uint32_le(s, 0); + s_mark_end(s); + size = (int)(s->end - s->data); + /* HANGING HERE WHEN IMAGE DATA IS TOO BIG!!!! */ + rv = send_channel_data(g_cliprdr_chan_id, s->data, size); + free_stream(s); + return rv; } /*****************************************************************************/ static int APP_CC clipboard_send_data_response(void) { - struct stream* s; - int size; - int rv; - int num_chars; - - LOG(10, ("clipboard_send_data_response:")); - num_chars = 0; - if (g_last_clip_data != 0) - { - if (g_last_clip_type == g_image_bmp_atom) + struct stream *s; + int size; + int rv; + int num_chars; + + LOG(10, ("clipboard_send_data_response:")); + num_chars = 0; + + if (g_last_clip_data != 0) { - return clipboard_send_data_response_for_image(); + if (g_last_clip_type == g_image_bmp_atom) + { + return clipboard_send_data_response_for_image(); + } + + if ((g_last_clip_type == XA_STRING) || (g_last_clip_type == g_utf8_atom)) + { + num_chars = g_mbstowcs(0, g_last_clip_data, 0); + + if (num_chars < 0) + { + LOGM((LOG_LEVEL_ERROR, "clipboard_send_data_response: bad string")); + num_chars = 0; + } + } } - if ((g_last_clip_type == XA_STRING) || (g_last_clip_type == g_utf8_atom)) + + LOG(10, ("clipboard_send_data_response: g_last_clip_size %d " + "num_chars %d", g_last_clip_size, num_chars)); + make_stream(s); + init_stream(s, 64 + num_chars * 2); + out_uint16_le(s, 5); /* CLIPRDR_DATA_RESPONSE */ + out_uint16_le(s, 1); /* status */ + out_uint32_le(s, num_chars * 2 + 2); /* length */ + + if (clipboard_out_unicode(s, g_last_clip_data, num_chars) != num_chars * 2) { - num_chars = g_mbstowcs(0, g_last_clip_data, 0); - if (num_chars < 0) - { - LOGM((LOG_LEVEL_ERROR, "clipboard_send_data_response: bad string")); - num_chars = 0; - } + LOGM((LOG_LEVEL_ERROR, "clipboard_send_data_response: error " + "clipboard_out_unicode didn't write right number of bytes")); } - } - LOG(10, ("clipboard_send_data_response: g_last_clip_size %d " - "num_chars %d", g_last_clip_size, num_chars)); - make_stream(s); - init_stream(s, 64 + num_chars * 2); - out_uint16_le(s, 5); /* CLIPRDR_DATA_RESPONSE */ - out_uint16_le(s, 1); /* status */ - out_uint32_le(s, num_chars * 2 + 2); /* length */ - if (clipboard_out_unicode(s, g_last_clip_data, num_chars) != num_chars * 2) - { - LOGM((LOG_LEVEL_ERROR,"clipboard_send_data_response: error " - "clipboard_out_unicode didn't write right number of bytes")); - } - out_uint16_le(s, 0); /* nil for string */ - out_uint32_le(s, 0); - s_mark_end(s); - size = (int)(s->end - s->data); - LOGM((LOG_LEVEL_DEBUG,"clipboard_send_data_response: data out, sending " - "CLIPRDR_DATA_RESPONSE (clip_msg_id = 5) size %d num_chars %d", - size, num_chars)); - rv = send_channel_data(g_cliprdr_chan_id, s->data, size); - free_stream(s); - return rv; + + out_uint16_le(s, 0); /* nil for string */ + out_uint32_le(s, 0); + s_mark_end(s); + size = (int)(s->end - s->data); + LOGM((LOG_LEVEL_DEBUG, "clipboard_send_data_response: data out, sending " + "CLIPRDR_DATA_RESPONSE (clip_msg_id = 5) size %d num_chars %d", + size, num_chars)); + rv = send_channel_data(g_cliprdr_chan_id, s->data, size); + free_stream(s); + return rv; } /*****************************************************************************/ static int APP_CC clipboard_set_selection_owner(void) { - Window owner; + Window owner; - g_selection_time = clipboard_get_server_time(); - XSetSelectionOwner(g_display, g_clipboard_atom, g_wnd, g_selection_time); - owner = XGetSelectionOwner(g_display, g_clipboard_atom); - if (owner != g_wnd) - { - g_got_selection = 0; - return 1; - } - g_got_selection = 1; - return 0; + g_selection_time = clipboard_get_server_time(); + XSetSelectionOwner(g_display, g_clipboard_atom, g_wnd, g_selection_time); + owner = XGetSelectionOwner(g_display, g_clipboard_atom); + + if (owner != g_wnd) + { + g_got_selection = 0; + return 1; + } + + g_got_selection = 1; + return 0; } /*****************************************************************************/ static int APP_CC -clipboard_provide_selection(XSelectionRequestEvent* req, Atom type, int format, - char* data, int length) +clipboard_provide_selection(XSelectionRequestEvent *req, Atom type, int format, + char *data, int length) { - XEvent xev; - - XChangeProperty(g_display, req->requestor, req->property, - type, format, PropModeReplace, (tui8*)data, length); - g_memset(&xev, 0, sizeof(xev)); - xev.xselection.type = SelectionNotify; - xev.xselection.send_event = True; - xev.xselection.display = req->display; - xev.xselection.requestor = req->requestor; - xev.xselection.selection = req->selection; - xev.xselection.target = req->target; - xev.xselection.property = req->property; - xev.xselection.time = req->time; - XSendEvent(g_display, req->requestor, False, NoEventMask, &xev); - return 0; + XEvent xev; + + XChangeProperty(g_display, req->requestor, req->property, + type, format, PropModeReplace, (tui8 *)data, length); + g_memset(&xev, 0, sizeof(xev)); + xev.xselection.type = SelectionNotify; + xev.xselection.send_event = True; + xev.xselection.display = req->display; + xev.xselection.requestor = req->requestor; + xev.xselection.selection = req->selection; + xev.xselection.target = req->target; + xev.xselection.property = req->property; + xev.xselection.time = req->time; + XSendEvent(g_display, req->requestor, False, NoEventMask, &xev); + return 0; } /*****************************************************************************/ static int APP_CC -clipboard_refuse_selection(XSelectionRequestEvent* req) +clipboard_refuse_selection(XSelectionRequestEvent *req) { - XEvent xev; - - g_memset(&xev, 0, sizeof(xev)); - xev.xselection.type = SelectionNotify; - xev.xselection.send_event = True; - xev.xselection.display = req->display; - xev.xselection.requestor = req->requestor; - xev.xselection.selection = req->selection; - xev.xselection.target = req->target; - xev.xselection.property = None; - xev.xselection.time = req->time; - XSendEvent(g_display, req->requestor, False, NoEventMask, &xev); - return 0; + XEvent xev; + + g_memset(&xev, 0, sizeof(xev)); + xev.xselection.type = SelectionNotify; + xev.xselection.send_event = True; + xev.xselection.display = req->display; + xev.xselection.requestor = req->requestor; + xev.xselection.selection = req->selection; + xev.xselection.target = req->target; + xev.xselection.property = None; + xev.xselection.time = req->time; + XSendEvent(g_display, req->requestor, False, NoEventMask, &xev); + return 0; } /*****************************************************************************/ @@ -527,47 +560,49 @@ clipboard_refuse_selection(XSelectionRequestEvent* req) updated with new clipboard data; contains Clipboard Format ID and name pairs of new Clipboard Formats on the clipboard. */ static int APP_CC -clipboard_process_format_announce(struct stream* s, int clip_msg_status, +clipboard_process_format_announce(struct stream *s, int clip_msg_status, int clip_msg_len) { - LOGM((LOG_LEVEL_DEBUG, "clipboard_process_format_announce: " - "CLIPRDR_FORMAT_ANNOUNCE")); - //g_hexdump(s->p, s->end - s->p); - clipboard_send_format_ack(); - g_got_format_announce = 1; - g_data_in_up_to_date = 0; - if (clipboard_set_selection_owner() != 0) - { - LOGM((LOG_LEVEL_ERROR, "clipboard_process_format_announce: " - "XSetSelectionOwner failed")); - } - return 0; + LOGM((LOG_LEVEL_DEBUG, "clipboard_process_format_announce: " + "CLIPRDR_FORMAT_ANNOUNCE")); + //g_hexdump(s->p, s->end - s->p); + clipboard_send_format_ack(); + g_got_format_announce = 1; + g_data_in_up_to_date = 0; + + if (clipboard_set_selection_owner() != 0) + { + LOGM((LOG_LEVEL_ERROR, "clipboard_process_format_announce: " + "XSetSelectionOwner failed")); + } + + return 0; } /*****************************************************************************/ /* response to CB_FORMAT_LIST; used to indicate whether processing of the Format List PDU was successful */ static int APP_CC -clipboard_prcoess_format_ack(struct stream* s, int clip_msg_status, +clipboard_prcoess_format_ack(struct stream *s, int clip_msg_status, int clip_msg_len) { - LOGM((LOG_LEVEL_DEBUG,"clipboard_prcoess_format_ack: CLIPRDR_FORMAT_ACK")); - //g_hexdump(s->p, s->end - s->p); - return 0; + LOGM((LOG_LEVEL_DEBUG, "clipboard_prcoess_format_ack: CLIPRDR_FORMAT_ACK")); + //g_hexdump(s->p, s->end - s->p); + return 0; } /*****************************************************************************/ /* sent by recipient of CB_FORMAT_LIST; used to request data for one of the formats that was listed in CB_FORMAT_LIST */ static int APP_CC -clipboard_process_data_request(struct stream* s, int clip_msg_status, +clipboard_process_data_request(struct stream *s, int clip_msg_status, int clip_msg_len) { - LOGM((LOG_LEVEL_DEBUG,"clipboard_process_data_request: " - "CLIPRDR_DATA_REQUEST")); - //g_hexdump(s->p, s->end - s->p); - clipboard_send_data_response(); - return 0; + LOGM((LOG_LEVEL_DEBUG, "clipboard_process_data_request: " + "CLIPRDR_DATA_REQUEST")); + //g_hexdump(s->p, s->end - s->p); + clipboard_send_data_response(); + return 0; } /*****************************************************************************/ @@ -576,54 +611,61 @@ clipboard_process_data_request(struct stream* s, int clip_msg_status, was successful, CB_FORMAT_DATA_RESPONSE includes contents of requested clipboard data. */ static int APP_CC -clipboard_process_data_response_for_image(struct stream * s, - int clip_msg_status, - int clip_msg_len) +clipboard_process_data_response_for_image(struct stream *s, + int clip_msg_status, + int clip_msg_len) { - XSelectionRequestEvent* lxev = &g_saved_selection_req_event; - char* cptr; - char cdata; - int len; - int index; - - LOGM((LOG_LEVEL_DEBUG, "clipboard_process_data_response_for_image: " - "CLIPRDR_DATA_RESPONSE_FOR_IMAGE")); - g_waiting_for_data_response = 0; - len = (int)(s->end - s->p); - if (len < 1) - { - return 0; - } - if (g_last_clip_type == g_image_bmp_atom) - { - /* space for inserting bmp image header */ - len += 14; - cptr = (char*)g_malloc(len, 0); - if (cptr == 0) + XSelectionRequestEvent *lxev = &g_saved_selection_req_event; + char *cptr; + char cdata; + int len; + int index; + + LOGM((LOG_LEVEL_DEBUG, "clipboard_process_data_response_for_image: " + "CLIPRDR_DATA_RESPONSE_FOR_IMAGE")); + g_waiting_for_data_response = 0; + len = (int)(s->end - s->p); + + if (len < 1) + { + return 0; + } + + if (g_last_clip_type == g_image_bmp_atom) { - return 0; + /* space for inserting bmp image header */ + len += 14; + cptr = (char *)g_malloc(len, 0); + + if (cptr == 0) + { + return 0; + } + + g_memcpy(cptr, g_bmp_image_header, 14); + index = 14; } - g_memcpy(cptr, g_bmp_image_header, 14); - index = 14; - } - else - { + else + { + return 0; + } + + while (s_check(s)) + { + in_uint8(s, cdata); + cptr[index++] = cdata; + } + + if (len >= 0) + { + g_data_in = cptr; + g_data_in_size = len; + g_data_in_time = clipboard_get_local_time(); + g_data_in_up_to_date = 1; + } + + clipboard_provide_selection(lxev, lxev->target, 8, cptr, len); return 0; - } - while (s_check(s)) - { - in_uint8(s, cdata); - cptr[index++] = cdata; - } - if (len >= 0) - { - g_data_in = cptr; - g_data_in_size = len; - g_data_in_time = clipboard_get_local_time(); - g_data_in_up_to_date = 1; - } - clipboard_provide_selection(lxev, lxev->target, 8, cptr, len); - return 0; } /*****************************************************************************/ @@ -633,159 +675,181 @@ clipboard_process_data_response_for_image(struct stream * s, clipboard data. */ /*****************************************************************************/ static int APP_CC -clipboard_process_data_response(struct stream* s, int clip_msg_status, +clipboard_process_data_response(struct stream *s, int clip_msg_status, int clip_msg_len) { - XSelectionRequestEvent* lxev; - twchar* wtext; - twchar wchr; - int len; - int index; - int data_in_len; - - if (g_want_image_data) - { - g_want_image_data = 0; - clipboard_process_data_response_for_image(s, clip_msg_status, clip_msg_len); - return 0; - } - LOGM((LOG_LEVEL_DEBUG,"clipboard_process_data_response: " - "CLIPRDR_DATA_RESPONSE")); - g_waiting_for_data_response = 0; - len = (int)(s->end - s->p); - if (len < 1) - { - return 0; - } - //g_hexdump(s->p, len); - wtext = (twchar*)g_malloc(((len / 2) + 1) * sizeof(twchar), 0); - if (wtext == 0) - { - return 0; - } - index = 0; - while (s_check(s)) - { - in_uint16_le(s, wchr); - wtext[index] = wchr; - if (wchr == 0) + XSelectionRequestEvent *lxev; + twchar *wtext; + twchar wchr; + int len; + int index; + int data_in_len; + + if (g_want_image_data) { - break; + g_want_image_data = 0; + clipboard_process_data_response_for_image(s, clip_msg_status, clip_msg_len); + return 0; } - index++; - } - wtext[index] = 0; - g_free(g_data_in); - g_data_in = 0; - g_data_in_size = 0; - g_data_in_time = 0; - len = g_wcstombs(0, wtext, 0); - if (len >= 0) - { - g_data_in = (char*)g_malloc(len + 16, 0); - if (g_data_in == 0) + + LOGM((LOG_LEVEL_DEBUG, "clipboard_process_data_response: " + "CLIPRDR_DATA_RESPONSE")); + g_waiting_for_data_response = 0; + len = (int)(s->end - s->p); + + if (len < 1) { - g_free(wtext); - return 0; + return 0; } - g_data_in_size = len; - g_wcstombs(g_data_in, wtext, len + 1); - g_data_in_time = xcommon_get_local_time(); - g_data_in_up_to_date = 1; - } - if (g_data_in != 0) - { - data_in_len = g_strlen(g_data_in); - for (index = 0; index < g_selection_request_event_count; index++) + + //g_hexdump(s->p, len); + wtext = (twchar *)g_malloc(((len / 2) + 1) * sizeof(twchar), 0); + + if (wtext == 0) + { + return 0; + } + + index = 0; + + while (s_check(s)) { - lxev = &(g_selection_request_event[index]); - clipboard_provide_selection(lxev, lxev->target, 8, g_data_in, - data_in_len); - LOGM((LOG_LEVEL_DEBUG,"clipboard_process_data_response: requestor %d " - "data_in_len %d", lxev->requestor, data_in_len)); + in_uint16_le(s, wchr); + wtext[index] = wchr; + + if (wchr == 0) + { + break; + } + + index++; } - } - g_selection_request_event_count = 0; - g_free(wtext); - return 0; + + wtext[index] = 0; + g_free(g_data_in); + g_data_in = 0; + g_data_in_size = 0; + g_data_in_time = 0; + len = g_wcstombs(0, wtext, 0); + + if (len >= 0) + { + g_data_in = (char *)g_malloc(len + 16, 0); + + if (g_data_in == 0) + { + g_free(wtext); + return 0; + } + + g_data_in_size = len; + g_wcstombs(g_data_in, wtext, len + 1); + g_data_in_time = xcommon_get_local_time(); + g_data_in_up_to_date = 1; + } + + if (g_data_in != 0) + { + data_in_len = g_strlen(g_data_in); + + for (index = 0; index < g_selection_request_event_count; index++) + { + lxev = &(g_selection_request_event[index]); + clipboard_provide_selection(lxev, lxev->target, 8, g_data_in, + data_in_len); + LOGM((LOG_LEVEL_DEBUG, "clipboard_process_data_response: requestor %d " + "data_in_len %d", lxev->requestor, data_in_len)); + } + } + + g_selection_request_event_count = 0; + g_free(wtext); + return 0; } /*****************************************************************************/ int APP_CC -clipboard_data_in(struct stream* s, int chan_id, int chan_flags, int length, +clipboard_data_in(struct stream *s, int chan_id, int chan_flags, int length, int total_length) { - int clip_msg_id; - int clip_msg_len; - int clip_msg_status; - int rv; - struct stream* ls; - - LOG(10, ("clipboard_data_in: chan_is %d " - "chan_flags %d length %d total_length %d", - chan_id, chan_flags, length, total_length)); - if ((chan_flags & 3) == 3) - { - ls = s; - } - else - { - if (chan_flags & 1) + int clip_msg_id; + int clip_msg_len; + int clip_msg_status; + int rv; + struct stream *ls; + + LOG(10, ("clipboard_data_in: chan_is %d " + "chan_flags %d length %d total_length %d", + chan_id, chan_flags, length, total_length)); + + if ((chan_flags & 3) == 3) { - init_stream(g_ins, total_length); + ls = s; } - in_uint8a(s, g_ins->end, length); - g_ins->end += length; - if ((chan_flags & 2) == 0) + else { - return 0; + if (chan_flags & 1) + { + init_stream(g_ins, total_length); + } + + in_uint8a(s, g_ins->end, length); + g_ins->end += length; + + if ((chan_flags & 2) == 0) + { + return 0; + } + + ls = g_ins; } - ls = g_ins; - } - in_uint16_le(ls, clip_msg_id); - in_uint16_le(ls, clip_msg_status); - in_uint32_le(ls, clip_msg_len); - LOG(10, ("clipboard_data_in: clip_msg_id %d " - "clip_msg_status %d clip_msg_len %d", - clip_msg_id, clip_msg_status, clip_msg_len)); - rv = 0; - switch (clip_msg_id) - { - /* sent by client or server when its local system clipboard is */ - /* updated with new clipboard data; contains Clipboard Format ID */ - /* and name pairs of new Clipboard Formats on the clipboard. */ - case CB_FORMAT_LIST: /* CLIPRDR_FORMAT_ANNOUNCE */ - rv = clipboard_process_format_announce(ls, clip_msg_status, - clip_msg_len); - break; - /* response to CB_FORMAT_LIST; used to indicate whether */ - /* processing of the Format List PDU was successful */ - case CB_FORMAT_LIST_RESPONSE: /* CLIPRDR_FORMAT_ACK */ - rv = clipboard_prcoess_format_ack(ls, clip_msg_status, - clip_msg_len); - break; - /* sent by recipient of CB_FORMAT_LIST; used to request data for one */ - /* of the formats that was listed in CB_FORMAT_LIST */ - case CB_FORMAT_DATA_REQUEST: /* CLIPRDR_DATA_REQUEST */ - rv = clipboard_process_data_request(ls, clip_msg_status, - clip_msg_len); - break; - /* sent as a reply to CB_FORMAT_DATA_REQUEST; used to indicate */ - /* whether processing of the CB_FORMAT_DATA_REQUEST was */ - /* successful; if processing was successful, */ - /* CB_FORMAT_DATA_RESPONSE includes contents of requested */ - /* clipboard data. */ - case CB_FORMAT_DATA_RESPONSE: /* CLIPRDR_DATA_RESPONSE */ - rv = clipboard_process_data_response(ls, clip_msg_status, - clip_msg_len); - break; - default: - LOGM((LOG_LEVEL_ERROR, "clipboard_data_in: unknown clip_msg_id %d", - clip_msg_id)); - break; - } - XFlush(g_display); - return rv; + + in_uint16_le(ls, clip_msg_id); + in_uint16_le(ls, clip_msg_status); + in_uint32_le(ls, clip_msg_len); + LOG(10, ("clipboard_data_in: clip_msg_id %d " + "clip_msg_status %d clip_msg_len %d", + clip_msg_id, clip_msg_status, clip_msg_len)); + rv = 0; + + switch (clip_msg_id) + { + /* sent by client or server when its local system clipboard is */ + /* updated with new clipboard data; contains Clipboard Format ID */ + /* and name pairs of new Clipboard Formats on the clipboard. */ + case CB_FORMAT_LIST: /* CLIPRDR_FORMAT_ANNOUNCE */ + rv = clipboard_process_format_announce(ls, clip_msg_status, + clip_msg_len); + break; + /* response to CB_FORMAT_LIST; used to indicate whether */ + /* processing of the Format List PDU was successful */ + case CB_FORMAT_LIST_RESPONSE: /* CLIPRDR_FORMAT_ACK */ + rv = clipboard_prcoess_format_ack(ls, clip_msg_status, + clip_msg_len); + break; + /* sent by recipient of CB_FORMAT_LIST; used to request data for one */ + /* of the formats that was listed in CB_FORMAT_LIST */ + case CB_FORMAT_DATA_REQUEST: /* CLIPRDR_DATA_REQUEST */ + rv = clipboard_process_data_request(ls, clip_msg_status, + clip_msg_len); + break; + /* sent as a reply to CB_FORMAT_DATA_REQUEST; used to indicate */ + /* whether processing of the CB_FORMAT_DATA_REQUEST was */ + /* successful; if processing was successful, */ + /* CB_FORMAT_DATA_RESPONSE includes contents of requested */ + /* clipboard data. */ + case CB_FORMAT_DATA_RESPONSE: /* CLIPRDR_DATA_RESPONSE */ + rv = clipboard_process_data_response(ls, clip_msg_status, + clip_msg_len); + break; + default: + LOGM((LOG_LEVEL_ERROR, "clipboard_data_in: unknown clip_msg_id %d", + clip_msg_id)); + break; + } + + XFlush(g_display); + return rv; } /*****************************************************************************/ @@ -805,132 +869,151 @@ clipboard_data_in(struct stream* s, int chan_id, int chan_flags, int length, Time selection_timestamp; } XFixesSelectionNotifyEvent; */ static int APP_CC -clipboard_event_selection_owner_notify(XEvent* xevent) +clipboard_event_selection_owner_notify(XEvent *xevent) { - XFixesSelectionNotifyEvent* lxevent; - - lxevent = (XFixesSelectionNotifyEvent*)xevent; - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_owner_notify: " - "window %d subtype %d owner %d g_wnd %d", - lxevent->window, lxevent->subtype, lxevent->owner, g_wnd)); - if (lxevent->owner == g_wnd) - { - LOGM((LOG_LEVEL_DEBUG,"clipboard_event_selection_owner_notify: skipping, " - "onwer == g_wnd")); - g_got_selection = 1; + XFixesSelectionNotifyEvent *lxevent; + + lxevent = (XFixesSelectionNotifyEvent *)xevent; + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_owner_notify: " + "window %d subtype %d owner %d g_wnd %d", + lxevent->window, lxevent->subtype, lxevent->owner, g_wnd)); + + if (lxevent->owner == g_wnd) + { + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_owner_notify: skipping, " + "onwer == g_wnd")); + g_got_selection = 1; + return 0; + } + + g_got_selection = 0; + XConvertSelection(g_display, g_clipboard_atom, g_targets_atom, + g_clip_property_atom, g_wnd, lxevent->timestamp); return 0; - } - g_got_selection = 0; - XConvertSelection(g_display, g_clipboard_atom, g_targets_atom, - g_clip_property_atom, g_wnd, lxevent->timestamp); - return 0; } /*****************************************************************************/ /* returns error get a window property from wnd */ static int APP_CC -clipboard_get_window_property(Window wnd, Atom prop, Atom* type, int* fmt, - int* n_items, char** xdata, int* xdata_size) +clipboard_get_window_property(Window wnd, Atom prop, Atom *type, int *fmt, + int *n_items, char **xdata, int *xdata_size) { - int lfmt; - int lxdata_size; - unsigned long ln_items; - unsigned long llen_after; - tui8* lxdata; - Atom ltype; - - lxdata = 0; - ltype = 0; - XGetWindowProperty(g_display, g_wnd, prop, 0, 0, 0, - AnyPropertyType, <ype, &lfmt, &ln_items, - &llen_after, &lxdata); - if (lxdata != 0) - { - XFree(lxdata); - } - if (ltype == 0) - { - /* XGetWindowProperty failed */ - return 1; - } - - if (ltype == g_incr_atom) - { - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_property_notify: INCR start")); - g_incr_in_progress = 1; - g_incr_atom_type = prop; - g_incr_data_size = 0; - g_free(g_incr_data); - g_incr_data = 0; - XDeleteProperty(g_display, g_wnd, prop); - return 0; - } + int lfmt; + int lxdata_size; + unsigned long ln_items; + unsigned long llen_after; + tui8 *lxdata; + Atom ltype; + + lxdata = 0; + ltype = 0; + XGetWindowProperty(g_display, g_wnd, prop, 0, 0, 0, + AnyPropertyType, <ype, &lfmt, &ln_items, + &llen_after, &lxdata); - if (llen_after < 1) - { - /* no data, ok */ - return 0; - } - lxdata = 0; - ltype = 0; - XGetWindowProperty(g_display, g_wnd, prop, 0, (llen_after + 3) / 4, 0, - AnyPropertyType, <ype, &lfmt, &ln_items, - &llen_after, &lxdata); - if (ltype == 0) - { - /* XGetWindowProperty failed */ if (lxdata != 0) { - XFree(lxdata); + XFree(lxdata); } - return 1; - } - lxdata_size = (lfmt / 8) * ln_items; - if (lxdata_size < 1) - { - /* should not happen */ - if (lxdata != 0) + + if (ltype == 0) + { + /* XGetWindowProperty failed */ + return 1; + } + + if (ltype == g_incr_atom) + { + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_property_notify: INCR start")); + g_incr_in_progress = 1; + g_incr_atom_type = prop; + g_incr_data_size = 0; + g_free(g_incr_data); + g_incr_data = 0; + XDeleteProperty(g_display, g_wnd, prop); + return 0; + } + + if (llen_after < 1) { - XFree(lxdata); + /* no data, ok */ + return 0; + } + + lxdata = 0; + ltype = 0; + XGetWindowProperty(g_display, g_wnd, prop, 0, (llen_after + 3) / 4, 0, + AnyPropertyType, <ype, &lfmt, &ln_items, + &llen_after, &lxdata); + + if (ltype == 0) + { + /* XGetWindowProperty failed */ + if (lxdata != 0) + { + XFree(lxdata); + } + + return 1; } - return 2; - } - if (llen_after > 0) - { - /* should not happen */ + + lxdata_size = (lfmt / 8) * ln_items; + + if (lxdata_size < 1) + { + /* should not happen */ + if (lxdata != 0) + { + XFree(lxdata); + } + + return 2; + } + + if (llen_after > 0) + { + /* should not happen */ + if (lxdata != 0) + { + XFree(lxdata); + } + + return 3; + } + + if (xdata != 0) + { + *xdata = (char *)g_malloc(lxdata_size, 0); + g_memcpy(*xdata, lxdata, lxdata_size); + } + if (lxdata != 0) { - XFree(lxdata); + XFree(lxdata); + } + + if (xdata_size != 0) + { + *xdata_size = lxdata_size; + } + + if (fmt != 0) + { + *fmt = (int)lfmt; + } + + if (n_items != 0) + { + *n_items = (int)ln_items; } - return 3; - } - if (xdata != 0) - { - *xdata = (char*)g_malloc(lxdata_size, 0); - g_memcpy(*xdata, lxdata, lxdata_size); - } - if (lxdata != 0) - { - XFree(lxdata); - } - if (xdata_size != 0) - { - *xdata_size = lxdata_size; - } - if (fmt != 0) - { - *fmt = (int)lfmt; - } - if (n_items != 0) - { - *n_items = (int)ln_items; - } - if (type != 0) - { - *type = ltype; - } - return 0; + + if (type != 0) + { + *type = ltype; + } + + return 0; } /*****************************************************************************/ @@ -948,178 +1031,188 @@ clipboard_get_window_property(Window wnd, Atom prop, Atom* type, int* fmt, Time time; } XSelectionEvent; */ static int APP_CC -clipboard_event_selection_notify(XEvent* xevent) +clipboard_event_selection_notify(XEvent *xevent) { - XSelectionEvent* lxevent; - char* data; - int data_size; - int n_items; - int fmt; - int rv; - int index; - int convert_to_string; - int convert_to_utf8; - int convert_to_bmp_image; - int send_format_announce; - int atom; - Atom* atoms; - Atom type; - tui32 format_id; - char format_name[32]; - - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify:")); - data_size = 0; - n_items = 0; - fmt = 0; - convert_to_string = 0; - convert_to_utf8 = 0; - convert_to_bmp_image = 0; - send_format_announce = 0; - format_id = 0; - rv = 0; - data = 0; - type = 0; - lxevent = (XSelectionEvent*)xevent; - g_memset(format_name, 0, 32); - if (lxevent->property == None) - { - LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_notify: clip could " - "not be converted")); - rv = 1; - } - if (rv == 0) - { - /* we need this if the call below turns out to be a - clipboard INCR operation */ - if (!g_incr_in_progress) + XSelectionEvent *lxevent; + char *data; + int data_size; + int n_items; + int fmt; + int rv; + int index; + int convert_to_string; + int convert_to_utf8; + int convert_to_bmp_image; + int send_format_announce; + int atom; + Atom *atoms; + Atom type; + tui32 format_id; + char format_name[32]; + + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify:")); + data_size = 0; + n_items = 0; + fmt = 0; + convert_to_string = 0; + convert_to_utf8 = 0; + convert_to_bmp_image = 0; + send_format_announce = 0; + format_id = 0; + rv = 0; + data = 0; + type = 0; + lxevent = (XSelectionEvent *)xevent; + g_memset(format_name, 0, 32); + + if (lxevent->property == None) { - g_incr_atom_target = lxevent->target; + LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_notify: clip could " + "not be converted")); + rv = 1; } - rv = clipboard_get_window_property(lxevent->requestor, lxevent->property, - &type, &fmt, - &n_items, &data, &data_size); - if (rv != 0) + if (rv == 0) { - LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_notify: " - "clipboard_get_window_property failed error %d", rv)); + /* we need this if the call below turns out to be a + clipboard INCR operation */ + if (!g_incr_in_progress) + { + g_incr_atom_target = lxevent->target; + } + + rv = clipboard_get_window_property(lxevent->requestor, lxevent->property, + &type, &fmt, + &n_items, &data, &data_size); + + if (rv != 0) + { + LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_notify: " + "clipboard_get_window_property failed error %d", rv)); + } + + XDeleteProperty(g_display, lxevent->requestor, lxevent->property); } - XDeleteProperty(g_display, lxevent->requestor, lxevent->property); - } - if (rv == 0) - { - if (lxevent->selection == g_clipboard_atom) + + if (rv == 0) { - if (lxevent->target == g_targets_atom) - { - /* on a 64 bit machine, actual_format_return of 32 implies long */ - if ((type == XA_ATOM) && (fmt == 32)) + if (lxevent->selection == g_clipboard_atom) { - atoms = (Atom*)data; - for (index = 0; index < n_items; index++) - { - atom = atoms[index]; - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: %d %s %d", - atom, XGetAtomName(g_display, atom), XA_STRING)); - if (atom == g_utf8_atom) + if (lxevent->target == g_targets_atom) + { + /* on a 64 bit machine, actual_format_return of 32 implies long */ + if ((type == XA_ATOM) && (fmt == 32)) + { + atoms = (Atom *)data; + + for (index = 0; index < n_items; index++) + { + atom = atoms[index]; + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: %d %s %d", + atom, XGetAtomName(g_display, atom), XA_STRING)); + + if (atom == g_utf8_atom) + { + convert_to_utf8 = 1; + } + else if (atom == XA_STRING) + { + convert_to_string = 1; + } + else if (atom == g_image_bmp_atom) + { + convert_to_bmp_image = 1; + } + } + } + else + { + LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_notify: error, " + "target is 'TARGETS' and type[%d] or fmt[%d] not right, " + "should be type[%d], fmt[%d]", type, fmt, XA_ATOM, 32)); + } + } + else if (lxevent->target == g_utf8_atom) + { + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: UTF8_STRING " + "data_size %d", data_size)); + g_free(g_last_clip_data); + g_last_clip_data = 0; + g_last_clip_size = data_size; + g_last_clip_data = g_malloc(g_last_clip_size + 1, 0); + g_last_clip_type = g_utf8_atom; + g_memcpy(g_last_clip_data, data, g_last_clip_size); + g_last_clip_data[g_last_clip_size] = 0; + send_format_announce = 1; + format_id = CB_FORMAT_UNICODETEXT; + } + else if (lxevent->target == XA_STRING) { - convert_to_utf8 = 1; + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: XA_STRING " + "data_size %d", data_size)); + g_free(g_last_clip_data); + g_last_clip_data = 0; + g_last_clip_size = data_size; + g_last_clip_data = g_malloc(g_last_clip_size + 1, 0); + g_last_clip_type = XA_STRING; + g_memcpy(g_last_clip_data, data, g_last_clip_size); + g_last_clip_data[g_last_clip_size] = 0; + send_format_announce = 1; + format_id = CB_FORMAT_UNICODETEXT; } - else if (atom == XA_STRING) + else if (lxevent->target == g_image_bmp_atom) { - convert_to_string = 1; + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: image/bmp " + "data_size %d", data_size)); + g_free(g_last_clip_data); + g_last_clip_data = 0; + g_last_clip_size = data_size; + g_last_clip_data = g_malloc(data_size, 0); + g_last_clip_type = g_image_bmp_atom; + g_memcpy(g_last_clip_data, data, data_size); + send_format_announce = 1; + format_id = CB_FORMAT_DIB; + g_strcpy(format_name, "image/bmp"); } - else if (atom == g_image_bmp_atom) + else { - convert_to_bmp_image = 1; + LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_notify: " + "unknown target")); } - } } else { - LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_notify: error, " - "target is 'TARGETS' and type[%d] or fmt[%d] not right, " - "should be type[%d], fmt[%d]", type, fmt, XA_ATOM, 32)); + LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_notify: " + "unknown selection")); } - } - else if (lxevent->target == g_utf8_atom) - { - LOGM((LOG_LEVEL_DEBUG,"clipboard_event_selection_notify: UTF8_STRING " - "data_size %d", data_size)); - g_free(g_last_clip_data); - g_last_clip_data = 0; - g_last_clip_size = data_size; - g_last_clip_data = g_malloc(g_last_clip_size + 1, 0); - g_last_clip_type = g_utf8_atom; - g_memcpy(g_last_clip_data, data, g_last_clip_size); - g_last_clip_data[g_last_clip_size] = 0; - send_format_announce = 1; - format_id = CB_FORMAT_UNICODETEXT; - } - else if (lxevent->target == XA_STRING) - { - LOGM((LOG_LEVEL_DEBUG,"clipboard_event_selection_notify: XA_STRING " - "data_size %d", data_size)); - g_free(g_last_clip_data); - g_last_clip_data = 0; - g_last_clip_size = data_size; - g_last_clip_data = g_malloc(g_last_clip_size + 1, 0); - g_last_clip_type = XA_STRING; - g_memcpy(g_last_clip_data, data, g_last_clip_size); - g_last_clip_data[g_last_clip_size] = 0; - send_format_announce = 1; - format_id = CB_FORMAT_UNICODETEXT; - } - else if (lxevent->target == g_image_bmp_atom) - { - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: image/bmp " - "data_size %d", data_size)); - g_free(g_last_clip_data); - g_last_clip_data = 0; - g_last_clip_size = data_size; - g_last_clip_data = g_malloc(data_size, 0); - g_last_clip_type = g_image_bmp_atom; - g_memcpy(g_last_clip_data, data, data_size); - send_format_announce = 1; - format_id = CB_FORMAT_DIB; - g_strcpy(format_name, "image/bmp"); - } - else - { - LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_notify: " - "unknown target")); - } } - else + + if (convert_to_utf8) { - LOGM((LOG_LEVEL_ERROR,"clipboard_event_selection_notify: " - "unknown selection")); + XConvertSelection(g_display, g_clipboard_atom, g_utf8_atom, + g_clip_property_atom, g_wnd, lxevent->time); } - } - if (convert_to_utf8) - { - XConvertSelection(g_display, g_clipboard_atom, g_utf8_atom, - g_clip_property_atom, g_wnd, lxevent->time); - } - else if (convert_to_string) - { - XConvertSelection(g_display, g_clipboard_atom, XA_STRING, - g_clip_property_atom, g_wnd, lxevent->time); - } - else if (convert_to_bmp_image) - { - XConvertSelection(g_display, g_clipboard_atom, g_image_bmp_atom, - g_clip_property_atom, g_wnd, lxevent->time); - } - if (send_format_announce) - { - if (clipboard_send_format_announce(format_id, format_name) != 0) + else if (convert_to_string) { - rv = 4; + XConvertSelection(g_display, g_clipboard_atom, XA_STRING, + g_clip_property_atom, g_wnd, lxevent->time); } - } - g_free(data); - return rv; + else if (convert_to_bmp_image) + { + XConvertSelection(g_display, g_clipboard_atom, g_image_bmp_atom, + g_clip_property_atom, g_wnd, lxevent->time); + } + + if (send_format_announce) + { + if (clipboard_send_format_announce(format_id, format_name) != 0) + { + rv = 4; + } + } + + g_free(data); + return rv; } /*****************************************************************************/ @@ -1143,113 +1236,120 @@ clipboard_event_selection_notify(XEvent* xevent) * a 32bit machine and 8 bytes on a 64 machine */ static int APP_CC -clipboard_event_selection_request(XEvent* xevent) +clipboard_event_selection_request(XEvent *xevent) { - XSelectionRequestEvent* lxev; - XEvent xev; - Atom atom_buf[10]; - Atom type; - int fmt; - int n_items; - int xdata_size; - char* xdata; - - lxev = (XSelectionRequestEvent*)xevent; - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: g_wnd %d, " - ".requestor %d .owner %d .selection %d '%s' .target %d .property %d", - g_wnd, lxev->requestor, lxev->owner, lxev->selection, - XGetAtomName(g_display, lxev->selection), - lxev->target, lxev->property)); - if (lxev->property == None) - { - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: " - "lxev->property is None")); - } - else if (lxev->target == g_targets_atom) - { - /* requestor is asking what the selection can be converted to */ - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: " - "g_targets_atom")); - atom_buf[0] = g_targets_atom; - atom_buf[1] = g_timestamp_atom; - atom_buf[2] = g_multiple_atom; - atom_buf[3] = XA_STRING; - atom_buf[4] = g_utf8_atom; - atom_buf[5] = g_image_bmp_atom; - return clipboard_provide_selection(lxev, XA_ATOM, 32, (char*)atom_buf, 6); - } - else if (lxev->target == g_timestamp_atom) - { - /* requestor is asking the time I got the selection */ - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: " - "g_timestamp_atom")); - atom_buf[0] = g_selection_time; - return clipboard_provide_selection(lxev, XA_INTEGER, 32, (char*)atom_buf, 1); - } - else if (lxev->target == g_multiple_atom) - { - /* target, property pairs */ - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: " - "g_multiple_atom")); - if (clipboard_get_window_property(xev.xselection.requestor, - xev.xselection.property, - &type, &fmt, &n_items, &xdata, - &xdata_size) == 0) + XSelectionRequestEvent *lxev; + XEvent xev; + Atom atom_buf[10]; + Atom type; + int fmt; + int n_items; + int xdata_size; + char *xdata; + + lxev = (XSelectionRequestEvent *)xevent; + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: g_wnd %d, " + ".requestor %d .owner %d .selection %d '%s' .target %d .property %d", + g_wnd, lxev->requestor, lxev->owner, lxev->selection, + XGetAtomName(g_display, lxev->selection), + lxev->target, lxev->property)); + + if (lxev->property == None) { - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: g_multiple_atom " - "n_items %d", n_items)); - /* todo */ - g_free(xdata); + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: " + "lxev->property is None")); } - } - else if ((lxev->target == XA_STRING) || (lxev->target == g_utf8_atom)) - { - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: %s", - XGetAtomName(g_display, lxev->target))); - clipboard_format_id = CB_FORMAT_UNICODETEXT; - if (g_data_in_up_to_date) + else if (lxev->target == g_targets_atom) { - return clipboard_provide_selection(lxev, lxev->target, 8, - g_data_in, g_strlen(g_data_in)); + /* requestor is asking what the selection can be converted to */ + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: " + "g_targets_atom")); + atom_buf[0] = g_targets_atom; + atom_buf[1] = g_timestamp_atom; + atom_buf[2] = g_multiple_atom; + atom_buf[3] = XA_STRING; + atom_buf[4] = g_utf8_atom; + atom_buf[5] = g_image_bmp_atom; + return clipboard_provide_selection(lxev, XA_ATOM, 32, (char *)atom_buf, 6); } - if (g_selection_request_event_count > 10) + else if (lxev->target == g_timestamp_atom) { - LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_request: error, " - "too many requests")); + /* requestor is asking the time I got the selection */ + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: " + "g_timestamp_atom")); + atom_buf[0] = g_selection_time; + return clipboard_provide_selection(lxev, XA_INTEGER, 32, (char *)atom_buf, 1); } - else + else if (lxev->target == g_multiple_atom) { - g_memcpy(&(g_selection_request_event[g_selection_request_event_count]), - lxev, sizeof(g_selection_request_event[0])); - if (g_selection_request_event_count == 0) - { + /* target, property pairs */ + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: " + "g_multiple_atom")); + + if (clipboard_get_window_property(xev.xselection.requestor, + xev.xselection.property, + &type, &fmt, &n_items, &xdata, + &xdata_size) == 0) + { + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: g_multiple_atom " + "n_items %d", n_items)); + /* todo */ + g_free(xdata); + } + } + else if ((lxev->target == XA_STRING) || (lxev->target == g_utf8_atom)) + { + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: %s", + XGetAtomName(g_display, lxev->target))); + clipboard_format_id = CB_FORMAT_UNICODETEXT; + + if (g_data_in_up_to_date) + { + return clipboard_provide_selection(lxev, lxev->target, 8, + g_data_in, g_strlen(g_data_in)); + } + + if (g_selection_request_event_count > 10) + { + LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_request: error, " + "too many requests")); + } + else + { + g_memcpy(&(g_selection_request_event[g_selection_request_event_count]), + lxev, sizeof(g_selection_request_event[0])); + + if (g_selection_request_event_count == 0) + { + clipboard_send_data_request(); + g_waiting_for_data_response = 1; + g_waiting_for_data_response_time = xcommon_get_local_time(); + } + + g_selection_request_event_count++; + return 0; + } + } + else if (lxev->target == g_image_bmp_atom) + { + g_memcpy(&g_saved_selection_req_event, lxev, + sizeof(g_saved_selection_req_event)); + g_last_clip_type = g_image_bmp_atom; + g_want_image_data = 1; + clipboard_format_id = CB_FORMAT_DIB; clipboard_send_data_request(); g_waiting_for_data_response = 1; - g_waiting_for_data_response_time = xcommon_get_local_time(); - } - g_selection_request_event_count++; - return 0; + g_waiting_for_data_response_time = clipboard_get_local_time(); + return 0; } - } - else if (lxev->target == g_image_bmp_atom) - { - g_memcpy(&g_saved_selection_req_event, lxev, - sizeof(g_saved_selection_req_event)); - g_last_clip_type = g_image_bmp_atom; - g_want_image_data = 1; - clipboard_format_id = CB_FORMAT_DIB; - clipboard_send_data_request(); - g_waiting_for_data_response = 1; - g_waiting_for_data_response_time = clipboard_get_local_time(); + else + { + LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_request: unknown " + "target %s", XGetAtomName(g_display, lxev->target))); + } + + clipboard_refuse_selection(lxev); return 0; - } - else - { - LOGM((LOG_LEVEL_ERROR,"clipboard_event_selection_request: unknown " - "target %s", XGetAtomName(g_display, lxev->target))); - } - clipboard_refuse_selection(lxev); - return 0; } /*****************************************************************************/ @@ -1265,10 +1365,10 @@ clipboard_event_selection_request(XEvent* xevent) Time time; } XSelectionClearEvent; */ static int APP_CC -clipboard_event_selection_clear(XEvent* xevent) +clipboard_event_selection_clear(XEvent *xevent) { - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_clear:")); - return 0; + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_clear:")); + return 0; } /*****************************************************************************/ @@ -1284,134 +1384,153 @@ clipboard_event_selection_clear(XEvent* xevent) int state; // PropertyNewValue or PropertyDelete } XPropertyEvent; */ static int APP_CC -clipboard_event_property_notify(XEvent* xevent) +clipboard_event_property_notify(XEvent *xevent) { - Atom actual_type_return; - int actual_format_return; - unsigned long nitems_returned; - unsigned long bytes_left; - unsigned char* data; - int rv; - int format_in_bytes; - int new_data_len; - char* cptr; - char format_name[32]; - - LOG(10, ("clipboard_check_wait_objs: PropertyNotify .window %d " - ".state %d .atom %d", xevent->xproperty.window, - xevent->xproperty.state, xevent->xproperty.atom)); - if (g_incr_in_progress && - (xevent->xproperty.atom == g_incr_atom_type) && - (xevent->xproperty.state == PropertyNewValue)) - { - rv = XGetWindowProperty(g_display, g_wnd, g_incr_atom_type, 0, 0, 0, - AnyPropertyType, &actual_type_return, &actual_format_return, - &nitems_returned, &bytes_left, (unsigned char **) &data); - if (data != 0) - { - XFree(data); - data = 0; - } - if (bytes_left <= 0) - { - LOGM((LOG_LEVEL_DEBUG, "clipboard_event_property_notify: INCR done")); - g_memset(format_name, 0, 32); - /* clipboard INCR cycle has completed */ - g_incr_in_progress = 0; - g_last_clip_size = g_incr_data_size; - g_last_clip_data = g_incr_data; - g_incr_data = 0; - g_last_clip_type = g_incr_atom_target; - if (g_incr_atom_target == g_image_bmp_atom) - { - g_snprintf(format_name, 31, "image/bmp"); - clipboard_send_format_announce(CB_FORMAT_DIB, format_name); - } - XDeleteProperty(g_display, g_wnd, g_incr_atom_type); - } - else + Atom actual_type_return; + int actual_format_return; + unsigned long nitems_returned; + unsigned long bytes_left; + unsigned char *data; + int rv; + int format_in_bytes; + int new_data_len; + char *cptr; + char format_name[32]; + + LOG(10, ("clipboard_check_wait_objs: PropertyNotify .window %d " + ".state %d .atom %d", xevent->xproperty.window, + xevent->xproperty.state, xevent->xproperty.atom)); + + if (g_incr_in_progress && + (xevent->xproperty.atom == g_incr_atom_type) && + (xevent->xproperty.state == PropertyNewValue)) { - rv = XGetWindowProperty(g_display, g_wnd, g_incr_atom_type, 0, bytes_left, 0, - AnyPropertyType, &actual_type_return, &actual_format_return, - &nitems_returned, &bytes_left, (unsigned char **) &data); - - format_in_bytes = actual_format_return / 8; - if ((actual_format_return == 32) && (sizeof(long) == 8)) - { - /* on a 64 bit machine, actual_format_return of 32 implies long */ - format_in_bytes = 8; - } - new_data_len = nitems_returned * format_in_bytes; - cptr = (char*)g_malloc(g_incr_data_size + new_data_len, 0); - g_memcpy(cptr, g_incr_data, g_incr_data_size); - g_free(g_incr_data); - if (cptr == NULL) - { - g_incr_data = 0; - /* cannot add any more data */ + rv = XGetWindowProperty(g_display, g_wnd, g_incr_atom_type, 0, 0, 0, + AnyPropertyType, &actual_type_return, &actual_format_return, + &nitems_returned, &bytes_left, (unsigned char **) &data); + if (data != 0) { - XFree(data); + XFree(data); + data = 0; + } + + if (bytes_left <= 0) + { + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_property_notify: INCR done")); + g_memset(format_name, 0, 32); + /* clipboard INCR cycle has completed */ + g_incr_in_progress = 0; + g_last_clip_size = g_incr_data_size; + g_last_clip_data = g_incr_data; + g_incr_data = 0; + g_last_clip_type = g_incr_atom_target; + + if (g_incr_atom_target == g_image_bmp_atom) + { + g_snprintf(format_name, 31, "image/bmp"); + clipboard_send_format_announce(CB_FORMAT_DIB, format_name); + } + + XDeleteProperty(g_display, g_wnd, g_incr_atom_type); + } + else + { + rv = XGetWindowProperty(g_display, g_wnd, g_incr_atom_type, 0, bytes_left, 0, + AnyPropertyType, &actual_type_return, &actual_format_return, + &nitems_returned, &bytes_left, (unsigned char **) &data); + + format_in_bytes = actual_format_return / 8; + + if ((actual_format_return == 32) && (sizeof(long) == 8)) + { + /* on a 64 bit machine, actual_format_return of 32 implies long */ + format_in_bytes = 8; + } + + new_data_len = nitems_returned * format_in_bytes; + cptr = (char *)g_malloc(g_incr_data_size + new_data_len, 0); + g_memcpy(cptr, g_incr_data, g_incr_data_size); + g_free(g_incr_data); + + if (cptr == NULL) + { + g_incr_data = 0; + + /* cannot add any more data */ + if (data != 0) + { + XFree(data); + } + + XDeleteProperty(g_display, g_wnd, g_incr_atom_type); + return 0; + } + + g_incr_data = cptr; + g_memcpy(g_incr_data + g_incr_data_size, data, new_data_len); + g_incr_data_size += new_data_len; + + if (data) + { + XFree(data); + } + + XDeleteProperty(g_display, g_wnd, g_incr_atom_type); } - XDeleteProperty(g_display, g_wnd, g_incr_atom_type); - return 0; - } - g_incr_data = cptr; - g_memcpy(g_incr_data + g_incr_data_size, data, new_data_len); - g_incr_data_size += new_data_len; - if (data) - { - XFree(data); - } - XDeleteProperty(g_display, g_wnd, g_incr_atom_type); } - } - return 0; + + return 0; } /*****************************************************************************/ /* returns 0, event handled, 1 unhandled */ int APP_CC -clipboard_xevent(void* xevent) +clipboard_xevent(void *xevent) { - XEvent* lxevent; - - if (!g_clip_up) - { - return 1; - } - lxevent = (XEvent*)xevent; - switch (lxevent->type) - { - case SelectionNotify: - clipboard_event_selection_notify(lxevent); - break; - case SelectionRequest: - clipboard_event_selection_request(lxevent); - break; - case SelectionClear: - clipboard_event_selection_clear(lxevent); - break; - case MappingNotify: - break; - case PropertyNotify: - clipboard_event_property_notify(lxevent); - break; - case UnmapNotify: - LOG(0, ("chansrv::clipboard_xevent: got UnmapNotify")); - break; - case ClientMessage: - LOG(0, ("chansrv::clipboard_xevent: got ClientMessage")); - break; - default: - if (lxevent->type == g_xfixes_event_base + - XFixesSetSelectionOwnerNotify) - { - clipboard_event_selection_owner_notify(lxevent); - break; - } - /* we didn't handle this message */ - return 1; - } - return 0; + XEvent *lxevent; + + if (!g_clip_up) + { + return 1; + } + + lxevent = (XEvent *)xevent; + + switch (lxevent->type) + { + case SelectionNotify: + clipboard_event_selection_notify(lxevent); + break; + case SelectionRequest: + clipboard_event_selection_request(lxevent); + break; + case SelectionClear: + clipboard_event_selection_clear(lxevent); + break; + case MappingNotify: + break; + case PropertyNotify: + clipboard_event_property_notify(lxevent); + break; + case UnmapNotify: + LOG(0, ("chansrv::clipboard_xevent: got UnmapNotify")); + break; + case ClientMessage: + LOG(0, ("chansrv::clipboard_xevent: got ClientMessage")); + break; + default: + + if (lxevent->type == g_xfixes_event_base + + XFixesSetSelectionOwnerNotify) + { + clipboard_event_selection_owner_notify(lxevent); + break; + } + + /* we didn't handle this message */ + return 1; + } + + return 0; } diff --git a/sesman/chansrv/devredir.c b/sesman/chansrv/devredir.c index dd244572..e6407211 100644 --- a/sesman/chansrv/devredir.c +++ b/sesman/chansrv/devredir.c @@ -26,34 +26,34 @@ extern int g_rdpdr_chan_id; /* in chansrv.c */ int APP_CC dev_redir_init(void) { - return 0; + return 0; } /*****************************************************************************/ int APP_CC dev_redir_deinit(void) { - return 0; + return 0; } /*****************************************************************************/ int APP_CC -dev_redir_data_in(struct stream* s, int chan_id, int chan_flags, int length, +dev_redir_data_in(struct stream *s, int chan_id, int chan_flags, int length, int total_length) { - return 0; + return 0; } /*****************************************************************************/ int APP_CC -dev_redir_get_wait_objs(tbus* objs, int* count, int* timeout) +dev_redir_get_wait_objs(tbus *objs, int *count, int *timeout) { - return 0; + return 0; } /*****************************************************************************/ int APP_CC dev_redir_check_wait_objs(void) { - return 0; + return 0; } diff --git a/sesman/chansrv/rail.c b/sesman/chansrv/rail.c index 6b47f867..1ea8d73a 100644 --- a/sesman/chansrv/rail.c +++ b/sesman/chansrv/rail.c @@ -31,13 +31,13 @@ extern int g_rail_chan_id; /* in chansrv.c */ extern int g_display_num; /* in chansrv.c */ -extern char* g_exec_name; /* in chansrv.c */ +extern char *g_exec_name; /* in chansrv.c */ extern tbus g_exec_event; /* in chansrv.c */ extern tbus g_exec_mutex; /* in chansrv.c */ extern tbus g_exec_sem; /* in chansrv.c */ -extern Display* g_display; /* in xcommon.c */ -extern Screen* g_screen; /* in xcommon.c */ +extern Display *g_display; /* in xcommon.c */ +extern Screen *g_screen; /* in xcommon.c */ extern Window g_root_window; /* in xcommon.c */ extern Atom g_wm_delete_window_atom; /* in xcommon.c */ extern Atom g_wm_protocols_atom; /* in xcommon.c */ @@ -105,573 +105,597 @@ static int g_rail_running = 1; static int APP_CC is_window_valid_child_of_root(unsigned int window_id) { - int found; - unsigned int i; - unsigned int nchild; - Window r; - Window p; - Window* children; - - found = 0; - XQueryTree(g_display, g_root_window, &r, &p, &children, &nchild); - for (i = 0; i < nchild; i++) - { - if (window_id == children[i]) + int found; + unsigned int i; + unsigned int nchild; + Window r; + Window p; + Window *children; + + found = 0; + XQueryTree(g_display, g_root_window, &r, &p, &children, &nchild); + + for (i = 0; i < nchild; i++) { - found = 1; - break; + if (window_id == children[i]) + { + found = 1; + break; + } } - } - XFree(children); - return found; + + XFree(children); + return found; } /*****************************************************************************/ static int APP_CC rail_send_init(void) { - struct stream* s; - int bytes; - char* size_ptr; - - LOG(10, ("chansrv::rail_send_init:")); - make_stream(s); - init_stream(s, 8182); - out_uint16_le(s, TS_RAIL_ORDER_HANDSHAKE); - size_ptr = s->p; - out_uint16_le(s, 0); /* size, set later */ - out_uint32_le(s, 1); /* build number */ - s_mark_end(s); - bytes = (int)((s->end - s->data) - 4); - size_ptr[0] = bytes; - size_ptr[1] = bytes >> 8; - bytes = (int)(s->end - s->data); - send_channel_data(g_rail_chan_id, s->data, bytes); - free_stream(s); - return 0; + struct stream *s; + int bytes; + char *size_ptr; + + LOG(10, ("chansrv::rail_send_init:")); + make_stream(s); + init_stream(s, 8182); + out_uint16_le(s, TS_RAIL_ORDER_HANDSHAKE); + size_ptr = s->p; + out_uint16_le(s, 0); /* size, set later */ + out_uint32_le(s, 1); /* build number */ + s_mark_end(s); + bytes = (int)((s->end - s->data) - 4); + size_ptr[0] = bytes; + size_ptr[1] = bytes >> 8; + bytes = (int)(s->end - s->data); + send_channel_data(g_rail_chan_id, s->data, bytes); + free_stream(s); + return 0; } /******************************************************************************/ static int DEFAULT_CC -anotherWMRunning(Display* display, XErrorEvent* xe) +anotherWMRunning(Display *display, XErrorEvent *xe) { - g_rail_running = 0; - return -1; + g_rail_running = 0; + return -1; } /******************************************************************************/ static int APP_CC rail_is_another_wm_running(void) { - XErrorHandler old; - - g_rail_running = 1; - old = XSetErrorHandler((XErrorHandler)anotherWMRunning); - XSelectInput(g_display, g_root_window, - PropertyChangeMask | StructureNotifyMask | - SubstructureRedirectMask | ButtonPressMask | - SubstructureNotifyMask | FocusChangeMask | - EnterWindowMask | LeaveWindowMask); - XSync(g_display, 0); - XSetErrorHandler((XErrorHandler)old); - g_rail_up = g_rail_running; - if (!g_rail_up) - { - return 1; - } - return 0; + XErrorHandler old; + + g_rail_running = 1; + old = XSetErrorHandler((XErrorHandler)anotherWMRunning); + XSelectInput(g_display, g_root_window, + PropertyChangeMask | StructureNotifyMask | + SubstructureRedirectMask | ButtonPressMask | + SubstructureNotifyMask | FocusChangeMask | + EnterWindowMask | LeaveWindowMask); + XSync(g_display, 0); + XSetErrorHandler((XErrorHandler)old); + g_rail_up = g_rail_running; + + if (!g_rail_up) + { + return 1; + } + + return 0; } /*****************************************************************************/ int APP_CC rail_init(void) { - LOG(10, ("chansrv::rail_init:")); - xcommon_init(); - if (rail_is_another_wm_running()) - { - log_message(LOG_LEVEL_ERROR, "rail_init: another window manager " - "is running"); - } - rail_send_init(); - g_rail_up = 1; - return 0; + LOG(10, ("chansrv::rail_init:")); + xcommon_init(); + + if (rail_is_another_wm_running()) + { + log_message(LOG_LEVEL_ERROR, "rail_init: another window manager " + "is running"); + } + + rail_send_init(); + g_rail_up = 1; + return 0; } /*****************************************************************************/ int APP_CC rail_deinit(void) { - if (g_rail_up) - { - /* no longer window manager */ - XSelectInput(g_display, g_root_window, 0); - g_rail_up = 0; - } - return 0; + if (g_rail_up) + { + /* no longer window manager */ + XSelectInput(g_display, g_root_window, 0); + g_rail_up = 0; + } + + return 0; } /*****************************************************************************/ -static char* APP_CC -read_uni(struct stream* s, int num_chars) +static char *APP_CC +read_uni(struct stream *s, int num_chars) { - twchar* rchrs; - char* rv; - int index; - int lchars; - - rchrs = 0; - rv = 0; - if (num_chars > 0) - { - rchrs = (twchar*)g_malloc((num_chars + 1) * sizeof(twchar), 0); - for (index = 0; index < num_chars; index++) - { - in_uint16_le(s, rchrs[index]); - } - rchrs[num_chars] = 0; - lchars = g_wcstombs(0, rchrs, 0); - if (lchars > 0) + twchar *rchrs; + char *rv; + int index; + int lchars; + + rchrs = 0; + rv = 0; + + if (num_chars > 0) { - rv = (char*)g_malloc((lchars + 1) * 4, 0); - g_wcstombs(rv, rchrs, lchars); - rv[lchars] = 0; + rchrs = (twchar *)g_malloc((num_chars + 1) * sizeof(twchar), 0); + + for (index = 0; index < num_chars; index++) + { + in_uint16_le(s, rchrs[index]); + } + + rchrs[num_chars] = 0; + lchars = g_wcstombs(0, rchrs, 0); + + if (lchars > 0) + { + rv = (char *)g_malloc((lchars + 1) * 4, 0); + g_wcstombs(rv, rchrs, lchars); + rv[lchars] = 0; + } } - } - g_free(rchrs); - return rv; + + g_free(rchrs); + return rv; } /*****************************************************************************/ static int APP_CC -rail_process_exec(struct stream* s, int size) +rail_process_exec(struct stream *s, int size) { - int pid; - int flags; - int ExeOrFileLength; - int WorkingDirLength; - int ArgumentsLen; - char* ExeOrFile; - char* WorkingDir; - char* Arguments; - - LOG(0, ("chansrv::rail_process_exec:")); - in_uint16_le(s, flags); - in_uint16_le(s, ExeOrFileLength); - in_uint16_le(s, WorkingDirLength); - in_uint16_le(s, ArgumentsLen); - ExeOrFile = read_uni(s, ExeOrFileLength); - WorkingDir = read_uni(s, WorkingDirLength); - Arguments = read_uni(s, ArgumentsLen); - LOG(10, (" flags 0x%8.8x ExeOrFileLength %d WorkingDirLength %d " - "ArgumentsLen %d ExeOrFile [%s] WorkingDir [%s] " - "Arguments [%s]", flags, ExeOrFileLength, WorkingDirLength, - ArgumentsLen, ExeOrFile, WorkingDir, Arguments)); - if (g_strlen(ExeOrFile) > 0) - { - LOG(10, ("rail_process_exec: pre")); - /* ask main thread to fork */ - tc_mutex_lock(g_exec_mutex); - g_exec_name = ExeOrFile; - g_set_wait_obj(g_exec_event); - tc_sem_dec(g_exec_sem); - tc_mutex_unlock(g_exec_mutex); - LOG(10, ("rail_process_exec: post")); - } - g_free(ExeOrFile); - g_free(WorkingDir); - g_free(Arguments); - return 0; + int pid; + int flags; + int ExeOrFileLength; + int WorkingDirLength; + int ArgumentsLen; + char *ExeOrFile; + char *WorkingDir; + char *Arguments; + + LOG(0, ("chansrv::rail_process_exec:")); + in_uint16_le(s, flags); + in_uint16_le(s, ExeOrFileLength); + in_uint16_le(s, WorkingDirLength); + in_uint16_le(s, ArgumentsLen); + ExeOrFile = read_uni(s, ExeOrFileLength); + WorkingDir = read_uni(s, WorkingDirLength); + Arguments = read_uni(s, ArgumentsLen); + LOG(10, (" flags 0x%8.8x ExeOrFileLength %d WorkingDirLength %d " + "ArgumentsLen %d ExeOrFile [%s] WorkingDir [%s] " + "Arguments [%s]", flags, ExeOrFileLength, WorkingDirLength, + ArgumentsLen, ExeOrFile, WorkingDir, Arguments)); + + if (g_strlen(ExeOrFile) > 0) + { + LOG(10, ("rail_process_exec: pre")); + /* ask main thread to fork */ + tc_mutex_lock(g_exec_mutex); + g_exec_name = ExeOrFile; + g_set_wait_obj(g_exec_event); + tc_sem_dec(g_exec_sem); + tc_mutex_unlock(g_exec_mutex); + LOG(10, ("rail_process_exec: post")); + } + + g_free(ExeOrFile); + g_free(WorkingDir); + g_free(Arguments); + return 0; } /*****************************************************************************/ static int APP_CC -rail_process_activate(struct stream* s, int size) +rail_process_activate(struct stream *s, int size) { - int window_id; - int enabled; - - LOG(10, ("chansrv::rail_process_activate:")); - in_uint32_le(s, window_id); - in_uint8(s, enabled); - LOG(10, (" window_id 0x%8.8x enabled %d", window_id, enabled)); - if (enabled) - { - LOG(10, ("chansrv::rail_process_activate: calling XRaiseWindow 0x%8.8x", window_id)); - XRaiseWindow(g_display, window_id); - LOG(10, ("chansrv::rail_process_activate: calling XSetInputFocus 0x%8.8x", window_id)); - XSetInputFocus(g_display, window_id, RevertToParent, CurrentTime); - } - return 0; + int window_id; + int enabled; + + LOG(10, ("chansrv::rail_process_activate:")); + in_uint32_le(s, window_id); + in_uint8(s, enabled); + LOG(10, (" window_id 0x%8.8x enabled %d", window_id, enabled)); + + if (enabled) + { + LOG(10, ("chansrv::rail_process_activate: calling XRaiseWindow 0x%8.8x", window_id)); + XRaiseWindow(g_display, window_id); + LOG(10, ("chansrv::rail_process_activate: calling XSetInputFocus 0x%8.8x", window_id)); + XSetInputFocus(g_display, window_id, RevertToParent, CurrentTime); + } + + return 0; } /*****************************************************************************/ static int APP_CC -rail_process_system_param(struct stream* s, int size) +rail_process_system_param(struct stream *s, int size) { - int system_param; + int system_param; - LOG(10, ("chansrv::rail_process_system_param:")); - in_uint32_le(s, system_param); - LOG(10, (" system_param 0x%8.8x", system_param)); - return 0; + LOG(10, ("chansrv::rail_process_system_param:")); + in_uint32_le(s, system_param); + LOG(10, (" system_param 0x%8.8x", system_param)); + return 0; } /******************************************************************************/ static int APP_CC rail_close_window(int window_id) { - XEvent ce; - - LOG(0, ("chansrv::rail_close_window:")); - g_memset(&ce, 0, sizeof(ce)); - ce.xclient.type = ClientMessage; - ce.xclient.message_type = g_wm_protocols_atom; - ce.xclient.display = g_display; - ce.xclient.window = window_id; - ce.xclient.format = 32; - ce.xclient.data.l[0] = g_wm_delete_window_atom; - ce.xclient.data.l[1] = CurrentTime; - XSendEvent(g_display, window_id, False, NoEventMask, &ce); - return 0; + XEvent ce; + + LOG(0, ("chansrv::rail_close_window:")); + g_memset(&ce, 0, sizeof(ce)); + ce.xclient.type = ClientMessage; + ce.xclient.message_type = g_wm_protocols_atom; + ce.xclient.display = g_display; + ce.xclient.window = window_id; + ce.xclient.format = 32; + ce.xclient.data.l[0] = g_wm_delete_window_atom; + ce.xclient.data.l[1] = CurrentTime; + XSendEvent(g_display, window_id, False, NoEventMask, &ce); + return 0; } /*****************************************************************************/ static int APP_CC -rail_process_system_command(struct stream* s, int size) +rail_process_system_command(struct stream *s, int size) { - int window_id; - int command; - - LOG(10, ("chansrv::rail_process_system_command:")); - in_uint32_le(s, window_id); - in_uint16_le(s, command); - switch (command) - { - case SC_SIZE: - LOG(10, (" window_id 0x%8.8x SC_SIZE", window_id)); - break; - case SC_MOVE: - LOG(10, (" window_id 0x%8.8x SC_MOVE", window_id)); - break; - case SC_MINIMIZE: - LOG(10, (" window_id 0x%8.8x SC_MINIMIZE", window_id)); - break; - case SC_MAXIMIZE: - LOG(10, (" window_id 0x%8.8x SC_MAXIMIZE", window_id)); - break; - case SC_CLOSE: - LOG(10, (" window_id 0x%8.8x SC_CLOSE", window_id)); - rail_close_window(window_id); - break; - case SC_KEYMENU: - LOG(10, (" window_id 0x%8.8x SC_KEYMENU", window_id)); - break; - case SC_RESTORE: - LOG(10, (" window_id 0x%8.8x SC_RESTORE", window_id)); - break; - case SC_DEFAULT: - LOG(10, (" window_id 0x%8.8x SC_DEFAULT", window_id)); - break; - default: - LOG(10, (" window_id 0x%8.8x unknown command command %d", - window_id, command)); - break; - } - return 0; + int window_id; + int command; + + LOG(10, ("chansrv::rail_process_system_command:")); + in_uint32_le(s, window_id); + in_uint16_le(s, command); + + switch (command) + { + case SC_SIZE: + LOG(10, (" window_id 0x%8.8x SC_SIZE", window_id)); + break; + case SC_MOVE: + LOG(10, (" window_id 0x%8.8x SC_MOVE", window_id)); + break; + case SC_MINIMIZE: + LOG(10, (" window_id 0x%8.8x SC_MINIMIZE", window_id)); + break; + case SC_MAXIMIZE: + LOG(10, (" window_id 0x%8.8x SC_MAXIMIZE", window_id)); + break; + case SC_CLOSE: + LOG(10, (" window_id 0x%8.8x SC_CLOSE", window_id)); + rail_close_window(window_id); + break; + case SC_KEYMENU: + LOG(10, (" window_id 0x%8.8x SC_KEYMENU", window_id)); + break; + case SC_RESTORE: + LOG(10, (" window_id 0x%8.8x SC_RESTORE", window_id)); + break; + case SC_DEFAULT: + LOG(10, (" window_id 0x%8.8x SC_DEFAULT", window_id)); + break; + default: + LOG(10, (" window_id 0x%8.8x unknown command command %d", + window_id, command)); + break; + } + + return 0; } /*****************************************************************************/ static int APP_CC -rail_process_handshake(struct stream* s, int size) +rail_process_handshake(struct stream *s, int size) { - int build_number; + int build_number; - LOG(10, ("chansrv::rail_process_handshake:")); - in_uint32_le(s, build_number); - LOG(10, (" build_number 0x%8.8x", build_number)); - return 0; + LOG(10, ("chansrv::rail_process_handshake:")); + in_uint32_le(s, build_number); + LOG(10, (" build_number 0x%8.8x", build_number)); + return 0; } /*****************************************************************************/ static int APP_CC -rail_process_notify_event(struct stream* s, int size) +rail_process_notify_event(struct stream *s, int size) { - int window_id; - int notify_id; - int message; - - LOG(10, ("chansrv::rail_process_notify_event:")); - in_uint32_le(s, window_id); - in_uint32_le(s, notify_id); - in_uint32_le(s, message); - LOG(10, (" window_id 0x%8.8x notify_id 0x%8.8x message 0x%8.8x", - window_id, notify_id, message)); - return 0; + int window_id; + int notify_id; + int message; + + LOG(10, ("chansrv::rail_process_notify_event:")); + in_uint32_le(s, window_id); + in_uint32_le(s, notify_id); + in_uint32_le(s, message); + LOG(10, (" window_id 0x%8.8x notify_id 0x%8.8x message 0x%8.8x", + window_id, notify_id, message)); + return 0; } /*****************************************************************************/ static int APP_CC -rail_process_window_move(struct stream* s, int size) +rail_process_window_move(struct stream *s, int size) { - int window_id; - int left; - int top; - int right; - int bottom; - - LOG(10, ("chansrv::rail_process_window_move:")); - in_uint32_le(s, window_id); - in_uint16_le(s, left); - in_uint16_le(s, top); - in_uint16_le(s, right); - in_uint16_le(s, bottom); - LOG(10, (" window_id 0x%8.8x left %d top %d right %d bottom %d width %d height %d", - window_id, left, top, right, bottom, right - left, bottom - top)); - XMoveResizeWindow(g_display, window_id, left, top, right - left, bottom - top); - return 0; + int window_id; + int left; + int top; + int right; + int bottom; + + LOG(10, ("chansrv::rail_process_window_move:")); + in_uint32_le(s, window_id); + in_uint16_le(s, left); + in_uint16_le(s, top); + in_uint16_le(s, right); + in_uint16_le(s, bottom); + LOG(10, (" window_id 0x%8.8x left %d top %d right %d bottom %d width %d height %d", + window_id, left, top, right, bottom, right - left, bottom - top)); + XMoveResizeWindow(g_display, window_id, left, top, right - left, bottom - top); + return 0; } /*****************************************************************************/ static int APP_CC -rail_process_local_move_size(struct stream* s, int size) +rail_process_local_move_size(struct stream *s, int size) { - int window_id; - int is_move_size_start; - int move_size_type; - int pos_x; - int pos_y; - - LOG(10, ("chansrv::rail_process_local_move_size:")); - in_uint32_le(s, window_id); - in_uint16_le(s, is_move_size_start); - in_uint16_le(s, move_size_type); - in_uint16_le(s, pos_x); - in_uint16_le(s, pos_y); - LOG(10, (" window_id 0x%8.8x is_move_size_start %d move_size_type %d " - "pos_x %d pos_y %d", window_id, is_move_size_start, move_size_type, - pos_x, pos_y)); - return 0; + int window_id; + int is_move_size_start; + int move_size_type; + int pos_x; + int pos_y; + + LOG(10, ("chansrv::rail_process_local_move_size:")); + in_uint32_le(s, window_id); + in_uint16_le(s, is_move_size_start); + in_uint16_le(s, move_size_type); + in_uint16_le(s, pos_x); + in_uint16_le(s, pos_y); + LOG(10, (" window_id 0x%8.8x is_move_size_start %d move_size_type %d " + "pos_x %d pos_y %d", window_id, is_move_size_start, move_size_type, + pos_x, pos_y)); + return 0; } /*****************************************************************************/ /* server to client only */ static int APP_CC -rail_process_min_max_info(struct stream* s, int size) +rail_process_min_max_info(struct stream *s, int size) { - LOG(10, ("chansrv::rail_process_min_max_info:")); - return 0; + LOG(10, ("chansrv::rail_process_min_max_info:")); + return 0; } /*****************************************************************************/ static int APP_CC -rail_process_client_status(struct stream* s, int size) +rail_process_client_status(struct stream *s, int size) { - int flags; + int flags; - LOG(10, ("chansrv::rail_process_client_status:")); - in_uint32_le(s, flags); - LOG(10, (" flags 0x%8.8x", flags)); - return 0; + LOG(10, ("chansrv::rail_process_client_status:")); + in_uint32_le(s, flags); + LOG(10, (" flags 0x%8.8x", flags)); + return 0; } /*****************************************************************************/ static int APP_CC -rail_process_sys_menu(struct stream* s, int size) +rail_process_sys_menu(struct stream *s, int size) { - int window_id; - int left; - int top; - - LOG(10, ("chansrv::rail_process_sys_menu:")); - in_uint32_le(s, window_id); - in_uint16_le(s, left); - in_uint16_le(s, top); - LOG(10, (" window_id 0x%8.8x left %d top %d", window_id, left, top)); - return 0; + int window_id; + int left; + int top; + + LOG(10, ("chansrv::rail_process_sys_menu:")); + in_uint32_le(s, window_id); + in_uint16_le(s, left); + in_uint16_le(s, top); + LOG(10, (" window_id 0x%8.8x left %d top %d", window_id, left, top)); + return 0; } /*****************************************************************************/ static int APP_CC -rail_process_lang_bar_info(struct stream* s, int size) +rail_process_lang_bar_info(struct stream *s, int size) { - int language_bar_status; + int language_bar_status; - LOG(10, ("chansrv::rail_process_lang_bar_info:")); - in_uint32_le(s, language_bar_status); - LOG(10, (" language_bar_status 0x%8.8x", language_bar_status)); - return 0; + LOG(10, ("chansrv::rail_process_lang_bar_info:")); + in_uint32_le(s, language_bar_status); + LOG(10, (" language_bar_status 0x%8.8x", language_bar_status)); + return 0; } /*****************************************************************************/ static int APP_CC -rail_process_appid_req(struct stream* s, int size) +rail_process_appid_req(struct stream *s, int size) { - LOG(10, ("chansrv::rail_process_appid_req:")); - return 0; + LOG(10, ("chansrv::rail_process_appid_req:")); + return 0; } /*****************************************************************************/ static int APP_CC -rail_process_appid_resp(struct stream* s, int size) +rail_process_appid_resp(struct stream *s, int size) { - LOG(10, ("chansrv::rail_process_appid_resp:")); - return 0; + LOG(10, ("chansrv::rail_process_appid_resp:")); + return 0; } /*****************************************************************************/ /* server to client only */ static int APP_CC -rail_process_exec_result(struct stream* s, int size) +rail_process_exec_result(struct stream *s, int size) { - LOG(10, ("chansrv::rail_process_exec_result:")); - return 0; + LOG(10, ("chansrv::rail_process_exec_result:")); + return 0; } /*****************************************************************************/ /* data in from client ( client -> xrdp -> chansrv ) */ int APP_CC -rail_data_in(struct stream* s, int chan_id, int chan_flags, int length, +rail_data_in(struct stream *s, int chan_id, int chan_flags, int length, int total_length) { - int code; - int size; - - LOG(10, ("chansrv::rail_data_in:")); - in_uint8(s, code); - in_uint8s(s, 1); - in_uint16_le(s, size); - switch (code) - { - case TS_RAIL_ORDER_EXEC: /* 1 */ - rail_process_exec(s, size); - break; - case TS_RAIL_ORDER_ACTIVATE: /* 2 */ - rail_process_activate(s, size); - break; - case TS_RAIL_ORDER_SYSPARAM: /* 3 */ - rail_process_system_param(s, size); - break; - case TS_RAIL_ORDER_SYSCOMMAND: /* 4 */ - rail_process_system_command(s, size); - break; - case TS_RAIL_ORDER_HANDSHAKE: /* 5 */ - rail_process_handshake(s, size); - break; - case TS_RAIL_ORDER_NOTIFY_EVENT: /* 6 */ - rail_process_notify_event(s, size); - break; - case TS_RAIL_ORDER_WINDOWMOVE: /* 8 */ - rail_process_window_move(s, size); - break; - case TS_RAIL_ORDER_LOCALMOVESIZE: /* 9 */ - rail_process_local_move_size(s, size); - break; - case TS_RAIL_ORDER_MINMAXINFO: /* 10 */ - rail_process_min_max_info(s, size); - break; - case TS_RAIL_ORDER_CLIENTSTATUS: /* 11 */ - rail_process_client_status(s, size); - break; - case TS_RAIL_ORDER_SYSMENU: /* 12 */ - rail_process_sys_menu(s, size); - break; - case TS_RAIL_ORDER_LANGBARINFO: /* 13 */ - rail_process_lang_bar_info(s, size); - break; - case TS_RAIL_ORDER_GET_APPID_REQ: /* 14 */ - rail_process_appid_req(s, size); - break; - case TS_RAIL_ORDER_GET_APPID_RESP: /* 15 */ - rail_process_appid_resp(s, size); - break; - case TS_RAIL_ORDER_EXEC_RESULT: /* 128 */ - rail_process_exec_result(s, size); - break; - default: - LOG(10, ("rail_data_in: unknown code %d size %d", code, size)); - break; - } - XFlush(g_display); - return 0; + int code; + int size; + + LOG(10, ("chansrv::rail_data_in:")); + in_uint8(s, code); + in_uint8s(s, 1); + in_uint16_le(s, size); + + switch (code) + { + case TS_RAIL_ORDER_EXEC: /* 1 */ + rail_process_exec(s, size); + break; + case TS_RAIL_ORDER_ACTIVATE: /* 2 */ + rail_process_activate(s, size); + break; + case TS_RAIL_ORDER_SYSPARAM: /* 3 */ + rail_process_system_param(s, size); + break; + case TS_RAIL_ORDER_SYSCOMMAND: /* 4 */ + rail_process_system_command(s, size); + break; + case TS_RAIL_ORDER_HANDSHAKE: /* 5 */ + rail_process_handshake(s, size); + break; + case TS_RAIL_ORDER_NOTIFY_EVENT: /* 6 */ + rail_process_notify_event(s, size); + break; + case TS_RAIL_ORDER_WINDOWMOVE: /* 8 */ + rail_process_window_move(s, size); + break; + case TS_RAIL_ORDER_LOCALMOVESIZE: /* 9 */ + rail_process_local_move_size(s, size); + break; + case TS_RAIL_ORDER_MINMAXINFO: /* 10 */ + rail_process_min_max_info(s, size); + break; + case TS_RAIL_ORDER_CLIENTSTATUS: /* 11 */ + rail_process_client_status(s, size); + break; + case TS_RAIL_ORDER_SYSMENU: /* 12 */ + rail_process_sys_menu(s, size); + break; + case TS_RAIL_ORDER_LANGBARINFO: /* 13 */ + rail_process_lang_bar_info(s, size); + break; + case TS_RAIL_ORDER_GET_APPID_REQ: /* 14 */ + rail_process_appid_req(s, size); + break; + case TS_RAIL_ORDER_GET_APPID_RESP: /* 15 */ + rail_process_appid_resp(s, size); + break; + case TS_RAIL_ORDER_EXEC_RESULT: /* 128 */ + rail_process_exec_result(s, size); + break; + default: + LOG(10, ("rail_data_in: unknown code %d size %d", code, size)); + break; + } + + XFlush(g_display); + return 0; } /*****************************************************************************/ /* returns 0, event handled, 1 unhandled */ int APP_CC -rail_xevent(void* xevent) +rail_xevent(void *xevent) { - XEvent* lxevent; - XWindowChanges xwc; - int rv; - int nchildren_return = 0; - Window root_return; - Window parent_return; - Window *children_return; - Window wreturn; - int revert_to; - XWindowAttributes wnd_attributes; - - LOG(10, ("chansrv::rail_xevent:")); - if (!g_rail_up) - { - return 1; - } - rv = 1; - lxevent = (XEvent*)xevent; - switch (lxevent->type) - { - case ConfigureRequest: - LOG(10, (" got ConfigureRequest window_id 0x%8.8x", lxevent->xconfigurerequest.window)); - g_memset(&xwc, 0, sizeof(xwc)); - xwc.x = lxevent->xconfigurerequest.x; - xwc.y = lxevent->xconfigurerequest.y; - xwc.width = lxevent->xconfigurerequest.width; - xwc.height = lxevent->xconfigurerequest.height; - xwc.border_width = lxevent->xconfigurerequest.border_width; - xwc.sibling = lxevent->xconfigurerequest.above; - xwc.stack_mode = lxevent->xconfigurerequest.detail; - XConfigureWindow(g_display, - lxevent->xconfigurerequest.window, - lxevent->xconfigurerequest.value_mask, - &xwc); - rv = 0; - break; - - case MapRequest: - LOG(10, (" got MapRequest")); - XMapWindow(g_display, lxevent->xmaprequest.window); - rv = 0; - break; - - case MapNotify: - LOG(10, (" got MapNotify")); - break; - - case UnmapNotify: - LOG(10, (" got UnmapNotify")); - break; - - case ConfigureNotify: - LOG(10, (" got ConfigureNotify")); - break; - - case FocusIn: - LOG(10, (" got FocusIn")); - break; - - case ButtonPress: - LOG(10, (" got ButtonPress")); - break; - - case EnterNotify: - LOG(10, (" got EnterNotify")); - break; - - case LeaveNotify: - LOG(10, (" got LeaveNotify")); - break; - - } - return rv; + XEvent *lxevent; + XWindowChanges xwc; + int rv; + int nchildren_return = 0; + Window root_return; + Window parent_return; + Window *children_return; + Window wreturn; + int revert_to; + XWindowAttributes wnd_attributes; + + LOG(10, ("chansrv::rail_xevent:")); + + if (!g_rail_up) + { + return 1; + } + + rv = 1; + lxevent = (XEvent *)xevent; + + switch (lxevent->type) + { + case ConfigureRequest: + LOG(10, (" got ConfigureRequest window_id 0x%8.8x", lxevent->xconfigurerequest.window)); + g_memset(&xwc, 0, sizeof(xwc)); + xwc.x = lxevent->xconfigurerequest.x; + xwc.y = lxevent->xconfigurerequest.y; + xwc.width = lxevent->xconfigurerequest.width; + xwc.height = lxevent->xconfigurerequest.height; + xwc.border_width = lxevent->xconfigurerequest.border_width; + xwc.sibling = lxevent->xconfigurerequest.above; + xwc.stack_mode = lxevent->xconfigurerequest.detail; + XConfigureWindow(g_display, + lxevent->xconfigurerequest.window, + lxevent->xconfigurerequest.value_mask, + &xwc); + rv = 0; + break; + + case MapRequest: + LOG(10, (" got MapRequest")); + XMapWindow(g_display, lxevent->xmaprequest.window); + rv = 0; + break; + + case MapNotify: + LOG(10, (" got MapNotify")); + break; + + case UnmapNotify: + LOG(10, (" got UnmapNotify")); + break; + + case ConfigureNotify: + LOG(10, (" got ConfigureNotify")); + break; + + case FocusIn: + LOG(10, (" got FocusIn")); + break; + + case ButtonPress: + LOG(10, (" got ButtonPress")); + break; + + case EnterNotify: + LOG(10, (" got EnterNotify")); + break; + + case LeaveNotify: + LOG(10, (" got LeaveNotify")); + break; + + } + + return rv; } diff --git a/sesman/chansrv/sound.c b/sesman/chansrv/sound.c index e4d54bb0..e8b801c6 100644 --- a/sesman/chansrv/sound.c +++ b/sesman/chansrv/sound.c @@ -28,100 +28,100 @@ static int g_training_sent_time = 0; static int g_cBlockNo = 0; #if defined(XRDP_SIMPLESOUND) -static void* DEFAULT_CC -read_raw_audio_data(void* arg); +static void *DEFAULT_CC +read_raw_audio_data(void *arg); #endif /*****************************************************************************/ static int APP_CC sound_send_server_formats(void) { - struct stream* s; - int bytes; - char* size_ptr; - - print_got_here(); - - make_stream(s); - init_stream(s, 8182); - out_uint16_le(s, SNDC_FORMATS); - size_ptr = s->p; - out_uint16_le(s, 0); /* size, set later */ - out_uint32_le(s, 0); /* dwFlags */ - out_uint32_le(s, 0); /* dwVolume */ - out_uint32_le(s, 0); /* dwPitch */ - out_uint16_le(s, 0); /* wDGramPort */ - out_uint16_le(s, 1); /* wNumberOfFormats */ - out_uint8(s, g_cBlockNo); /* cLastBlockConfirmed */ - out_uint16_le(s, 2); /* wVersion */ - out_uint8(s, 0); /* bPad */ - - /* sndFormats */ - /* - wFormatTag 2 byte offset 0 - nChannels 2 byte offset 2 - nSamplesPerSec 4 byte offset 4 - nAvgBytesPerSec 4 byte offset 8 - nBlockAlign 2 byte offset 12 - wBitsPerSample 2 byte offset 14 - cbSize 2 byte offset 16 - data variable offset 18 - */ - - /* examples - 01 00 02 00 44 ac 00 00 10 b1 02 00 04 00 10 00 ....D........... - 00 00 - 01 00 02 00 22 56 00 00 88 58 01 00 04 00 10 00 ...."V...X...... - 00 00 - */ - - out_uint16_le(s, 1); // wFormatTag - WAVE_FORMAT_PCM - out_uint16_le(s, 2); // num of channels - out_uint32_le(s, 44100); // samples per sec - out_uint32_le(s, 176400); // avg bytes per sec - out_uint16_le(s, 4); // block align - out_uint16_le(s, 16); // bits per sample - out_uint16_le(s, 0); // size - - s_mark_end(s); - bytes = (int)((s->end - s->data) - 4); - size_ptr[0] = bytes; - size_ptr[1] = bytes >> 8; - bytes = (int)(s->end - s->data); - send_channel_data(g_rdpsnd_chan_id, s->data, bytes); - free_stream(s); - return 0; + struct stream *s; + int bytes; + char *size_ptr; + + print_got_here(); + + make_stream(s); + init_stream(s, 8182); + out_uint16_le(s, SNDC_FORMATS); + size_ptr = s->p; + out_uint16_le(s, 0); /* size, set later */ + out_uint32_le(s, 0); /* dwFlags */ + out_uint32_le(s, 0); /* dwVolume */ + out_uint32_le(s, 0); /* dwPitch */ + out_uint16_le(s, 0); /* wDGramPort */ + out_uint16_le(s, 1); /* wNumberOfFormats */ + out_uint8(s, g_cBlockNo); /* cLastBlockConfirmed */ + out_uint16_le(s, 2); /* wVersion */ + out_uint8(s, 0); /* bPad */ + + /* sndFormats */ + /* + wFormatTag 2 byte offset 0 + nChannels 2 byte offset 2 + nSamplesPerSec 4 byte offset 4 + nAvgBytesPerSec 4 byte offset 8 + nBlockAlign 2 byte offset 12 + wBitsPerSample 2 byte offset 14 + cbSize 2 byte offset 16 + data variable offset 18 + */ + + /* examples + 01 00 02 00 44 ac 00 00 10 b1 02 00 04 00 10 00 ....D........... + 00 00 + 01 00 02 00 22 56 00 00 88 58 01 00 04 00 10 00 ...."V...X...... + 00 00 + */ + + out_uint16_le(s, 1); // wFormatTag - WAVE_FORMAT_PCM + out_uint16_le(s, 2); // num of channels + out_uint32_le(s, 44100); // samples per sec + out_uint32_le(s, 176400); // avg bytes per sec + out_uint16_le(s, 4); // block align + out_uint16_le(s, 16); // bits per sample + out_uint16_le(s, 0); // size + + s_mark_end(s); + bytes = (int)((s->end - s->data) - 4); + size_ptr[0] = bytes; + size_ptr[1] = bytes >> 8; + bytes = (int)(s->end - s->data); + send_channel_data(g_rdpsnd_chan_id, s->data, bytes); + free_stream(s); + return 0; } /*****************************************************************************/ static int sound_send_training(void) { - struct stream* s; - int bytes; - int time; - char* size_ptr; - - print_got_here(); - - make_stream(s); - init_stream(s, 8182); - out_uint16_le(s, SNDC_TRAINING); - size_ptr = s->p; - out_uint16_le(s, 0); /* size, set later */ - time = g_time2(); - g_training_sent_time = time; - out_uint16_le(s, time); - out_uint16_le(s, 1024); - out_uint8s(s, (1024 - 4)); - s_mark_end(s); - bytes = (int)((s->end - s->data) - 4); - size_ptr[0] = bytes; - size_ptr[1] = bytes >> 8; - bytes = (int)(s->end - s->data); - send_channel_data(g_rdpsnd_chan_id, s->data, bytes); - free_stream(s); - return 0; + struct stream *s; + int bytes; + int time; + char *size_ptr; + + print_got_here(); + + make_stream(s); + init_stream(s, 8182); + out_uint16_le(s, SNDC_TRAINING); + size_ptr = s->p; + out_uint16_le(s, 0); /* size, set later */ + time = g_time2(); + g_training_sent_time = time; + out_uint16_le(s, time); + out_uint16_le(s, 1024); + out_uint8s(s, (1024 - 4)); + s_mark_end(s); + bytes = (int)((s->end - s->data) - 4); + size_ptr[0] = bytes; + size_ptr[1] = bytes >> 8; + bytes = (int)(s->end - s->data); + send_channel_data(g_rdpsnd_chan_id, s->data, bytes); + free_stream(s); + return 0; } /*****************************************************************************/ @@ -132,318 +132,339 @@ sound_send_training(void) */ static int APP_CC -sound_process_formats(struct stream* s, int size) +sound_process_formats(struct stream *s, int size) { - int num_formats; - - print_got_here(); - - LOG(0, ("sound_process_formats:")); - if (size < 16) - { - return 1; - } - in_uint8s(s, 14); - in_uint16_le(s, num_formats); - if (num_formats > 0) - { - sound_send_training(); - } - return 0; + int num_formats; + + print_got_here(); + + LOG(0, ("sound_process_formats:")); + + if (size < 16) + { + return 1; + } + + in_uint8s(s, 14); + in_uint16_le(s, num_formats); + + if (num_formats > 0) + { + sound_send_training(); + } + + return 0; } /*****************************************************************************/ static int -sound_send_wave_data(char* data, int data_bytes) +sound_send_wave_data(char *data, int data_bytes) { - struct stream* s; - int bytes; - int time; - char* size_ptr; - - print_got_here(); - - if ((data_bytes < 4) || (data_bytes > 32 * 1024)) - { - LOG(0, ("sound_send_wave_data: bad data_bytes %d", data_bytes)); - } - - /* part one of 2 PDU wave info */ - - LOG(10, ("sound_send_wave_data: sending %d bytes", data_bytes)); - - make_stream(s); - init_stream(s, data_bytes); - out_uint16_le(s, SNDC_WAVE); - size_ptr = s->p; - out_uint16_le(s, 0); /* size, set later */ - time = g_time2(); - out_uint16_le(s, time); - out_uint16_le(s, 0); /* wFormatNo */ - g_cBlockNo++; - out_uint8(s, g_cBlockNo); - - LOG(10, ("sound_send_wave_data: sending time %d, g_cBlockNo %d", - time & 0xffff, g_cBlockNo & 0xff)); - - out_uint8s(s, 3); - out_uint8a(s, data, 4); - s_mark_end(s); - bytes = (int)((s->end - s->data) - 4); - bytes += data_bytes; - bytes -= 4; - size_ptr[0] = bytes; - size_ptr[1] = bytes >> 8; - bytes = (int)(s->end - s->data); - send_channel_data(g_rdpsnd_chan_id, s->data, bytes); - - /* part two of 2 PDU wave info */ - init_stream(s, data_bytes); - out_uint32_le(s, 0); - out_uint8a(s, data + 4, data_bytes - 4); - s_mark_end(s); - bytes = (int)(s->end - s->data); - send_channel_data(g_rdpsnd_chan_id, s->data, bytes); - free_stream(s); - return 0; + struct stream *s; + int bytes; + int time; + char *size_ptr; + + print_got_here(); + + if ((data_bytes < 4) || (data_bytes > 32 * 1024)) + { + LOG(0, ("sound_send_wave_data: bad data_bytes %d", data_bytes)); + } + + /* part one of 2 PDU wave info */ + + LOG(10, ("sound_send_wave_data: sending %d bytes", data_bytes)); + + make_stream(s); + init_stream(s, data_bytes); + out_uint16_le(s, SNDC_WAVE); + size_ptr = s->p; + out_uint16_le(s, 0); /* size, set later */ + time = g_time2(); + out_uint16_le(s, time); + out_uint16_le(s, 0); /* wFormatNo */ + g_cBlockNo++; + out_uint8(s, g_cBlockNo); + + LOG(10, ("sound_send_wave_data: sending time %d, g_cBlockNo %d", + time & 0xffff, g_cBlockNo & 0xff)); + + out_uint8s(s, 3); + out_uint8a(s, data, 4); + s_mark_end(s); + bytes = (int)((s->end - s->data) - 4); + bytes += data_bytes; + bytes -= 4; + size_ptr[0] = bytes; + size_ptr[1] = bytes >> 8; + bytes = (int)(s->end - s->data); + send_channel_data(g_rdpsnd_chan_id, s->data, bytes); + + /* part two of 2 PDU wave info */ + init_stream(s, data_bytes); + out_uint32_le(s, 0); + out_uint8a(s, data + 4, data_bytes - 4); + s_mark_end(s); + bytes = (int)(s->end - s->data); + send_channel_data(g_rdpsnd_chan_id, s->data, bytes); + free_stream(s); + return 0; } /*****************************************************************************/ static int APP_CC -sound_process_training(struct stream* s, int size) +sound_process_training(struct stream *s, int size) { - int time_diff; + int time_diff; - print_got_here(); + print_got_here(); - time_diff = g_time2() - g_training_sent_time; - LOG(0, ("sound_process_training: round trip time %u", time_diff)); - return 0; + time_diff = g_time2() - g_training_sent_time; + LOG(0, ("sound_process_training: round trip time %u", time_diff)); + return 0; } /*****************************************************************************/ static int APP_CC -sound_process_wave_confirm(struct stream* s, int size) +sound_process_wave_confirm(struct stream *s, int size) { - int wTimeStamp; - int cConfirmedBlockNo; + int wTimeStamp; + int cConfirmedBlockNo; - print_got_here(); + print_got_here(); - in_uint16_le(s, wTimeStamp); - in_uint8(s, cConfirmedBlockNo); + in_uint16_le(s, wTimeStamp); + in_uint8(s, cConfirmedBlockNo); - LOG(10, ("sound_process_wave_confirm: wTimeStamp %d, cConfirmedBlockNo %d", - wTimeStamp, cConfirmedBlockNo)); + LOG(10, ("sound_process_wave_confirm: wTimeStamp %d, cConfirmedBlockNo %d", + wTimeStamp, cConfirmedBlockNo)); - return 0; + return 0; } /*****************************************************************************/ static int APP_CC -process_pcm_message(int id, int size, struct stream* s) +process_pcm_message(int id, int size, struct stream *s) { - print_got_here(); + print_got_here(); - sound_send_wave_data(s->p, size); - return 0; + sound_send_wave_data(s->p, size); + return 0; } /*****************************************************************************/ /* data coming in from audio source, eg pulse, alsa */ static int DEFAULT_CC -sound_trans_audio_data_in(struct trans* trans) +sound_trans_audio_data_in(struct trans *trans) { - struct stream *s; - int id; - int size; - int error; + struct stream *s; + int id; + int size; + int error; - if (trans == 0) - { - return 0; - } - if (trans != g_audio_c_trans) - { - return 1; - } - s = trans_get_in_s(trans); - in_uint32_le(s, id); - in_uint32_le(s, size); - if ((id != 0) || (size > 32 * 1024 + 8) || (size < 1)) - { - LOG(0, ("sound_trans_audio_data_in: bad message id %d size %d", id, size)); - return 1; - } - error = trans_force_read(trans, size - 8); - if (error == 0) - { - /* here, the entire message block is read in, process it */ - error = process_pcm_message(id, size - 8, s); - } - return error; + if (trans == 0) + { + return 0; + } + + if (trans != g_audio_c_trans) + { + return 1; + } + + s = trans_get_in_s(trans); + in_uint32_le(s, id); + in_uint32_le(s, size); + + if ((id != 0) || (size > 32 * 1024 + 8) || (size < 1)) + { + LOG(0, ("sound_trans_audio_data_in: bad message id %d size %d", id, size)); + return 1; + } + + error = trans_force_read(trans, size - 8); + + if (error == 0) + { + /* here, the entire message block is read in, process it */ + error = process_pcm_message(id, size - 8, s); + } + + return error; } /*****************************************************************************/ static int DEFAULT_CC sound_trans_audio_conn_in(struct trans *trans, struct trans *new_trans) { - print_got_here(); - - if (trans == 0) - { - return 1; - } - if (trans != g_audio_l_trans) - { - return 1; - } - if (g_audio_c_trans != 0) /* if already set, error */ - { - return 1; - } - if (new_trans == 0) - { - return 1; - } - g_audio_c_trans = new_trans; - g_audio_c_trans->trans_data_in = sound_trans_audio_data_in; - g_audio_c_trans->header_size = 8; - trans_delete(g_audio_l_trans); - g_audio_l_trans = 0; - return 0; + print_got_here(); + + if (trans == 0) + { + return 1; + } + + if (trans != g_audio_l_trans) + { + return 1; + } + + if (g_audio_c_trans != 0) /* if already set, error */ + { + return 1; + } + + if (new_trans == 0) + { + return 1; + } + + g_audio_c_trans = new_trans; + g_audio_c_trans->trans_data_in = sound_trans_audio_data_in; + g_audio_c_trans->header_size = 8; + trans_delete(g_audio_l_trans); + g_audio_l_trans = 0; + return 0; } /*****************************************************************************/ int APP_CC sound_init(void) { - char port[256]; - int error; - - print_got_here(); - LOG(0, ("sound_init:")); - - sound_send_server_formats(); - g_audio_l_trans = trans_create(2, 33 * 1024, 8192); - g_snprintf(port, 255, "/tmp/xrdp_chansrv_audio_socket_%d", g_display_num); - g_audio_l_trans->trans_conn_in = sound_trans_audio_conn_in; - error = trans_listen(g_audio_l_trans, port); - if (error != 0) - { - LOG(0, ("sound_init: trans_listen failed")); - } + char port[256]; + int error; + + print_got_here(); + LOG(0, ("sound_init:")); + + sound_send_server_formats(); + g_audio_l_trans = trans_create(2, 33 * 1024, 8192); + g_snprintf(port, 255, "/tmp/xrdp_chansrv_audio_socket_%d", g_display_num); + g_audio_l_trans->trans_conn_in = sound_trans_audio_conn_in; + error = trans_listen(g_audio_l_trans, port); + + if (error != 0) + { + LOG(0, ("sound_init: trans_listen failed")); + } #if defined(XRDP_SIMPLESOUND) - /* start thread to read raw audio data from pulseaudio device */ - tc_thread_create(read_raw_audio_data, 0); + /* start thread to read raw audio data from pulseaudio device */ + tc_thread_create(read_raw_audio_data, 0); #endif - return 0; + return 0; } /*****************************************************************************/ int APP_CC sound_deinit(void) { - print_got_here(); + print_got_here(); - if (g_audio_l_trans != 0) - { - trans_delete(g_audio_l_trans); - g_audio_l_trans = 0; - } - if (g_audio_c_trans != 0) - { - trans_delete(g_audio_c_trans); - g_audio_l_trans = 0; - } + if (g_audio_l_trans != 0) + { + trans_delete(g_audio_l_trans); + g_audio_l_trans = 0; + } - return 0; + if (g_audio_c_trans != 0) + { + trans_delete(g_audio_c_trans); + g_audio_l_trans = 0; + } + + return 0; } /*****************************************************************************/ /* data in from client ( clinet -> xrdp -> chansrv ) */ int APP_CC -sound_data_in(struct stream* s, int chan_id, int chan_flags, int length, +sound_data_in(struct stream *s, int chan_id, int chan_flags, int length, int total_length) { - int code; - int size; - - print_got_here(); - - in_uint8(s, code); - in_uint8s(s, 1); - in_uint16_le(s, size); - switch (code) - { - case SNDC_WAVECONFIRM: - sound_process_wave_confirm(s, size); - break; - - case SNDC_TRAINING: - sound_process_training(s, size); - break; - - case SNDC_FORMATS: - sound_process_formats(s, size); - break; - - default: - LOG(0, ("sound_data_in: unknown code %d size %d", code, size)); - break; - } - return 0; + int code; + int size; + + print_got_here(); + + in_uint8(s, code); + in_uint8s(s, 1); + in_uint16_le(s, size); + + switch (code) + { + case SNDC_WAVECONFIRM: + sound_process_wave_confirm(s, size); + break; + + case SNDC_TRAINING: + sound_process_training(s, size); + break; + + case SNDC_FORMATS: + sound_process_formats(s, size); + break; + + default: + LOG(0, ("sound_data_in: unknown code %d size %d", code, size)); + break; + } + + return 0; } /*****************************************************************************/ int APP_CC -sound_get_wait_objs(tbus* objs, int* count, int* timeout) +sound_get_wait_objs(tbus *objs, int *count, int *timeout) { - int lcount; - - lcount = *count; - if (g_audio_l_trans != 0) - { - objs[lcount] = g_audio_l_trans->sck; - lcount++; - } - if (g_audio_c_trans != 0) - { - objs[lcount] = g_audio_c_trans->sck; - lcount++; - } - *count = lcount; - return 0; + int lcount; + + lcount = *count; + + if (g_audio_l_trans != 0) + { + objs[lcount] = g_audio_l_trans->sck; + lcount++; + } + + if (g_audio_c_trans != 0) + { + objs[lcount] = g_audio_c_trans->sck; + lcount++; + } + + *count = lcount; + return 0; } /*****************************************************************************/ int APP_CC sound_check_wait_objs(void) { - if (g_audio_l_trans != 0) - { - trans_check_wait_objs(g_audio_l_trans); - } + if (g_audio_l_trans != 0) + { + trans_check_wait_objs(g_audio_l_trans); + } - if (g_audio_c_trans != 0) - { - trans_check_wait_objs(g_audio_c_trans); - } + if (g_audio_c_trans != 0) + { + trans_check_wait_objs(g_audio_c_trans); + } - return 0; + return 0; } #if defined(XRDP_SIMPLESOUND) static int DEFAULT_CC -sttrans_data_in(struct trans* self) +sttrans_data_in(struct trans *self) { - LOG(0, ("sttrans_data_in:\n")); - return 0; + LOG(0, ("sttrans_data_in:\n")); + return 0; } /** @@ -451,103 +472,112 @@ sttrans_data_in(struct trans* self) * to a unix domain socket on which trans server is listening */ -static void* DEFAULT_CC -read_raw_audio_data(void* arg) +static void *DEFAULT_CC +read_raw_audio_data(void *arg) { - pa_sample_spec samp_spec; - pa_simple* simple = NULL; - uint32_t bytes_read; - char* cptr; - int i; - int error; - struct trans* strans; - char path[256]; - struct stream* outs; - - strans = trans_create(TRANS_MODE_UNIX, 8192, 8192); - if (strans == 0) - { - LOG(0, ("read_raw_audio_data: trans_create failed\n")); - return 0; - } - strans->trans_data_in = sttrans_data_in; - g_snprintf(path, 255, "/tmp/xrdp_chansrv_audio_socket_%d", g_display_num); - if (trans_connect(strans, "", path, 100) != 0) - { - LOG(0, ("read_raw_audio_data: trans_connect failed\n")); - trans_delete(strans); - return 0; - } - - /* setup audio format */ - samp_spec.format = PA_SAMPLE_S16LE; - samp_spec.rate = 44100; - samp_spec.channels = 2; - - /* if we are root, then for first 8 seconds connection to pulseaudo server - fails; if we are non-root, then connection succeeds on first attempt; - for now we have changed code to be non-root, but this may change in the - future - so pretend we are root and try connecting to pulseaudio server - for upto one minute */ - for (i = 0; i < 60; i++) - { - simple = pa_simple_new(NULL, "xrdp", PA_STREAM_RECORD, NULL, - "record", &samp_spec, NULL, NULL, &error); - if (simple) + pa_sample_spec samp_spec; + pa_simple *simple = NULL; + uint32_t bytes_read; + char *cptr; + int i; + int error; + struct trans *strans; + char path[256]; + struct stream *outs; + + strans = trans_create(TRANS_MODE_UNIX, 8192, 8192); + + if (strans == 0) { - /* connected to pulseaudio server */ - LOG(0, ("read_raw_audio_data: connected to pulseaudio server\n")); - break; + LOG(0, ("read_raw_audio_data: trans_create failed\n")); + return 0; } - LOG(0, ("read_raw_audio_data: ERROR creating PulseAudio async interface\n")); - LOG(0, ("read_raw_audio_data: %s\n", pa_strerror(error))); - g_sleep(1000); - } - - if (i == 60) - { - /* failed to connect to audio server */ - trans_delete(strans); - return NULL; - } - - /* insert header just once */ - outs = trans_get_out_s(strans, 8192); - out_uint32_le(outs, 0); - out_uint32_le(outs, AUDIO_BUF_SIZE + 8); - cptr = outs->p; - out_uint8s(outs, AUDIO_BUF_SIZE); - s_mark_end(outs); - - while (1) - { - /* read a block of raw audio data... */ - g_memset(cptr, 0, 4); - bytes_read = pa_simple_read(simple, cptr, AUDIO_BUF_SIZE, &error); - if (bytes_read < 0) + + strans->trans_data_in = sttrans_data_in; + g_snprintf(path, 255, "/tmp/xrdp_chansrv_audio_socket_%d", g_display_num); + + if (trans_connect(strans, "", path, 100) != 0) { - LOG(0, ("read_raw_audio_data: ERROR reading from pulseaudio stream\n")); - LOG(0, ("read_raw_audio_data: %s\n", pa_strerror(error))); - break; + LOG(0, ("read_raw_audio_data: trans_connect failed\n")); + trans_delete(strans); + return 0; } - /* bug workaround: - even when there is no audio data, pulseaudio is returning without - errors but the data itself is zero; we use this zero data to - determine that there is no audio data present */ - if (*cptr == 0 && *(cptr + 1) == 0 && *(cptr + 2) == 0 && *(cptr + 3) == 0) + + /* setup audio format */ + samp_spec.format = PA_SAMPLE_S16LE; + samp_spec.rate = 44100; + samp_spec.channels = 2; + + /* if we are root, then for first 8 seconds connection to pulseaudo server + fails; if we are non-root, then connection succeeds on first attempt; + for now we have changed code to be non-root, but this may change in the + future - so pretend we are root and try connecting to pulseaudio server + for upto one minute */ + for (i = 0; i < 60; i++) { - g_sleep(10); - continue; + simple = pa_simple_new(NULL, "xrdp", PA_STREAM_RECORD, NULL, + "record", &samp_spec, NULL, NULL, &error); + + if (simple) + { + /* connected to pulseaudio server */ + LOG(0, ("read_raw_audio_data: connected to pulseaudio server\n")); + break; + } + + LOG(0, ("read_raw_audio_data: ERROR creating PulseAudio async interface\n")); + LOG(0, ("read_raw_audio_data: %s\n", pa_strerror(error))); + g_sleep(1000); } - if (trans_force_write_s(strans, outs) != 0) + + if (i == 60) { - LOG(0, ("read_raw_audio_data: ERROR writing audio data to server\n")); - break; + /* failed to connect to audio server */ + trans_delete(strans); + return NULL; } - } - pa_simple_free(simple); - trans_delete(strans); - return NULL; + + /* insert header just once */ + outs = trans_get_out_s(strans, 8192); + out_uint32_le(outs, 0); + out_uint32_le(outs, AUDIO_BUF_SIZE + 8); + cptr = outs->p; + out_uint8s(outs, AUDIO_BUF_SIZE); + s_mark_end(outs); + + while (1) + { + /* read a block of raw audio data... */ + g_memset(cptr, 0, 4); + bytes_read = pa_simple_read(simple, cptr, AUDIO_BUF_SIZE, &error); + + if (bytes_read < 0) + { + LOG(0, ("read_raw_audio_data: ERROR reading from pulseaudio stream\n")); + LOG(0, ("read_raw_audio_data: %s\n", pa_strerror(error))); + break; + } + + /* bug workaround: + even when there is no audio data, pulseaudio is returning without + errors but the data itself is zero; we use this zero data to + determine that there is no audio data present */ + if (*cptr == 0 && *(cptr + 1) == 0 && *(cptr + 2) == 0 && *(cptr + 3) == 0) + { + g_sleep(10); + continue; + } + + if (trans_force_write_s(strans, outs) != 0) + { + LOG(0, ("read_raw_audio_data: ERROR writing audio data to server\n")); + break; + } + } + + pa_simple_free(simple); + trans_delete(strans); + return NULL; } #endif diff --git a/sesman/chansrv/xcommon.c b/sesman/chansrv/xcommon.c index 70b52694..f7f95768 100644 --- a/sesman/chansrv/xcommon.c +++ b/sesman/chansrv/xcommon.c @@ -31,10 +31,10 @@ extern int g_waiting_for_data_response_time; /* in clipboard.c */ extern int g_rail_up; /* in rail.c */ -Display* g_display = 0; +Display *g_display = 0; int g_x_socket = 0; tbus g_x_wait_obj = 0; -Screen* g_screen = 0; +Screen *g_screen = 0; int g_screen_num = 0; Window g_root_window = 0; Atom g_wm_delete_window_atom = 0; @@ -42,15 +42,15 @@ Atom g_wm_protocols_atom = 0; /*****************************************************************************/ static int DEFAULT_CC -xcommon_error_handler(Display* dis, XErrorEvent* xer) +xcommon_error_handler(Display *dis, XErrorEvent *xer) { - char text[256]; + char text[256]; - XGetErrorText(dis, xer->error_code, text, 255); - LOGM((LOG_LEVEL_ERROR, "X error [%s](%d) opcodes %d/%d " - "resource 0x%lx", text, xer->error_code, - xer->request_code, xer->minor_code, xer->resourceid)); - return 0; + XGetErrorText(dis, xer->error_code, text, 255); + LOGM((LOG_LEVEL_ERROR, "X error [%s](%d) opcodes %d/%d " + "resource 0x%lx", text, xer->error_code, + xer->request_code, xer->minor_code, xer->resourceid)); + return 0; } /*****************************************************************************/ @@ -58,9 +58,9 @@ xcommon_error_handler(Display* dis, XErrorEvent* xer) Do any cleanup that needs to be done on exit, like removing temporary files. Don't worry about memory leaks */ static int DEFAULT_CC -xcommon_fatal_handler(Display* dis) +xcommon_fatal_handler(Display *dis) { - return 0; + return 0; } /*****************************************************************************/ @@ -71,7 +71,7 @@ xcommon_fatal_handler(Display* dis) int APP_CC xcommon_get_local_time(void) { - return g_time3(); + return g_time3(); } /******************************************************************************/ @@ -79,42 +79,45 @@ xcommon_get_local_time(void) int APP_CC xcommon_init(void) { - if (g_display != 0) - { - LOG(10, ("xcommon_init: xcommon_init already called")); + if (g_display != 0) + { + LOG(10, ("xcommon_init: xcommon_init already called")); + return 0; + } + + g_display = XOpenDisplay(0); + + if (g_display == 0) + { + LOGM((LOG_LEVEL_ERROR, "xcommon_init: error, XOpenDisplay failed")); + return 1; + } + + LOG(0, ("xcommon_init: connected to display ok")); + + /* setting the error handlers can cause problem when shutting down + chansrv on some xlibs */ + XSetErrorHandler(xcommon_error_handler); + //XSetIOErrorHandler(xcommon_fatal_handler); + + g_x_socket = XConnectionNumber(g_display); + + if (g_x_socket == 0) + { + LOGM((LOG_LEVEL_ERROR, "xcommon_init: XConnectionNumber failed")); + return 1; + } + + g_x_wait_obj = g_create_wait_obj_from_socket(g_x_socket, 0); + g_screen_num = DefaultScreen(g_display); + g_screen = ScreenOfDisplay(g_display, g_screen_num); + + g_root_window = RootWindowOfScreen(g_screen); + + g_wm_delete_window_atom = XInternAtom(g_display, "WM_DELETE_WINDOW", 0); + g_wm_protocols_atom = XInternAtom(g_display, "WM_PROTOCOLS", 0); + return 0; - } - g_display = XOpenDisplay(0); - if (g_display == 0) - { - LOGM((LOG_LEVEL_ERROR, "xcommon_init: error, XOpenDisplay failed")); - return 1; - } - - LOG(0, ("xcommon_init: connected to display ok")); - - /* setting the error handlers can cause problem when shutting down - chansrv on some xlibs */ - XSetErrorHandler(xcommon_error_handler); - //XSetIOErrorHandler(xcommon_fatal_handler); - - g_x_socket = XConnectionNumber(g_display); - if (g_x_socket == 0) - { - LOGM((LOG_LEVEL_ERROR, "xcommon_init: XConnectionNumber failed")); - return 1; - } - - g_x_wait_obj = g_create_wait_obj_from_socket(g_x_socket, 0); - g_screen_num = DefaultScreen(g_display); - g_screen = ScreenOfDisplay(g_display, g_screen_num); - - g_root_window = RootWindowOfScreen(g_screen); - - g_wm_delete_window_atom = XInternAtom(g_display, "WM_DELETE_WINDOW", 0); - g_wm_protocols_atom = XInternAtom(g_display, "WM_PROTOCOLS", 0); - - return 0; } /*****************************************************************************/ @@ -122,66 +125,73 @@ xcommon_init(void) this is called to get any wait objects for the main loop timeout can be nil */ int APP_CC -xcommon_get_wait_objs(tbus* objs, int* count, int* timeout) +xcommon_get_wait_objs(tbus *objs, int *count, int *timeout) { - int lcount; + int lcount; + + if (((!g_clip_up) && (!g_rail_up)) || (objs == 0) || (count == 0)) + { + LOG(10, ("xcommon_get_wait_objs: nothing to do")); + return 0; + } - if (((!g_clip_up) && (!g_rail_up)) || (objs == 0) || (count == 0)) - { - LOG(10, ("xcommon_get_wait_objs: nothing to do")); + lcount = *count; + objs[lcount] = g_x_wait_obj; + lcount++; + *count = lcount; return 0; - } - lcount = *count; - objs[lcount] = g_x_wait_obj; - lcount++; - *count = lcount; - return 0; } /*****************************************************************************/ int APP_CC xcommon_check_wait_objs(void) { - XEvent xevent; - int time_diff; - int clip_rv; - int rail_rv; - - if ((!g_clip_up) && (!g_rail_up)) - { - LOG(10, ("xcommon_check_wait_objs: nothing to do")); - return 0; - } - if (g_is_wait_obj_set(g_x_wait_obj)) - { - if (XPending(g_display) < 1) - { - /* something is wrong, should not get here */ - LOGM((LOG_LEVEL_ERROR, "xcommon_check_wait_objs: sck closed")); - return 0; - } - if (g_waiting_for_data_response) + XEvent xevent; + int time_diff; + int clip_rv; + int rail_rv; + + if ((!g_clip_up) && (!g_rail_up)) { - time_diff = xcommon_get_local_time() - - g_waiting_for_data_response_time; - if (time_diff > 10000) - { - LOGM((LOG_LEVEL_ERROR, "xcommon_check_wait_objs: warning, " - "waiting for data response too long")); - } + LOG(10, ("xcommon_check_wait_objs: nothing to do")); + return 0; } - while (XPending(g_display) > 0) + + if (g_is_wait_obj_set(g_x_wait_obj)) { - g_memset(&xevent, 0, sizeof(xevent)); - XNextEvent(g_display, &xevent); - - clip_rv = clipboard_xevent(&xevent); - rail_rv = rail_xevent(&xevent); - if ((clip_rv == 1) && (rail_rv == 1)) - { - LOG(10, ("xcommon_check_wait_objs unknown xevent type %d", xevent.type)); - } + if (XPending(g_display) < 1) + { + /* something is wrong, should not get here */ + LOGM((LOG_LEVEL_ERROR, "xcommon_check_wait_objs: sck closed")); + return 0; + } + + if (g_waiting_for_data_response) + { + time_diff = xcommon_get_local_time() - + g_waiting_for_data_response_time; + + if (time_diff > 10000) + { + LOGM((LOG_LEVEL_ERROR, "xcommon_check_wait_objs: warning, " + "waiting for data response too long")); + } + } + + while (XPending(g_display) > 0) + { + g_memset(&xevent, 0, sizeof(xevent)); + XNextEvent(g_display, &xevent); + + clip_rv = clipboard_xevent(&xevent); + rail_rv = rail_xevent(&xevent); + + if ((clip_rv == 1) && (rail_rv == 1)) + { + LOG(10, ("xcommon_check_wait_objs unknown xevent type %d", xevent.type)); + } + } } - } - return 0; + + return 0; } diff --git a/sesman/config.c b/sesman/config.c index a4342676..9938249f 100644 --- a/sesman/config.c +++ b/sesman/config.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -31,146 +30,153 @@ #include "sesman.h" #include "log.h" -extern struct config_sesman* g_cfg; /* in sesman.c */ +extern struct config_sesman *g_cfg; /* in sesman.c */ /******************************************************************************/ int DEFAULT_CC -config_read(struct config_sesman* cfg) +config_read(struct config_sesman *cfg) { - int fd; - struct list* sec; - struct list* param_n; - struct list* param_v; - char cfg_file[256]; - - g_snprintf(cfg_file, 255, "%s/sesman.ini", XRDP_CFG_PATH); - fd = g_file_open(cfg_file); - if (-1 == fd) - { - //if (g_cfg->log.fd >= 0) - //{ - /* logging is already active */ - log_message(LOG_LEVEL_ALWAYS, "error opening %s in \ + int fd; + struct list *sec; + struct list *param_n; + struct list *param_v; + char cfg_file[256]; + + g_snprintf(cfg_file, 255, "%s/sesman.ini", XRDP_CFG_PATH); + fd = g_file_open(cfg_file); + + if (-1 == fd) + { + //if (g_cfg->log.fd >= 0) + //{ + /* logging is already active */ + log_message(LOG_LEVEL_ALWAYS, "error opening %s in \ config_read", cfg_file); - //} - //else - //{ - g_printf("error opening %s in config_read", cfg_file); - //} - return 1; - } - g_memset(cfg, 0, sizeof(struct config_sesman)); - sec = list_create(); - sec->auto_free = 1; - file_read_sections(fd, sec); - param_n = list_create(); - param_n->auto_free = 1; - param_v = list_create(); - param_v->auto_free = 1; - - /* read global config */ - config_read_globals(fd, cfg, param_n, param_v); - - /* read Xvnc/X11rdp parameter list */ - config_read_vnc_params(fd, cfg, param_n, param_v); - config_read_rdp_params(fd, cfg, param_n, param_v); - - /* read logging config */ - // config_read_logging(fd, &(cfg->log), param_n, param_v); - - /* read security config */ - config_read_security(fd, &(cfg->sec), param_n, param_v); - - /* read session config */ - config_read_sessions(fd, &(cfg->sess), param_n, param_v); - - /* cleanup */ - list_delete(sec); - list_delete(param_v); - list_delete(param_n); - g_file_close(fd); - return 0; + //} + //else + //{ + g_printf("error opening %s in config_read", cfg_file); + //} + return 1; + } + + g_memset(cfg, 0, sizeof(struct config_sesman)); + sec = list_create(); + sec->auto_free = 1; + file_read_sections(fd, sec); + param_n = list_create(); + param_n->auto_free = 1; + param_v = list_create(); + param_v->auto_free = 1; + + /* read global config */ + config_read_globals(fd, cfg, param_n, param_v); + + /* read Xvnc/X11rdp parameter list */ + config_read_vnc_params(fd, cfg, param_n, param_v); + config_read_rdp_params(fd, cfg, param_n, param_v); + + /* read logging config */ + // config_read_logging(fd, &(cfg->log), param_n, param_v); + + /* read security config */ + config_read_security(fd, &(cfg->sec), param_n, param_v); + + /* read session config */ + config_read_sessions(fd, &(cfg->sess), param_n, param_v); + + /* cleanup */ + list_delete(sec); + list_delete(param_v); + list_delete(param_n); + g_file_close(fd); + return 0; } /******************************************************************************/ int DEFAULT_CC -config_read_globals(int file, struct config_sesman* cf, struct list* param_n, - struct list* param_v) +config_read_globals(int file, struct config_sesman *cf, struct list *param_n, + struct list *param_v) { - int i; - char* buf; + int i; + char *buf; - list_clear(param_v); - list_clear(param_n); + list_clear(param_v); + list_clear(param_n); - /* resetting the struct */ - cf->listen_address[0] = '\0'; - cf->listen_port[0] = '\0'; - cf->enable_user_wm = 0; - cf->user_wm[0] = '\0'; - cf->default_wm[0] = '\0'; - cf->auth_file_path = 0; + /* resetting the struct */ + cf->listen_address[0] = '\0'; + cf->listen_port[0] = '\0'; + cf->enable_user_wm = 0; + cf->user_wm[0] = '\0'; + cf->default_wm[0] = '\0'; + cf->auth_file_path = 0; - file_read_section(file, SESMAN_CFG_GLOBALS, param_n, param_v); - for (i = 0; i < param_n->count; i++) - { - buf = (char*)list_get_item(param_n, i); - if (0 == g_strcasecmp(buf, SESMAN_CFG_DEFWM)) - { - g_strncpy(cf->default_wm, (char*)list_get_item(param_v, i), 31); - } - else if (0 == g_strcasecmp(buf, SESMAN_CFG_USERWM)) + file_read_section(file, SESMAN_CFG_GLOBALS, param_n, param_v); + + for (i = 0; i < param_n->count; i++) { - g_strncpy(cf->user_wm, (char*)list_get_item(param_v, i), 31); + buf = (char *)list_get_item(param_n, i); + + if (0 == g_strcasecmp(buf, SESMAN_CFG_DEFWM)) + { + g_strncpy(cf->default_wm, (char *)list_get_item(param_v, i), 31); + } + else if (0 == g_strcasecmp(buf, SESMAN_CFG_USERWM)) + { + g_strncpy(cf->user_wm, (char *)list_get_item(param_v, i), 31); + } + else if (0 == g_strcasecmp(buf, SESMAN_CFG_ENABLE_USERWM)) + { + cf->enable_user_wm = text2bool((char *)list_get_item(param_v, i)); + } + else if (0 == g_strcasecmp(buf, SESMAN_CFG_PORT)) + { + g_strncpy(cf->listen_port, (char *)list_get_item(param_v, i), 15); + } + else if (0 == g_strcasecmp(buf, SESMAN_CFG_ADDRESS)) + { + g_strncpy(cf->listen_address, (char *)list_get_item(param_v, i), 31); + } + else if (0 == g_strcasecmp(buf, SESMAN_CFG_AUTH_FILE_PATH)) + { + cf->auth_file_path = g_strdup((char *)list_get_item(param_v, i)); + } } - else if (0 == g_strcasecmp(buf, SESMAN_CFG_ENABLE_USERWM)) + + /* checking for missing required parameters */ + if ('\0' == cf->listen_address[0]) { - cf->enable_user_wm = text2bool((char*)list_get_item(param_v, i)); + g_strncpy(cf->listen_address, "0.0.0.0", 8); } - else if (0 == g_strcasecmp(buf, SESMAN_CFG_PORT)) + + if ('\0' == cf->listen_port[0]) { - g_strncpy(cf->listen_port, (char*)list_get_item(param_v, i), 15); + g_strncpy(cf->listen_port, "3350", 5); } - else if (0 == g_strcasecmp(buf, SESMAN_CFG_ADDRESS)) + + if ('\0' == cf->user_wm[0]) { - g_strncpy(cf->listen_address, (char*)list_get_item(param_v, i), 31); + cf->enable_user_wm = 0; } - else if (0 == g_strcasecmp(buf, SESMAN_CFG_AUTH_FILE_PATH)) + + if ('\0' == cf->default_wm[0]) { - cf->auth_file_path = g_strdup((char*)list_get_item(param_v, i)); + g_strncpy(cf->default_wm, "startwm.sh", 11); } - } - /* checking for missing required parameters */ - if ('\0' == cf->listen_address[0]) - { - g_strncpy(cf->listen_address, "0.0.0.0", 8); - } - if ('\0' == cf->listen_port[0]) - { - g_strncpy(cf->listen_port, "3350", 5); - } - if ('\0' == cf->user_wm[0]) - { - cf->enable_user_wm = 0; - } - if ('\0' == cf->default_wm[0]) - { - g_strncpy(cf->default_wm, "startwm.sh", 11); - } - - /* showing read config */ - g_printf("sesman config:\r\n"); - g_printf("\tListenAddress: %s\r\n", cf->listen_address); - g_printf("\tListenPort: %s\r\n", cf->listen_port); - g_printf("\tEnableUserWindowManager: %i\r\n", cf->enable_user_wm); - g_printf("\tUserWindowManager: %s\r\n", cf->user_wm); - g_printf("\tDefaultWindowManager: %s\r\n", cf->default_wm); - g_printf("\tAuthFilePath: %s\r\n", ((cf->auth_file_path) ? (cf->auth_file_path) : ("disabled"))); + /* showing read config */ + g_printf("sesman config:\r\n"); + g_printf("\tListenAddress: %s\r\n", cf->listen_address); + g_printf("\tListenPort: %s\r\n", cf->listen_port); + g_printf("\tEnableUserWindowManager: %i\r\n", cf->enable_user_wm); + g_printf("\tUserWindowManager: %s\r\n", cf->user_wm); + g_printf("\tDefaultWindowManager: %s\r\n", cf->default_wm); + g_printf("\tAuthFilePath: %s\r\n", ((cf->auth_file_path) ? (cf->auth_file_path) : ("disabled"))); - return 0; + return 0; } /****************************************************************************** @@ -184,7 +190,7 @@ config_read_logging(int file, struct log_config* lc, struct list* param_n, list_clear(param_v); list_clear(param_n); - // setting defaults + // setting defaults lc->program_name = g_strdup("sesman"); lc->log_file = 0; lc->fd = 0; @@ -230,185 +236,201 @@ config_read_logging(int file, struct log_config* lc, struct list* param_n, */ /******************************************************************************/ int DEFAULT_CC -config_read_security(int file, struct config_security* sc, - struct list* param_n, - struct list* param_v) +config_read_security(int file, struct config_security *sc, + struct list *param_n, + struct list *param_v) { - int i; - int gid; - char* buf; + int i; + int gid; + char *buf; - list_clear(param_v); - list_clear(param_n); + list_clear(param_v); + list_clear(param_n); - /* setting defaults */ - sc->allow_root = 0; - sc->login_retry = 3; - sc->ts_users_enable = 0; - sc->ts_admins_enable = 0; + /* setting defaults */ + sc->allow_root = 0; + sc->login_retry = 3; + sc->ts_users_enable = 0; + sc->ts_admins_enable = 0; - file_read_section(file, SESMAN_CFG_SECURITY, param_n, param_v); - for (i = 0; i < param_n->count; i++) - { - buf = (char*)list_get_item(param_n, i); - if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_ALLOW_ROOT)) + file_read_section(file, SESMAN_CFG_SECURITY, param_n, param_v); + + for (i = 0; i < param_n->count; i++) { - sc->allow_root = text2bool((char*)list_get_item(param_v, i)); + buf = (char *)list_get_item(param_n, i); + + if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_ALLOW_ROOT)) + { + sc->allow_root = text2bool((char *)list_get_item(param_v, i)); + } + + if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_LOGIN_RETRY)) + { + sc->login_retry = g_atoi((char *)list_get_item(param_v, i)); + } + + if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_USR_GROUP)) + { + if (g_getgroup_info((char *)list_get_item(param_v, i), &gid) == 0) + { + sc->ts_users_enable = 1; + sc->ts_users = gid; + } + } + + if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_ADM_GROUP)) + { + if (g_getgroup_info((char *)list_get_item(param_v, i), &gid) == 0) + { + sc->ts_admins_enable = 1; + sc->ts_admins = gid; + } + } } - if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_LOGIN_RETRY)) + + /* printing security config */ + g_printf("security configuration:\r\n"); + g_printf("\tAllowRootLogin: %i\r\n", sc->allow_root); + g_printf("\tMaxLoginRetry: %i\r\n", sc->login_retry); + + if (sc->ts_users_enable) { - sc->login_retry = g_atoi((char*)list_get_item(param_v, i)); + g_printf("\tTSUsersGroup: %i\r\n", sc->ts_users); } - if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_USR_GROUP)) + else { - if (g_getgroup_info((char*)list_get_item(param_v, i), &gid) == 0) - { - sc->ts_users_enable = 1; - sc->ts_users = gid; - } + g_printf("\tNo TSUsersGroup defined\r\n"); } - if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_ADM_GROUP)) + + if (sc->ts_admins_enable) { - if (g_getgroup_info((char*)list_get_item(param_v, i), &gid) == 0) - { - sc->ts_admins_enable = 1; - sc->ts_admins = gid; - } + g_printf("\tTSAdminsGroup: %i\r\n", sc->ts_admins); + } + else + { + g_printf("\tNo TSAdminsGroup defined\r\n"); } - } - - /* printing security config */ - g_printf("security configuration:\r\n"); - g_printf("\tAllowRootLogin: %i\r\n",sc->allow_root); - g_printf("\tMaxLoginRetry: %i\r\n",sc->login_retry); - if (sc->ts_users_enable) - { - g_printf("\tTSUsersGroup: %i\r\n", sc->ts_users); - } - else - { - g_printf("\tNo TSUsersGroup defined\r\n"); - } - if (sc->ts_admins_enable) - { - g_printf("\tTSAdminsGroup: %i\r\n", sc->ts_admins); - } - else - { - g_printf("\tNo TSAdminsGroup defined\r\n"); - } - return 0; + return 0; } /******************************************************************************/ int DEFAULT_CC -config_read_sessions(int file, struct config_sessions* se, struct list* param_n, - struct list* param_v) +config_read_sessions(int file, struct config_sessions *se, struct list *param_n, + struct list *param_v) { - int i; - char* buf; + int i; + char *buf; - list_clear(param_v); - list_clear(param_n); + list_clear(param_v); + list_clear(param_n); - /* setting defaults */ - se->x11_display_offset=10; - se->max_sessions=0; - se->max_idle_time=0; - se->max_disc_time=0; - se->kill_disconnected=0; + /* setting defaults */ + se->x11_display_offset = 10; + se->max_sessions = 0; + se->max_idle_time = 0; + se->max_disc_time = 0; + se->kill_disconnected = 0; - file_read_section(file, SESMAN_CFG_SESSIONS, param_n, param_v); - for (i = 0; i < param_n->count; i++) - { - buf = (char*)list_get_item(param_n, i); - if (0 == g_strcasecmp(buf, SESMAN_CFG_X11DISPLAYOFFSET)) - { - se->x11_display_offset = g_atoi((char*)list_get_item(param_v, i)); - } - if (0 == g_strcasecmp(buf, SESMAN_CFG_SESS_MAX)) - { - se->max_sessions = g_atoi((char*)list_get_item(param_v, i)); - } - if (0 == g_strcasecmp(buf, SESMAN_CFG_SESS_KILL_DISC)) - { - se->kill_disconnected = text2bool((char*)list_get_item(param_v, i)); - } - if (0 == g_strcasecmp(buf, SESMAN_CFG_SESS_IDLE_LIMIT)) - { - se->max_idle_time=g_atoi((char*)list_get_item(param_v, i)); - } - if (0 == g_strcasecmp(buf, SESMAN_CFG_SESS_DISC_LIMIT)) + file_read_section(file, SESMAN_CFG_SESSIONS, param_n, param_v); + + for (i = 0; i < param_n->count; i++) { - se->max_disc_time=g_atoi((char*)list_get_item(param_v, i)); + buf = (char *)list_get_item(param_n, i); + + if (0 == g_strcasecmp(buf, SESMAN_CFG_X11DISPLAYOFFSET)) + { + se->x11_display_offset = g_atoi((char *)list_get_item(param_v, i)); + } + + if (0 == g_strcasecmp(buf, SESMAN_CFG_SESS_MAX)) + { + se->max_sessions = g_atoi((char *)list_get_item(param_v, i)); + } + + if (0 == g_strcasecmp(buf, SESMAN_CFG_SESS_KILL_DISC)) + { + se->kill_disconnected = text2bool((char *)list_get_item(param_v, i)); + } + + if (0 == g_strcasecmp(buf, SESMAN_CFG_SESS_IDLE_LIMIT)) + { + se->max_idle_time = g_atoi((char *)list_get_item(param_v, i)); + } + + if (0 == g_strcasecmp(buf, SESMAN_CFG_SESS_DISC_LIMIT)) + { + se->max_disc_time = g_atoi((char *)list_get_item(param_v, i)); + } } - } - /* printing security config */ - g_printf("session configuration:\r\n"); - g_printf("\tMaxSessions: %i\r\n", se->max_sessions); - g_printf("\tX11DisplayOffset: %i\r\n", se->x11_display_offset); - g_printf("\tKillDisconnected: %i\r\n", se->kill_disconnected); - g_printf("\tIdleTimeLimit: %i\r\n", se->max_idle_time); - g_printf("\tDisconnectedTimeLimit: %i\r\n", se->max_idle_time); + /* printing security config */ + g_printf("session configuration:\r\n"); + g_printf("\tMaxSessions: %i\r\n", se->max_sessions); + g_printf("\tX11DisplayOffset: %i\r\n", se->x11_display_offset); + g_printf("\tKillDisconnected: %i\r\n", se->kill_disconnected); + g_printf("\tIdleTimeLimit: %i\r\n", se->max_idle_time); + g_printf("\tDisconnectedTimeLimit: %i\r\n", se->max_idle_time); - return 0; + return 0; } /******************************************************************************/ int DEFAULT_CC -config_read_rdp_params(int file, struct config_sesman* cs, struct list* param_n, - struct list* param_v) +config_read_rdp_params(int file, struct config_sesman *cs, struct list *param_n, + struct list *param_v) { - int i; + int i; - list_clear(param_v); - list_clear(param_n); + list_clear(param_v); + list_clear(param_n); - cs->rdp_params=list_create(); + cs->rdp_params = list_create(); - file_read_section(file, SESMAN_CFG_RDP_PARAMS, param_n, param_v); - for (i = 0; i < param_n->count; i++) - { - list_add_item(cs->rdp_params, (long)g_strdup((char*)list_get_item(param_v, i))); - } + file_read_section(file, SESMAN_CFG_RDP_PARAMS, param_n, param_v); - /* printing security config */ - g_printf("X11rdp parameters:\r\n"); - for (i = 0; i < cs->rdp_params->count; i++) - { - g_printf("\tParameter %02d %s\r\n", i, (char*)list_get_item(cs->rdp_params, i)); - } + for (i = 0; i < param_n->count; i++) + { + list_add_item(cs->rdp_params, (long)g_strdup((char *)list_get_item(param_v, i))); + } - return 0; + /* printing security config */ + g_printf("X11rdp parameters:\r\n"); + + for (i = 0; i < cs->rdp_params->count; i++) + { + g_printf("\tParameter %02d %s\r\n", i, (char *)list_get_item(cs->rdp_params, i)); + } + + return 0; } /******************************************************************************/ int DEFAULT_CC -config_read_vnc_params(int file, struct config_sesman* cs, struct list* param_n, - struct list* param_v) +config_read_vnc_params(int file, struct config_sesman *cs, struct list *param_n, + struct list *param_v) { - int i; + int i; - list_clear(param_v); - list_clear(param_n); + list_clear(param_v); + list_clear(param_n); - cs->vnc_params=list_create(); + cs->vnc_params = list_create(); - file_read_section(file, SESMAN_CFG_VNC_PARAMS, param_n, param_v); - for (i = 0; i < param_n->count; i++) - { - list_add_item(cs->vnc_params, (long)g_strdup((char*)list_get_item(param_v, i))); - } + file_read_section(file, SESMAN_CFG_VNC_PARAMS, param_n, param_v); - /* printing security config */ - g_printf("Xvnc parameters:\r\n"); - for (i = 0; i < cs->vnc_params->count; i++) - { - g_printf("\tParameter %02d %s\r\n", i, (char*)list_get_item(cs->vnc_params, i)); - } + for (i = 0; i < param_n->count; i++) + { + list_add_item(cs->vnc_params, (long)g_strdup((char *)list_get_item(param_v, i))); + } - return 0; -} + /* printing security config */ + g_printf("Xvnc parameters:\r\n"); + for (i = 0; i < cs->vnc_params->count; i++) + { + g_printf("\tParameter %02d %s\r\n", i, (char *)list_get_item(cs->vnc_params, i)); + } + + return 0; +} diff --git a/sesman/config.h b/sesman/config.h index 73fab38f..72c6cac4 100644 --- a/sesman/config.h +++ b/sesman/config.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -296,4 +295,3 @@ config_read_vnc_params(int file, struct config_sesman* cs, struct list* param_n, struct list* param_v); #endif - diff --git a/sesman/env.c b/sesman/env.c index f7abe120..9f35f368 100644 --- a/sesman/env.c +++ b/sesman/env.c @@ -1,28 +1,27 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * * @file env.c * @brief User environment handling code * @author Jay Sorg - * + * */ #include "sesman.h" @@ -31,95 +30,105 @@ #include "grp.h" extern unsigned char g_fixedkey[8]; /* in sesman.c */ -extern struct config_sesman* g_cfg; /* in sesman.c */ +extern struct config_sesman *g_cfg; /* in sesman.c */ /******************************************************************************/ int DEFAULT_CC -env_check_password_file(char* filename, char* password) +env_check_password_file(char *filename, char *password) { - char encryptedPasswd[16]; - int fd; - - g_memset(encryptedPasswd, 0, 16); - g_strncpy(encryptedPasswd, password, 8); - rfbDesKey(g_fixedkey, 0); - rfbDes((unsigned char*)encryptedPasswd, (unsigned char*)encryptedPasswd); - fd = g_file_open(filename); - if (fd == -1) - { - log_message(LOG_LEVEL_WARNING, - "can't read vnc password file - %s", - filename); - return 1; - } - g_file_write(fd, encryptedPasswd, 8); - g_file_close(fd); - return 0; + char encryptedPasswd[16]; + int fd; + + g_memset(encryptedPasswd, 0, 16); + g_strncpy(encryptedPasswd, password, 8); + rfbDesKey(g_fixedkey, 0); + rfbDes((unsigned char *)encryptedPasswd, (unsigned char *)encryptedPasswd); + fd = g_file_open(filename); + + if (fd == -1) + { + log_message(LOG_LEVEL_WARNING, + "can't read vnc password file - %s", + filename); + return 1; + } + + g_file_write(fd, encryptedPasswd, 8); + g_file_close(fd); + return 0; } /******************************************************************************/ int DEFAULT_CC -env_set_user(char* username, char* passwd_file, int display) +env_set_user(char *username, char *passwd_file, int display) { - int error; - int pw_uid; - int pw_gid; - int uid; - char pw_shell[256]; - char pw_dir[256]; - char pw_gecos[256]; - char text[256]; - - error = g_getuser_info(username, &pw_gid, &pw_uid, pw_shell, pw_dir, - pw_gecos); - if (error == 0) - { - g_rm_temp_dir(); - error = g_setgid(pw_gid); - if (error == 0) - { - error = g_initgroups(username, pw_gid); - } - if (error == 0) - { - uid = pw_uid; - error = g_setuid(uid); - } - g_mk_temp_dir(0); + int error; + int pw_uid; + int pw_gid; + int uid; + char pw_shell[256]; + char pw_dir[256]; + char pw_gecos[256]; + char text[256]; + + error = g_getuser_info(username, &pw_gid, &pw_uid, pw_shell, pw_dir, + pw_gecos); + if (error == 0) { - g_clearenv(); - g_setenv("SHELL", pw_shell, 1); - g_setenv("PATH", "/bin:/usr/bin:/usr/X11R6/bin:/usr/local/bin", 1); - g_setenv("USER", username, 1); - g_sprintf(text, "%d", uid); - g_setenv("UID", text, 1); - g_setenv("HOME", pw_dir, 1); - g_set_current_dir(pw_dir); - g_sprintf(text, ":%d.0", display); - g_setenv("DISPLAY", text, 1); - if (passwd_file != 0) - { - if (0 == g_cfg->auth_file_path) + g_rm_temp_dir(); + error = g_setgid(pw_gid); + + if (error == 0) { - /* if no auth_file_path is set, then we go for - $HOME/.vnc/sesman_username_passwd */ - g_mkdir(".vnc"); - g_sprintf(passwd_file, "%s/.vnc/sesman_%s_passwd", pw_dir, username); + error = g_initgroups(username, pw_gid); } - else + + if (error == 0) { - /* we use auth_file_path as requested */ - g_sprintf(passwd_file, g_cfg->auth_file_path, username); + uid = pw_uid; + error = g_setuid(uid); } - LOG_DBG("pass file: %s", passwd_file); - } + + g_mk_temp_dir(0); + + if (error == 0) + { + g_clearenv(); + g_setenv("SHELL", pw_shell, 1); + g_setenv("PATH", "/bin:/usr/bin:/usr/X11R6/bin:/usr/local/bin", 1); + g_setenv("USER", username, 1); + g_sprintf(text, "%d", uid); + g_setenv("UID", text, 1); + g_setenv("HOME", pw_dir, 1); + g_set_current_dir(pw_dir); + g_sprintf(text, ":%d.0", display); + g_setenv("DISPLAY", text, 1); + + if (passwd_file != 0) + { + if (0 == g_cfg->auth_file_path) + { + /* if no auth_file_path is set, then we go for + $HOME/.vnc/sesman_username_passwd */ + g_mkdir(".vnc"); + g_sprintf(passwd_file, "%s/.vnc/sesman_%s_passwd", pw_dir, username); + } + else + { + /* we use auth_file_path as requested */ + g_sprintf(passwd_file, g_cfg->auth_file_path, username); + } + + LOG_DBG("pass file: %s", passwd_file); + } + } + } + else + { + log_message(LOG_LEVEL_ERROR, + "error getting user info for user %s", username); } - } - else - { - log_message(LOG_LEVEL_ERROR, - "error getting user info for user %s", username); - } - return error; + + return error; } diff --git a/sesman/env.h b/sesman/env.h index b14344af..c185ae30 100644 --- a/sesman/env.h +++ b/sesman/env.h @@ -1,28 +1,27 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * * @file env.h * @brief User environment handling code declarations * @author Jay Sorg - * + * */ #ifndef ENV_H @@ -42,7 +41,7 @@ env_check_password_file(char* filename, char* password); /** * * @brief Sets user environment ($PATH, $HOME, $UID, and others) - * @param username Username + * @param username Username * @param passwd_file VNC password file * @param display The session display * @return 0 on success, g_getuser_info() error codes on error @@ -52,4 +51,3 @@ int DEFAULT_CC env_set_user(char* username, char* passwd_file, int display); #endif - diff --git a/sesman/libscp/libscp.h b/sesman/libscp/libscp.h index e06803cf..ed73380f 100644 --- a/sesman/libscp/libscp.h +++ b/sesman/libscp/libscp.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * diff --git a/sesman/libscp/libscp_commands.h b/sesman/libscp/libscp_commands.h index 8745c6bf..8c8d5f08 100644 --- a/sesman/libscp/libscp_commands.h +++ b/sesman/libscp/libscp_commands.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * diff --git a/sesman/libscp/libscp_commands_mng.h b/sesman/libscp/libscp_commands_mng.h index 78dffcf4..e1d6ba7c 100644 --- a/sesman/libscp/libscp_commands_mng.h +++ b/sesman/libscp/libscp_commands_mng.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * diff --git a/sesman/libscp/libscp_connection.c b/sesman/libscp/libscp_connection.c index bf49fb84..6366d51a 100644 --- a/sesman/libscp/libscp_connection.c +++ b/sesman/libscp/libscp_connection.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -29,32 +28,32 @@ //extern struct log_config* s_log; -struct SCP_CONNECTION* +struct SCP_CONNECTION * scp_connection_create(int sck) { - struct SCP_CONNECTION* conn; + struct SCP_CONNECTION *conn; - conn = g_malloc(sizeof(struct SCP_CONNECTION), 0); + conn = g_malloc(sizeof(struct SCP_CONNECTION), 0); - if (0 == conn) - { - log_message(LOG_LEVEL_WARNING, "[connection:%d] connection create: malloc error", __LINE__); - return 0; - } + if (0 == conn) + { + log_message(LOG_LEVEL_WARNING, "[connection:%d] connection create: malloc error", __LINE__); + return 0; + } - conn->in_sck=sck; - make_stream(conn->in_s); - init_stream(conn->in_s, 8196); - make_stream(conn->out_s); - init_stream(conn->out_s, 8196); + conn->in_sck = sck; + make_stream(conn->in_s); + init_stream(conn->in_s, 8196); + make_stream(conn->out_s); + init_stream(conn->out_s, 8196); - return conn; + return conn; } void -scp_connection_destroy(struct SCP_CONNECTION* c) +scp_connection_destroy(struct SCP_CONNECTION *c) { - free_stream(c->in_s); - free_stream(c->out_s); - g_free(c); + free_stream(c->in_s); + free_stream(c->out_s); + g_free(c); } diff --git a/sesman/libscp/libscp_connection.h b/sesman/libscp/libscp_connection.h index ba94f429..e5bdbe27 100644 --- a/sesman/libscp/libscp_connection.h +++ b/sesman/libscp/libscp_connection.h @@ -1,28 +1,27 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * * @file libscp_connection.h * @brief SCP_CONNECTION handling code * @author Simone Fedele - * + * */ #ifndef LIBSCP_CONNECTION_H @@ -37,7 +36,7 @@ * * @return a struct SCP_CONNECTION* object on success, NULL otherwise * - */ + */ struct SCP_CONNECTION* scp_connection_create(int sck); @@ -45,10 +44,9 @@ scp_connection_create(int sck); * * @brief destroys a struct SCP_CONNECTION* object * @param c the object to be destroyed - * + * */ void scp_connection_destroy(struct SCP_CONNECTION* c); #endif - diff --git a/sesman/libscp/libscp_init.c b/sesman/libscp/libscp_init.c index 4c48fb1f..eae57c6e 100644 --- a/sesman/libscp/libscp_init.c +++ b/sesman/libscp/libscp_init.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -33,19 +32,18 @@ int DEFAULT_CC scp_init() { -/* - if (0 == log) - { - return 1; - } -*/ + /* + if (0 == log) + { + return 1; + } + */ - //s_log = log; + //s_log = log; - scp_lock_init(); + scp_lock_init(); - log_message(LOG_LEVEL_WARNING, "[init:%d] libscp initialized", __LINE__); + log_message(LOG_LEVEL_WARNING, "[init:%d] libscp initialized", __LINE__); - return 0; + return 0; } - diff --git a/sesman/libscp/libscp_init.h b/sesman/libscp/libscp_init.h index 92dbc659..20a75857 100644 --- a/sesman/libscp/libscp_init.h +++ b/sesman/libscp/libscp_init.h @@ -1,28 +1,27 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * * @file libscp_init.h * @brief libscp initialization code header * @author Simone Fedele - * + * */ #ifndef LIBSCP_INIT_H @@ -41,8 +40,7 @@ * It this memory needs to be g_free()d * */ -int DEFAULT_CC +int DEFAULT_CC scp_init(); #endif - diff --git a/sesman/libscp/libscp_lock.c b/sesman/libscp/libscp_lock.c index 9556b872..4db05422 100644 --- a/sesman/libscp/libscp_lock.c +++ b/sesman/libscp/libscp_lock.c @@ -1,25 +1,23 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 - - session manager - linux only - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * session manager + * linux only + */ #include "libscp_lock.h" @@ -37,110 +35,114 @@ int lock_fork_waiting_count; /* threads suspended until the fork finish void DEFAULT_CC scp_lock_init(void) { - /* initializing fork lock */ - pthread_mutexattr_init(&lock_fork_attr); - pthread_mutex_init(&lock_fork, &lock_fork_attr); - sem_init(&lock_fork_req, 0, 0); - sem_init(&lock_fork_wait, 0, 0); - - /* here we don't use locking because lock_init() should be called BEFORE */ - /* any thread is created */ - lock_fork_blockers_count=0; - lock_fork_waiting_count=0; - lock_fork_forkers_count=0; + /* initializing fork lock */ + pthread_mutexattr_init(&lock_fork_attr); + pthread_mutex_init(&lock_fork, &lock_fork_attr); + sem_init(&lock_fork_req, 0, 0); + sem_init(&lock_fork_wait, 0, 0); + + /* here we don't use locking because lock_init() should be called BEFORE */ + /* any thread is created */ + lock_fork_blockers_count = 0; + lock_fork_waiting_count = 0; + lock_fork_forkers_count = 0; } /******************************************************************************/ void DEFAULT_CC scp_lock_fork_request(void) { - /* lock mutex */ - pthread_mutex_lock(&lock_fork); - if (lock_fork_blockers_count == 0) - { - /* if noone is blocking fork(), then we're allowed to fork */ - sem_post(&lock_fork_req); - } - lock_fork_forkers_count++; - pthread_mutex_unlock(&lock_fork); - - /* we wait to be allowed to fork() */ - sem_wait(&lock_fork_req); + /* lock mutex */ + pthread_mutex_lock(&lock_fork); + + if (lock_fork_blockers_count == 0) + { + /* if noone is blocking fork(), then we're allowed to fork */ + sem_post(&lock_fork_req); + } + + lock_fork_forkers_count++; + pthread_mutex_unlock(&lock_fork); + + /* we wait to be allowed to fork() */ + sem_wait(&lock_fork_req); } /******************************************************************************/ void DEFAULT_CC scp_lock_fork_release(void) { - pthread_mutex_lock(&lock_fork); - lock_fork_forkers_count--; - - /* if there's someone else that want to fork, we let him fork() */ - if (lock_fork_forkers_count > 0) - { - sem_post(&lock_fork_req); - } - - for (;lock_fork_waiting_count > 0; lock_fork_waiting_count--) - { - /* waking up the other processes */ - sem_post(&lock_fork_wait); - } - pthread_mutex_unlock(&lock_fork); + pthread_mutex_lock(&lock_fork); + lock_fork_forkers_count--; + + /* if there's someone else that want to fork, we let him fork() */ + if (lock_fork_forkers_count > 0) + { + sem_post(&lock_fork_req); + } + + for (; lock_fork_waiting_count > 0; lock_fork_waiting_count--) + { + /* waking up the other processes */ + sem_post(&lock_fork_wait); + } + + pthread_mutex_unlock(&lock_fork); } /******************************************************************************/ void DEFAULT_CC scp_lock_fork_critical_section_end(int blocking) { - //LOG_DBG("lock_fork_critical_secection_end()",0); - /* lock mutex */ - pthread_mutex_lock(&lock_fork); - - if (blocking == LIBSCP_LOCK_FORK_BLOCKER) - { - lock_fork_blockers_count--; - } - - /* if there's someone who wants to fork and we're the last blocking */ - /* then we let him go */ - if ((lock_fork_blockers_count == 0) && (lock_fork_forkers_count>0)) - { - sem_post(&lock_fork_req); - } - pthread_mutex_unlock(&lock_fork); + //LOG_DBG("lock_fork_critical_secection_end()",0); + /* lock mutex */ + pthread_mutex_lock(&lock_fork); + + if (blocking == LIBSCP_LOCK_FORK_BLOCKER) + { + lock_fork_blockers_count--; + } + + /* if there's someone who wants to fork and we're the last blocking */ + /* then we let him go */ + if ((lock_fork_blockers_count == 0) && (lock_fork_forkers_count > 0)) + { + sem_post(&lock_fork_req); + } + + pthread_mutex_unlock(&lock_fork); } /******************************************************************************/ int DEFAULT_CC scp_lock_fork_critical_section_start(void) { - //LOG_DBG("lock_fork_critical_secection_start()",0); - do - { - pthread_mutex_lock(&lock_fork); - - /* someone requested to fork */ - if (lock_fork_forkers_count > 0) + //LOG_DBG("lock_fork_critical_secection_start()",0); + do { - lock_fork_waiting_count++; - pthread_mutex_unlock(&lock_fork); - - /* we wait until the fork finishes */ - sem_wait(&lock_fork_wait); - + pthread_mutex_lock(&lock_fork); + + /* someone requested to fork */ + if (lock_fork_forkers_count > 0) + { + lock_fork_waiting_count++; + pthread_mutex_unlock(&lock_fork); + + /* we wait until the fork finishes */ + sem_wait(&lock_fork_wait); + + } + else + { + /* no fork, so we can go on... */ + lock_fork_blockers_count++; + pthread_mutex_unlock(&lock_fork); + + return LIBSCP_LOCK_FORK_BLOCKER; + } } - else - { - /* no fork, so we can go on... */ - lock_fork_blockers_count++; - pthread_mutex_unlock(&lock_fork); - - return LIBSCP_LOCK_FORK_BLOCKER; - } - } while (1); + while (1); - /* we'll never get here */ - return LIBSCP_LOCK_FORK_WAITING; + /* we'll never get here */ + return LIBSCP_LOCK_FORK_WAITING; } - diff --git a/sesman/libscp/libscp_lock.h b/sesman/libscp/libscp_lock.h index 5c96cc5b..b4e93c52 100644 --- a/sesman/libscp/libscp_lock.h +++ b/sesman/libscp/libscp_lock.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #ifndef LIBSCP_LOCK_H #define LIBSCP_LOCK_H @@ -72,4 +71,3 @@ void DEFAULT_CC scp_lock_fork_critical_section_end(int blocking); #endif - diff --git a/sesman/libscp/libscp_session.c b/sesman/libscp/libscp_session.c index 3ed5070a..4c389655 100644 --- a/sesman/libscp/libscp_session.c +++ b/sesman/libscp/libscp_session.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -34,379 +33,425 @@ //extern struct log_config* s_log; /*******************************************************************/ -struct SCP_SESSION* +struct SCP_SESSION * scp_session_create() { - struct SCP_SESSION* s; + struct SCP_SESSION *s; - s = (struct SCP_SESSION*)g_malloc(sizeof(struct SCP_SESSION), 1); - if (0 == s) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] session create: malloc error", __LINE__); - return 0; - } - return s; + s = (struct SCP_SESSION *)g_malloc(sizeof(struct SCP_SESSION), 1); + + if (0 == s) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] session create: malloc error", __LINE__); + return 0; + } + + return s; } /*******************************************************************/ int -scp_session_set_type(struct SCP_SESSION* s, tui8 type) +scp_session_set_type(struct SCP_SESSION *s, tui8 type) { - switch (type) - { - case SCP_SESSION_TYPE_XVNC: - s->type = SCP_SESSION_TYPE_XVNC; - break; - case SCP_SESSION_TYPE_XRDP: - s->type = SCP_SESSION_TYPE_XRDP; - break; - case SCP_GW_AUTHENTICATION: - s->type = SCP_GW_AUTHENTICATION; - break; - 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_message(LOG_LEVEL_ERROR, "[session:%d] set_type: internal error", __LINE__); - return 1; - } - break; - default: - log_message(LOG_LEVEL_WARNING, "[session:%d] set_type: unknown type", __LINE__); - return 1; - } - return 0; + switch (type) + { + case SCP_SESSION_TYPE_XVNC: + s->type = SCP_SESSION_TYPE_XVNC; + break; + case SCP_SESSION_TYPE_XRDP: + s->type = SCP_SESSION_TYPE_XRDP; + break; + case SCP_GW_AUTHENTICATION: + s->type = SCP_GW_AUTHENTICATION; + break; + 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_message(LOG_LEVEL_ERROR, "[session:%d] set_type: internal error", __LINE__); + return 1; + } + + break; + default: + log_message(LOG_LEVEL_WARNING, "[session:%d] set_type: unknown type", __LINE__); + return 1; + } + + return 0; } /*******************************************************************/ int -scp_session_set_version(struct SCP_SESSION* s, tui32 version) +scp_session_set_version(struct SCP_SESSION *s, tui32 version) { - switch (version) - { - case 0: - s->version = 0; - break; - case 1: - s->version = 1; - break; - default: - log_message(LOG_LEVEL_WARNING, "[session:%d] set_version: unknown version", __LINE__); - return 1; - } - return 0; + switch (version) + { + case 0: + s->version = 0; + break; + case 1: + s->version = 1; + break; + default: + log_message(LOG_LEVEL_WARNING, "[session:%d] set_version: unknown version", __LINE__); + return 1; + } + + return 0; } /*******************************************************************/ int -scp_session_set_height(struct SCP_SESSION* s, tui16 h) +scp_session_set_height(struct SCP_SESSION *s, tui16 h) { - s->height = h; - return 0; + s->height = h; + return 0; } /*******************************************************************/ int -scp_session_set_width(struct SCP_SESSION* s, tui16 w) +scp_session_set_width(struct SCP_SESSION *s, tui16 w) { - s->width = w; - return 0; + s->width = w; + return 0; } /*******************************************************************/ int -scp_session_set_bpp(struct SCP_SESSION* s, tui8 bpp) +scp_session_set_bpp(struct SCP_SESSION *s, tui8 bpp) { - switch (bpp) - { - case 8: - case 15: - case 16: - case 24: - s->bpp = bpp; - default: - return 1; - } - return 0; + switch (bpp) + { + case 8: + case 15: + case 16: + case 24: + s->bpp = bpp; + default: + return 1; + } + + return 0; } /*******************************************************************/ int -scp_session_set_rsr(struct SCP_SESSION* s, tui8 rsr) +scp_session_set_rsr(struct SCP_SESSION *s, tui8 rsr) { - if (s->rsr) - { - s->rsr = 1; - } - else - { - s->rsr = 0; - } - return 0; + if (s->rsr) + { + s->rsr = 1; + } + else + { + s->rsr = 0; + } + + return 0; } /*******************************************************************/ int -scp_session_set_locale(struct SCP_SESSION* s, char* str) +scp_session_set_locale(struct SCP_SESSION *s, char *str) { - if (0 == str) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_locale: null locale", __LINE__); - s->locale[0]='\0'; - return 1; - } - g_strncpy(s->locale, str, 17); - s->locale[17]='\0'; - return 0; + if (0 == str) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_locale: null locale", __LINE__); + s->locale[0] = '\0'; + return 1; + } + + g_strncpy(s->locale, str, 17); + s->locale[17] = '\0'; + return 0; } /*******************************************************************/ int -scp_session_set_username(struct SCP_SESSION* s, char* str) +scp_session_set_username(struct SCP_SESSION *s, char *str) { - if (0 == str) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_username: null username", __LINE__); - return 1; - } - if (0 != s->username) - { - g_free(s->username); - } - s->username = g_strdup(str); - if (0 == s->username) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_username: strdup error", __LINE__); - return 1; - } - return 0; + if (0 == str) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_username: null username", __LINE__); + return 1; + } + + if (0 != s->username) + { + g_free(s->username); + } + + s->username = g_strdup(str); + + if (0 == s->username) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_username: strdup error", __LINE__); + return 1; + } + + return 0; } /*******************************************************************/ int -scp_session_set_password(struct SCP_SESSION* s, char* str) +scp_session_set_password(struct SCP_SESSION *s, char *str) { - if (0 == str) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_password: null password", __LINE__); - return 1; - } - if (0 != s->password) - { - g_free(s->password); - } - s->password = g_strdup(str); - if (0 == s->password) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_password: strdup error", __LINE__); - return 1; - } - return 0; + if (0 == str) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_password: null password", __LINE__); + return 1; + } + + if (0 != s->password) + { + g_free(s->password); + } + + s->password = g_strdup(str); + + if (0 == s->password) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_password: strdup error", __LINE__); + return 1; + } + + return 0; } /*******************************************************************/ int -scp_session_set_domain(struct SCP_SESSION* s, char* str) +scp_session_set_domain(struct SCP_SESSION *s, char *str) { - if (0 == str) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_domain: null domain", __LINE__); - return 1; - } - if (0 != s->domain) - { - g_free(s->domain); - } - s->domain = g_strdup(str); - if (0 == s->domain) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_domain: strdup error", __LINE__); - return 1; - } - return 0; + if (0 == str) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_domain: null domain", __LINE__); + return 1; + } + + if (0 != s->domain) + { + g_free(s->domain); + } + + s->domain = g_strdup(str); + + if (0 == s->domain) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_domain: strdup error", __LINE__); + return 1; + } + + return 0; } /*******************************************************************/ int -scp_session_set_program(struct SCP_SESSION* s, char* str) +scp_session_set_program(struct SCP_SESSION *s, char *str) { - if (0 == str) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_program: null program", __LINE__); - return 1; - } - if (0 != s->program) - { - g_free(s->program); - } - s->program = g_strdup(str); - if (0 == s->program) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_program: strdup error", __LINE__); - return 1; - } - return 0; + if (0 == str) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_program: null program", __LINE__); + return 1; + } + + if (0 != s->program) + { + g_free(s->program); + } + + s->program = g_strdup(str); + + if (0 == s->program) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_program: strdup error", __LINE__); + return 1; + } + + return 0; } /*******************************************************************/ int -scp_session_set_directory(struct SCP_SESSION* s, char* str) +scp_session_set_directory(struct SCP_SESSION *s, char *str) { - if (0 == str) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_directory: null directory", __LINE__); - return 1; - } - if (0 != s->directory) - { - g_free(s->directory); - } - s->directory = g_strdup(str); - if (0 == s->directory) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_directory: strdup error", __LINE__); - return 1; - } - return 0; + if (0 == str) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_directory: null directory", __LINE__); + return 1; + } + + if (0 != s->directory) + { + g_free(s->directory); + } + + s->directory = g_strdup(str); + + if (0 == s->directory) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_directory: strdup error", __LINE__); + return 1; + } + + return 0; } /*******************************************************************/ int -scp_session_set_client_ip(struct SCP_SESSION* s, char* str) +scp_session_set_client_ip(struct SCP_SESSION *s, char *str) { - if (0 == str) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_client_ip: null ip", __LINE__); - return 1; - } - if (0 != s->client_ip) - { - g_free(s->client_ip); - } - s->client_ip = g_strdup(str); - if (0 == s->client_ip) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_client_ip: strdup error", __LINE__); - return 1; - } - return 0; + if (0 == str) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_client_ip: null ip", __LINE__); + return 1; + } + + if (0 != s->client_ip) + { + g_free(s->client_ip); + } + + s->client_ip = g_strdup(str); + + if (0 == s->client_ip) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_client_ip: strdup error", __LINE__); + return 1; + } + + return 0; } /*******************************************************************/ int -scp_session_set_hostname(struct SCP_SESSION* s, char* str) +scp_session_set_hostname(struct SCP_SESSION *s, char *str) { - if (0 == str) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_hostname: null hostname", __LINE__); - return 1; - } - if (0 != s->hostname) - { - g_free(s->hostname); - } - s->hostname = g_strdup(str); - if (0 == s->hostname) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_hostname: strdup error", __LINE__); - return 1; - } - return 0; + if (0 == str) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_hostname: null hostname", __LINE__); + return 1; + } + + if (0 != s->hostname) + { + g_free(s->hostname); + } + + s->hostname = g_strdup(str); + + if (0 == s->hostname) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_hostname: strdup error", __LINE__); + return 1; + } + + return 0; } /*******************************************************************/ int -scp_session_set_errstr(struct SCP_SESSION* s, char* str) +scp_session_set_errstr(struct SCP_SESSION *s, char *str) { - if (0 == str) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_errstr: null string", __LINE__); - return 1; - } - if (0 != s->errstr) - { - g_free(s->errstr); - } - s->errstr = g_strdup(str); - if (0 == s->errstr) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_errstr: strdup error", __LINE__); - return 1; - } - return 0; + if (0 == str) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_errstr: null string", __LINE__); + return 1; + } + + if (0 != s->errstr) + { + g_free(s->errstr); + } + + s->errstr = g_strdup(str); + + if (0 == s->errstr) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_errstr: strdup error", __LINE__); + return 1; + } + + return 0; } /*******************************************************************/ int -scp_session_set_display(struct SCP_SESSION* s, SCP_DISPLAY display) +scp_session_set_display(struct SCP_SESSION *s, SCP_DISPLAY display) { - s->display = display; - return 0; + s->display = display; + return 0; } /*******************************************************************/ int -scp_session_set_addr(struct SCP_SESSION* s, int type, void* addr) +scp_session_set_addr(struct SCP_SESSION *s, int type, void *addr) { - struct in_addr ip4; + struct in_addr ip4; #ifdef IN6ADDR_ANY_INIT - struct in6_addr ip6; + struct in6_addr ip6; #endif - int ret; - - switch (type) - { - case SCP_ADDRESS_TYPE_IPV4: - /* convert from char to 32bit*/ - ret = inet_pton(AF_INET, addr, &ip4); - if (ret == 0) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_addr: invalid address", __LINE__); - inet_pton(AF_INET, "127.0.0.1", &ip4); - g_memcpy(&(s->ipv4addr), &(ip4.s_addr), 4); - return 1; - } - g_memcpy(&(s->ipv4addr), &(ip4.s_addr), 4); - break; - case SCP_ADDRESS_TYPE_IPV4_BIN: - g_memcpy(&(s->ipv4addr), addr, 4); - break; + int ret; + + switch (type) + { + case SCP_ADDRESS_TYPE_IPV4: + /* convert from char to 32bit*/ + ret = inet_pton(AF_INET, addr, &ip4); + + if (ret == 0) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_addr: invalid address", __LINE__); + inet_pton(AF_INET, "127.0.0.1", &ip4); + g_memcpy(&(s->ipv4addr), &(ip4.s_addr), 4); + return 1; + } + + g_memcpy(&(s->ipv4addr), &(ip4.s_addr), 4); + break; + case SCP_ADDRESS_TYPE_IPV4_BIN: + g_memcpy(&(s->ipv4addr), addr, 4); + break; #ifdef IN6ADDR_ANY_INIT - case SCP_ADDRESS_TYPE_IPV6: - /* convert from char to 128bit*/ - ret = inet_pton(AF_INET6, addr, &ip6); - if (ret == 0) - { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_addr: invalid address", __LINE__); - inet_pton(AF_INET, "::1", &ip6); - g_memcpy(s->ipv6addr, &(ip6.s6_addr), 16); - return 1; - } - g_memcpy(s->ipv6addr, &(ip6.s6_addr), 16); - break; - case SCP_ADDRESS_TYPE_IPV6_BIN: - g_memcpy(s->ipv6addr, addr, 16); - break; + case SCP_ADDRESS_TYPE_IPV6: + /* convert from char to 128bit*/ + ret = inet_pton(AF_INET6, addr, &ip6); + + if (ret == 0) + { + log_message(LOG_LEVEL_WARNING, "[session:%d] set_addr: invalid address", __LINE__); + inet_pton(AF_INET, "::1", &ip6); + g_memcpy(s->ipv6addr, &(ip6.s6_addr), 16); + return 1; + } + + g_memcpy(s->ipv6addr, &(ip6.s6_addr), 16); + break; + case SCP_ADDRESS_TYPE_IPV6_BIN: + g_memcpy(s->ipv6addr, addr, 16); + break; #endif - default: - return 1; - } - return 0; + default: + return 1; + } + + return 0; } /*******************************************************************/ void -scp_session_destroy(struct SCP_SESSION* s) +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); + 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); } diff --git a/sesman/libscp/libscp_session.h b/sesman/libscp/libscp_session.h index f5fe413e..b545af9e 100644 --- a/sesman/libscp/libscp_session.h +++ b/sesman/libscp/libscp_session.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * diff --git a/sesman/libscp/libscp_tcp.c b/sesman/libscp/libscp_tcp.c index 459992fe..29870563 100644 --- a/sesman/libscp/libscp_tcp.c +++ b/sesman/libscp/libscp_tcp.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -33,102 +32,103 @@ #include <stdlib.h> #include <string.h> -extern struct log_config* s_log; +extern struct log_config *s_log; /*****************************************************************************/ int DEFAULT_CC -scp_tcp_force_recv(int sck, char* data, int len) +scp_tcp_force_recv(int sck, char *data, int len) { - int rcvd; - int block; + int rcvd; + int block; - LOG_DBG("scp_tcp_force_recv()"); - block = scp_lock_fork_critical_section_start(); + LOG_DBG("scp_tcp_force_recv()"); + block = scp_lock_fork_critical_section_start(); - while (len > 0) - { - rcvd = g_tcp_recv(sck, data, len, 0); - if (rcvd == -1) + while (len > 0) { - if (g_tcp_last_error_would_block(sck)) - { - g_sleep(1); - } - else - { - scp_lock_fork_critical_section_end(block); - return 1; - } + rcvd = g_tcp_recv(sck, data, len, 0); + + if (rcvd == -1) + { + if (g_tcp_last_error_would_block(sck)) + { + g_sleep(1); + } + else + { + scp_lock_fork_critical_section_end(block); + return 1; + } + } + else if (rcvd == 0) + { + scp_lock_fork_critical_section_end(block); + return 1; + } + else + { + data += rcvd; + len -= rcvd; + } } - else if (rcvd == 0) - { - scp_lock_fork_critical_section_end(block); - return 1; - } - else - { - data += rcvd; - len -= rcvd; - } - } - scp_lock_fork_critical_section_end(block); + scp_lock_fork_critical_section_end(block); - return 0; + return 0; } /*****************************************************************************/ int DEFAULT_CC -scp_tcp_force_send(int sck, char* data, int len) +scp_tcp_force_send(int sck, char *data, int len) { - int sent; - int block; + int sent; + int block; - LOG_DBG("scp_tcp_force_send()"); - block = scp_lock_fork_critical_section_start(); + LOG_DBG("scp_tcp_force_send()"); + block = scp_lock_fork_critical_section_start(); - while (len > 0) - { - sent = g_tcp_send(sck, data, len, 0); - if (sent == -1) + while (len > 0) { - if (g_tcp_last_error_would_block(sck)) - { - g_sleep(1); - } - else - { - scp_lock_fork_critical_section_end(block); - return 1; - } + sent = g_tcp_send(sck, data, len, 0); + + if (sent == -1) + { + if (g_tcp_last_error_would_block(sck)) + { + g_sleep(1); + } + else + { + scp_lock_fork_critical_section_end(block); + return 1; + } + } + else if (sent == 0) + { + scp_lock_fork_critical_section_end(block); + return 1; + } + else + { + data += sent; + len -= sent; + } } - else if (sent == 0) - { - scp_lock_fork_critical_section_end(block); - return 1; - } - else - { - data += sent; - len -= sent; - } - } - scp_lock_fork_critical_section_end(block); + scp_lock_fork_critical_section_end(block); - return 0; + return 0; } /*****************************************************************************/ int DEFAULT_CC -scp_tcp_bind(int sck, char* addr, char* port) +scp_tcp_bind(int sck, char *addr, char *port) { - struct sockaddr_in s; + struct sockaddr_in s; - memset(&s, 0, sizeof(struct sockaddr_in)); - s.sin_family = AF_INET; - s.sin_port = htons(atoi(port)); - s.sin_addr.s_addr = inet_addr(addr); - return bind(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_in)); + memset(&s, 0, sizeof(struct sockaddr_in)); + s.sin_family = AF_INET; + s.sin_port = htons(atoi(port)); + s.sin_addr.s_addr = inet_addr(addr); + return bind(sck, (struct sockaddr *)&s, sizeof(struct sockaddr_in)); } - diff --git a/sesman/libscp/libscp_tcp.h b/sesman/libscp/libscp_tcp.h index 985984dc..1db70797 100644 --- a/sesman/libscp/libscp_tcp.h +++ b/sesman/libscp/libscp_tcp.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * diff --git a/sesman/libscp/libscp_types.h b/sesman/libscp/libscp_types.h index e6521741..2140eced 100644 --- a/sesman/libscp/libscp_types.h +++ b/sesman/libscp/libscp_types.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -43,7 +42,7 @@ #define SCP_SESSION_TYPE_XRDP 0x01 #define SCP_SESSION_TYPE_MANAGE 0x02 /* SCP_GW_AUTHENTICATION can be used when XRDP + sesman act as a gateway - * XRDP sends this command to let sesman verify if the user is allowed + * XRDP sends this command to let sesman verify if the user is allowed * to use the gateway */ #define SCP_GW_AUTHENTICATION 0x04 diff --git a/sesman/libscp/libscp_types_mng.h b/sesman/libscp/libscp_types_mng.h index e34dd413..e0edad55 100644 --- a/sesman/libscp/libscp_types_mng.h +++ b/sesman/libscp/libscp_types_mng.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * diff --git a/sesman/libscp/libscp_v0.c b/sesman/libscp/libscp_v0.c index f8b5a9d6..afa09bd8 100644 --- a/sesman/libscp/libscp_v0.c +++ b/sesman/libscp/libscp_v0.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -29,361 +28,386 @@ #include "os_calls.h" -extern struct log_config* s_log; +extern struct log_config *s_log; /* client API */ /******************************************************************************/ enum SCP_CLIENT_STATES_E -scp_v0c_connect(struct SCP_CONNECTION* c, struct SCP_SESSION* s) +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 - { - 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; -} + tui32 version; + tui32 size; + tui16 sz; + + init_stream(c->in_s, c->in_s->size); + init_stream(c->out_s, c->in_s->size); -/* server API */ -/******************************************************************************/ -enum SCP_SERVER_STATES_E -scp_v0s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk) -{ - tui32 version = 0; - tui32 size; - struct SCP_SESSION* session = 0; - tui16 sz; - tui32 code = 0; - char buf[257]; - - if (!skipVchk) - { LOG_DBG("[v0:%d] starting connection", __LINE__); - if (0 == scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) + 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) { - c->in_s->end = c->in_s->data + 8; - in_uint32_be(c->in_s, version); - if (version != 0) - { - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: version error", __LINE__); - return SCP_SERVER_STATE_VERSION_ERR; - } + out_uint16_be(c->out_s, 0); + } + else if (s->type == SCP_SESSION_TYPE_XRDP) + { + out_uint16_be(c->out_s, 10); } else { - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); - return SCP_SERVER_STATE_NETWORK_ERR; + log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); + return SCP_CLIENT_STATE_INTERNAL_ERR; } - } - in_uint32_be(c->in_s, size); + 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); - init_stream(c->in_s, 8196); - 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_SERVER_STATE_NETWORK_ERR; - } - c->in_s->end = c->in_s->data + (size - 8); + s_mark_end(c->out_s); + s_pop_layer(c->out_s, channel_hdr); - in_uint16_be(c->in_s, code); + /* version */ + out_uint32_be(c->out_s, 0); + /* size */ + out_uint32_be(c->out_s, c->out_s->end - c->out_s->data); - if (code == 0 || code == 10) - { - session = scp_session_create(); - if (0 == session) + 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_INTERNAL_ERR; + log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); + return SCP_CLIENT_STATE_NETWORK_ERR; } - scp_session_set_version(session, version); - if (code == 0) + if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) { - scp_session_set_type(session, SCP_SESSION_TYPE_XVNC); + log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); + return SCP_CLIENT_STATE_NETWORK_ERR; } - else + + in_uint32_be(c->in_s, version); + + if (0 != version) { - scp_session_set_type(session, SCP_SESSION_TYPE_XRDP); + log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: version error", __LINE__); + return SCP_CLIENT_STATE_VERSION_ERR; } - /* reading username */ - in_uint16_be(c->in_s, sz); - buf[sz]='\0'; - in_uint8a(c->in_s, buf, sz); - if (0 != scp_session_set_username(session, buf)) + in_uint32_be(c->in_s, size); + + if (size < 14) { - scp_session_destroy(session); - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting username", __LINE__); - return SCP_SERVER_STATE_INTERNAL_ERR; + log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: packet size error", __LINE__); + return SCP_CLIENT_STATE_SIZE_ERR; } - /* reading password */ - in_uint16_be(c->in_s, sz); - buf[sz]='\0'; - in_uint8a(c->in_s, buf, sz); - if (0 != scp_session_set_password(session, buf)) + /* 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)) { - scp_session_destroy(session); - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting password", __LINE__); - return SCP_SERVER_STATE_INTERNAL_ERR; + log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); + return SCP_CLIENT_STATE_NETWORK_ERR; } - /* width */ + /* check code */ in_uint16_be(c->in_s, sz); - scp_session_set_width(session, sz); - /* height */ + + 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); - scp_session_set_height(session, sz); - /* bpp */ + + 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); - scp_session_set_bpp(session, (tui8)sz); - if (s_check_rem(c->in_s, 2)) + s->display = sz; + + LOG_DBG("[v0:%d] connection terminated", __LINE__); + return SCP_CLIENT_STATE_END; +} + +/* server API */ +/******************************************************************************/ +enum SCP_SERVER_STATES_E +scp_v0s_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s, int skipVchk) +{ + tui32 version = 0; + tui32 size; + struct SCP_SESSION *session = 0; + tui16 sz; + tui32 code = 0; + char buf[257]; + + if (!skipVchk) { - /* reading domain */ - in_uint16_be(c->in_s, sz); - if (sz > 0) - { - in_uint8a(c->in_s, buf, sz); - buf[sz] = '\0'; - scp_session_set_domain(session, buf); - } + LOG_DBG("[v0:%d] starting connection", __LINE__); + + if (0 == scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) + { + c->in_s->end = c->in_s->data + 8; + in_uint32_be(c->in_s, version); + + if (version != 0) + { + log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: version error", __LINE__); + return SCP_SERVER_STATE_VERSION_ERR; + } + } + else + { + log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); + return SCP_SERVER_STATE_NETWORK_ERR; + } } - if (s_check_rem(c->in_s, 2)) + + in_uint32_be(c->in_s, size); + + init_stream(c->in_s, 8196); + + if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8)) { - /* reading program */ - in_uint16_be(c->in_s, sz); - if (sz > 0) - { - in_uint8a(c->in_s, buf, sz); - buf[sz] = '\0'; - scp_session_set_program(session, buf); - } + log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); + return SCP_SERVER_STATE_NETWORK_ERR; } - if (s_check_rem(c->in_s, 2)) + + c->in_s->end = c->in_s->data + (size - 8); + + in_uint16_be(c->in_s, code); + + if (code == 0 || code == 10) { - /* reading directory */ - in_uint16_be(c->in_s, sz); - if (sz > 0) - { + session = scp_session_create(); + + if (0 == session) + { + log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); + return SCP_SERVER_STATE_INTERNAL_ERR; + } + + scp_session_set_version(session, version); + + if (code == 0) + { + scp_session_set_type(session, SCP_SESSION_TYPE_XVNC); + } + else + { + scp_session_set_type(session, SCP_SESSION_TYPE_XRDP); + } + + /* reading username */ + in_uint16_be(c->in_s, sz); + buf[sz] = '\0'; in_uint8a(c->in_s, buf, sz); + + if (0 != scp_session_set_username(session, buf)) + { + scp_session_destroy(session); + log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting username", __LINE__); + return SCP_SERVER_STATE_INTERNAL_ERR; + } + + /* reading password */ + in_uint16_be(c->in_s, sz); buf[sz] = '\0'; - scp_session_set_directory(session, buf); - } + in_uint8a(c->in_s, buf, sz); + + if (0 != scp_session_set_password(session, buf)) + { + scp_session_destroy(session); + log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting password", __LINE__); + return SCP_SERVER_STATE_INTERNAL_ERR; + } + + /* width */ + in_uint16_be(c->in_s, sz); + scp_session_set_width(session, sz); + /* height */ + in_uint16_be(c->in_s, sz); + scp_session_set_height(session, sz); + /* bpp */ + in_uint16_be(c->in_s, sz); + scp_session_set_bpp(session, (tui8)sz); + + if (s_check_rem(c->in_s, 2)) + { + /* reading domain */ + in_uint16_be(c->in_s, sz); + + if (sz > 0) + { + in_uint8a(c->in_s, buf, sz); + buf[sz] = '\0'; + scp_session_set_domain(session, buf); + } + } + + if (s_check_rem(c->in_s, 2)) + { + /* reading program */ + in_uint16_be(c->in_s, sz); + + if (sz > 0) + { + in_uint8a(c->in_s, buf, sz); + buf[sz] = '\0'; + scp_session_set_program(session, buf); + } + } + + if (s_check_rem(c->in_s, 2)) + { + /* reading directory */ + in_uint16_be(c->in_s, sz); + + if (sz > 0) + { + in_uint8a(c->in_s, buf, sz); + buf[sz] = '\0'; + scp_session_set_directory(session, buf); + } + } + + if (s_check_rem(c->in_s, 2)) + { + /* reading client IP address */ + in_uint16_be(c->in_s, sz); + + if (sz > 0) + { + in_uint8a(c->in_s, buf, sz); + buf[sz] = '\0'; + scp_session_set_client_ip(session, buf); + } + } } - if (s_check_rem(c->in_s, 2)) + else if (code == SCP_GW_AUTHENTICATION) { - /* reading client IP address */ - in_uint16_be(c->in_s, sz); - if (sz > 0) - { + /* g_writeln("Command is SCP_GW_AUTHENTICATION"); */ + session = scp_session_create(); + + if (0 == session) + { + /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);*/ + return SCP_SERVER_STATE_INTERNAL_ERR; + } + + scp_session_set_version(session, version); + scp_session_set_type(session, SCP_GW_AUTHENTICATION); + /* reading username */ + in_uint16_be(c->in_s, sz); + buf[sz] = '\0'; in_uint8a(c->in_s, buf, sz); + + /* g_writeln("Received user name: %s",buf); */ + if (0 != scp_session_set_username(session, buf)) + { + scp_session_destroy(session); + /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting username", __LINE__);*/ + return SCP_SERVER_STATE_INTERNAL_ERR; + } + + /* reading password */ + in_uint16_be(c->in_s, sz); buf[sz] = '\0'; - scp_session_set_client_ip(session, buf); - } - } - } - else if (code == SCP_GW_AUTHENTICATION) - { - /* g_writeln("Command is SCP_GW_AUTHENTICATION"); */ - session = scp_session_create(); - if (0 == session) - { - /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);*/ - return SCP_SERVER_STATE_INTERNAL_ERR; - } + in_uint8a(c->in_s, buf, sz); - scp_session_set_version(session, version); - scp_session_set_type(session, SCP_GW_AUTHENTICATION); - /* reading username */ - in_uint16_be(c->in_s, sz); - buf[sz]='\0'; - in_uint8a(c->in_s, buf, sz); - /* g_writeln("Received user name: %s",buf); */ - if (0 != scp_session_set_username(session, buf)) - { - scp_session_destroy(session); - /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting username", __LINE__);*/ - return SCP_SERVER_STATE_INTERNAL_ERR; + /* g_writeln("Received password: %s",buf); */ + if (0 != scp_session_set_password(session, buf)) + { + scp_session_destroy(session); + /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting password", __LINE__); */ + return SCP_SERVER_STATE_INTERNAL_ERR; + } } - - /* reading password */ - in_uint16_be(c->in_s, sz); - buf[sz] = '\0'; - in_uint8a(c->in_s, buf, sz); - /* g_writeln("Received password: %s",buf); */ - if (0 != scp_session_set_password(session, buf)) + else { - scp_session_destroy(session); - /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting password", __LINE__); */ - return SCP_SERVER_STATE_INTERNAL_ERR; + log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: sequence error", __LINE__); + return SCP_SERVER_STATE_SEQUENCE_ERR; } - } - else - { - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: sequence error", __LINE__); - return SCP_SERVER_STATE_SEQUENCE_ERR; - } - - (*s)=session; - return SCP_SERVER_STATE_OK; + + (*s) = session; + return SCP_SERVER_STATE_OK; } /******************************************************************************/ enum SCP_SERVER_STATES_E -scp_v0s_allow_connection(struct SCP_CONNECTION* c, SCP_DISPLAY d) +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; + 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; } /******************************************************************************/ enum SCP_SERVER_STATES_E -scp_v0s_deny_connection(struct SCP_CONNECTION* c) +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; + 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_replyauthentication(struct SCP_CONNECTION* c, unsigned short int value) +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; + 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; } diff --git a/sesman/libscp/libscp_v0.h b/sesman/libscp/libscp_v0.h index 92b835f0..16e49e05 100644 --- a/sesman/libscp/libscp_v0.h +++ b/sesman/libscp/libscp_v0.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -39,7 +38,7 @@ * @param d display * */ -enum SCP_CLIENT_STATES_E +enum SCP_CLIENT_STATES_E scp_v0c_connect(struct SCP_CONNECTION* c, struct SCP_SESSION* s); /* server API */ @@ -52,7 +51,7 @@ scp_v0c_connect(struct SCP_CONNECTION* c, struct SCP_SESSION* s); * scp_vXs_accept() ) * */ -enum SCP_SERVER_STATES_E +enum SCP_SERVER_STATES_E scp_v0s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk); /** @@ -61,7 +60,7 @@ scp_v0s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk); * @param c connection descriptor * */ -enum SCP_SERVER_STATES_E +enum SCP_SERVER_STATES_E scp_v0s_allow_connection(struct SCP_CONNECTION* c, SCP_DISPLAY d); /** @@ -70,17 +69,16 @@ scp_v0s_allow_connection(struct SCP_CONNECTION* c, SCP_DISPLAY d); * @param c connection descriptor * */ -enum SCP_SERVER_STATES_E +enum SCP_SERVER_STATES_E scp_v0s_deny_connection(struct SCP_CONNECTION* c); /** * @brief send reply to an authentication request * @param c connection descriptor * @param value the reply code 0 means ok - * @return + * @return */ enum SCP_SERVER_STATES_E scp_v0s_replyauthentication(struct SCP_CONNECTION* c, unsigned short int value); #endif - diff --git a/sesman/libscp/libscp_v1c.c b/sesman/libscp/libscp_v1c.c index 6e1c3b8a..7d1b9db8 100644 --- a/sesman/libscp/libscp_v1c.c +++ b/sesman/libscp/libscp_v1c.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -31,443 +30,477 @@ #include <stdio.h> static enum SCP_CLIENT_STATES_E -_scp_v1c_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s); +_scp_v1c_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s); /* client API */ /* 001 */ enum SCP_CLIENT_STATES_E -scp_v1c_connect(struct SCP_CONNECTION* c, struct SCP_SESSION* s) +scp_v1c_connect(struct 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); + 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); } /* 004 */ enum SCP_CLIENT_STATES_E -scp_v1c_resend_credentials(struct SCP_CONNECTION* c, struct SCP_SESSION* s) +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); + 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); } /* 021 */ enum SCP_CLIENT_STATES_E -scp_v1c_pwd_change(struct SCP_CONNECTION* c, char* newpass); +scp_v1c_pwd_change(struct SCP_CONNECTION *c, char *newpass); /* 022 */ enum SCP_CLIENT_STATES_E -scp_v1c_pwd_change_cancel(struct SCP_CONNECTION* c); +scp_v1c_pwd_change_cancel(struct SCP_CONNECTION *c); /* 041 */ enum SCP_CLIENT_STATES_E -scp_v1c_get_session_list(struct SCP_CONNECTION* c, int* scount, - struct SCP_DISCONNECTED_SESSION** s) +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_malloc(sizeof(struct SCP_DISCONNECTED_SESSION) * sescnt, 0); + + if (ds == 0) + { + return SCP_CLIENT_STATE_INTERNAL_ERR; + } + } + else + { + in_uint32_be(c->in_s, sestmp); + } + + in_uint8(c->in_s, continued); + in_uint8(c->in_s, pktcnt); + + for (idx = 0; idx < pktcnt; idx++) + { + in_uint32_be(c->in_s, (ds[totalcnt]).SID); /* session id */ + in_uint8(c->in_s, (ds[totalcnt]).type); + in_uint16_be(c->in_s, (ds[totalcnt]).height); + in_uint16_be(c->in_s, (ds[totalcnt]).width); + in_uint8(c->in_s, (ds[totalcnt]).bpp); + in_uint8(c->in_s, (ds[totalcnt]).idle_days); + in_uint8(c->in_s, (ds[totalcnt]).idle_hours); + in_uint8(c->in_s, (ds[totalcnt]).idle_minutes); + + 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++; + } + } + while (continued); + + printf("fine\n"); + /* return data... */ + (*scount) = sescnt; + (*s) = ds; + + return SCP_CLIENT_STATE_LIST_OK; +} + +/* 043 */ +enum SCP_CLIENT_STATES_E +scp_v1c_select_session(struct SCP_CONNECTION *c, struct SCP_SESSION *s, + SCP_SID sid) { - 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 */ + tui32 version = 1; + tui32 size = 16; + tui16 cmd = 43; + + init_stream(c->out_s, c->out_s->size); + + /* sending our selection */ + out_uint32_be(c->out_s, version); /* version */ + out_uint32_be(c->out_s, size); /* size */ + out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */ + out_uint16_be(c->out_s, cmd); /* cmd */ + + out_uint32_be(c->out_s, sid); + + if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size)) + { + return SCP_CLIENT_STATE_NETWORK_ERR; + } + + /* waiting for 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; + return SCP_CLIENT_STATE_NETWORK_ERR; } in_uint32_be(c->in_s, version); + if (version != 1) { - return SCP_CLIENT_STATE_VERSION_ERR; + return SCP_CLIENT_STATE_VERSION_ERR; } in_uint32_be(c->in_s, size); + if (size < 12) { - return SCP_CLIENT_STATE_SIZE_ERR; + return SCP_CLIENT_STATE_SIZE_ERR; } init_stream(c->in_s, c->in_s->size); + + /* read the rest of the packet */ if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8)) { - return SCP_CLIENT_STATE_NETWORK_ERR; + 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; + return SCP_CLIENT_STATE_SEQUENCE_ERR; } in_uint16_be(c->in_s, cmd); - if (cmd != 42) - { - return SCP_CLIENT_STATE_SEQUENCE_ERR; - } - - if (firstpkt) - { - firstpkt = 0; - in_uint32_be(c->in_s, sescnt); - sestmp = sescnt; - - ds = g_malloc(sizeof(struct SCP_DISCONNECTED_SESSION) * sescnt, 0); - if (ds == 0) - { - return SCP_CLIENT_STATE_INTERNAL_ERR; - } - } - else - { - in_uint32_be(c->in_s, sestmp); - } - in_uint8(c->in_s, continued); - in_uint8(c->in_s, pktcnt); - for (idx = 0; idx < pktcnt; idx++) + if (cmd != 46) { - 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++; + return SCP_CLIENT_STATE_SEQUENCE_ERR; } - } - while (continued); - printf("fine\n"); - /* return data... */ - (*scount) = sescnt; - (*s) = ds; + /* session display */ + in_uint16_be(c->in_s, (s->display)); + /*we don't need to return any data other than the display */ + /*because we already sent that */ - return SCP_CLIENT_STATE_LIST_OK; + return SCP_CLIENT_STATE_OK; } -/* 043 */ +/* 044 */ enum SCP_CLIENT_STATES_E -scp_v1c_select_session(struct SCP_CONNECTION* c, struct SCP_SESSION* s, - SCP_SID sid) +scp_v1c_select_session_cancel(struct SCP_CONNECTION *c) { - tui32 version = 1; - tui32 size = 16; - tui16 cmd = 43; - - init_stream(c->out_s, c->out_s->size); - - /* sending our selection */ - out_uint32_be(c->out_s, version); /* version */ - out_uint32_be(c->out_s, size); /* size */ - out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */ - out_uint16_be(c->out_s, cmd); /* cmd */ - - out_uint32_be(c->out_s, sid); - - if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size)) - { - return SCP_CLIENT_STATE_NETWORK_ERR; - } - - /* waiting for 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); - /* read the rest of the packet */ - 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; - } + tui32 version = 1; + tui32 size = 12; + tui16 cmd = 44; - in_uint16_be(c->in_s, cmd); - if (cmd != 46) - { - return SCP_CLIENT_STATE_SEQUENCE_ERR; - } + init_stream(c->out_s, c->out_s->size); - /* session display */ - in_uint16_be(c->in_s, (s->display)); - /*we don't need to return any data other than the display */ - /*because we already sent that */ + /* sending our selection */ + out_uint32_be(c->out_s, version); /* version */ + out_uint32_be(c->out_s, size); /* size */ + out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */ + out_uint16_be(c->out_s, cmd); /* cmd */ + + if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size)) + { + return SCP_CLIENT_STATE_NETWORK_ERR; + } - return SCP_CLIENT_STATE_OK; + return SCP_CLIENT_STATE_END; } -/* 044 */ -enum SCP_CLIENT_STATES_E -scp_v1c_select_session_cancel(struct SCP_CONNECTION* c) +static enum SCP_CLIENT_STATES_E +_scp_v1c_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s) { - tui32 version = 1; - tui32 size = 12; - tui16 cmd = 44; + tui32 version; + tui32 size; + tui16 cmd; + tui16 dim; - init_stream(c->out_s, c->out_s->size); + init_stream(c->in_s, c->in_s->size); - /* sending our selection */ - out_uint32_be(c->out_s, version); /* version */ - out_uint32_be(c->out_s, size); /* size */ - out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */ - out_uint16_be(c->out_s, cmd); /* cmd */ + if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) + { + return SCP_CLIENT_STATE_NETWORK_ERR; + } - if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size)) - { - return SCP_CLIENT_STATE_NETWORK_ERR; - } + in_uint32_be(c->in_s, version); - return SCP_CLIENT_STATE_END; -} + if (version != 1) + { + return SCP_CLIENT_STATE_VERSION_ERR; + } -static enum SCP_CLIENT_STATES_E -_scp_v1c_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s) -{ - tui32 version; - tui32 size; - tui16 cmd; - tui16 dim; - - 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); - - init_stream(c->in_s, c->in_s->size); - /* read the rest of the packet */ - 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_uint32_be(c->in_s, size); + + init_stream(c->in_s, c->in_s->size); + + /* read the rest of the packet */ + 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); - in_uint16_be(c->in_s, cmd); - if (cmd == 2) /* connection denied */ - { - in_uint16_be(c->in_s, dim); - if (s->errstr != 0) + if (cmd != SCP_COMMAND_SET_DEFAULT) { - g_free(s->errstr); + return SCP_CLIENT_STATE_SEQUENCE_ERR; } - s->errstr = g_malloc(dim + 1, 0); - if (s->errstr == 0) + + in_uint16_be(c->in_s, cmd); + + if (cmd == 2) /* connection denied */ { - return SCP_CLIENT_STATE_INTERNAL_ERR; + in_uint16_be(c->in_s, dim); + + if (s->errstr != 0) + { + g_free(s->errstr); + } + + s->errstr = g_malloc(dim + 1, 0); + + if (s->errstr == 0) + { + return SCP_CLIENT_STATE_INTERNAL_ERR; + } + + in_uint8a(c->in_s, s->errstr, dim); + (s->errstr)[dim] = '\0'; + + return SCP_CLIENT_STATE_CONNECTION_DENIED; } - in_uint8a(c->in_s, s->errstr, dim); - (s->errstr)[dim] = '\0'; - - return SCP_CLIENT_STATE_CONNECTION_DENIED; - } - else if (cmd == 3) /* resend usr/pwd */ - { - in_uint16_be(c->in_s, dim); - if (s->errstr != 0) + else if (cmd == 3) /* resend usr/pwd */ { - g_free(s->errstr); + in_uint16_be(c->in_s, dim); + + if (s->errstr != 0) + { + g_free(s->errstr); + } + + s->errstr = g_malloc(dim + 1, 0); + + if (s->errstr == 0) + { + return SCP_CLIENT_STATE_INTERNAL_ERR; + } + + in_uint8a(c->in_s, s->errstr, dim); + (s->errstr)[dim] = '\0'; + + return SCP_CLIENT_STATE_RESEND_CREDENTIALS; } - s->errstr = g_malloc(dim + 1, 0); - if (s->errstr == 0) + else if (cmd == 20) /* password change */ { - return SCP_CLIENT_STATE_INTERNAL_ERR; + in_uint16_be(c->in_s, dim); + + if (s->errstr != 0) + { + g_free(s->errstr); + } + + s->errstr = g_malloc(dim + 1, 0); + + if (s->errstr == 0) + { + return SCP_CLIENT_STATE_INTERNAL_ERR; + } + + in_uint8a(c->in_s, s->errstr, dim); + (s->errstr)[dim] = '\0'; + + return SCP_CLIENT_STATE_PWD_CHANGE_REQ; } - in_uint8a(c->in_s, s->errstr, dim); - (s->errstr)[dim] = '\0'; - - return SCP_CLIENT_STATE_RESEND_CREDENTIALS; - } - else if (cmd == 20) /* password change */ - { - in_uint16_be(c->in_s, dim); - if (s->errstr != 0) + else if (cmd == 30) /* display */ { - g_free(s->errstr); + in_uint16_be(c->in_s, s->display); + + return SCP_CLIENT_STATE_OK; } - s->errstr = g_malloc(dim + 1, 0); - if (s->errstr == 0) + //else if (cmd == 31) /* there's a disconnected session */ + //{ + // return SCP_CLIENT_STATE_RECONNECT_SINGLE; + //} + //else if (cmd == 33) /* display of a disconnected session */ + //{ + // return SCP_CLIENT_STATE_RECONNECT; + //} + else if (cmd == 40) /* session list */ { - return SCP_CLIENT_STATE_INTERNAL_ERR; + return SCP_CLIENT_STATE_SESSION_LIST; } - in_uint8a(c->in_s, s->errstr, dim); - (s->errstr)[dim] = '\0'; - - return SCP_CLIENT_STATE_PWD_CHANGE_REQ; - } - else if (cmd == 30) /* display */ - { - in_uint16_be(c->in_s, s->display); - return SCP_CLIENT_STATE_OK; - } - //else if (cmd == 31) /* there's a disconnected session */ - //{ - // return SCP_CLIENT_STATE_RECONNECT_SINGLE; - //} - //else if (cmd == 33) /* display of a disconnected session */ - //{ - // return SCP_CLIENT_STATE_RECONNECT; - //} - else if (cmd == 40) /* session list */ - { - return SCP_CLIENT_STATE_SESSION_LIST; - } - - return SCP_CLIENT_STATE_SEQUENCE_ERR; + return SCP_CLIENT_STATE_SEQUENCE_ERR; } diff --git a/sesman/libscp/libscp_v1c.h b/sesman/libscp/libscp_v1c.h index f6fd4492..ef5a06cb 100644 --- a/sesman/libscp/libscp_v1c.h +++ b/sesman/libscp/libscp_v1c.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * diff --git a/sesman/libscp/libscp_v1c_mng.c b/sesman/libscp/libscp_v1c_mng.c index 88f86f4f..59762e36 100644 --- a/sesman/libscp/libscp_v1c_mng.c +++ b/sesman/libscp/libscp_v1c_mng.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -33,215 +32,228 @@ //extern struct log_config* s_log; static enum SCP_CLIENT_STATES_E -_scp_v1c_mng_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s); +_scp_v1c_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s); /* client API */ /* 001 */ enum SCP_CLIENT_STATES_E -scp_v1c_mng_connect(struct SCP_CONNECTION* c, struct SCP_SESSION* s) +scp_v1c_mng_connect(struct 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); + tui8 sz; + tui32 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; - } + init_stream(c->out_s, c->out_s->size); + init_stream(c->in_s, c->in_s->size); - /* wait for response */ - return _scp_v1c_mng_check_response(c, s); -} + size = 12 + 4 + g_strlen(s->hostname) + g_strlen(s->username) + + g_strlen(s->password); -/* 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]; + if (s->addr_type == SCP_ADDRESS_TYPE_IPV4) + { + size = size + 4; + } + else + { + size = size + 16; + } - init_stream(c->out_s, c->out_s->size); + /* sending request */ - /* 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 */ + /* 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); - 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; - } + /* 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); - 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; - } + /* address */ + out_uint8(c->out_s, s->addr_type); - in_uint32_be(c->in_s, version); - if (version != 1) + if (s->addr_type == SCP_ADDRESS_TYPE_IPV4) { - log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: version error", __LINE__); - return SCP_CLIENT_STATE_VERSION_ERR; + out_uint32_be(c->out_s, s->ipv4addr); } - - in_uint32_be(c->in_s, size); - if (size < 12) + else { - log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: size error", __LINE__); - return SCP_CLIENT_STATE_SIZE_ERR; + out_uint8p(c->out_s, s->ipv6addr, 16); } - 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; - } + /* hostname */ + sz = g_strlen(s->hostname); + out_uint8(c->out_s, sz); + out_uint8p(c->out_s, s->hostname, sz); - in_uint16_be(c->in_s, cmd); - if (cmd != SCP_COMMAND_SET_MANAGE) + if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size)) { - log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__); - return SCP_CLIENT_STATE_SEQUENCE_ERR; + 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_CMD_MNG_LIST) /* session list */ - { - log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__); - return SCP_CLIENT_STATE_SEQUENCE_ERR; - } + /* wait for response */ + return _scp_v1c_mng_check_response(c, s); +} - 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 +/* 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)) { - in_uint32_be(c->in_s, sestmp); + log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__); + return SCP_CLIENT_STATE_NETWORK_ERR; } - in_uint8(c->in_s, continued); - in_uint8(c->in_s, pktcnt); - for (idx = 0; idx < pktcnt; idx++) + do { - 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++; + /* 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); + while (continued); - /* return data... */ - (*scount) = sescnt; - (*s) = ds; + /* return data... */ + (*scount) = sescnt; + (*s) = ds; - LOG_DBG("[v1c_mng] end list"); - return SCP_CLIENT_STATE_LIST_OK; + LOG_DBG("[v1c_mng] end list"); + return SCP_CLIENT_STATE_LIST_OK; } /* 043 * / @@ -339,62 +351,67 @@ scp_v1c_select_session_cancel(struct SCP_CONNECTION* c) }*/ static enum SCP_CLIENT_STATES_E -_scp_v1c_mng_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s) +_scp_v1c_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s) { - tui32 version; - tui32 size; - tui16 cmd; - tui8 dim; - char buf[257]; + tui32 version; + tui32 size; + tui16 cmd; + tui8 dim; + char buf[257]; - 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; - } + init_stream(c->in_s, c->in_s->size); - 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; - } + 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, size); + in_uint32_be(c->in_s, version); - init_stream(c->in_s, c->in_s->size); - /* read the rest of the packet */ - 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; - } + if (version != 1) + { + log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: version error", __LINE__); + return SCP_CLIENT_STATE_VERSION_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_uint32_be(c->in_s, size); - in_uint16_be(c->in_s, cmd); - if (cmd == SCP_CMD_MNG_LOGIN_ALLOW) /* connection ok */ - { - log_message(LOG_LEVEL_INFO, "[v1c_mng:%d] connection ok", __LINE__); - return SCP_CLIENT_STATE_OK; - } - else if (cmd == SCP_CMD_MNG_LOGIN_DENY) /* connection denied */ - { - in_uint8(c->in_s, dim); - buf[dim]='\0'; - in_uint8a(c->in_s, buf, dim); - scp_session_set_errstr(s, buf); + init_stream(c->in_s, c->in_s->size); - log_message(LOG_LEVEL_INFO, "[v1c_mng:%d] connection denied: %s", __LINE__ , s->errstr); - return SCP_CLIENT_STATE_CONNECTION_DENIED; - } + /* read the rest of the packet */ + 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; + } - 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_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_LOGIN_ALLOW) /* connection ok */ + { + log_message(LOG_LEVEL_INFO, "[v1c_mng:%d] connection ok", __LINE__); + return SCP_CLIENT_STATE_OK; + } + else if (cmd == SCP_CMD_MNG_LOGIN_DENY) /* connection denied */ + { + in_uint8(c->in_s, dim); + buf[dim] = '\0'; + in_uint8a(c->in_s, buf, dim); + scp_session_set_errstr(s, buf); + + log_message(LOG_LEVEL_INFO, "[v1c_mng:%d] connection denied: %s", __LINE__ , s->errstr); + return SCP_CLIENT_STATE_CONNECTION_DENIED; + } + + log_message(LOG_LEVEL_WARNING, "[v1c-mng:%d] connection aborted: sequence error", __LINE__); + return SCP_CLIENT_STATE_SEQUENCE_ERR; } diff --git a/sesman/libscp/libscp_v1c_mng.h b/sesman/libscp/libscp_v1c_mng.h index f030d4bf..126c9113 100644 --- a/sesman/libscp/libscp_v1c_mng.h +++ b/sesman/libscp/libscp_v1c_mng.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * diff --git a/sesman/libscp/libscp_v1s.c b/sesman/libscp/libscp_v1s.c index e10af26c..69997ab2 100644 --- a/sesman/libscp/libscp_v1s.c +++ b/sesman/libscp/libscp_v1s.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -33,634 +32,668 @@ //extern struct log_config* s_log; /* 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 SCP_CONNECTION *c, struct SCP_SESSION **s, int skipVchk) { - struct SCP_SESSION* session; - tui32 version; - tui32 size; - tui16 cmdset; - tui16 cmd; - tui8 sz; - char buf[257]; - - 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_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__); - return SCP_SERVER_STATE_VERSION_ERR; - } - } - else + struct SCP_SESSION *session; + tui32 version; + tui32 size; + tui16 cmdset; + tui16 cmd; + tui8 sz; + char buf[257]; + + if (!skipVchk) { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); - return SCP_SERVER_STATE_NETWORK_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; - } - - /* reading command set */ - in_uint16_be(c->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(c, 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; - } - - /* reading command */ - in_uint16_be(c->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(c->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(c->in_s, cmd); - scp_session_set_height(session, cmd); - in_uint16_be(c->in_s, cmd); - scp_session_set_height(session, cmd); - in_uint8(c->in_s, sz); - scp_session_set_bpp(session, sz); - in_uint8(c->in_s, sz); - scp_session_set_rsr(session, sz); - in_uint8a(c->in_s, buf, 17); - buf[17]='\0'; - scp_session_set_locale(session, buf); - - in_uint8(c->in_s, sz); - if (sz == SCP_ADDRESS_TYPE_IPV4) - { + + 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_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__); + return SCP_SERVER_STATE_VERSION_ERR; + } + } + else + { + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); + return SCP_SERVER_STATE_NETWORK_ERR; + } + } + in_uint32_be(c->in_s, size); - scp_session_set_addr(session, SCP_ADDRESS_TYPE_IPV4_BIN, &size); - } - else if (sz == SCP_ADDRESS_TYPE_IPV6) - { - in_uint8a(c->in_s, buf, 16); - scp_session_set_addr(session, SCP_ADDRESS_TYPE_IPV6_BIN, buf); - } - - buf[256] = '\0'; - /* reading hostname */ - in_uint8(c->in_s, sz); - buf[sz]='\0'; - in_uint8a(c->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 */ - in_uint8(c->in_s, sz); - buf[sz]='\0'; - in_uint8a(c->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 */ - in_uint8(c->in_s, sz); - buf[sz]='\0'; - in_uint8a(c->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; + 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; + } + + /* reading command set */ + in_uint16_be(c->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(c, 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; + } + + /* reading command */ + in_uint16_be(c->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); - return SCP_SERVER_STATE_OK; + in_uint8(c->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(c->in_s, cmd); + scp_session_set_height(session, cmd); + in_uint16_be(c->in_s, cmd); + scp_session_set_height(session, cmd); + in_uint8(c->in_s, sz); + scp_session_set_bpp(session, sz); + in_uint8(c->in_s, sz); + scp_session_set_rsr(session, sz); + in_uint8a(c->in_s, buf, 17); + buf[17] = '\0'; + scp_session_set_locale(session, buf); + + in_uint8(c->in_s, sz); + + if (sz == SCP_ADDRESS_TYPE_IPV4) + { + in_uint32_be(c->in_s, size); + scp_session_set_addr(session, SCP_ADDRESS_TYPE_IPV4_BIN, &size); + } + else if (sz == SCP_ADDRESS_TYPE_IPV6) + { + in_uint8a(c->in_s, buf, 16); + scp_session_set_addr(session, SCP_ADDRESS_TYPE_IPV6_BIN, buf); + } + + buf[256] = '\0'; + /* reading hostname */ + in_uint8(c->in_s, sz); + buf[sz] = '\0'; + in_uint8a(c->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 */ + in_uint8(c->in_s, sz); + buf[sz] = '\0'; + in_uint8a(c->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 */ + in_uint8(c->in_s, sz); + buf[sz] = '\0'; + in_uint8a(c->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, char* reason) +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; + 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; } enum SCP_SERVER_STATES_E -scp_v1s_request_password(struct SCP_CONNECTION* c, struct SCP_SESSION* s, char* reason) +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; - } + 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); - return SCP_SERVER_STATE_OK; + 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; } /* 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 SCP_CONNECTION *c, char *reason, char *npw) { - return SCP_SERVER_STATE_INTERNAL_ERR; + 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 SCP_CONNECTION *c, char *error, int retry, char *npw) { - return SCP_SERVER_STATE_INTERNAL_ERR; + 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 SCP_CONNECTION *c, SCP_DISPLAY d) { - /* send password request */ - tui32 version=1; - tui32 size=14; - tui16 cmd=30; + /* send password request */ + tui32 version = 1; + tui32 size = 14; + tui16 cmd = 30; - init_stream(c->out_s, c->out_s->size); + init_stream(c->out_s, c->out_s->size); - out_uint32_be(c->out_s, version); /* version */ - out_uint32_be(c->out_s, size); /* size */ - out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */ - out_uint16_be(c->out_s, cmd); /* cmd */ + out_uint32_be(c->out_s, 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 */ + 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; - } + 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; + return SCP_SERVER_STATE_OK; } /* 032 */ enum SCP_SERVER_STATES_E -scp_v1s_connection_error(struct SCP_CONNECTION* c, char* error) +scp_v1s_connection_error(struct SCP_CONNECTION *c, char *error) { - tui16 len; + tui16 len; - len = g_strlen(error); - init_stream(c->out_s,c->out_s->size); + 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); + 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; - } + 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; + return SCP_SERVER_STATE_END; } /* 040 */ enum SCP_SERVER_STATES_E -scp_v1s_list_sessions(struct SCP_CONNECTION* c, int sescnt, struct SCP_DISCONNECTED_SESSION* ds, SCP_SID* sid) +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 */ + 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); + init_stream(c->in_s, c->in_s->size); - /* size: ver+size+cmdset+cmd+sescnt+continue+count */ - size=4+4+2+2+4+1+1; + 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; + } - /* 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); + in_uint32_be(c->in_s, version); - /* session count */ - out_uint32_be(c->out_s, sescnt); + if (version != 1) + { + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__); + return SCP_SERVER_STATE_VERSION_ERR; + } - /* setting the continue flag */ - if ((idx+1)*SCP_SERVER_MAX_LIST_SIZE >= sescnt) + in_uint32_be(c->in_s, size); + + if (size < 12) { - 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); + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__); + return SCP_SERVER_STATE_SIZE_ERR; } - else + + init_stream(c->in_s, c->in_s->size); + + if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, (size - 8))) { - 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); + log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); + return SCP_SERVER_STATE_NETWORK_ERR; + } - if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size)) + 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: 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; + 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; } /* 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 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; + 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; } #endif diff --git a/sesman/libscp/libscp_v1s.h b/sesman/libscp/libscp_v1s.h index 32de0bba..5e3ec980 100644 --- a/sesman/libscp/libscp_v1s.h +++ b/sesman/libscp/libscp_v1s.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * diff --git a/sesman/libscp/libscp_v1s_mng.c b/sesman/libscp/libscp_v1s_mng.c index 599545ab..24553429 100644 --- a/sesman/libscp/libscp_v1s_mng.c +++ b/sesman/libscp/libscp_v1s_mng.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -33,309 +32,323 @@ //extern struct log_config* s_log; static enum SCP_SERVER_STATES_E -_scp_v1s_mng_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s); +_scp_v1s_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s); /* server API */ enum SCP_SERVER_STATES_E -scp_v1s_mng_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s) +scp_v1s_mng_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s) { - struct SCP_SESSION* session; - tui32 ipaddr; - tui16 cmd; - tui8 sz; - char buf[257]; - - /* reading command */ - in_uint16_be(c->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 */ - in_uint8(c->in_s, sz); - buf[sz]='\0'; - in_uint8a(c->in_s, buf, sz); - if (0 != scp_session_set_username(session, buf)) - { - scp_session_destroy(session); - 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(session, buf)) - { - scp_session_destroy(session); - return SCP_SERVER_STATE_INTERNAL_ERR; - } - - /* reading remote address */ - in_uint8(c->in_s, sz); - if (sz == SCP_ADDRESS_TYPE_IPV4) - { - in_uint32_be(c->in_s, ipaddr); - scp_session_set_addr(session, SCP_ADDRESS_TYPE_IPV4_BIN, &ipaddr); - } - else if (sz == SCP_ADDRESS_TYPE_IPV6) - { - in_uint8a(c->in_s, buf, 16); - scp_session_set_addr(session, SCP_ADDRESS_TYPE_IPV6_BIN, buf); - } - - /* reading hostname */ - in_uint8(c->in_s, sz); - buf[sz]='\0'; - in_uint8a(c->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; + struct SCP_SESSION *session; + tui32 ipaddr; + tui16 cmd; + tui8 sz; + char buf[257]; + + /* reading command */ + in_uint16_be(c->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 */ + in_uint8(c->in_s, sz); + buf[sz] = '\0'; + in_uint8a(c->in_s, buf, sz); + + if (0 != scp_session_set_username(session, buf)) + { + scp_session_destroy(session); + 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(session, buf)) + { + scp_session_destroy(session); + return SCP_SERVER_STATE_INTERNAL_ERR; + } + + /* reading remote address */ + in_uint8(c->in_s, sz); + + if (sz == SCP_ADDRESS_TYPE_IPV4) + { + in_uint32_be(c->in_s, ipaddr); + scp_session_set_addr(session, SCP_ADDRESS_TYPE_IPV4_BIN, &ipaddr); + } + else if (sz == SCP_ADDRESS_TYPE_IPV6) + { + in_uint8a(c->in_s, buf, 16); + scp_session_set_addr(session, SCP_ADDRESS_TYPE_IPV6_BIN, buf); + } + + /* reading hostname */ + in_uint8(c->in_s, sz); + buf[sz] = '\0'; + in_uint8a(c->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) +scp_v1s_mng_allow_connection(struct SCP_CONNECTION *c, struct SCP_SESSION *s) { - init_stream(c->out_s,c->out_s->size); + 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); + 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; - } + 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); + return _scp_v1s_mng_check_response(c, s); } /* 003 */ enum SCP_SERVER_STATES_E -scp_v1s_mng_deny_connection(struct SCP_CONNECTION* c, char* reason) +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; + 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; } /* 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) +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); + 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++; + } - /* size: ver+size+cmdset+cmd+sescnt+continue+count */ - size=4+4+2+2+4+1+1; + 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; + } + } - /* 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); + return _scp_v1s_mng_check_response(c, s); +} - /* session count */ - out_uint32_be(c->out_s, sescnt); +static enum SCP_SERVER_STATES_E +_scp_v1s_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s) +{ + tui32 version; + tui32 size; + tui16 cmd; + // tui8 dim; + // char buf[257]; + + init_stream(c->in_s, c->in_s->size); - /* setting the continue flag */ - if ((idx+1)*SCP_SERVER_MAX_LIST_SIZE >= sescnt) + if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) { - 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); + log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__); + return SCP_SERVER_STATE_NETWORK_ERR; } - else + + in_uint32_be(c->in_s, version); + + if (version != 1) { - out_uint8(c->out_s, 1); - /* setting session count for this packet */ - pidx=SCP_SERVER_MAX_LIST_SIZE; - out_uint8(c->out_s, pidx); + log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: version error", __LINE__); + return SCP_SERVER_STATE_VERSION_ERR; } - /* adding session descriptors */ - for (sidx=0; sidx<pidx; sidx++) + in_uint32_be(c->in_s, size); + + init_stream(c->in_s, c->in_s->size); + + /* read the rest of the packet */ + if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8)) { - /* 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; - } + log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__); + return SCP_SERVER_STATE_NETWORK_ERR; } - s_pop_layer(c->out_s, channel_hdr); - out_uint32_be(c->out_s, version); - out_uint32_be(c->out_s, size); + in_uint16_be(c->in_s, cmd); - if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, size)) + if (cmd != SCP_COMMAND_SET_MANAGE) { - log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__); - return SCP_SERVER_STATE_NETWORK_ERR; + log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: sequence error", __LINE__); + return SCP_SERVER_STATE_SEQUENCE_ERR; } - } - return _scp_v1s_mng_check_response(c, s); -} + in_uint16_be(c->in_s, cmd); + + if (cmd == SCP_CMD_MNG_LIST_REQ) /* request session list */ + { + log_message(LOG_LEVEL_INFO, "[v1s_mng:%d] request session list", __LINE__); + return SCP_SERVER_STATE_MNG_LISTREQ; + } + else if (cmd == SCP_CMD_MNG_ACTION) /* execute an action */ + { + /*in_uint8(c->in_s, dim); + buf[dim]='\0'; + in_uint8a(c->in_s, buf, dim); + scp_session_set_errstr(s, buf);*/ + + log_message(LOG_LEVEL_INFO, "[v1s_mng:%d] action request", __LINE__); + return SCP_SERVER_STATE_MNG_ACTION; + } + + /* else if (cmd == 20) / * password change * / + { + in_uint16_be(c->in_s, s->display); + + return SCP_SERVER_STATE_OK; + } + else if (cmd == 40) / * session list * / + { + return SCP_SERVER_STATE_SESSION_LIST; + }*/ -static enum SCP_SERVER_STATES_E -_scp_v1s_mng_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s) -{ - tui32 version; - tui32 size; - tui16 cmd; -// tui8 dim; -// char buf[257]; - - 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_mng:%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_mng:%d] connection aborted: version error", __LINE__); - return SCP_SERVER_STATE_VERSION_ERR; - } - - in_uint32_be(c->in_s, size); - - init_stream(c->in_s, c->in_s->size); - /* read the rest of the packet */ - if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8)) - { - log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__); - return SCP_SERVER_STATE_NETWORK_ERR; - } - - in_uint16_be(c->in_s, cmd); - if (cmd != SCP_COMMAND_SET_MANAGE) - { log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: sequence error", __LINE__); return SCP_SERVER_STATE_SEQUENCE_ERR; - } - - in_uint16_be(c->in_s, cmd); - if (cmd == SCP_CMD_MNG_LIST_REQ) /* request session list */ - { - log_message(LOG_LEVEL_INFO, "[v1s_mng:%d] request session list", __LINE__); - return SCP_SERVER_STATE_MNG_LISTREQ; - } - else if (cmd == SCP_CMD_MNG_ACTION) /* execute an action */ - { - /*in_uint8(c->in_s, dim); - buf[dim]='\0'; - in_uint8a(c->in_s, buf, dim); - scp_session_set_errstr(s, buf);*/ - - log_message(LOG_LEVEL_INFO, "[v1s_mng:%d] action request", __LINE__); - return SCP_SERVER_STATE_MNG_ACTION; - } - /* else if (cmd == 20) / * password change * / - { - in_uint16_be(c->in_s, s->display); - - return SCP_SERVER_STATE_OK; - } - else if (cmd == 40) / * session list * / - { - return SCP_SERVER_STATE_SESSION_LIST; - }*/ - - log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: sequence error", __LINE__); - return SCP_SERVER_STATE_SEQUENCE_ERR; } #endif diff --git a/sesman/libscp/libscp_v1s_mng.h b/sesman/libscp/libscp_v1s_mng.h index ab296632..72df9fa6 100644 --- a/sesman/libscp/libscp_v1s_mng.h +++ b/sesman/libscp/libscp_v1s_mng.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * diff --git a/sesman/libscp/libscp_vX.c b/sesman/libscp/libscp_vX.c index b121da2d..e590fe73 100644 --- a/sesman/libscp/libscp_vX.c +++ b/sesman/libscp/libscp_vX.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -28,26 +27,26 @@ #include "libscp_vX.h" /* server API */ -enum SCP_SERVER_STATES_E scp_vXs_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s) +enum SCP_SERVER_STATES_E scp_vXs_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s) { - tui32 version; - - /* reading version and packet size */ - if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) - { - return SCP_SERVER_STATE_NETWORK_ERR; - } - - in_uint32_be(c->in_s, version); - - if (version == 0) - { - return scp_v0s_accept(c, s, 1); - } - else if (version == 1) - { - return scp_v1s_accept(c, s, 1); - } - - return SCP_SERVER_STATE_VERSION_ERR; + tui32 version; + + /* reading version and packet size */ + if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) + { + return SCP_SERVER_STATE_NETWORK_ERR; + } + + in_uint32_be(c->in_s, version); + + if (version == 0) + { + return scp_v0s_accept(c, s, 1); + } + else if (version == 1) + { + return scp_v1s_accept(c, s, 1); + } + + return SCP_SERVER_STATE_VERSION_ERR; } diff --git a/sesman/libscp/libscp_vX.h b/sesman/libscp/libscp_vX.h index c59bc1af..a68a9ede 100644 --- a/sesman/libscp/libscp_vX.h +++ b/sesman/libscp/libscp_vX.h @@ -1,28 +1,27 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * * @file libscp_vX.h * @brief libscp version neutral code header * @author Simone Fedele - * + * */ #ifndef LIBSCP_VX_H diff --git a/sesman/lock.c b/sesman/lock.c index 83023cba..dd78ebbe 100644 --- a/sesman/lock.c +++ b/sesman/lock.c @@ -1,29 +1,27 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 - - session manager - linux only - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * session manager + * linux only + */ #include "sesman.h" -extern struct config_sesman* g_cfg; /* in sesman.c */ +extern struct config_sesman *g_cfg; /* in sesman.c */ static tbus g_sync_mutex = 0; static tbus g_lock_chain = 0; @@ -34,90 +32,90 @@ static tbus g_lock_socket = 0; void APP_CC lock_init(void) { - g_sync_mutex = tc_mutex_create(); - g_lock_chain = tc_mutex_create(); - g_sync_sem = tc_sem_create(0); - g_lock_socket = tc_sem_create(1); + g_sync_mutex = tc_mutex_create(); + g_lock_chain = tc_mutex_create(); + g_sync_sem = tc_sem_create(0); + g_lock_socket = tc_sem_create(1); } /******************************************************************************/ void APP_CC lock_deinit(void) { - tc_mutex_delete(g_sync_mutex); - tc_mutex_delete(g_lock_chain); - tc_sem_delete(g_sync_sem); - tc_sem_delete(g_lock_socket); + tc_mutex_delete(g_sync_mutex); + tc_mutex_delete(g_lock_chain); + tc_sem_delete(g_sync_sem); + tc_sem_delete(g_lock_socket); } /******************************************************************************/ void APP_CC lock_chain_acquire(void) { - /* lock the chain */ - LOG_DBG("lock_chain_acquire()"); - tc_mutex_lock(g_lock_chain); + /* lock the chain */ + LOG_DBG("lock_chain_acquire()"); + tc_mutex_lock(g_lock_chain); } /******************************************************************************/ void APP_CC lock_chain_release(void) { - /* unlock the chain */ - LOG_DBG("lock_chain_release()"); - tc_mutex_unlock(g_lock_chain); + /* unlock the chain */ + LOG_DBG("lock_chain_release()"); + tc_mutex_unlock(g_lock_chain); } /******************************************************************************/ void APP_CC lock_socket_acquire(void) { - /* lock socket variable */ - LOG_DBG("lock_socket_acquire()"); - tc_sem_dec(g_lock_socket); + /* lock socket variable */ + LOG_DBG("lock_socket_acquire()"); + tc_sem_dec(g_lock_socket); } /******************************************************************************/ void APP_CC lock_socket_release(void) { - /* unlock socket variable */ - LOG_DBG("lock_socket_release()"); - tc_sem_inc(g_lock_socket); + /* unlock socket variable */ + LOG_DBG("lock_socket_release()"); + tc_sem_inc(g_lock_socket); } /******************************************************************************/ void APP_CC lock_sync_acquire(void) { - /* lock sync variable */ - LOG_DBG("lock_sync_acquire()"); - tc_mutex_lock(g_sync_mutex); + /* lock sync variable */ + LOG_DBG("lock_sync_acquire()"); + tc_mutex_lock(g_sync_mutex); } /******************************************************************************/ void APP_CC lock_sync_release(void) { - /* unlock socket variable */ - LOG_DBG("lock_sync_release()"); - tc_mutex_unlock(g_sync_mutex); + /* unlock socket variable */ + LOG_DBG("lock_sync_release()"); + tc_mutex_unlock(g_sync_mutex); } /******************************************************************************/ void APP_CC lock_sync_sem_acquire(void) { - /* dec sem */ - LOG_DBG("lock_sync_sem_acquire()"); - tc_sem_dec(g_sync_sem); + /* dec sem */ + LOG_DBG("lock_sync_sem_acquire()"); + tc_sem_dec(g_sync_sem); } /******************************************************************************/ void APP_CC lock_sync_sem_release(void) { - /* inc sem */ - LOG_DBG("lock_sync_sem_release()"); - tc_sem_inc(g_sync_sem); + /* inc sem */ + LOG_DBG("lock_sync_sem_release()"); + tc_sem_inc(g_sync_sem); } diff --git a/sesman/lock.h b/sesman/lock.h index 28c147f2..0b7c905f 100644 --- a/sesman/lock.h +++ b/sesman/lock.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #ifndef LOCK_H #define LOCK_H diff --git a/sesman/scp.c b/sesman/scp.c index bbe495ea..db97fda5 100644 --- a/sesman/scp.c +++ b/sesman/scp.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2008 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -31,72 +30,75 @@ #include "sesman.h" extern int g_thread_sck; /* in thread.c */ -extern struct config_sesman* g_cfg; /* in sesman.c */ +extern struct config_sesman *g_cfg; /* in sesman.c */ /******************************************************************************/ -void* DEFAULT_CC -scp_process_start(void* sck) +void *DEFAULT_CC +scp_process_start(void *sck) { - struct SCP_CONNECTION scon; - struct SCP_SESSION* sdata; + struct SCP_CONNECTION scon; + struct SCP_SESSION *sdata; + + /* making a local copy of the socket (it's on the stack) */ + /* probably this is just paranoia */ + scon.in_sck = g_thread_sck; + LOG_DBG("started scp thread on socket %d", scon.in_sck); + + /* unlocking g_thread_sck */ + lock_socket_release(); + + make_stream(scon.in_s); + make_stream(scon.out_s); - /* making a local copy of the socket (it's on the stack) */ - /* probably this is just paranoia */ - scon.in_sck = g_thread_sck; - LOG_DBG("started scp thread on socket %d", scon.in_sck); + init_stream(scon.in_s, 8192); + init_stream(scon.out_s, 8192); - /* unlocking g_thread_sck */ - lock_socket_release(); + switch (scp_vXs_accept(&scon, &(sdata))) + { + case SCP_SERVER_STATE_OK: - make_stream(scon.in_s); - make_stream(scon.out_s); + if (sdata->version == 0) + { + /* starts processing an scp v0 connection */ + LOG_DBG("accept ok, go on with scp v0\n", 0); + scp_v0_process(&scon, sdata); + } + else + { + LOG_DBG("accept ok, go on with scp v1\n", 0); + /*LOG_DBG("user: %s\npass: %s",sdata->username, sdata->password);*/ + scp_v1_process(&scon, sdata); + } - init_stream(scon.in_s, 8192); - init_stream(scon.out_s, 8192); + break; + case SCP_SERVER_STATE_START_MANAGE: + /* starting a management session */ + log_message(LOG_LEVEL_WARNING, + "starting a sesman management session..."); + scp_v1_mng_process(&scon, sdata); + break; + case SCP_SERVER_STATE_VERSION_ERR: + /* an unknown scp version was requested, so we shut down the */ + /* connection (and log the fact) */ + log_message(LOG_LEVEL_WARNING, + "unknown protocol version specified. connection refused."); + break; + case SCP_SERVER_STATE_NETWORK_ERR: + log_message(LOG_LEVEL_WARNING, "libscp network error."); + break; + case SCP_SERVER_STATE_SEQUENCE_ERR: + log_message(LOG_LEVEL_WARNING, "libscp sequence error."); + break; + case SCP_SERVER_STATE_INTERNAL_ERR: + /* internal error occurred (eg. malloc() error, ecc.) */ + log_message(LOG_LEVEL_ERROR, "libscp internal error occurred."); + break; + default: + log_message(LOG_LEVEL_ALWAYS, "unknown return from scp_vXs_accept()"); + } - switch (scp_vXs_accept(&scon, &(sdata))) - { - case SCP_SERVER_STATE_OK: - if (sdata->version == 0) - { - /* starts processing an scp v0 connection */ - LOG_DBG("accept ok, go on with scp v0\n",0); - scp_v0_process(&scon, sdata); - } - else - { - LOG_DBG("accept ok, go on with scp v1\n",0); - /*LOG_DBG("user: %s\npass: %s",sdata->username, sdata->password);*/ - scp_v1_process(&scon, sdata); - } - break; - case SCP_SERVER_STATE_START_MANAGE: - /* starting a management session */ - log_message(LOG_LEVEL_WARNING, - "starting a sesman management session..."); - scp_v1_mng_process(&scon, sdata); - break; - case SCP_SERVER_STATE_VERSION_ERR: - /* an unknown scp version was requested, so we shut down the */ - /* connection (and log the fact) */ - log_message(LOG_LEVEL_WARNING, - "unknown protocol version specified. connection refused."); - break; - case SCP_SERVER_STATE_NETWORK_ERR: - log_message(LOG_LEVEL_WARNING, "libscp network error."); - break; - case SCP_SERVER_STATE_SEQUENCE_ERR: - log_message(LOG_LEVEL_WARNING, "libscp sequence error."); - break; - case SCP_SERVER_STATE_INTERNAL_ERR: - /* internal error occurred (eg. malloc() error, ecc.) */ - log_message(LOG_LEVEL_ERROR, "libscp internal error occurred."); - break; - default: - log_message(LOG_LEVEL_ALWAYS, "unknown return from scp_vXs_accept()"); - } - g_tcp_close(scon.in_sck); - free_stream(scon.in_s); - free_stream(scon.out_s); - return 0; + g_tcp_close(scon.in_sck); + free_stream(scon.in_s); + free_stream(scon.out_s); + return 0; } diff --git a/sesman/scp.h b/sesman/scp.h index b3433f4e..c4f3de3a 100644 --- a/sesman/scp.h +++ b/sesman/scp.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2008 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * diff --git a/sesman/scp_v0.c b/sesman/scp_v0.c index dac04ad3..da6ab919 100644 --- a/sesman/scp_v0.c +++ b/sesman/scp_v0.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2008 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -27,121 +26,128 @@ #include "sesman.h" -extern struct config_sesman* g_cfg; /* in sesman.c */ +extern struct config_sesman *g_cfg; /* in sesman.c */ /******************************************************************************/ void DEFAULT_CC -scp_v0_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s) +scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s) { - int display = 0; - tbus data; - struct session_item* s_item; + int display = 0; + tbus data; + struct session_item *s_item; - data = auth_userpass(s->username, s->password); - if (s->type == SCP_GW_AUTHENTICATION) - { - /* this is just authentication in a gateway situation */ - /* g_writeln("SCP_GW_AUTHENTICATION message received"); */ - if (data) - { - if (1 == access_login_allowed(s->username)) - { - /* the user is member of the correct groups. */ - scp_v0s_replyauthentication(c, 0); - log_message(LOG_LEVEL_INFO, "Access permitted for user: %s", - s->username); - /* g_writeln("Connection allowed"); */ - } - else - { - scp_v0s_replyauthentication(c,3); - log_message(LOG_LEVEL_INFO, "Username okey but group problem for " - "user: %s", s->username); - /* g_writeln("user password ok, but group problem"); */ - } - } - else - { - /* g_writeln("username or password error"); */ - log_message(LOG_LEVEL_INFO, "Username or password error for user: %s", - s->username); - scp_v0s_replyauthentication(c, 2); - } - auth_end(data); - } - else if (data) - { - s_item = session_get_bydata(s->username, s->width, s->height, - s->bpp, s->type); - if (s_item != 0) + data = auth_userpass(s->username, s->password); + + if (s->type == SCP_GW_AUTHENTICATION) { - display = s_item->display; - if (0 != s->client_ip) - { - log_message( LOG_LEVEL_INFO, "++ reconnected session: username %s, " - "display :%d.0, session_pid %d, ip %s", - s->username, display, s_item->pid, s->client_ip); - } - else - { - log_message(LOG_LEVEL_INFO, "++ reconnected session: username %s, " - "display :%d.0, session_pid %d", s->username, display, - s_item->pid); - } - session_reconnect(display, s->username); - auth_end(data); - /* don't set data to null here */ + /* this is just authentication in a gateway situation */ + /* g_writeln("SCP_GW_AUTHENTICATION message received"); */ + if (data) + { + if (1 == access_login_allowed(s->username)) + { + /* the user is member of the correct groups. */ + scp_v0s_replyauthentication(c, 0); + log_message(LOG_LEVEL_INFO, "Access permitted for user: %s", + s->username); + /* g_writeln("Connection allowed"); */ + } + else + { + scp_v0s_replyauthentication(c, 3); + log_message(LOG_LEVEL_INFO, "Username okey but group problem for " + "user: %s", s->username); + /* g_writeln("user password ok, but group problem"); */ + } + } + else + { + /* g_writeln("username or password error"); */ + log_message(LOG_LEVEL_INFO, "Username or password error for user: %s", + s->username); + scp_v0s_replyauthentication(c, 2); + } + + auth_end(data); } - else + else if (data) { - LOG_DBG("pre auth"); - if (1 == access_login_allowed(s->username)) - { - if (0 != s->client_ip) + s_item = session_get_bydata(s->username, s->width, s->height, + s->bpp, s->type); + + if (s_item != 0) { - log_message(LOG_LEVEL_INFO, "++ created session (access granted): " - "username %s, ip %s", s->username, s->client_ip); + display = s_item->display; + + if (0 != s->client_ip) + { + log_message( LOG_LEVEL_INFO, "++ reconnected session: username %s, " + "display :%d.0, session_pid %d, ip %s", + s->username, display, s_item->pid, s->client_ip); + } + else + { + log_message(LOG_LEVEL_INFO, "++ reconnected session: username %s, " + "display :%d.0, session_pid %d", s->username, display, + s_item->pid); + } + + session_reconnect(display, s->username); + auth_end(data); + /* don't set data to null here */ } else { - log_message(LOG_LEVEL_INFO, "++ created session (access granted): " - "username %s", s->username); + LOG_DBG("pre auth"); + + if (1 == access_login_allowed(s->username)) + { + if (0 != s->client_ip) + { + log_message(LOG_LEVEL_INFO, "++ created session (access granted): " + "username %s, ip %s", s->username, s->client_ip); + } + else + { + log_message(LOG_LEVEL_INFO, "++ created session (access granted): " + "username %s", s->username); + } + + if (SCP_SESSION_TYPE_XVNC == s->type) + { + log_message( LOG_LEVEL_INFO, "starting Xvnc session..."); + display = session_start(s->width, s->height, s->bpp, s->username, + s->password, data, SESMAN_SESSION_TYPE_XVNC, + s->domain, s->program, s->directory, + s->client_ip); + } + else + { + log_message(LOG_LEVEL_INFO, "starting X11rdp session..."); + display = session_start(s->width, s->height, s->bpp, s->username, + s->password, data, SESMAN_SESSION_TYPE_XRDP, + s->domain, s->program, s->directory, + s->client_ip); + } + } + else + { + display = 0; + } } - if (SCP_SESSION_TYPE_XVNC == s->type) + if (display == 0) { - log_message( LOG_LEVEL_INFO, "starting Xvnc session..."); - display = session_start(s->width, s->height, s->bpp, s->username, - s->password, data, SESMAN_SESSION_TYPE_XVNC, - s->domain, s->program, s->directory, - s->client_ip); + auth_end(data); + scp_v0s_deny_connection(c); } else { - log_message(LOG_LEVEL_INFO, "starting X11rdp session..."); - display = session_start(s->width, s->height, s->bpp, s->username, - s->password, data, SESMAN_SESSION_TYPE_XRDP, - s->domain, s->program, s->directory, - s->client_ip); + scp_v0s_allow_connection(c, display); } - } - else - { - display = 0; - } - } - if (display == 0) - { - auth_end(data); - scp_v0s_deny_connection(c); } else { - scp_v0s_allow_connection(c, display); + scp_v0s_deny_connection(c); } - } - else - { - scp_v0s_deny_connection(c); - } } diff --git a/sesman/scp_v0.h b/sesman/scp_v0.h index 64d2475a..e5c2f576 100644 --- a/sesman/scp_v0.h +++ b/sesman/scp_v0.h @@ -1,28 +1,27 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2008 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * * @file scp_v0.h * @brief scp version 0 declarations * @author Simone Fedele - * + * */ #ifndef SCP_V0_H @@ -38,7 +37,7 @@ * @param out_s output stream * */ -void DEFAULT_CC +void DEFAULT_CC scp_v0_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s); #endif diff --git a/sesman/scp_v1.c b/sesman/scp_v1.c index f93f89ee..295fbce4 100644 --- a/sesman/scp_v1.c +++ b/sesman/scp_v1.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2008 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -30,203 +29,213 @@ //#include "libscp_types.h" #include "libscp.h" -extern struct config_sesman* g_cfg; /* in sesman.c */ +extern struct config_sesman *g_cfg; /* in sesman.c */ -static void parseCommonStates(enum SCP_SERVER_STATES_E e, char* f); +static void parseCommonStates(enum SCP_SERVER_STATES_E e, char *f); /******************************************************************************/ void DEFAULT_CC -scp_v1_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s) +scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s) { - long data; - int display; - int retries; - int current_try; - enum SCP_SERVER_STATES_E e; - struct SCP_DISCONNECTED_SESSION* slist; - struct session_item* sitem; - int scount; - SCP_SID sid; - - retries = g_cfg->sec.login_retry; - current_try = retries; - - data = auth_userpass(s->username, s->password); - /*LOG_DBG("user: %s\npass: %s", s->username, s->password);*/ - - while ((!data) && ((retries == 0) || (current_try > 0))) - { - LOG_DBG("data %d - 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) + long data; + int display; + int retries; + int current_try; + enum SCP_SERVER_STATES_E e; + struct SCP_DISCONNECTED_SESSION *slist; + struct session_item *sitem; + int scount; + SCP_SID sid; + + retries = g_cfg->sec.login_retry; + current_try = retries; + + data = auth_userpass(s->username, s->password); + /*LOG_DBG("user: %s\npass: %s", s->username, s->password);*/ + + while ((!data) && ((retries == 0) || (current_try > 0))) { - case SCP_SERVER_STATE_OK: - /* all ok, we got new username and password */ - data = auth_userpass(s->username, s->password); - /* one try less */ - if (current_try > 0) + LOG_DBG("data %d - 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) { - current_try--; + case SCP_SERVER_STATE_OK: + /* all ok, we got new username and password */ + data = auth_userpass(s->username, s->password); + + /* one try less */ + if (current_try > 0) + { + current_try--; + } + + break; + default: + /* we check the other errors */ + parseCommonStates(e, "scp_v1s_list_sessions()"); + scp_session_destroy(s); + return; + //break; } - break; - default: - /* we check the other errors */ - parseCommonStates(e, "scp_v1s_list_sessions()"); + } + + if (!data) + { + scp_v1s_deny_connection(c, "Login failed"); + log_message( LOG_LEVEL_INFO, + "Login failed for user %s. Connection terminated", s->username); scp_session_destroy(s); return; - //break; } - } - if (!data) - { - scp_v1s_deny_connection(c, "Login failed"); - log_message( LOG_LEVEL_INFO, - "Login failed for user %s. Connection terminated", s->username); - scp_session_destroy(s); - return; - } - - /* testing if login is allowed*/ - if (0 == access_login_allowed(s->username)) - { - scp_v1s_deny_connection(c, "Access to Terminal Server not allowed."); - log_message(LOG_LEVEL_INFO, - "User %s not allowed on TS. Connection terminated", s->username); - scp_session_destroy(s); - return; - } + /* testing if login is allowed*/ + if (0 == access_login_allowed(s->username)) + { + scp_v1s_deny_connection(c, "Access to Terminal Server not allowed."); + log_message(LOG_LEVEL_INFO, + "User %s not allowed on TS. Connection terminated", s->username); + scp_session_destroy(s); + return; + } - //check if we need password change + //check if we need password change - /* list disconnected sessions */ - slist = session_get_byuser(s->username, &scount, SESMAN_SESSION_STATUS_DISCONNECTED); + /* list disconnected sessions */ + slist = session_get_byuser(s->username, &scount, SESMAN_SESSION_STATUS_DISCONNECTED); - if (scount == 0) - { - /* no disconnected sessions - start a new one */ - log_message(LOG_LEVEL_DEBUG,"No disconnected sessions for this user" - "- we create a new one"); - if (0 != s->client_ip) - { - log_message(LOG_LEVEL_INFO, "++ created session (access granted): username %s, ip %s", s->username, s->client_ip); - } - else - { - log_message(LOG_LEVEL_INFO, "++ created session (access granted): username %s", s->username); - } - if (SCP_SESSION_TYPE_XVNC == s->type) - { - log_message(LOG_LEVEL_INFO, "starting Xvnc session..."); - display = session_start(s->width, s->height, s->bpp, s->username, - s->password, data, SESMAN_SESSION_TYPE_XVNC, - s->domain, s->program, s->directory, s->client_ip); - } - else + if (scount == 0) { - log_message(LOG_LEVEL_INFO, "starting X11rdp session..."); - display = session_start(s->width, s->height, s->bpp, s->username, - s->password, data, SESMAN_SESSION_TYPE_XRDP, - s->domain, s->program, s->directory, s->client_ip); - } + /* no disconnected sessions - start a new one */ + log_message(LOG_LEVEL_DEBUG, "No disconnected sessions for this user" + "- we create a new one"); - e = scp_v1s_connect_new_session(c, display); - switch (e) - { - case SCP_SERVER_STATE_OK: - /* all ok, we got new username and password */ - break; - default: - /* we check the other errors */ - parseCommonStates(e, "scp_v1s_connect_new_session()"); - break; - } - } - else - { - /* one or more disconnected sessions - listing */ - e = scp_v1s_list_sessions(c, scount, slist, &sid); + if (0 != s->client_ip) + { + log_message(LOG_LEVEL_INFO, "++ created session (access granted): username %s, ip %s", s->username, s->client_ip); + } + else + { + log_message(LOG_LEVEL_INFO, "++ created session (access granted): username %s", s->username); + } - switch (e) - { - /*case SCP_SERVER_STATE_FORCE_NEW:*/ - /* we should check for MaxSessions */ - case SCP_SERVER_STATE_SELECTION_CANCEL: - log_message( LOG_LEVEL_INFO, "Connection cancelled after session listing"); - break; - case SCP_SERVER_STATE_OK: - /* ok, reconnecting... */ - sitem=session_get_bypid(sid); - if (0 == sitem) + if (SCP_SESSION_TYPE_XVNC == s->type) { - e = scp_v1s_connection_error(c, "Internal error"); - log_message(LOG_LEVEL_INFO, "Cannot find session item on the chain"); + log_message(LOG_LEVEL_INFO, "starting Xvnc session..."); + display = session_start(s->width, s->height, s->bpp, s->username, + s->password, data, SESMAN_SESSION_TYPE_XVNC, + s->domain, s->program, s->directory, s->client_ip); } 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_message(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_message(LOG_LEVEL_INFO, "++ reconnected session: username %s, display :%d.0, session_pid %d", s->username, display, sitem->pid); - } - g_free(sitem); + log_message(LOG_LEVEL_INFO, "starting X11rdp session..."); + display = session_start(s->width, s->height, s->bpp, s->username, + s->password, data, SESMAN_SESSION_TYPE_XRDP, + s->domain, s->program, s->directory, s->client_ip); + } + + e = scp_v1s_connect_new_session(c, display); + + switch (e) + { + case SCP_SERVER_STATE_OK: + /* all ok, we got new username and password */ + break; + default: + /* we check the other errors */ + parseCommonStates(e, "scp_v1s_connect_new_session()"); + break; } - break; - default: - /* we check the other errors */ - parseCommonStates(e, "scp_v1s_list_sessions()"); - break; } - g_free(slist); - } - - /* resource management */ - if ((e == SCP_SERVER_STATE_OK) && (s->rsr)) - { - /* here goes scp resource sharing code */ - } - - /* cleanup */ - scp_session_destroy(s); - auth_end(data); + 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_message( LOG_LEVEL_INFO, "Connection cancelled after session listing"); + break; + case SCP_SERVER_STATE_OK: + /* ok, reconnecting... */ + sitem = session_get_bypid(sid); + + if (0 == sitem) + { + e = scp_v1s_connection_error(c, "Internal error"); + log_message(LOG_LEVEL_INFO, "Cannot find session item on the chain"); + } + 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_message(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_message(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; + } + + g_free(slist); + } + + /* resource management */ + if ((e == SCP_SERVER_STATE_OK) && (s->rsr)) + { + /* here goes scp resource sharing code */ + } + + /* cleanup */ + scp_session_destroy(s); + auth_end(data); } -static void parseCommonStates(enum SCP_SERVER_STATES_E e, char* f) +static void parseCommonStates(enum SCP_SERVER_STATES_E e, char *f) { - switch (e) - { - case SCP_SERVER_STATE_VERSION_ERR: - LOG_DBG("version error") - case SCP_SERVER_STATE_SIZE_ERR: - /* an unknown scp version was requested, so we shut down the */ - /* connection (and log the fact) */ - log_message(LOG_LEVEL_WARNING, - "protocol violation. connection closed."); - break; - case SCP_SERVER_STATE_NETWORK_ERR: - log_message(LOG_LEVEL_WARNING, "libscp network error."); - break; - case SCP_SERVER_STATE_SEQUENCE_ERR: - log_message(LOG_LEVEL_WARNING, "libscp sequence error."); - break; - case SCP_SERVER_STATE_INTERNAL_ERR: - /* internal error occurred (eg. malloc() error, ecc.) */ - log_message(LOG_LEVEL_ERROR, "libscp internal error occurred."); - break; - default: - /* dummy: scp_v1s_request_password won't generate any other */ - /* error other than the ones before */ - log_message(LOG_LEVEL_ALWAYS, "unknown return from %s", f); - break; - } + switch (e) + { + case SCP_SERVER_STATE_VERSION_ERR: + LOG_DBG("version error") + case SCP_SERVER_STATE_SIZE_ERR: + /* an unknown scp version was requested, so we shut down the */ + /* connection (and log the fact) */ + log_message(LOG_LEVEL_WARNING, + "protocol violation. connection closed."); + break; + case SCP_SERVER_STATE_NETWORK_ERR: + log_message(LOG_LEVEL_WARNING, "libscp network error."); + break; + case SCP_SERVER_STATE_SEQUENCE_ERR: + log_message(LOG_LEVEL_WARNING, "libscp sequence error."); + break; + case SCP_SERVER_STATE_INTERNAL_ERR: + /* internal error occurred (eg. malloc() error, ecc.) */ + log_message(LOG_LEVEL_ERROR, "libscp internal error occurred."); + break; + default: + /* dummy: scp_v1s_request_password won't generate any other */ + /* error other than the ones before */ + log_message(LOG_LEVEL_ALWAYS, "unknown return from %s", f); + break; + } } diff --git a/sesman/scp_v1.h b/sesman/scp_v1.h index 648855f9..0d224129 100644 --- a/sesman/scp_v1.h +++ b/sesman/scp_v1.h @@ -1,28 +1,27 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2008 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * * @file scp_v1.h * @brief scp version 1 declarations * @author Simone Fedele - * + * */ #ifndef SCP_V1_H @@ -36,7 +35,7 @@ * @param out_s output stream * */ -void DEFAULT_CC +void DEFAULT_CC scp_v1_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s); #endif diff --git a/sesman/scp_v1_mng.c b/sesman/scp_v1_mng.c index e4d97b77..0e20007d 100644 --- a/sesman/scp_v1_mng.c +++ b/sesman/scp_v1_mng.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2008 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -29,112 +28,113 @@ #include "libscp.h" -extern struct config_sesman* g_cfg; /* in sesman.c */ +extern struct config_sesman *g_cfg; /* in sesman.c */ -static void parseCommonStates(enum SCP_SERVER_STATES_E e, char* f); +static void parseCommonStates(enum SCP_SERVER_STATES_E e, char *f); /******************************************************************************/ void DEFAULT_CC -scp_v1_mng_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s) +scp_v1_mng_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s) { - long data; - enum SCP_SERVER_STATES_E e; - struct SCP_DISCONNECTED_SESSION* slist = 0; - int scount; - int end = 0; - - data = auth_userpass(s->username, s->password); - /*LOG_DBG("user: %s\npass: %s", s->username, s->password);*/ - - if (!data) - { - scp_v1s_mng_deny_connection(c, "Login failed"); - log_message(LOG_LEVEL_INFO, - "[MNG] Login failed for user %s. Connection terminated", s->username); - scp_session_destroy(s); - auth_end(data); - return; - } - - /* testing if login is allowed */ - if (0 == access_login_mng_allowed(s->username)) - { - scp_v1s_mng_deny_connection(c, "Access to Terminal Server not allowed."); - log_message(LOG_LEVEL_INFO, - "[MNG] User %s not allowed on TS. Connection terminated", s->username); - scp_session_destroy(s); - auth_end(data); - return; - } + long data; + enum SCP_SERVER_STATES_E e; + struct SCP_DISCONNECTED_SESSION *slist = 0; + int scount; + int end = 0; - e = scp_v1s_mng_allow_connection(c, s); + data = auth_userpass(s->username, s->password); + /*LOG_DBG("user: %s\npass: %s", s->username, s->password);*/ - end = 1; - while (end) - { - switch (e) + if (!data) { - case SCP_SERVER_STATE_MNG_ACTION: - log_message(LOG_LEVEL_INFO, "Connection cancelled after session listing"); - break; + scp_v1s_mng_deny_connection(c, "Login failed"); + log_message(LOG_LEVEL_INFO, + "[MNG] Login failed for user %s. Connection terminated", s->username); + scp_session_destroy(s); + auth_end(data); + return; + } - case SCP_SERVER_STATE_MNG_LISTREQ: - /* list disconnected sessions */ - slist = session_get_byuser(NULL, &scount, SESMAN_SESSION_STATUS_ALL); - LOG_DBG("sessions on TS: %d (slist: %x)", scount, slist); + /* testing if login is allowed */ + if (0 == access_login_mng_allowed(s->username)) + { + scp_v1s_mng_deny_connection(c, "Access to Terminal Server not allowed."); + log_message(LOG_LEVEL_INFO, + "[MNG] User %s not allowed on TS. Connection terminated", s->username); + scp_session_destroy(s); + auth_end(data); + return; + } - if (0 == slist) - { -// e=scp_v1s_connection_error(c, "Internal error"); - log_message(LOG_LEVEL_INFO, "No sessions on Terminal Server"); - end = 0; - } - else + e = scp_v1s_mng_allow_connection(c, s); + + end = 1; + + while (end) + { + switch (e) { - e = scp_v1s_mng_list_sessions(c, s, scount, slist); - g_free(slist); + case SCP_SERVER_STATE_MNG_ACTION: + log_message(LOG_LEVEL_INFO, "Connection cancelled after session listing"); + break; + + case SCP_SERVER_STATE_MNG_LISTREQ: + /* list disconnected sessions */ + slist = session_get_byuser(NULL, &scount, SESMAN_SESSION_STATUS_ALL); + LOG_DBG("sessions on TS: %d (slist: %x)", scount, slist); + + if (0 == slist) + { + // e=scp_v1s_connection_error(c, "Internal error"); + log_message(LOG_LEVEL_INFO, "No sessions on Terminal Server"); + end = 0; + } + else + { + e = scp_v1s_mng_list_sessions(c, s, scount, slist); + g_free(slist); + } + + break; + default: + /* we check the other errors */ + parseCommonStates(e, "scp_v1s_mng_list_sessions()"); + end = 0; + break; } - - break; - default: - /* we check the other errors */ - parseCommonStates(e, "scp_v1s_mng_list_sessions()"); - end = 0; - break; } - } - /* cleanup */ - scp_session_destroy(s); - auth_end(data); + /* cleanup */ + scp_session_destroy(s); + auth_end(data); } -static void parseCommonStates(enum SCP_SERVER_STATES_E e, char* f) +static void parseCommonStates(enum SCP_SERVER_STATES_E e, char *f) { - switch (e) - { - case SCP_SERVER_STATE_VERSION_ERR: - LOG_DBG("version error") - case SCP_SERVER_STATE_SIZE_ERR: - /* an unknown scp version was requested, so we shut down the */ - /* connection (and log the fact) */ - log_message(LOG_LEVEL_WARNING, - "protocol violation. connection closed."); - break; - case SCP_SERVER_STATE_NETWORK_ERR: - log_message(LOG_LEVEL_WARNING, "libscp network error."); - break; - case SCP_SERVER_STATE_SEQUENCE_ERR: - log_message(LOG_LEVEL_WARNING, "libscp sequence error."); - break; - case SCP_SERVER_STATE_INTERNAL_ERR: - /* internal error occurred (eg. malloc() error, ecc.) */ - log_message(LOG_LEVEL_ERROR, "libscp internal error occurred."); - break; - default: - /* dummy: scp_v1s_request_password won't generate any other */ - /* error other than the ones before */ - log_message(LOG_LEVEL_ALWAYS, "unknown return from %s", f); - break; - } + switch (e) + { + case SCP_SERVER_STATE_VERSION_ERR: + LOG_DBG("version error") + case SCP_SERVER_STATE_SIZE_ERR: + /* an unknown scp version was requested, so we shut down the */ + /* connection (and log the fact) */ + log_message(LOG_LEVEL_WARNING, + "protocol violation. connection closed."); + break; + case SCP_SERVER_STATE_NETWORK_ERR: + log_message(LOG_LEVEL_WARNING, "libscp network error."); + break; + case SCP_SERVER_STATE_SEQUENCE_ERR: + log_message(LOG_LEVEL_WARNING, "libscp sequence error."); + break; + case SCP_SERVER_STATE_INTERNAL_ERR: + /* internal error occurred (eg. malloc() error, ecc.) */ + log_message(LOG_LEVEL_ERROR, "libscp internal error occurred."); + break; + default: + /* dummy: scp_v1s_request_password won't generate any other */ + /* error other than the ones before */ + log_message(LOG_LEVEL_ALWAYS, "unknown return from %s", f); + break; + } } diff --git a/sesman/scp_v1_mng.h b/sesman/scp_v1_mng.h index d4ef88ae..0317ba5f 100644 --- a/sesman/scp_v1_mng.h +++ b/sesman/scp_v1_mng.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2008 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * diff --git a/sesman/sesman.c b/sesman/sesman.c index b882c49d..50652b37 100644 --- a/sesman/sesman.c +++ b/sesman/sesman.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2008 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -30,7 +29,7 @@ int g_sck; int g_pid; unsigned char g_fixedkey[8] = { 23, 82, 107, 6, 35, 78, 88, 7 }; -struct config_sesman* g_cfg; /* defined in config.h */ +struct config_sesman *g_cfg; /* defined in config.h */ tbus g_term_event = 0; tbus g_sync_event = 0; @@ -46,325 +45,346 @@ extern int g_thread_sck; /* in thread.c */ static void DEFAULT_CC sesman_main_loop(void) { - int in_sck; - int error; - int robjs_count; - int cont; - tbus sck_obj; - tbus robjs[8]; - - /*main program loop*/ - log_message(LOG_LEVEL_INFO, "listening..."); - g_sck = g_tcp_socket(); - g_tcp_set_non_blocking(g_sck); - error = scp_tcp_bind(g_sck, g_cfg->listen_address, g_cfg->listen_port); - if (error == 0) - { - error = g_tcp_listen(g_sck); + int in_sck; + int error; + int robjs_count; + int cont; + tbus sck_obj; + tbus robjs[8]; + + /*main program loop*/ + log_message(LOG_LEVEL_INFO, "listening..."); + g_sck = g_tcp_socket(); + g_tcp_set_non_blocking(g_sck); + error = scp_tcp_bind(g_sck, g_cfg->listen_address, g_cfg->listen_port); + if (error == 0) { - sck_obj = g_create_wait_obj_from_socket(g_sck, 0); - cont = 1; - while (cont) - { - /* build the wait obj list */ - robjs_count = 0; - robjs[robjs_count++] = sck_obj; - robjs[robjs_count++] = g_term_event; - robjs[robjs_count++] = g_sync_event; - /* wait */ - if (g_obj_wait(robjs, robjs_count, 0, 0, -1) != 0) - { - /* error, should not get here */ - g_sleep(100); - } - if (g_is_wait_obj_set(g_term_event)) /* term */ - { - break; - } - if (g_is_wait_obj_set(g_sync_event)) /* sync */ + error = g_tcp_listen(g_sck); + + if (error == 0) { - g_reset_wait_obj(g_sync_event); - session_sync_start(); + sck_obj = g_create_wait_obj_from_socket(g_sck, 0); + cont = 1; + + while (cont) + { + /* build the wait obj list */ + robjs_count = 0; + robjs[robjs_count++] = sck_obj; + robjs[robjs_count++] = g_term_event; + robjs[robjs_count++] = g_sync_event; + + /* wait */ + if (g_obj_wait(robjs, robjs_count, 0, 0, -1) != 0) + { + /* error, should not get here */ + g_sleep(100); + } + + if (g_is_wait_obj_set(g_term_event)) /* term */ + { + break; + } + + if (g_is_wait_obj_set(g_sync_event)) /* sync */ + { + g_reset_wait_obj(g_sync_event); + session_sync_start(); + } + + if (g_is_wait_obj_set(sck_obj)) /* incoming connection */ + { + in_sck = g_tcp_accept(g_sck); + + if ((in_sck == -1) && g_tcp_last_error_would_block(g_sck)) + { + /* should not get here */ + g_sleep(100); + } + else if (in_sck == -1) + { + /* error, should not get here */ + break; + } + else + { + /* we've got a connection, so we pass it to scp code */ + LOG_DBG("new connection"); + thread_scp_start(in_sck); + /* todo, do we have to wait here ? */ + } + } + } + + g_delete_wait_obj_from_socket(sck_obj); } - if (g_is_wait_obj_set(sck_obj)) /* incoming connection */ + else { - in_sck = g_tcp_accept(g_sck); - if ((in_sck == -1) && g_tcp_last_error_would_block(g_sck)) - { - /* should not get here */ - g_sleep(100); - } - else if (in_sck == -1) - { - /* error, should not get here */ - break; - } - else - { - /* we've got a connection, so we pass it to scp code */ - LOG_DBG("new connection"); - thread_scp_start(in_sck); - /* todo, do we have to wait here ? */ - } + log_message(LOG_LEVEL_ERROR, "listen error %d (%s)", + g_get_errno(), g_get_strerror()); } - } - g_delete_wait_obj_from_socket(sck_obj); } else { - log_message(LOG_LEVEL_ERROR, "listen error %d (%s)", - g_get_errno(), g_get_strerror()); + log_message(LOG_LEVEL_ERROR, "bind error on " + "port '%s': %d (%s)", g_cfg->listen_port, + g_get_errno(), g_get_strerror()); } - } - else - { - log_message(LOG_LEVEL_ERROR, "bind error on " - "port '%s': %d (%s)", g_cfg->listen_port, - g_get_errno(), g_get_strerror()); - } - g_tcp_close(g_sck); + + g_tcp_close(g_sck); } /******************************************************************************/ int DEFAULT_CC -main(int argc, char** argv) +main(int argc, char **argv) { - int fd; - enum logReturns error; - int daemon = 1; - int pid; - char pid_s[8]; - char text[256]; - char pid_file[256]; - char cfg_file[256]; - - g_init("xrdp-sesman"); - g_snprintf(pid_file, 255, "%s/xrdp-sesman.pid", XRDP_PID_PATH); - if (1 == argc) - { - /* no options on command line. normal startup */ - g_printf("starting sesman...\n"); - daemon = 1; - } - else if ((2 == argc) && ((0 == g_strcasecmp(argv[1], "--nodaemon")) || - (0 == g_strcasecmp(argv[1], "-nodaemon")) || - (0 == g_strcasecmp(argv[1], "-n")) || - (0 == g_strcasecmp(argv[1], "-ns")))) - { - /* starts sesman not daemonized */ - g_printf("starting sesman in foregroud...\n"); - daemon = 0; - } - else if ((2 == argc) && ((0 == g_strcasecmp(argv[1], "--help")) || - (0 == g_strcasecmp(argv[1], "-help")) || - (0 == g_strcasecmp(argv[1], "-h")))) - { - /* help screen */ - g_printf("sesman - xrdp session manager\n\n"); - g_printf("usage: sesman [command]\n\n"); - g_printf("command can be one of the following:\n"); - g_printf("-n, -ns, --nodaemon starts sesman in foreground\n"); - g_printf("-k, --kill kills running sesman\n"); - g_printf("-h, --help shows this help\n"); - g_printf("if no command is specified, sesman is started in background"); - g_deinit(); - g_exit(0); - } - else if ((2 == argc) && ((0 == g_strcasecmp(argv[1], "--kill")) || - (0 == g_strcasecmp(argv[1], "-kill")) || - (0 == g_strcasecmp(argv[1], "-k")))) - { - /* killing running sesman */ - /* check if sesman is running */ - if (!g_file_exist(pid_file)) + int fd; + enum logReturns error; + int daemon = 1; + int pid; + char pid_s[8]; + char text[256]; + char pid_file[256]; + char cfg_file[256]; + + g_init("xrdp-sesman"); + g_snprintf(pid_file, 255, "%s/xrdp-sesman.pid", XRDP_PID_PATH); + + if (1 == argc) + { + /* no options on command line. normal startup */ + g_printf("starting sesman...\n"); + daemon = 1; + } + else if ((2 == argc) && ((0 == g_strcasecmp(argv[1], "--nodaemon")) || + (0 == g_strcasecmp(argv[1], "-nodaemon")) || + (0 == g_strcasecmp(argv[1], "-n")) || + (0 == g_strcasecmp(argv[1], "-ns")))) + { + /* starts sesman not daemonized */ + g_printf("starting sesman in foregroud...\n"); + daemon = 0; + } + else if ((2 == argc) && ((0 == g_strcasecmp(argv[1], "--help")) || + (0 == g_strcasecmp(argv[1], "-help")) || + (0 == g_strcasecmp(argv[1], "-h")))) { - g_printf("sesman is not running (pid file not found - %s)\n", pid_file); - g_deinit(); - g_exit(1); + /* help screen */ + g_printf("sesman - xrdp session manager\n\n"); + g_printf("usage: sesman [command]\n\n"); + g_printf("command can be one of the following:\n"); + g_printf("-n, -ns, --nodaemon starts sesman in foreground\n"); + g_printf("-k, --kill kills running sesman\n"); + g_printf("-h, --help shows this help\n"); + g_printf("if no command is specified, sesman is started in background"); + g_deinit(); + g_exit(0); } + else if ((2 == argc) && ((0 == g_strcasecmp(argv[1], "--kill")) || + (0 == g_strcasecmp(argv[1], "-kill")) || + (0 == g_strcasecmp(argv[1], "-k")))) + { + /* killing running sesman */ + /* check if sesman is running */ + if (!g_file_exist(pid_file)) + { + g_printf("sesman is not running (pid file not found - %s)\n", pid_file); + g_deinit(); + g_exit(1); + } + + fd = g_file_open(pid_file); + + if (-1 == fd) + { + g_printf("error opening pid file[%s]: %s\n", pid_file, g_get_strerror()); + return 1; + } + + error = g_file_read(fd, pid_s, 7); + + if (-1 == error) + { + g_printf("error reading pid file: %s\n", g_get_strerror()); + g_file_close(fd); + g_deinit(); + g_exit(error); + } + + g_file_close(fd); + pid = g_atoi(pid_s); - fd = g_file_open(pid_file); + error = g_sigterm(pid); + + if (0 != error) + { + g_printf("error killing sesman: %s\n", g_get_strerror()); + } + else + { + g_file_delete(pid_file); + } - if (-1 == fd) + g_deinit(); + g_exit(error); + } + else { - g_printf("error opening pid file[%s]: %s\n", pid_file, g_get_strerror()); - return 1; + /* there's something strange on the command line */ + g_printf("sesman - xrdp session manager\n\n"); + g_printf("error: invalid command line\n"); + g_printf("usage: sesman [ --nodaemon | --kill | --help ]\n"); + g_deinit(); + g_exit(1); } - error = g_file_read(fd, pid_s, 7); - if (-1 == error) + if (g_file_exist(pid_file)) { - g_printf("error reading pid file: %s\n", g_get_strerror()); - g_file_close(fd); - g_deinit(); - g_exit(error); + g_printf("sesman is already running.\n"); + g_printf("if it's not running, try removing "); + g_printf(pid_file); + g_printf("\n"); + g_deinit(); + g_exit(1); } - g_file_close(fd); - pid = g_atoi(pid_s); - error = g_sigterm(pid); - if (0 != error) + /* reading config */ + g_cfg = g_malloc(sizeof(struct config_sesman), 1); + + if (0 == g_cfg) { - g_printf("error killing sesman: %s\n", g_get_strerror()); + g_printf("error creating config: quitting.\n"); + g_deinit(); + g_exit(1); } - else + + //g_cfg->log.fd = -1; /* don't use logging before reading its config */ + if (0 != config_read(g_cfg)) { - g_file_delete(pid_file); + g_printf("error reading config: %s\nquitting.\n", g_get_strerror()); + g_deinit(); + g_exit(1); } - g_deinit(); - g_exit(error); - } - else - { - /* there's something strange on the command line */ - g_printf("sesman - xrdp session manager\n\n"); - g_printf("error: invalid command line\n"); - g_printf("usage: sesman [ --nodaemon | --kill | --help ]\n"); - g_deinit(); - g_exit(1); - } - - if (g_file_exist(pid_file)) - { - g_printf("sesman is already running.\n"); - g_printf("if it's not running, try removing "); - g_printf(pid_file); - g_printf("\n"); - g_deinit(); - g_exit(1); - } - - /* reading config */ - g_cfg = g_malloc(sizeof(struct config_sesman), 1); - if (0 == g_cfg) - { - g_printf("error creating config: quitting.\n"); - g_deinit(); - g_exit(1); - } - //g_cfg->log.fd = -1; /* don't use logging before reading its config */ - if (0 != config_read(g_cfg)) - { - g_printf("error reading config: %s\nquitting.\n", g_get_strerror()); - g_deinit(); - g_exit(1); - } - g_snprintf(cfg_file,255,"%s/sesman.ini",XRDP_CFG_PATH); + g_snprintf(cfg_file, 255, "%s/sesman.ini", XRDP_CFG_PATH); - /* starting logging subsystem */ - error = log_start(cfg_file,"XRDP-sesman"); + /* starting logging subsystem */ + error = log_start(cfg_file, "XRDP-sesman"); - if (error != LOG_STARTUP_OK) - { - switch (error) + if (error != LOG_STARTUP_OK) { - case LOG_ERROR_MALLOC: - g_writeln("error on malloc. cannot start logging. quitting."); - break; - case LOG_ERROR_FILE_OPEN: - g_writeln("error opening log file [%s]. quitting.", - getLogFile(text, 255)); - break; - } - g_deinit(); - g_exit(1); - } + switch (error) + { + case LOG_ERROR_MALLOC: + g_writeln("error on malloc. cannot start logging. quitting."); + break; + case LOG_ERROR_FILE_OPEN: + g_writeln("error opening log file [%s]. quitting.", + getLogFile(text, 255)); + break; + } - /* libscp initialization */ - scp_init(); + g_deinit(); + g_exit(1); + } - if (daemon) - { - /* start of daemonizing code */ - g_pid = g_fork(); + /* libscp initialization */ + scp_init(); - if (0 != g_pid) + if (daemon) { - g_deinit(); - g_exit(0); + /* start of daemonizing code */ + g_pid = g_fork(); + + if (0 != g_pid) + { + g_deinit(); + g_exit(0); + } + + g_file_close(0); + g_file_close(1); + g_file_close(2); + + g_file_open("/dev/null"); + g_file_open("/dev/null"); + g_file_open("/dev/null"); } - g_file_close(0); - g_file_close(1); - g_file_close(2); - - g_file_open("/dev/null"); - g_file_open("/dev/null"); - g_file_open("/dev/null"); - } - - /* initializing locks */ - lock_init(); - - /* signal handling */ - g_pid = g_getpid(); - /* old style signal handling is now managed synchronously by a - * separate thread. uncomment this block if you need old style - * signal handling and comment out thread_sighandler_start() - * going back to old style for the time being - * problem with the sigaddset functions in sig.c - jts */ + /* initializing locks */ + lock_init(); + + /* signal handling */ + g_pid = g_getpid(); + /* old style signal handling is now managed synchronously by a + * separate thread. uncomment this block if you need old style + * signal handling and comment out thread_sighandler_start() + * going back to old style for the time being + * problem with the sigaddset functions in sig.c - jts */ #if 1 - g_signal_hang_up(sig_sesman_reload_cfg); /* SIGHUP */ - g_signal_user_interrupt(sig_sesman_shutdown); /* SIGINT */ - g_signal_kill(sig_sesman_shutdown); /* SIGKILL */ - g_signal_terminate(sig_sesman_shutdown); /* SIGTERM */ - g_signal_child_stop(sig_sesman_session_end); /* SIGCHLD */ + g_signal_hang_up(sig_sesman_reload_cfg); /* SIGHUP */ + g_signal_user_interrupt(sig_sesman_shutdown); /* SIGINT */ + g_signal_kill(sig_sesman_shutdown); /* SIGKILL */ + g_signal_terminate(sig_sesman_shutdown); /* SIGTERM */ + g_signal_child_stop(sig_sesman_session_end); /* SIGCHLD */ #endif #if 0 - thread_sighandler_start(); + thread_sighandler_start(); #endif - if (daemon) - { - /* writing pid file */ - fd = g_file_open(pid_file); - if (-1 == fd) + + if (daemon) { - log_message(LOG_LEVEL_ERROR, - "error opening pid file[%s]: %s", - pid_file, g_get_strerror()); - log_end(); - g_deinit(); - g_exit(1); + /* writing pid file */ + fd = g_file_open(pid_file); + + if (-1 == fd) + { + log_message(LOG_LEVEL_ERROR, + "error opening pid file[%s]: %s", + pid_file, g_get_strerror()); + log_end(); + g_deinit(); + g_exit(1); + } + + g_sprintf(pid_s, "%d", g_pid); + g_file_write(fd, pid_s, g_strlen(pid_s)); + g_file_close(fd); + } + + /* start program main loop */ + log_message(LOG_LEVEL_ALWAYS, + "starting sesman with pid %d", g_pid); + + /* make sure the /tmp/.X11-unix directory exist */ + if (!g_directory_exist("/tmp/.X11-unix")) + { + g_create_dir("/tmp/.X11-unix"); + g_chmod_hex("/tmp/.X11-unix", 0x1777); } - g_sprintf(pid_s, "%d", g_pid); - g_file_write(fd, pid_s, g_strlen(pid_s)); - g_file_close(fd); - } - - /* start program main loop */ - log_message(LOG_LEVEL_ALWAYS, - "starting sesman with pid %d", g_pid); - - /* make sure the /tmp/.X11-unix directory exist */ - if (!g_directory_exist("/tmp/.X11-unix")) - { - g_create_dir("/tmp/.X11-unix"); - g_chmod_hex("/tmp/.X11-unix", 0x1777); - } - - g_snprintf(text, 255, "xrdp_sesman_%8.8x_main_term", g_pid); - g_term_event = g_create_wait_obj(text); - g_snprintf(text, 255, "xrdp_sesman_%8.8x_main_sync", g_pid); - g_sync_event = g_create_wait_obj(text); - - sesman_main_loop(); - - /* clean up PID file on exit */ - if (daemon) - { - g_file_delete(pid_file); - } - - g_delete_wait_obj(g_term_event); - g_delete_wait_obj(g_sync_event); - - if (!daemon) - { - log_end(); - } - - g_deinit(); - return 0; + + g_snprintf(text, 255, "xrdp_sesman_%8.8x_main_term", g_pid); + g_term_event = g_create_wait_obj(text); + g_snprintf(text, 255, "xrdp_sesman_%8.8x_main_sync", g_pid); + g_sync_event = g_create_wait_obj(text); + + sesman_main_loop(); + + /* clean up PID file on exit */ + if (daemon) + { + g_file_delete(pid_file); + } + + g_delete_wait_obj(g_term_event); + g_delete_wait_obj(g_sync_event); + + if (!daemon) + { + log_end(); + } + + g_deinit(); + return 0; } diff --git a/sesman/sesman.h b/sesman/sesman.h index 0344ccd5..2eb70df9 100644 --- a/sesman/sesman.h +++ b/sesman/sesman.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2008 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * diff --git a/sesman/session.c b/sesman/session.c index 94c5bf91..6f98fbc7 100644 --- a/sesman/session.c +++ b/sesman/session.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2008 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -33,19 +32,19 @@ extern tbus g_sync_event; extern unsigned char g_fixedkey[8]; -extern struct config_sesman* g_cfg; /* in sesman.c */ -struct session_chain* g_sessions; +extern struct config_sesman *g_cfg; /* in sesman.c */ +struct session_chain *g_sessions; int g_session_count; static int g_sync_width; static int g_sync_height; static int g_sync_bpp; -static char* g_sync_username; -static char* g_sync_password; -static char* g_sync_domain; -static char* g_sync_program; -static char* g_sync_directory; -static char* g_sync_client_ip; +static char *g_sync_username; +static char *g_sync_password; +static char *g_sync_domain; +static char *g_sync_program; +static char *g_sync_directory; +static char *g_sync_client_ip; static tbus g_sync_data; static tui8 g_sync_type; static int g_sync_result; @@ -58,87 +57,92 @@ static int g_sync_cmd; * @param len the allocated len for outstr * @return */ -char* APP_CC -dumpItemsToString(struct list* self, char *outstr, int len) +char *APP_CC +dumpItemsToString(struct list *self, char *outstr, int len) { - g_memset(outstr,0,len); - int index; - tbus item; - int totalLen= 0; - - if (self->count == 0) - { - g_writeln("List is empty"); - } - for (index = 0; index < self->count; index++) - { - /* +1 = one space*/ - totalLen = totalLen + g_strlen((char*)list_get_item(self, index))+1; - if(len>totalLen) - { - g_strcat(outstr,(char*)list_get_item(self, index)); - g_strcat(outstr," "); - } - } - return outstr ; + g_memset(outstr, 0, len); + int index; + tbus item; + int totalLen = 0; + + if (self->count == 0) + { + g_writeln("List is empty"); + } + + for (index = 0; index < self->count; index++) + { + /* +1 = one space*/ + totalLen = totalLen + g_strlen((char *)list_get_item(self, index)) + 1; + + if (len > totalLen) + { + g_strcat(outstr, (char *)list_get_item(self, index)); + g_strcat(outstr, " "); + } + } + + return outstr ; } /******************************************************************************/ -struct session_item* DEFAULT_CC -session_get_bydata(char* name, int width, int height, int bpp, int type) +struct session_item *DEFAULT_CC +session_get_bydata(char *name, int width, int height, int bpp, int type) { - struct session_chain* tmp; - - /*THREAD-FIX require chain lock */ - lock_chain_acquire(); - - tmp = g_sessions; - - /* convert from SCP_SESSION_TYPE namespace to SESMAN_SESSION_TYPE namespace */ - switch (type) - { - case SCP_SESSION_TYPE_XVNC: /* 0 */ - type = SESMAN_SESSION_TYPE_XVNC; /* 2 */ - break; - case SCP_SESSION_TYPE_XRDP: /* 1 */ - type = SESMAN_SESSION_TYPE_XRDP; /* 1 */ - break; - default: - lock_chain_release(); - return 0; - } - - while (tmp != 0) - { - if (type == SESMAN_SESSION_TYPE_XRDP) - { - /* only name and bpp need to match for X11rdp, it can resize */ - if (g_strncmp(name, tmp->item->name, 255) == 0 && - tmp->item->bpp == bpp && - tmp->item->type == type) - { - /*THREAD-FIX release chain lock */ - lock_chain_release(); - return tmp->item; - } + struct session_chain *tmp; + + /*THREAD-FIX require chain lock */ + lock_chain_acquire(); + + tmp = g_sessions; + + /* convert from SCP_SESSION_TYPE namespace to SESMAN_SESSION_TYPE namespace */ + switch (type) + { + case SCP_SESSION_TYPE_XVNC: /* 0 */ + type = SESMAN_SESSION_TYPE_XVNC; /* 2 */ + break; + case SCP_SESSION_TYPE_XRDP: /* 1 */ + type = SESMAN_SESSION_TYPE_XRDP; /* 1 */ + break; + default: + lock_chain_release(); + return 0; } - if (g_strncmp(name, tmp->item->name, 255) == 0 && - tmp->item->width == width && - tmp->item->height == height && - tmp->item->bpp == bpp && - tmp->item->type == type) + + while (tmp != 0) { - /*THREAD-FIX release chain lock */ - lock_chain_release(); - return tmp->item; + if (type == SESMAN_SESSION_TYPE_XRDP) + { + /* only name and bpp need to match for X11rdp, it can resize */ + if (g_strncmp(name, tmp->item->name, 255) == 0 && + tmp->item->bpp == bpp && + tmp->item->type == type) + { + /*THREAD-FIX release chain lock */ + lock_chain_release(); + return tmp->item; + } + } + + if (g_strncmp(name, tmp->item->name, 255) == 0 && + tmp->item->width == width && + tmp->item->height == height && + tmp->item->bpp == bpp && + tmp->item->type == type) + { + /*THREAD-FIX release chain lock */ + lock_chain_release(); + return tmp->item; + } + + tmp = tmp->next; } - tmp = tmp->next; - } - /*THREAD-FIX release chain lock */ - lock_chain_release(); - return 0; + /*THREAD-FIX release chain lock */ + lock_chain_release(); + return 0; } /******************************************************************************/ @@ -152,39 +156,44 @@ session_get_bydata(char* name, int width, int height, int bpp, int type) static int DEFAULT_CC x_server_running_check_ports(int display) { - char text[256]; - int x_running; - int sck; - - g_sprintf(text, "/tmp/.X11-unix/X%d", display); - x_running = g_file_exist(text); - if (!x_running) - { - g_sprintf(text, "/tmp/.X%d-lock", display); + char text[256]; + int x_running; + int sck; + + g_sprintf(text, "/tmp/.X11-unix/X%d", display); x_running = g_file_exist(text); - } - if (!x_running) /* check 59xx */ - { - sck = g_tcp_socket(); - g_sprintf(text, "59%2.2d", display); - x_running = g_tcp_bind(sck, text); - g_tcp_close(sck); - } - if (!x_running) /* check 60xx */ - { - sck = g_tcp_socket(); - g_sprintf(text, "60%2.2d", display); - x_running = g_tcp_bind(sck, text); - g_tcp_close(sck); - } - if (!x_running) /* check 62xx */ - { - sck = g_tcp_socket(); - g_sprintf(text, "62%2.2d", display); - x_running = g_tcp_bind(sck, text); - g_tcp_close(sck); - } - return x_running; + + if (!x_running) + { + g_sprintf(text, "/tmp/.X%d-lock", display); + x_running = g_file_exist(text); + } + + if (!x_running) /* check 59xx */ + { + sck = g_tcp_socket(); + g_sprintf(text, "59%2.2d", display); + x_running = g_tcp_bind(sck, text); + g_tcp_close(sck); + } + + if (!x_running) /* check 60xx */ + { + sck = g_tcp_socket(); + g_sprintf(text, "60%2.2d", display); + x_running = g_tcp_bind(sck, text); + g_tcp_close(sck); + } + + if (!x_running) /* check 62xx */ + { + sck = g_tcp_socket(); + g_sprintf(text, "62%2.2d", display); + x_running = g_tcp_bind(sck, text); + g_tcp_close(sck); + } + + return x_running; } /******************************************************************************/ @@ -198,83 +207,87 @@ x_server_running_check_ports(int display) static int DEFAULT_CC x_server_running(int display) { - char text[256]; - int x_running; - int sck; - - g_sprintf(text, "/tmp/.X11-unix/X%d", display); - x_running = g_file_exist(text); - if (!x_running) - { - g_sprintf(text, "/tmp/.X%d-lock", display); + char text[256]; + int x_running; + int sck; + + g_sprintf(text, "/tmp/.X11-unix/X%d", display); x_running = g_file_exist(text); - } - return x_running; + + if (!x_running) + { + g_sprintf(text, "/tmp/.X%d-lock", display); + x_running = g_file_exist(text); + } + + return x_running; } /******************************************************************************/ static void DEFAULT_CC -session_start_sessvc(int xpid, int wmpid, long data, char* username, int display) +session_start_sessvc(int xpid, int wmpid, long data, char *username, int display) { - struct list * sessvc_params = (struct list *)NULL; - char wmpid_str[25]; - char xpid_str[25]; - char exe_path[262]; - int i = 0; - - /* initialize (zero out) local variables: */ - g_memset(wmpid_str,0,sizeof(char) * 25); - g_memset(xpid_str,0,sizeof(char) * 25); - g_memset(exe_path,0,sizeof(char) * 262); - - /* new style waiting for clients */ - g_sprintf(wmpid_str, "%d", wmpid); - g_sprintf(xpid_str, "%d", xpid); - log_message(LOG_LEVEL_INFO, - "starting xrdp-sessvc - xpid=%s - wmpid=%s", - xpid_str, wmpid_str); - - sessvc_params = list_create(); - sessvc_params->auto_free = 1; - - /* building parameters */ - g_snprintf(exe_path, 261, "%s/xrdp-sessvc", XRDP_SBIN_PATH); - - list_add_item(sessvc_params, (long)g_strdup(exe_path)); - list_add_item(sessvc_params, (long)g_strdup(xpid_str)); - list_add_item(sessvc_params, (long)g_strdup(wmpid_str)); - list_add_item(sessvc_params, 0); /* mandatory */ - - env_set_user(username, 0, display); - - /* executing sessvc */ - g_execvp(exe_path, ((char**)sessvc_params->items)); - - /* should not get here */ - log_message(LOG_LEVEL_ALWAYS, - "error starting xrdp-sessvc - pid %d - xpid=%s - wmpid=%s", - g_getpid(), xpid_str, wmpid_str); - - /* logging parameters */ - /* no problem calling strerror for thread safety: other threads - are blocked */ - log_message(LOG_LEVEL_DEBUG, "errno: %d, description: %s", - errno, g_get_strerror()); - log_message(LOG_LEVEL_DEBUG, "execve parameter list:"); - for (i = 0; i < (sessvc_params->count); i++) - { - log_message(LOG_LEVEL_DEBUG, " argv[%d] = %s", i, - (char*)list_get_item(sessvc_params, i)); - } - list_delete(sessvc_params); - - /* keep the old waitpid if some error occurs during execlp */ - g_waitpid(wmpid); - g_sigterm(xpid); - g_sigterm(wmpid); - g_sleep(1000); - auth_end(data); - g_exit(0); + struct list *sessvc_params = (struct list *)NULL; + char wmpid_str[25]; + char xpid_str[25]; + char exe_path[262]; + int i = 0; + + /* initialize (zero out) local variables: */ + g_memset(wmpid_str, 0, sizeof(char) * 25); + g_memset(xpid_str, 0, sizeof(char) * 25); + g_memset(exe_path, 0, sizeof(char) * 262); + + /* new style waiting for clients */ + g_sprintf(wmpid_str, "%d", wmpid); + g_sprintf(xpid_str, "%d", xpid); + log_message(LOG_LEVEL_INFO, + "starting xrdp-sessvc - xpid=%s - wmpid=%s", + xpid_str, wmpid_str); + + sessvc_params = list_create(); + sessvc_params->auto_free = 1; + + /* building parameters */ + g_snprintf(exe_path, 261, "%s/xrdp-sessvc", XRDP_SBIN_PATH); + + list_add_item(sessvc_params, (long)g_strdup(exe_path)); + list_add_item(sessvc_params, (long)g_strdup(xpid_str)); + list_add_item(sessvc_params, (long)g_strdup(wmpid_str)); + list_add_item(sessvc_params, 0); /* mandatory */ + + env_set_user(username, 0, display); + + /* executing sessvc */ + g_execvp(exe_path, ((char **)sessvc_params->items)); + + /* should not get here */ + log_message(LOG_LEVEL_ALWAYS, + "error starting xrdp-sessvc - pid %d - xpid=%s - wmpid=%s", + g_getpid(), xpid_str, wmpid_str); + + /* logging parameters */ + /* no problem calling strerror for thread safety: other threads + are blocked */ + log_message(LOG_LEVEL_DEBUG, "errno: %d, description: %s", + errno, g_get_strerror()); + log_message(LOG_LEVEL_DEBUG, "execve parameter list:"); + + for (i = 0; i < (sessvc_params->count); i++) + { + log_message(LOG_LEVEL_DEBUG, " argv[%d] = %s", i, + (char *)list_get_item(sessvc_params, i)); + } + + list_delete(sessvc_params); + + /* keep the old waitpid if some error occurs during execlp */ + g_waitpid(wmpid); + g_sigterm(xpid); + g_sigterm(wmpid); + g_sleep(1000); + auth_end(data); + g_exit(0); } /******************************************************************************/ @@ -283,20 +296,24 @@ session_start_sessvc(int xpid, int wmpid, long data, char* username, int display static int APP_CC session_is_display_in_chain(int display) { - struct session_chain* chain; - struct session_item* item; + struct session_chain *chain; + struct session_item *item; - chain = g_sessions; - while (chain != 0) - { - item = chain->item; - if (item->display == display) + chain = g_sessions; + + while (chain != 0) { - return 1; + item = chain->item; + + if (item->display == display) + { + return 1; + } + + chain = chain->next; } - chain = chain->next; - } - return 0; + + return 0; } /******************************************************************************/ @@ -304,412 +321,442 @@ session_is_display_in_chain(int display) static int APP_CC session_get_aval_display_from_chain(void) { - int display; + int display; - display = g_cfg->sess.x11_display_offset; - lock_chain_acquire(); - while ((display - g_cfg->sess.x11_display_offset) <= g_cfg->sess.max_sessions) - { - if (!session_is_display_in_chain(display)) + display = g_cfg->sess.x11_display_offset; + lock_chain_acquire(); + + while ((display - g_cfg->sess.x11_display_offset) <= g_cfg->sess.max_sessions) { - if (!x_server_running_check_ports(display)) - { - lock_chain_release(); - return display; - } - } - display++; - } - lock_chain_release(); - log_message(LOG_LEVEL_ERROR, "X server -- no display in range is available"); - return 0; + if (!session_is_display_in_chain(display)) + { + if (!x_server_running_check_ports(display)) + { + lock_chain_release(); + return display; + } + } + + display++; + } + + lock_chain_release(); + log_message(LOG_LEVEL_ERROR, "X server -- no display in range is available"); + return 0; } /******************************************************************************/ static int APP_CC wait_for_xserver(int display) { - int i; - - /* give X a bit to start */ - /* wait up to 10 secs for x server to start */ - i = 0; - while (!x_server_running(display)) - { - i++; - if (i > 40) - { - log_message(LOG_LEVEL_ERROR, - "X server for display %d startup timeout", - display); - break; - } - g_sleep(250); - } - return 0; + int i; + + /* give X a bit to start */ + /* wait up to 10 secs for x server to start */ + i = 0; + + while (!x_server_running(display)) + { + i++; + + if (i > 40) + { + log_message(LOG_LEVEL_ERROR, + "X server for display %d startup timeout", + display); + break; + } + + g_sleep(250); + } + + return 0; } /******************************************************************************/ /* called with the main thread */ static int APP_CC -session_start_fork(int width, int height, int bpp, char* username, - char* password, tbus data, tui8 type, char* domain, - char* program, char* directory, char* client_ip) +session_start_fork(int width, int height, int bpp, char *username, + char *password, tbus data, tui8 type, char *domain, + char *program, char *directory, char *client_ip) { - int display = 0; - int pid = 0; - int wmpid = 0; - int xpid = 0; - int i = 0; - char geometry[32]; - char depth[32]; - char screen[32]; - char text[256]; - char passwd_file[256]; - char ** pp1 = (char **)NULL; - struct session_chain * temp = (struct session_chain *)NULL; - struct list * xserver_params = (struct list *)NULL; - time_t ltime; - struct tm stime; - char execvpparams[2048]; - - /* initialize (zero out) local variables: */ - g_memset(<ime,0,sizeof(time_t)); - g_memset(&stime,0,sizeof(struct tm)); - g_memset(geometry,0,sizeof(char) * 32); - g_memset(depth,0,sizeof(char) * 32); - g_memset(screen,0,sizeof(char) * 32); - g_memset(text,0,sizeof(char) * 256); - g_memset(passwd_file,0,sizeof(char) * 256); - - /* check to limit concurrent sessions */ - if (g_session_count >= g_cfg->sess.max_sessions) - { - log_message(LOG_LEVEL_INFO, "max concurrent session limit " - "exceeded. login for user %s denied", username); - return 0; - } + int display = 0; + int pid = 0; + int wmpid = 0; + int xpid = 0; + int i = 0; + char geometry[32]; + char depth[32]; + char screen[32]; + char text[256]; + char passwd_file[256]; + char **pp1 = (char **)NULL; + struct session_chain *temp = (struct session_chain *)NULL; + struct list *xserver_params = (struct list *)NULL; + time_t ltime; + struct tm stime; + char execvpparams[2048]; + + /* initialize (zero out) local variables: */ + g_memset(<ime, 0, sizeof(time_t)); + g_memset(&stime, 0, sizeof(struct tm)); + g_memset(geometry, 0, sizeof(char) * 32); + g_memset(depth, 0, sizeof(char) * 32); + g_memset(screen, 0, sizeof(char) * 32); + g_memset(text, 0, sizeof(char) * 256); + g_memset(passwd_file, 0, sizeof(char) * 256); + + /* check to limit concurrent sessions */ + if (g_session_count >= g_cfg->sess.max_sessions) + { + log_message(LOG_LEVEL_INFO, "max concurrent session limit " + "exceeded. login for user %s denied", username); + return 0; + } - temp = (struct session_chain*)g_malloc(sizeof(struct session_chain), 0); - if (temp == 0) - { - log_message(LOG_LEVEL_ERROR, "cannot create new chain " - "element - user %s", username); - return 0; - } - temp->item = (struct session_item*)g_malloc(sizeof(struct session_item), 0); - if (temp->item == 0) - { - g_free(temp); - log_message(LOG_LEVEL_ERROR, "cannot create new session " - "item - user %s", username); - return 0; - } - display = session_get_aval_display_from_chain(); - if (display == 0) - { - g_free(temp->item); - g_free(temp); - return 0; - } - pid = g_fork(); - if (pid == -1) - { - } - else if (pid == 0) /* child sesman */ - { - auth_start_session(data, display); - g_sprintf(geometry, "%dx%d", width, height); - g_sprintf(depth, "%d", bpp); - g_sprintf(screen, ":%d", display); - wmpid = g_fork(); - if (wmpid == -1) - { - } - else if (wmpid == 0) /* child (child sesman) xserver */ - { - wait_for_xserver(display); - env_set_user(username, 0, display); - if (x_server_running(display)) - { - auth_set_env(data); - if (directory != 0) - { - if (directory[0] != 0) - { - g_set_current_dir(directory); - } - } - if (program != 0) - { - if (program[0] != 0) - { - g_execlp3(program, program, 0); - log_message(LOG_LEVEL_ALWAYS, - "error starting program %s for user %s - pid %d", - program, username, g_getpid()); - } - } - /* try to execute user window manager if enabled */ - if (g_cfg->enable_user_wm) - { - g_sprintf(text,"%s/%s", g_getenv("HOME"), g_cfg->user_wm); - if (g_file_exist(text)) - { - g_execlp3(text, g_cfg->user_wm, 0); - log_message(LOG_LEVEL_ALWAYS,"error starting user " - "wm for user %s - pid %d", username, g_getpid()); - /* logging parameters */ - log_message(LOG_LEVEL_DEBUG, "errno: %d, " - "description: %s", errno, g_get_strerror()); - log_message(LOG_LEVEL_DEBUG,"execlp3 parameter " - "list:"); - log_message(LOG_LEVEL_DEBUG, " argv[0] = %s", - text); - log_message(LOG_LEVEL_DEBUG, " argv[1] = %s", - g_cfg->user_wm); - } - } - /* if we're here something happened to g_execlp3 - so we try running the default window manager */ - g_sprintf(text, "%s/%s", XRDP_CFG_PATH, g_cfg->default_wm); - g_execlp3(text, g_cfg->default_wm, 0); - - log_message( LOG_LEVEL_ALWAYS,"error starting default " - "wm for user %s - pid %d", username, g_getpid()); - /* logging parameters */ - log_message( LOG_LEVEL_DEBUG, "errno: %d, description: " - "%s", errno, g_get_strerror()); - log_message(LOG_LEVEL_DEBUG,"execlp3 parameter list:"); - log_message(LOG_LEVEL_DEBUG, " argv[0] = %s", - text); - log_message(LOG_LEVEL_DEBUG, " argv[1] = %s", - g_cfg->default_wm); - - /* still a problem starting window manager just start xterm */ - g_execlp3("xterm", "xterm", 0); - - /* should not get here */ - log_message(LOG_LEVEL_ALWAYS,"error starting xterm " - "for user %s - pid %d", username, g_getpid()); - /* logging parameters */ - log_message(LOG_LEVEL_DEBUG, "errno: %d, description: " - "%s", errno, g_get_strerror()); - } - else - { - log_message(LOG_LEVEL_ERROR, "another Xserver might " - "already be active on display %d - see log", display); - } - log_message(LOG_LEVEL_DEBUG,"aborting connection..."); - g_exit(0); - } - else /* parent (child sesman) */ - { - xpid = g_fork(); - if (xpid == -1) - { - } - else if (xpid == 0) /* child */ - { - env_set_user(username, passwd_file, display); - env_check_password_file(passwd_file, password); - if (type == SESMAN_SESSION_TYPE_XVNC) + temp = (struct session_chain *)g_malloc(sizeof(struct session_chain), 0); + + if (temp == 0) + { + log_message(LOG_LEVEL_ERROR, "cannot create new chain " + "element - user %s", username); + return 0; + } + + temp->item = (struct session_item *)g_malloc(sizeof(struct session_item), 0); + + if (temp->item == 0) + { + g_free(temp); + log_message(LOG_LEVEL_ERROR, "cannot create new session " + "item - user %s", username); + return 0; + } + + display = session_get_aval_display_from_chain(); + + if (display == 0) + { + g_free(temp->item); + g_free(temp); + return 0; + } + + pid = g_fork(); + + if (pid == -1) + { + } + else if (pid == 0) /* child sesman */ + { + auth_start_session(data, display); + g_sprintf(geometry, "%dx%d", width, height); + g_sprintf(depth, "%d", bpp); + g_sprintf(screen, ":%d", display); + wmpid = g_fork(); + + if (wmpid == -1) { - xserver_params = list_create(); - xserver_params->auto_free = 1; - /* these are the must have parameters */ - list_add_item(xserver_params, (long)g_strdup("Xvnc")); - list_add_item(xserver_params, (long)g_strdup(screen)); - list_add_item(xserver_params, (long)g_strdup("-geometry")); - list_add_item(xserver_params, (long)g_strdup(geometry)); - list_add_item(xserver_params, (long)g_strdup("-depth")); - list_add_item(xserver_params, (long)g_strdup(depth)); - list_add_item(xserver_params, (long)g_strdup("-rfbauth")); - list_add_item(xserver_params, (long)g_strdup(passwd_file)); - - /* additional parameters from sesman.ini file */ - //config_read_xserver_params(SESMAN_SESSION_TYPE_XVNC, - // xserver_params); - list_append_list_strdup(g_cfg->vnc_params, xserver_params, 0); - - /* make sure it ends with a zero */ - list_add_item(xserver_params, 0); - pp1 = (char**)xserver_params->items; - log_message(LOG_LEVEL_INFO,"Xvnc start:%s",dumpItemsToString(xserver_params, execvpparams, 2048)); - g_execvp("Xvnc", pp1); } - else if (type == SESMAN_SESSION_TYPE_XRDP) + else if (wmpid == 0) /* child (child sesman) xserver */ { - xserver_params = list_create(); - xserver_params->auto_free = 1; - /* these are the must have parameters */ - list_add_item(xserver_params, (long)g_strdup("X11rdp")); - list_add_item(xserver_params, (long)g_strdup(screen)); - list_add_item(xserver_params, (long)g_strdup("-geometry")); - list_add_item(xserver_params, (long)g_strdup(geometry)); - list_add_item(xserver_params, (long)g_strdup("-depth")); - list_add_item(xserver_params, (long)g_strdup(depth)); - - /* additional parameters from sesman.ini file */ - //config_read_xserver_params(SESMAN_SESSION_TYPE_XRDP, - // xserver_params); - list_append_list_strdup(g_cfg->rdp_params, xserver_params, 0); - - /* make sure it ends with a zero */ - list_add_item(xserver_params, 0); - pp1 = (char**)xserver_params->items; - log_message(LOG_LEVEL_INFO,"X11rdp start:%s",dumpItemsToString(xserver_params, execvpparams, 2048)); - g_execvp("X11rdp", pp1); + wait_for_xserver(display); + env_set_user(username, 0, display); + + if (x_server_running(display)) + { + auth_set_env(data); + + if (directory != 0) + { + if (directory[0] != 0) + { + g_set_current_dir(directory); + } + } + + if (program != 0) + { + if (program[0] != 0) + { + g_execlp3(program, program, 0); + log_message(LOG_LEVEL_ALWAYS, + "error starting program %s for user %s - pid %d", + program, username, g_getpid()); + } + } + + /* try to execute user window manager if enabled */ + if (g_cfg->enable_user_wm) + { + g_sprintf(text, "%s/%s", g_getenv("HOME"), g_cfg->user_wm); + + if (g_file_exist(text)) + { + g_execlp3(text, g_cfg->user_wm, 0); + log_message(LOG_LEVEL_ALWAYS, "error starting user " + "wm for user %s - pid %d", username, g_getpid()); + /* logging parameters */ + log_message(LOG_LEVEL_DEBUG, "errno: %d, " + "description: %s", errno, g_get_strerror()); + log_message(LOG_LEVEL_DEBUG, "execlp3 parameter " + "list:"); + log_message(LOG_LEVEL_DEBUG, " argv[0] = %s", + text); + log_message(LOG_LEVEL_DEBUG, " argv[1] = %s", + g_cfg->user_wm); + } + } + + /* if we're here something happened to g_execlp3 + so we try running the default window manager */ + g_sprintf(text, "%s/%s", XRDP_CFG_PATH, g_cfg->default_wm); + g_execlp3(text, g_cfg->default_wm, 0); + + log_message( LOG_LEVEL_ALWAYS, "error starting default " + "wm for user %s - pid %d", username, g_getpid()); + /* logging parameters */ + log_message( LOG_LEVEL_DEBUG, "errno: %d, description: " + "%s", errno, g_get_strerror()); + log_message(LOG_LEVEL_DEBUG, "execlp3 parameter list:"); + log_message(LOG_LEVEL_DEBUG, " argv[0] = %s", + text); + log_message(LOG_LEVEL_DEBUG, " argv[1] = %s", + g_cfg->default_wm); + + /* still a problem starting window manager just start xterm */ + g_execlp3("xterm", "xterm", 0); + + /* should not get here */ + log_message(LOG_LEVEL_ALWAYS, "error starting xterm " + "for user %s - pid %d", username, g_getpid()); + /* logging parameters */ + log_message(LOG_LEVEL_DEBUG, "errno: %d, description: " + "%s", errno, g_get_strerror()); + } + else + { + log_message(LOG_LEVEL_ERROR, "another Xserver might " + "already be active on display %d - see log", display); + } + + log_message(LOG_LEVEL_DEBUG, "aborting connection..."); + g_exit(0); } - else + else /* parent (child sesman) */ { - log_message(LOG_LEVEL_ALWAYS, "bad session type - " - "user %s - pid %d", username, g_getpid()); - g_exit(1); + xpid = g_fork(); + + if (xpid == -1) + { + } + else if (xpid == 0) /* child */ + { + env_set_user(username, passwd_file, display); + env_check_password_file(passwd_file, password); + + if (type == SESMAN_SESSION_TYPE_XVNC) + { + xserver_params = list_create(); + xserver_params->auto_free = 1; + /* these are the must have parameters */ + list_add_item(xserver_params, (long)g_strdup("Xvnc")); + list_add_item(xserver_params, (long)g_strdup(screen)); + list_add_item(xserver_params, (long)g_strdup("-geometry")); + list_add_item(xserver_params, (long)g_strdup(geometry)); + list_add_item(xserver_params, (long)g_strdup("-depth")); + list_add_item(xserver_params, (long)g_strdup(depth)); + list_add_item(xserver_params, (long)g_strdup("-rfbauth")); + list_add_item(xserver_params, (long)g_strdup(passwd_file)); + + /* additional parameters from sesman.ini file */ + //config_read_xserver_params(SESMAN_SESSION_TYPE_XVNC, + // xserver_params); + list_append_list_strdup(g_cfg->vnc_params, xserver_params, 0); + + /* make sure it ends with a zero */ + list_add_item(xserver_params, 0); + pp1 = (char **)xserver_params->items; + log_message(LOG_LEVEL_INFO, "Xvnc start:%s", dumpItemsToString(xserver_params, execvpparams, 2048)); + g_execvp("Xvnc", pp1); + } + else if (type == SESMAN_SESSION_TYPE_XRDP) + { + xserver_params = list_create(); + xserver_params->auto_free = 1; + /* these are the must have parameters */ + list_add_item(xserver_params, (long)g_strdup("X11rdp")); + list_add_item(xserver_params, (long)g_strdup(screen)); + list_add_item(xserver_params, (long)g_strdup("-geometry")); + list_add_item(xserver_params, (long)g_strdup(geometry)); + list_add_item(xserver_params, (long)g_strdup("-depth")); + list_add_item(xserver_params, (long)g_strdup(depth)); + + /* additional parameters from sesman.ini file */ + //config_read_xserver_params(SESMAN_SESSION_TYPE_XRDP, + // xserver_params); + list_append_list_strdup(g_cfg->rdp_params, xserver_params, 0); + + /* make sure it ends with a zero */ + list_add_item(xserver_params, 0); + pp1 = (char **)xserver_params->items; + log_message(LOG_LEVEL_INFO, "X11rdp start:%s", dumpItemsToString(xserver_params, execvpparams, 2048)); + g_execvp("X11rdp", pp1); + } + else + { + log_message(LOG_LEVEL_ALWAYS, "bad session type - " + "user %s - pid %d", username, g_getpid()); + g_exit(1); + } + + /* should not get here */ + log_message(LOG_LEVEL_ALWAYS, "error starting X server " + "- user %s - pid %d", username, g_getpid()); + + /* logging parameters */ + log_message(LOG_LEVEL_DEBUG, "errno: %d, description: " + "%s", errno, g_get_strerror()); + log_message(LOG_LEVEL_DEBUG, "execve parameter list size: " + "%d", (xserver_params)->count); + + for (i = 0; i < (xserver_params->count); i++) + { + log_message(LOG_LEVEL_DEBUG, " argv[%d] = %s", + i, (char *)list_get_item(xserver_params, i)); + } + + list_delete(xserver_params); + g_exit(1); + } + else /* parent (child sesman)*/ + { + wait_for_xserver(display); + g_snprintf(text, 255, "%d", display); + g_setenv("XRDP_SESSVC_DISPLAY", text, 1); + g_snprintf(text, 255, ":%d.0", display); + g_setenv("DISPLAY", text, 1); + /* new style waiting for clients */ + session_start_sessvc(xpid, wmpid, data, username, display); + } } + } + else /* parent sesman process */ + { + temp->item->pid = pid; + temp->item->display = display; + temp->item->width = width; + temp->item->height = height; + temp->item->bpp = bpp; + temp->item->data = data; + g_strncpy(temp->item->client_ip, client_ip, 255); /* store client ip data */ + g_strncpy(temp->item->name, username, 255); + + ltime = g_time1(); + localtime_r(<ime, &stime); + temp->item->connect_time.year = (tui16)(stime.tm_year + 1900); + temp->item->connect_time.month = (tui8)stime.tm_mon; + temp->item->connect_time.day = (tui8)stime.tm_mday; + temp->item->connect_time.hour = (tui8)stime.tm_hour; + temp->item->connect_time.minute = (tui8)stime.tm_min; + zero_time(&(temp->item->disconnect_time)); + zero_time(&(temp->item->idle_time)); + + temp->item->type = type; + temp->item->status = SESMAN_SESSION_STATUS_ACTIVE; + + temp->next = g_sessions; + g_sessions = temp; + g_session_count++; + } - /* should not get here */ - log_message(LOG_LEVEL_ALWAYS, "error starting X server " - "- user %s - pid %d", username, g_getpid()); - - /* logging parameters */ - log_message(LOG_LEVEL_DEBUG, "errno: %d, description: " - "%s", errno, g_get_strerror()); - log_message(LOG_LEVEL_DEBUG, "execve parameter list size: " - "%d", (xserver_params)->count); - - for (i=0; i<(xserver_params->count); i++) - { - log_message(LOG_LEVEL_DEBUG, " argv[%d] = %s", - i, (char*)list_get_item(xserver_params, i)); - } - list_delete(xserver_params); - g_exit(1); - } - else /* parent (child sesman)*/ - { - wait_for_xserver(display); - g_snprintf(text, 255, "%d", display); - g_setenv("XRDP_SESSVC_DISPLAY", text, 1); - g_snprintf(text, 255, ":%d.0", display); - g_setenv("DISPLAY", text, 1); - /* new style waiting for clients */ - session_start_sessvc(xpid, wmpid, data, username, display); - } - } - } - else /* parent sesman process */ - { - temp->item->pid = pid; - temp->item->display = display; - temp->item->width = width; - temp->item->height = height; - temp->item->bpp = bpp; - temp->item->data = data; - g_strncpy(temp->item->client_ip, client_ip, 255); /* store client ip data */ - g_strncpy(temp->item->name, username, 255); - - ltime = g_time1(); - localtime_r(<ime, &stime); - temp->item->connect_time.year = (tui16)(stime.tm_year + 1900); - temp->item->connect_time.month = (tui8)stime.tm_mon; - temp->item->connect_time.day = (tui8)stime.tm_mday; - temp->item->connect_time.hour = (tui8)stime.tm_hour; - temp->item->connect_time.minute = (tui8)stime.tm_min; - zero_time(&(temp->item->disconnect_time)); - zero_time(&(temp->item->idle_time)); - - temp->item->type=type; - temp->item->status=SESMAN_SESSION_STATUS_ACTIVE; - - temp->next=g_sessions; - g_sessions=temp; - g_session_count++; - } - return display; + return display; } /******************************************************************************/ /* called with the main thread */ static int APP_CC -session_reconnect_fork(int display, char* username) +session_reconnect_fork(int display, char *username) { - int pid; - char text[256]; - - pid = g_fork(); - if (pid == -1) - { - } - else if (pid == 0) - { - env_set_user(username, 0, display); - g_snprintf(text, 255, "%s/%s", XRDP_CFG_PATH, "reconnectwm.sh"); - if (g_file_exist(text)) + int pid; + char text[256]; + + pid = g_fork(); + + if (pid == -1) { - g_execlp3(text, g_cfg->default_wm, 0); } - g_exit(0); - } - return display; + else if (pid == 0) + { + env_set_user(username, 0, display); + g_snprintf(text, 255, "%s/%s", XRDP_CFG_PATH, "reconnectwm.sh"); + + if (g_file_exist(text)) + { + g_execlp3(text, g_cfg->default_wm, 0); + } + + g_exit(0); + } + + return display; } /******************************************************************************/ /* called by a worker thread, ask the main thread to call session_sync_start and wait till done */ int DEFAULT_CC -session_start(int width, int height, int bpp, char* username, char* password, - long data, tui8 type, char* domain, char* program, - char* directory, char* client_ip) +session_start(int width, int height, int bpp, char *username, char *password, + long data, tui8 type, char *domain, char *program, + char *directory, char *client_ip) { - int display; - - /* lock mutex */ - lock_sync_acquire(); - /* set shared vars */ - g_sync_cmd = 0; - g_sync_width = width; - g_sync_height = height; - g_sync_bpp = bpp; - g_sync_username = username; - g_sync_password = password; - g_sync_domain = domain; - g_sync_program = program; - g_sync_directory = directory; - g_sync_client_ip = client_ip; - g_sync_data = data; - g_sync_type = type; - /* set event for main thread to see */ - g_set_wait_obj(g_sync_event); - /* wait for main thread to get done */ - lock_sync_sem_acquire(); - /* read result(display) from shared var */ - display = g_sync_result; - /* unlock mutex */ - lock_sync_release(); - return display; + int display; + + /* lock mutex */ + lock_sync_acquire(); + /* set shared vars */ + g_sync_cmd = 0; + g_sync_width = width; + g_sync_height = height; + g_sync_bpp = bpp; + g_sync_username = username; + g_sync_password = password; + g_sync_domain = domain; + g_sync_program = program; + g_sync_directory = directory; + g_sync_client_ip = client_ip; + g_sync_data = data; + g_sync_type = type; + /* set event for main thread to see */ + g_set_wait_obj(g_sync_event); + /* wait for main thread to get done */ + lock_sync_sem_acquire(); + /* read result(display) from shared var */ + display = g_sync_result; + /* unlock mutex */ + lock_sync_release(); + return display; } /******************************************************************************/ /* called by a worker thread, ask the main thread to call session_sync_start and wait till done */ int DEFAULT_CC -session_reconnect(int display, char* username) +session_reconnect(int display, char *username) { - /* lock mutex */ - lock_sync_acquire(); - /* set shared vars */ - g_sync_cmd = 1; - g_sync_width = display; - g_sync_username = username; - /* set event for main thread to see */ - g_set_wait_obj(g_sync_event); - /* wait for main thread to get done */ - lock_sync_sem_acquire(); - /* unlock mutex */ - lock_sync_release(); - return 0; + /* lock mutex */ + lock_sync_acquire(); + /* set shared vars */ + g_sync_cmd = 1; + g_sync_width = display; + g_sync_username = username; + /* set event for main thread to see */ + g_set_wait_obj(g_sync_event); + /* wait for main thread to get done */ + lock_sync_sem_acquire(); + /* unlock mutex */ + lock_sync_release(); + return 0; } /******************************************************************************/ @@ -717,267 +764,279 @@ session_reconnect(int display, char* username) int APP_CC session_sync_start(void) { - if (g_sync_cmd == 0) - { - g_sync_result = session_start_fork(g_sync_width, g_sync_height, g_sync_bpp, - g_sync_username, g_sync_password, - g_sync_data, g_sync_type, g_sync_domain, - g_sync_program, g_sync_directory, - g_sync_client_ip); - } - else - { - /* g_sync_width is really display */ - g_sync_result = session_reconnect_fork(g_sync_width, g_sync_username); - } - lock_sync_sem_release(); - return 0; + if (g_sync_cmd == 0) + { + g_sync_result = session_start_fork(g_sync_width, g_sync_height, g_sync_bpp, + g_sync_username, g_sync_password, + g_sync_data, g_sync_type, g_sync_domain, + g_sync_program, g_sync_directory, + g_sync_client_ip); + } + else + { + /* g_sync_width is really display */ + g_sync_result = session_reconnect_fork(g_sync_width, g_sync_username); + } + + lock_sync_sem_release(); + return 0; } /******************************************************************************/ int DEFAULT_CC session_kill(int pid) { - struct session_chain* tmp; - struct session_chain* prev; - - /*THREAD-FIX require chain lock */ - lock_chain_acquire(); - - tmp=g_sessions; - prev=0; - - while (tmp != 0) - { - if (tmp->item == 0) - { - log_message(LOG_LEVEL_ERROR, "session descriptor for " - "pid %d is null!", pid); - if (prev == 0) - { - /* prev does no exist, so it's the first element - so we set - g_sessions */ - g_sessions = tmp->next; - } - else - { - prev->next = tmp->next; - } - /*THREAD-FIX release chain lock */ - lock_chain_release(); - return SESMAN_SESSION_KILL_NULLITEM; - } - - if (tmp->item->pid == pid) - { - /* deleting the session */ - log_message(LOG_LEVEL_INFO, "++ terminated session: username %s, display :%d.0, session_pid %d, ip %s", tmp->item->name, tmp->item->display, tmp->item->pid, tmp->item->client_ip); - g_free(tmp->item); - if (prev == 0) - { - /* prev does no exist, so it's the first element - so we set - g_sessions */ - g_sessions = tmp->next; - } - else - { - prev->next = tmp->next; - } - g_free(tmp); - g_session_count--; - /*THREAD-FIX release chain lock */ - lock_chain_release(); - return SESMAN_SESSION_KILL_OK; - } - - /* go on */ - prev = tmp; - tmp=tmp->next; - } - - /*THREAD-FIX release chain lock */ - lock_chain_release(); - return SESMAN_SESSION_KILL_NOTFOUND; + struct session_chain *tmp; + struct session_chain *prev; + + /*THREAD-FIX require chain lock */ + lock_chain_acquire(); + + tmp = g_sessions; + prev = 0; + + while (tmp != 0) + { + if (tmp->item == 0) + { + log_message(LOG_LEVEL_ERROR, "session descriptor for " + "pid %d is null!", pid); + + if (prev == 0) + { + /* prev does no exist, so it's the first element - so we set + g_sessions */ + g_sessions = tmp->next; + } + else + { + prev->next = tmp->next; + } + + /*THREAD-FIX release chain lock */ + lock_chain_release(); + return SESMAN_SESSION_KILL_NULLITEM; + } + + if (tmp->item->pid == pid) + { + /* deleting the session */ + log_message(LOG_LEVEL_INFO, "++ terminated session: username %s, display :%d.0, session_pid %d, ip %s", tmp->item->name, tmp->item->display, tmp->item->pid, tmp->item->client_ip); + g_free(tmp->item); + + if (prev == 0) + { + /* prev does no exist, so it's the first element - so we set + g_sessions */ + g_sessions = tmp->next; + } + else + { + prev->next = tmp->next; + } + + g_free(tmp); + g_session_count--; + /*THREAD-FIX release chain lock */ + lock_chain_release(); + return SESMAN_SESSION_KILL_OK; + } + + /* go on */ + prev = tmp; + tmp = tmp->next; + } + + /*THREAD-FIX release chain lock */ + lock_chain_release(); + return SESMAN_SESSION_KILL_NOTFOUND; } /******************************************************************************/ void DEFAULT_CC session_sigkill_all() { - struct session_chain* tmp; + struct session_chain *tmp; - /*THREAD-FIX require chain lock */ - lock_chain_acquire(); + /*THREAD-FIX require chain lock */ + lock_chain_acquire(); - tmp=g_sessions; + tmp = g_sessions; - while (tmp != 0) - { - if (tmp->item == 0) - { - log_message(LOG_LEVEL_ERROR, "found null session " - "descriptor!"); - } - else + while (tmp != 0) { - g_sigterm(tmp->item->pid); - } + if (tmp->item == 0) + { + log_message(LOG_LEVEL_ERROR, "found null session " + "descriptor!"); + } + else + { + g_sigterm(tmp->item->pid); + } - /* go on */ - tmp=tmp->next; - } + /* go on */ + tmp = tmp->next; + } - /*THREAD-FIX release chain lock */ - lock_chain_release(); + /*THREAD-FIX release chain lock */ + lock_chain_release(); } /******************************************************************************/ -struct session_item* DEFAULT_CC +struct session_item *DEFAULT_CC session_get_bypid(int pid) { - struct session_chain* tmp; - struct session_item* dummy; - - dummy = g_malloc(sizeof(struct session_item), 1); - if (0 == dummy) - { - log_message(LOG_LEVEL_ERROR, "internal error", pid); - return 0; - } + struct session_chain *tmp; + struct session_item *dummy; - /*THREAD-FIX require chain lock */ - lock_chain_acquire(); + dummy = g_malloc(sizeof(struct session_item), 1); - tmp = g_sessions; - while (tmp != 0) - { - if (tmp->item == 0) + if (0 == dummy) { - log_message(LOG_LEVEL_ERROR, "session descriptor for " - "pid %d is null!", pid); - /*THREAD-FIX release chain lock */ - lock_chain_release(); - return 0; + log_message(LOG_LEVEL_ERROR, "internal error", pid); + return 0; } - if (tmp->item->pid == pid) + /*THREAD-FIX require chain lock */ + lock_chain_acquire(); + + tmp = g_sessions; + + while (tmp != 0) { - /*THREAD-FIX release chain lock */ - g_memcpy(dummy, tmp->item, sizeof(struct session_item)); - lock_chain_release(); - /*return tmp->item;*/ - return dummy; - } + if (tmp->item == 0) + { + log_message(LOG_LEVEL_ERROR, "session descriptor for " + "pid %d is null!", pid); + /*THREAD-FIX release chain lock */ + lock_chain_release(); + return 0; + } + + if (tmp->item->pid == pid) + { + /*THREAD-FIX release chain lock */ + g_memcpy(dummy, tmp->item, sizeof(struct session_item)); + lock_chain_release(); + /*return tmp->item;*/ + return dummy; + } - /* go on */ - tmp=tmp->next; - } + /* go on */ + tmp = tmp->next; + } - /*THREAD-FIX release chain lock */ - lock_chain_release(); - return 0; + /*THREAD-FIX release chain lock */ + lock_chain_release(); + return 0; } /******************************************************************************/ -struct SCP_DISCONNECTED_SESSION* -session_get_byuser(char* user, int* cnt, unsigned char flags) +struct SCP_DISCONNECTED_SESSION * +session_get_byuser(char *user, int *cnt, unsigned char flags) { - struct session_chain* tmp; - struct SCP_DISCONNECTED_SESSION* sess; - int count; - int index; - - count = 0; - - /*THREAD-FIX require chain lock */ - lock_chain_acquire(); - - tmp = g_sessions; - while (tmp != 0) - { - LOG_DBG("user: %s", user); - if ((NULL == user) || (!g_strncasecmp(user, tmp->item->name, 256))) - { - LOG_DBG("session_get_byuser: status=%d, flags=%d, " - "result=%d", (tmp->item->status), flags, - ((tmp->item->status) & flags)); - if ((tmp->item->status) & flags) - { - count++; - } - } - - /* go on */ - tmp=tmp->next; - } - - if (count == 0) - { - (*cnt) = 0; - /*THREAD-FIX release chain lock */ - lock_chain_release(); - return 0; - } + struct session_chain *tmp; + struct SCP_DISCONNECTED_SESSION *sess; + int count; + int index; - /* malloc() an array of disconnected sessions */ - sess=g_malloc(count * sizeof(struct SCP_DISCONNECTED_SESSION),1); - if (sess == 0) - { - (*cnt) = 0; - /*THREAD-FIX release chain lock */ - lock_chain_release(); - return 0; - } + count = 0; + + /*THREAD-FIX require chain lock */ + lock_chain_acquire(); + + tmp = g_sessions; - tmp = g_sessions; - index = 0; - while (tmp != 0) - { + while (tmp != 0) + { + LOG_DBG("user: %s", user); + + if ((NULL == user) || (!g_strncasecmp(user, tmp->item->name, 256))) + { + LOG_DBG("session_get_byuser: status=%d, flags=%d, " + "result=%d", (tmp->item->status), flags, + ((tmp->item->status) & flags)); + + if ((tmp->item->status) & flags) + { + count++; + } + } + + /* go on */ + tmp = tmp->next; + } + + if (count == 0) + { + (*cnt) = 0; + /*THREAD-FIX release chain lock */ + lock_chain_release(); + return 0; + } + + /* malloc() an array of disconnected sessions */ + sess = g_malloc(count *sizeof(struct SCP_DISCONNECTED_SESSION), 1); + + if (sess == 0) + { + (*cnt) = 0; + /*THREAD-FIX release chain lock */ + lock_chain_release(); + return 0; + } + + tmp = g_sessions; + index = 0; + + while (tmp != 0) + { #warning FIXME: we should get only disconnected sessions! - if ((NULL == user) || (!g_strncasecmp(user, tmp->item->name, 256))) - { - if ((tmp->item->status) & flags) - { - (sess[index]).SID=tmp->item->pid; - (sess[index]).type=tmp->item->type; - (sess[index]).height=tmp->item->height; - (sess[index]).width=tmp->item->width; - (sess[index]).bpp=tmp->item->bpp; + if ((NULL == user) || (!g_strncasecmp(user, tmp->item->name, 256))) + { + if ((tmp->item->status) & flags) + { + (sess[index]).SID = tmp->item->pid; + (sess[index]).type = tmp->item->type; + (sess[index]).height = tmp->item->height; + (sess[index]).width = tmp->item->width; + (sess[index]).bpp = tmp->item->bpp; #warning FIXME: setting idle times and such - /*(sess[index]).connect_time.year = tmp->item->connect_time.year; - (sess[index]).connect_time.month = tmp->item->connect_time.month; - (sess[index]).connect_time.day = tmp->item->connect_time.day; - (sess[index]).connect_time.hour = tmp->item->connect_time.hour; - (sess[index]).connect_time.minute = tmp->item->connect_time.minute; - (sess[index]).disconnect_time.year = tmp->item->disconnect_time.year; - (sess[index]).disconnect_time.month = tmp->item->disconnect_time.month; - (sess[index]).disconnect_time.day = tmp->item->disconnect_time.day; - (sess[index]).disconnect_time.hour = tmp->item->disconnect_time.hour; - (sess[index]).disconnect_time.minute = tmp->item->disconnect_time.minute; - (sess[index]).idle_time.year = tmp->item->idle_time.year; - (sess[index]).idle_time.month = tmp->item->idle_time.month; - (sess[index]).idle_time.day = tmp->item->idle_time.day; - (sess[index]).idle_time.hour = tmp->item->idle_time.hour; - (sess[index]).idle_time.minute = tmp->item->idle_time.minute;*/ - (sess[index]).conn_year = tmp->item->connect_time.year; - (sess[index]).conn_month = tmp->item->connect_time.month; - (sess[index]).conn_day = tmp->item->connect_time.day; - (sess[index]).conn_hour = tmp->item->connect_time.hour; - (sess[index]).conn_minute = tmp->item->connect_time.minute; - (sess[index]).idle_days = tmp->item->idle_time.day; - (sess[index]).idle_hours = tmp->item->idle_time.hour; - (sess[index]).idle_minutes = tmp->item->idle_time.minute; - - index++; - } - } - - /* go on */ - tmp=tmp->next; - } - - /*THREAD-FIX release chain lock */ - lock_chain_release(); - (*cnt)=count; - return sess; + /*(sess[index]).connect_time.year = tmp->item->connect_time.year; + (sess[index]).connect_time.month = tmp->item->connect_time.month; + (sess[index]).connect_time.day = tmp->item->connect_time.day; + (sess[index]).connect_time.hour = tmp->item->connect_time.hour; + (sess[index]).connect_time.minute = tmp->item->connect_time.minute; + (sess[index]).disconnect_time.year = tmp->item->disconnect_time.year; + (sess[index]).disconnect_time.month = tmp->item->disconnect_time.month; + (sess[index]).disconnect_time.day = tmp->item->disconnect_time.day; + (sess[index]).disconnect_time.hour = tmp->item->disconnect_time.hour; + (sess[index]).disconnect_time.minute = tmp->item->disconnect_time.minute; + (sess[index]).idle_time.year = tmp->item->idle_time.year; + (sess[index]).idle_time.month = tmp->item->idle_time.month; + (sess[index]).idle_time.day = tmp->item->idle_time.day; + (sess[index]).idle_time.hour = tmp->item->idle_time.hour; + (sess[index]).idle_time.minute = tmp->item->idle_time.minute;*/ + (sess[index]).conn_year = tmp->item->connect_time.year; + (sess[index]).conn_month = tmp->item->connect_time.month; + (sess[index]).conn_day = tmp->item->connect_time.day; + (sess[index]).conn_hour = tmp->item->connect_time.hour; + (sess[index]).conn_minute = tmp->item->connect_time.minute; + (sess[index]).idle_days = tmp->item->idle_time.day; + (sess[index]).idle_hours = tmp->item->idle_time.hour; + (sess[index]).idle_minutes = tmp->item->idle_time.minute; + + index++; + } + } + + /* go on */ + tmp = tmp->next; + } + + /*THREAD-FIX release chain lock */ + lock_chain_release(); + (*cnt) = count; + return sess; } diff --git a/sesman/session.h b/sesman/session.h index a8de90d5..b62b2aee 100644 --- a/sesman/session.h +++ b/sesman/session.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2008 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * diff --git a/sesman/sessvc/sessvc.c b/sesman/sessvc/sessvc.c index 1ca32b00..2344229c 100644 --- a/sesman/sessvc/sessvc.c +++ b/sesman/sessvc/sessvc.c @@ -1,28 +1,27 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * * @file sessvc.c * @brief Session supervisor * @author Simone Fedele - * + * */ #if defined(HAVE_CONFIG_H) @@ -38,15 +37,15 @@ static int g_term = 0; void DEFAULT_CC term_signal_handler(int sig) { - g_writeln("xrdp-sessvc: term_signal_handler: got signal %d", sig); - g_term = 1; + g_writeln("xrdp-sessvc: term_signal_handler: got signal %d", sig); + g_term = 1; } /*****************************************************************************/ void DEFAULT_CC nil_signal_handler(int sig) { - g_writeln("xrdp-sessvc: nil_signal_handler: got signal %d", sig); + g_writeln("xrdp-sessvc: nil_signal_handler: got signal %d", sig); } /******************************************************************************/ @@ -54,101 +53,115 @@ nil_signal_handler(int sig) int APP_CC chansrv_cleanup(int pid) { - char text[256]; - - g_snprintf(text, 255, "/tmp/.xrdp/xrdp_chansrv_%8.8x_main_term", pid); - if (g_file_exist(text)) - { - g_file_delete(text); - } - g_snprintf(text, 255, "/tmp/.xrdp/xrdp_chansrv_%8.8x_thread_done", pid); - if (g_file_exist(text)) - { - g_file_delete(text); - } - return 0; + char text[256]; + + g_snprintf(text, 255, "/tmp/.xrdp/xrdp_chansrv_%8.8x_main_term", pid); + + if (g_file_exist(text)) + { + g_file_delete(text); + } + + g_snprintf(text, 255, "/tmp/.xrdp/xrdp_chansrv_%8.8x_thread_done", pid); + + if (g_file_exist(text)) + { + g_file_delete(text); + } + + return 0; } /******************************************************************************/ int DEFAULT_CC -main(int argc, char** argv) +main(int argc, char **argv) { - int ret = 0; - int chansrv_pid = 0; - int wm_pid = 0; - int x_pid = 0; - int lerror = 0; - char exe_path[262]; - - g_init("xrdp-sessvc"); - g_memset(exe_path,0,sizeof(exe_path)); - - if (argc < 3) - { - g_writeln("xrdp-sessvc: exiting, not enough parameters"); - g_deinit(); - return 1; - } - g_signal_kill(term_signal_handler); /* SIGKILL */ - g_signal_terminate(term_signal_handler); /* SIGTERM */ - g_signal_user_interrupt(term_signal_handler); /* SIGINT */ - g_signal_pipe(nil_signal_handler); /* SIGPIPE */ - x_pid = g_atoi(argv[1]); - wm_pid = g_atoi(argv[2]); - g_writeln("xrdp-sessvc: waiting for X (pid %d) and WM (pid %d)", - x_pid, wm_pid); - /* run xrdp-chansrv as a seperate process */ - chansrv_pid = g_fork(); - if (chansrv_pid == -1) - { - g_writeln("xrdp-sessvc: fork error"); - g_deinit(); - return 1; - } - else if (chansrv_pid == 0) /* child */ - { - g_set_current_dir(XRDP_SBIN_PATH); - g_snprintf(exe_path, 261, "%s/xrdp-chansrv", XRDP_SBIN_PATH); - g_execlp3(exe_path, "xrdp-chansrv", 0); - /* should not get here */ - g_writeln("xrdp-sessvc: g_execlp3() failed"); - g_deinit(); - return 1; - } - lerror = 0; - /* wait for window manager to get done */ - ret = g_waitpid(wm_pid); - while ((ret == 0) && !g_term) - { + int ret = 0; + int chansrv_pid = 0; + int wm_pid = 0; + int x_pid = 0; + int lerror = 0; + char exe_path[262]; + + g_init("xrdp-sessvc"); + g_memset(exe_path, 0, sizeof(exe_path)); + + if (argc < 3) + { + g_writeln("xrdp-sessvc: exiting, not enough parameters"); + g_deinit(); + return 1; + } + + g_signal_kill(term_signal_handler); /* SIGKILL */ + g_signal_terminate(term_signal_handler); /* SIGTERM */ + g_signal_user_interrupt(term_signal_handler); /* SIGINT */ + g_signal_pipe(nil_signal_handler); /* SIGPIPE */ + x_pid = g_atoi(argv[1]); + wm_pid = g_atoi(argv[2]); + g_writeln("xrdp-sessvc: waiting for X (pid %d) and WM (pid %d)", + x_pid, wm_pid); + /* run xrdp-chansrv as a seperate process */ + chansrv_pid = g_fork(); + + if (chansrv_pid == -1) + { + g_writeln("xrdp-sessvc: fork error"); + g_deinit(); + return 1; + } + else if (chansrv_pid == 0) /* child */ + { + g_set_current_dir(XRDP_SBIN_PATH); + g_snprintf(exe_path, 261, "%s/xrdp-chansrv", XRDP_SBIN_PATH); + g_execlp3(exe_path, "xrdp-chansrv", 0); + /* should not get here */ + g_writeln("xrdp-sessvc: g_execlp3() failed"); + g_deinit(); + return 1; + } + + lerror = 0; + /* wait for window manager to get done */ ret = g_waitpid(wm_pid); - g_sleep(1); - } - if (ret < 0) - { - lerror = g_get_errno(); - } - g_writeln("xrdp-sessvc: WM is dead (waitpid said %d, errno is %d) " - "exiting...", ret, lerror); - /* kill channel server */ - g_writeln("xrdp-sessvc: stopping channel server"); - g_sigterm(chansrv_pid); - ret = g_waitpid(chansrv_pid); - while ((ret == 0) && !g_term) - { + + while ((ret == 0) && !g_term) + { + ret = g_waitpid(wm_pid); + g_sleep(1); + } + + if (ret < 0) + { + lerror = g_get_errno(); + } + + g_writeln("xrdp-sessvc: WM is dead (waitpid said %d, errno is %d) " + "exiting...", ret, lerror); + /* kill channel server */ + g_writeln("xrdp-sessvc: stopping channel server"); + g_sigterm(chansrv_pid); ret = g_waitpid(chansrv_pid); - g_sleep(1); - } - chansrv_cleanup(chansrv_pid); - /* kill X server */ - g_writeln("xrdp-sessvc: stopping X server"); - g_sigterm(x_pid); - ret = g_waitpid(x_pid); - while ((ret == 0) && !g_term) - { + + while ((ret == 0) && !g_term) + { + ret = g_waitpid(chansrv_pid); + g_sleep(1); + } + + chansrv_cleanup(chansrv_pid); + /* kill X server */ + g_writeln("xrdp-sessvc: stopping X server"); + g_sigterm(x_pid); ret = g_waitpid(x_pid); - g_sleep(1); - } - g_writeln("xrdp-sessvc: clean exit"); - g_deinit(); - return 0; + + while ((ret == 0) && !g_term) + { + ret = g_waitpid(x_pid); + g_sleep(1); + } + + g_writeln("xrdp-sessvc: clean exit"); + g_deinit(); + return 0; } diff --git a/sesman/sig.c b/sesman/sig.c index 151c0c57..b8f320f1 100644 --- a/sesman/sig.c +++ b/sesman/sig.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -31,170 +30,176 @@ extern int g_sck; extern int g_pid; -extern struct config_sesman* g_cfg; /* in sesman.c */ +extern struct config_sesman *g_cfg; /* in sesman.c */ extern tbus g_term_event; /******************************************************************************/ void DEFAULT_CC sig_sesman_shutdown(int sig) { - char pid_file[256]; + char pid_file[256]; - log_message(LOG_LEVEL_INFO, "shutting down sesman %d", 1); + log_message(LOG_LEVEL_INFO, "shutting down sesman %d", 1); - if (g_getpid() != g_pid) - { - LOG_DBG("g_getpid() [%d] differs from g_pid [%d]", (g_getpid()), g_pid); - return; - } + if (g_getpid() != g_pid) + { + LOG_DBG("g_getpid() [%d] differs from g_pid [%d]", (g_getpid()), g_pid); + return; + } - LOG_DBG(" - getting signal %d pid %d", sig, g_getpid()); + LOG_DBG(" - getting signal %d pid %d", sig, g_getpid()); - g_set_wait_obj(g_term_event); + g_set_wait_obj(g_term_event); - g_tcp_close(g_sck); + g_tcp_close(g_sck); - session_sigkill_all(); + session_sigkill_all(); - g_snprintf(pid_file, 255, "%s/xrdp-sesman.pid", XRDP_PID_PATH); - g_file_delete(pid_file); + g_snprintf(pid_file, 255, "%s/xrdp-sesman.pid", XRDP_PID_PATH); + g_file_delete(pid_file); } /******************************************************************************/ void DEFAULT_CC sig_sesman_reload_cfg(int sig) { - int error; - struct config_sesman *cfg; - char cfg_file[256]; - - log_message(LOG_LEVEL_WARNING, "receiving SIGHUP %d", 1); - - if (g_getpid() != g_pid) - { - LOG_DBG("g_getpid() [%d] differs from g_pid [%d]", g_getpid(), g_pid); - return; - } - - cfg = g_malloc(sizeof(struct config_sesman), 1); - if (0 == cfg) - { - log_message(LOG_LEVEL_ERROR, "error creating new config: - keeping old cfg"); - return; - } - - if (config_read(cfg) != 0) - { - log_message(LOG_LEVEL_ERROR, "error reading config - keeping old cfg"); - return; - } - - /* stop logging subsystem */ - log_end(); - - /* replace old config with new readed one */ - g_cfg = cfg; - - g_snprintf(cfg_file, 255, "%s/sesman.ini", XRDP_CFG_PATH); - - /* start again logging subsystem */ - error = log_start(cfg_file,"XRDP-sesman"); - - if (error != LOG_STARTUP_OK) - { - char buf[256]; - switch (error) + int error; + struct config_sesman *cfg; + char cfg_file[256]; + + log_message(LOG_LEVEL_WARNING, "receiving SIGHUP %d", 1); + + if (g_getpid() != g_pid) + { + LOG_DBG("g_getpid() [%d] differs from g_pid [%d]", g_getpid(), g_pid); + return; + } + + cfg = g_malloc(sizeof(struct config_sesman), 1); + + if (0 == cfg) { - case LOG_ERROR_MALLOC: - g_printf("error on malloc. cannot restart logging. log stops here, sorry.\n"); - break; - case LOG_ERROR_FILE_OPEN: - g_printf("error reopening log file [%s]. log stops here, sorry.\n", getLogFile(buf,255)); - break; + log_message(LOG_LEVEL_ERROR, "error creating new config: - keeping old cfg"); + return; } - } - log_message(LOG_LEVEL_INFO, "configuration reloaded, log subsystem restarted"); + if (config_read(cfg) != 0) + { + log_message(LOG_LEVEL_ERROR, "error reading config - keeping old cfg"); + return; + } + + /* stop logging subsystem */ + log_end(); + + /* replace old config with new readed one */ + g_cfg = cfg; + + g_snprintf(cfg_file, 255, "%s/sesman.ini", XRDP_CFG_PATH); + + /* start again logging subsystem */ + error = log_start(cfg_file, "XRDP-sesman"); + + if (error != LOG_STARTUP_OK) + { + char buf[256]; + + switch (error) + { + case LOG_ERROR_MALLOC: + g_printf("error on malloc. cannot restart logging. log stops here, sorry.\n"); + break; + case LOG_ERROR_FILE_OPEN: + g_printf("error reopening log file [%s]. log stops here, sorry.\n", getLogFile(buf, 255)); + break; + } + } + + log_message(LOG_LEVEL_INFO, "configuration reloaded, log subsystem restarted"); } /******************************************************************************/ void DEFAULT_CC sig_sesman_session_end(int sig) { - int pid; - - if (g_getpid() != g_pid) - { - return; - } - pid = g_waitchild(); - if (pid > 0) - { - session_kill(pid); - } + int pid; + + if (g_getpid() != g_pid) + { + return; + } + + pid = g_waitchild(); + + if (pid > 0) + { + session_kill(pid); + } } /******************************************************************************/ -void* DEFAULT_CC -sig_handler_thread(void* arg) +void *DEFAULT_CC +sig_handler_thread(void *arg) { - int recv_signal; - sigset_t sigmask; - sigset_t oldmask; - sigset_t waitmask; - - /* mask signals to be able to wait for them... */ - sigfillset(&sigmask); - /* it is a good idea not to block SIGILL SIGSEGV */ - /* SIGFPE -- see sigaction(2) NOTES */ - pthread_sigmask(SIG_BLOCK, &sigmask, &oldmask); - - /* building the signal wait mask... */ - sigemptyset(&waitmask); - sigaddset(&waitmask, SIGHUP); - sigaddset(&waitmask, SIGCHLD); - sigaddset(&waitmask, SIGTERM); - sigaddset(&waitmask, SIGKILL); - sigaddset(&waitmask, SIGINT); - -// sigaddset(&waitmask, SIGFPE); -// sigaddset(&waitmask, SIGILL); -// sigaddset(&waitmask, SIGSEGV); - - do - { - LOG_DBG(&(g_cfg->log), "calling sigwait()",0); - sigwait(&waitmask, &recv_signal); - switch (recv_signal) + int recv_signal; + sigset_t sigmask; + sigset_t oldmask; + sigset_t waitmask; + + /* mask signals to be able to wait for them... */ + sigfillset(&sigmask); + /* it is a good idea not to block SIGILL SIGSEGV */ + /* SIGFPE -- see sigaction(2) NOTES */ + pthread_sigmask(SIG_BLOCK, &sigmask, &oldmask); + + /* building the signal wait mask... */ + sigemptyset(&waitmask); + sigaddset(&waitmask, SIGHUP); + sigaddset(&waitmask, SIGCHLD); + sigaddset(&waitmask, SIGTERM); + sigaddset(&waitmask, SIGKILL); + sigaddset(&waitmask, SIGINT); + + // sigaddset(&waitmask, SIGFPE); + // sigaddset(&waitmask, SIGILL); + // sigaddset(&waitmask, SIGSEGV); + + do { - case SIGHUP: - //reload cfg - //we must stop & restart logging, or copy logging cfg!!!! - LOG_DBG("sesman received SIGHUP", 0); - //return 0; - break; - case SIGCHLD: - /* a session died */ - LOG_DBG("sesman received SIGCHLD", 0); - sig_sesman_session_end(SIGCHLD); - break; - case SIGINT: - /* we die */ - LOG_DBG("sesman received SIGINT", 0); - sig_sesman_shutdown(recv_signal); - break; - case SIGKILL: - /* we die */ - LOG_DBG("sesman received SIGKILL", 0); - sig_sesman_shutdown(recv_signal); - break; - case SIGTERM: - /* we die */ - LOG_DBG("sesman received SIGTERM", 0); - sig_sesman_shutdown(recv_signal); - break; + LOG_DBG(&(g_cfg->log), "calling sigwait()", 0); + sigwait(&waitmask, &recv_signal); + + switch (recv_signal) + { + case SIGHUP: + //reload cfg + //we must stop & restart logging, or copy logging cfg!!!! + LOG_DBG("sesman received SIGHUP", 0); + //return 0; + break; + case SIGCHLD: + /* a session died */ + LOG_DBG("sesman received SIGCHLD", 0); + sig_sesman_session_end(SIGCHLD); + break; + case SIGINT: + /* we die */ + LOG_DBG("sesman received SIGINT", 0); + sig_sesman_shutdown(recv_signal); + break; + case SIGKILL: + /* we die */ + LOG_DBG("sesman received SIGKILL", 0); + sig_sesman_shutdown(recv_signal); + break; + case SIGTERM: + /* we die */ + LOG_DBG("sesman received SIGTERM", 0); + sig_sesman_shutdown(recv_signal); + break; + } } - } while (1); + while (1); - return 0; + return 0; } diff --git a/sesman/sig.h b/sesman/sig.h index 7c6d2bfe..ac648da0 100644 --- a/sesman/sig.h +++ b/sesman/sig.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -64,4 +63,3 @@ void* DEFAULT_CC sig_handler_thread(void* arg); #endif - diff --git a/sesman/thread.c b/sesman/thread.c index 98a92533..a33b93d9 100644 --- a/sesman/thread.c +++ b/sesman/thread.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -31,7 +30,7 @@ #include <signal.h> #include <pthread.h> -extern struct config_sesman* g_cfg; /* in sesman.c */ +extern struct config_sesman *g_cfg; /* in sesman.c */ static pthread_t g_thread_sighandler; //static pthread_t g_thread_updater; @@ -43,53 +42,53 @@ int g_thread_sck; int DEFAULT_CC thread_sighandler_start(void) { - int ret; - sigset_t sigmask; - sigset_t oldmask; - sigset_t waitmask; - - /* mask signals to be able to wait for them... */ - sigfillset(&sigmask); - pthread_sigmask(SIG_BLOCK, &sigmask, &oldmask); - - /* unblock some signals... */ - sigemptyset(&waitmask); - - /* it is a good idea not to block SIGILL SIGSEGV */ - /* SIGFPE -- see sigaction(2) NOTES */ - sigaddset(&waitmask, SIGILL); - sigaddset(&waitmask, SIGSEGV); - sigaddset(&waitmask, SIGFPE); - pthread_sigmask(SIG_UNBLOCK, &waitmask, NULL); - - log_message(LOG_LEVEL_INFO,"starting signal handling thread..."); - - ret = pthread_create(&g_thread_sighandler, NULL, sig_handler_thread, ""); - pthread_detach(g_thread_sighandler); - - if (ret == 0) - { - log_message(LOG_LEVEL_INFO, "signal handler thread started successfully"); - return 0; - } - - /* if something happened while starting a new thread... */ - switch (ret) - { - case EINVAL: - log_message(LOG_LEVEL_ERROR, "invalid attributes for signal handling thread (creation returned EINVAL)"); - break; - case EAGAIN: - log_message(LOG_LEVEL_ERROR, "not enough resources to start signal handling thread (creation returned EAGAIN)"); - break; - case EPERM: - log_message(LOG_LEVEL_ERROR, "invalid permissions for signal handling thread (creation returned EPERM)"); - break; - default: - log_message(LOG_LEVEL_ERROR, "unknown error starting signal handling thread"); - } - - return 1; + int ret; + sigset_t sigmask; + sigset_t oldmask; + sigset_t waitmask; + + /* mask signals to be able to wait for them... */ + sigfillset(&sigmask); + pthread_sigmask(SIG_BLOCK, &sigmask, &oldmask); + + /* unblock some signals... */ + sigemptyset(&waitmask); + + /* it is a good idea not to block SIGILL SIGSEGV */ + /* SIGFPE -- see sigaction(2) NOTES */ + sigaddset(&waitmask, SIGILL); + sigaddset(&waitmask, SIGSEGV); + sigaddset(&waitmask, SIGFPE); + pthread_sigmask(SIG_UNBLOCK, &waitmask, NULL); + + log_message(LOG_LEVEL_INFO, "starting signal handling thread..."); + + ret = pthread_create(&g_thread_sighandler, NULL, sig_handler_thread, ""); + pthread_detach(g_thread_sighandler); + + if (ret == 0) + { + log_message(LOG_LEVEL_INFO, "signal handler thread started successfully"); + return 0; + } + + /* if something happened while starting a new thread... */ + switch (ret) + { + case EINVAL: + log_message(LOG_LEVEL_ERROR, "invalid attributes for signal handling thread (creation returned EINVAL)"); + break; + case EAGAIN: + log_message(LOG_LEVEL_ERROR, "not enough resources to start signal handling thread (creation returned EAGAIN)"); + break; + case EPERM: + log_message(LOG_LEVEL_ERROR, "invalid permissions for signal handling thread (creation returned EPERM)"); + break; + default: + log_message(LOG_LEVEL_ERROR, "unknown error starting signal handling thread"); + } + + return 1; } #ifdef JUST_TO_AVOID_COMPILER_ERRORS @@ -97,38 +96,38 @@ thread_sighandler_start(void) int DEFAULT_CC thread_session_update_start(void) { - int ret; - //starts the session update thread - //that checks for idle time, destroys sessions, ecc... + int ret; + //starts the session update thread + //that checks for idle time, destroys sessions, ecc... #warning this thread should always request lock_fork before read or write #warning (so we can Fork() In Peace) - ret = pthread_create(&g_thread_updater, NULL, , ""); - pthread_detach(g_thread_updater); - - if (ret == 0) - { - log_message(&(g_cfg->log), LOG_LEVEL_INFO, "session update thread started successfully"); - return 0; - } - - /* if something happened while starting a new thread... */ - switch (ret) - { - case EINVAL: - log_message(LOG_LEVEL_ERROR, "invalid attributes for session update thread (creation returned EINVAL)"); - break; - case EAGAIN: - log_message(LOG_LEVEL_ERROR, "not enough resources to start session update thread (creation returned EAGAIN)"); - break; - case EPERM: - log_message(LOG_LEVEL_ERROR, "invalid permissions for session update thread (creation returned EPERM)"); - break; - default: - log_message(LOG_LEVEL_ERROR, "unknown error starting session update thread"); - } - - return 1; + ret = pthread_create(&g_thread_updater, NULL, , ""); + pthread_detach(g_thread_updater); + + if (ret == 0) + { + log_message(&(g_cfg->log), LOG_LEVEL_INFO, "session update thread started successfully"); + return 0; + } + + /* if something happened while starting a new thread... */ + switch (ret) + { + case EINVAL: + log_message(LOG_LEVEL_ERROR, "invalid attributes for session update thread (creation returned EINVAL)"); + break; + case EAGAIN: + log_message(LOG_LEVEL_ERROR, "not enough resources to start session update thread (creation returned EAGAIN)"); + break; + case EPERM: + log_message(LOG_LEVEL_ERROR, "invalid permissions for session update thread (creation returned EPERM)"); + break; + default: + log_message(LOG_LEVEL_ERROR, "unknown error starting session update thread"); + } + + return 1; } #endif @@ -136,39 +135,39 @@ thread_session_update_start(void) int DEFAULT_CC thread_scp_start(int skt) { - int ret; - pthread_t th; - - /* blocking the use of thread_skt */ - lock_socket_acquire(); - g_thread_sck = skt; - - /* start a thread that processes a connection */ - ret = pthread_create(&th, NULL, scp_process_start, ""); - //ret = pthread_create(&th, NULL, scp_process_start, (void*) (&g_thread_sck)); - pthread_detach(th); - - if (ret == 0) - { - log_message(LOG_LEVEL_INFO, "scp thread on sck %d started successfully", skt); - return 0; - } - - /* if something happened while starting a new thread... */ - switch (ret) - { - case EINVAL: - log_message(LOG_LEVEL_ERROR, "invalid attributes for scp thread on sck %d (creation returned EINVAL)", skt); - break; - case EAGAIN: - log_message(LOG_LEVEL_ERROR, "not enough resources to start scp thread on sck %d (creation returned EAGAIN)", skt); - break; - case EPERM: - log_message(LOG_LEVEL_ERROR, "invalid permissions for scp thread on sck %d (creation returned EPERM)", skt); - break; - default: - log_message(LOG_LEVEL_ERROR, "unknown error starting scp thread on sck %d"); - } - - return 1; + int ret; + pthread_t th; + + /* blocking the use of thread_skt */ + lock_socket_acquire(); + g_thread_sck = skt; + + /* start a thread that processes a connection */ + ret = pthread_create(&th, NULL, scp_process_start, ""); + //ret = pthread_create(&th, NULL, scp_process_start, (void*) (&g_thread_sck)); + pthread_detach(th); + + if (ret == 0) + { + log_message(LOG_LEVEL_INFO, "scp thread on sck %d started successfully", skt); + return 0; + } + + /* if something happened while starting a new thread... */ + switch (ret) + { + case EINVAL: + log_message(LOG_LEVEL_ERROR, "invalid attributes for scp thread on sck %d (creation returned EINVAL)", skt); + break; + case EAGAIN: + log_message(LOG_LEVEL_ERROR, "not enough resources to start scp thread on sck %d (creation returned EAGAIN)", skt); + break; + case EPERM: + log_message(LOG_LEVEL_ERROR, "invalid permissions for scp thread on sck %d (creation returned EPERM)", skt); + break; + default: + log_message(LOG_LEVEL_ERROR, "unknown error starting scp thread on sck %d"); + } + + return 1; } diff --git a/sesman/thread.h b/sesman/thread.h index b3c12258..9dcb53b4 100644 --- a/sesman/thread.h +++ b/sesman/thread.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * diff --git a/sesman/tools/dis.c b/sesman/tools/dis.c index 0dbc74d8..52400847 100644 --- a/sesman/tools/dis.c +++ b/sesman/tools/dis.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2011 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include <stdio.h> #include <stdlib.h> @@ -24,42 +23,48 @@ #include <sys/socket.h> #include <sys/un.h> -int main(int argc, char** argv) +int main(int argc, char **argv) { - int sck; - int dis; - struct sockaddr_un sa; - size_t len; - char* p; - char* display; + int sck; + int dis; + struct sockaddr_un sa; + size_t len; + char *p; + char *display; - if (argc != 1) - { - printf("xrdp disconnect utility\n"); - printf("run with no parameters to disconnect you xrdp session\n"); - return 0; - } + if (argc != 1) + { + printf("xrdp disconnect utility\n"); + printf("run with no parameters to disconnect you xrdp session\n"); + return 0; + } + + display = getenv("DISPLAY"); + + if (display == 0) + { + printf("display not set\n"); + return 1; + } - display = getenv("DISPLAY"); - if (display == 0) - { - printf("display not set\n"); - return 1; - } - dis = strtol(display + 1, &p, 10); - memset(&sa, 0, sizeof(sa)); - sa.sun_family = AF_UNIX; - sprintf(sa.sun_path, "/tmp/.xrdp/xrdp_disconnect_display_%d", dis); - if (access(sa.sun_path, F_OK) != 0) - { - printf("not in an xrdp session\n"); - return 1; - } - sck = socket(PF_UNIX, SOCK_DGRAM, 0); - len = sizeof(sa); - if (sendto(sck, "sig", 4, 0, (struct sockaddr*)&sa, len) > 0) - { - printf("message sent ok\n"); - } - return 0; + dis = strtol(display + 1, &p, 10); + memset(&sa, 0, sizeof(sa)); + sa.sun_family = AF_UNIX; + sprintf(sa.sun_path, "/tmp/.xrdp/xrdp_disconnect_display_%d", dis); + + if (access(sa.sun_path, F_OK) != 0) + { + printf("not in an xrdp session\n"); + return 1; + } + + sck = socket(PF_UNIX, SOCK_DGRAM, 0); + len = sizeof(sa); + + if (sendto(sck, "sig", 4, 0, (struct sockaddr *)&sa, len) > 0) + { + printf("message sent ok\n"); + } + + return 0; } diff --git a/sesman/tools/sesadmin.c b/sesman/tools/sesadmin.c index 22f20c23..25af850b 100644 --- a/sesman/tools/sesadmin.c +++ b/sesman/tools/sesadmin.c @@ -22,174 +22,176 @@ char port[257]; struct log_config logging; -void cmndList(struct SCP_CONNECTION* c); -void cmndKill(struct SCP_CONNECTION* c, struct SCP_SESSION* s); +void cmndList(struct SCP_CONNECTION *c); +void cmndKill(struct SCP_CONNECTION *c, struct SCP_SESSION *s); void cmndHelp(); -int inputSession(struct SCP_SESSION* s); +int inputSession(struct SCP_SESSION *s); unsigned int menuSelect(unsigned int choices); -int main(int argc, char** argv) +int main(int argc, char **argv) { - struct SCP_SESSION* s; - struct SCP_CONNECTION* c; - enum SCP_CLIENT_STATES_E e; - //int end; - int idx; - //int sel; - int sock; - char* pwd; - - user[0]='\0'; - pass[0]='\0'; - cmnd[0]='\0'; - serv[0]='\0'; - port[0]='\0'; - - logging.program_name = g_strdup("sesadmin"); - logging.log_file = g_strdup("xrdp-sesadmin.log"); - logging.log_level = LOG_LEVEL_DEBUG; - logging.enable_syslog = 0; - log_start_from_param(&logging); - - for (idx = 0; idx < argc; idx++) - { - if (0 == g_strncmp(argv[idx], "-u=", 3)) + struct SCP_SESSION *s; + struct SCP_CONNECTION *c; + enum SCP_CLIENT_STATES_E e; + //int end; + int idx; + //int sel; + int sock; + char *pwd; + + user[0] = '\0'; + pass[0] = '\0'; + cmnd[0] = '\0'; + serv[0] = '\0'; + port[0] = '\0'; + + logging.program_name = g_strdup("sesadmin"); + logging.log_file = g_strdup("xrdp-sesadmin.log"); + logging.log_level = LOG_LEVEL_DEBUG; + logging.enable_syslog = 0; + log_start_from_param(&logging); + + for (idx = 0; idx < argc; idx++) { - g_strncpy(user, (argv[idx])+3, 256); + if (0 == g_strncmp(argv[idx], "-u=", 3)) + { + g_strncpy(user, (argv[idx]) + 3, 256); + } + else if (0 == g_strncmp(argv[idx], "-p=", 3)) + { + g_strncpy(pass, (argv[idx]) + 3, 256); + } + else if (0 == g_strncmp(argv[idx], "-s=", 3)) + { + g_strncpy(serv, (argv[idx]) + 3, 256); + } + else if (0 == g_strncmp(argv[idx], "-i=", 3)) + { + g_strncpy(port, (argv[idx]) + 3, 256); + } + else if (0 == g_strncmp(argv[idx], "-c=", 3)) + { + g_strncpy(cmnd, (argv[idx]) + 3, 256); + } } - else if (0 == g_strncmp(argv[idx], "-p=", 3)) - { - g_strncpy(pass, (argv[idx])+3, 256); - } - else if (0 == g_strncmp(argv[idx], "-s=", 3)) + + if (0 == g_strncmp(serv, "", 1)) { - g_strncpy(serv, (argv[idx])+3, 256); + g_strncpy(serv, "localhost", 256); } - else if (0 == g_strncmp(argv[idx], "-i=", 3)) + + if (0 == g_strncmp(port, "", 1)) { - g_strncpy(port, (argv[idx])+3, 256); + g_strncpy(port, "3350", 256); } - else if (0 == g_strncmp(argv[idx], "-c=", 3)) + + if (0 == g_strncmp(user, "", 1)) { - g_strncpy(cmnd, (argv[idx])+3, 256); + g_strncpy(user, "root", 256); } - } - - if (0 == g_strncmp(serv, "", 1)) - { - g_strncpy(serv, "localhost", 256); - } - - if (0 == g_strncmp(port, "", 1)) - { - g_strncpy(port, "3350", 256); - } - - if (0 == g_strncmp(user, "", 1)) - { - g_strncpy(user, "root", 256); - } - - if (0 == g_strncmp(pass, "", 1)) - { - pwd = getpass("password:"); - g_strncpy(pass, pwd, 256); - - /* zeroing the password */ - while ((*pwd) != '\0') + + if (0 == g_strncmp(pass, "", 1)) { - (*pwd) = 0x00; - pwd++; + pwd = getpass("password:"); + g_strncpy(pass, pwd, 256); + + /* zeroing the password */ + while ((*pwd) != '\0') + { + (*pwd) = 0x00; + pwd++; + } } - } - scp_init(&logging); + scp_init(&logging); - sock = g_tcp_socket(); - s = scp_session_create(); - c = scp_connection_create(sock); + sock = g_tcp_socket(); + s = scp_session_create(); + c = scp_connection_create(sock); - LOG_DBG("Connecting to %s:%s with user %s (%s)\n", serv, port, user, pass); + LOG_DBG("Connecting to %s:%s with user %s (%s)\n", serv, port, user, pass); - if (0 != g_tcp_connect(sock, serv, port)) - { - LOG_DBG("g_tcp_connect() error\n"); - return 1; - } + if (0 != g_tcp_connect(sock, serv, port)) + { + LOG_DBG("g_tcp_connect() error\n"); + return 1; + } - scp_session_set_type(s, SCP_SESSION_TYPE_MANAGE); - scp_session_set_version(s, 1); - scp_session_set_username(s, user); - scp_session_set_password(s, pass); + scp_session_set_type(s, SCP_SESSION_TYPE_MANAGE); + scp_session_set_version(s, 1); + scp_session_set_username(s, user); + scp_session_set_password(s, pass); - e = scp_v1c_mng_connect(c,s); + e = scp_v1c_mng_connect(c, s); - if (SCP_CLIENT_STATE_OK != e) - { - LOG_DBG("libscp error connecting: %s %d\n", s->errstr, (int)e); - } + if (SCP_CLIENT_STATE_OK != e) + { + LOG_DBG("libscp error connecting: %s %d\n", s->errstr, (int)e); + } - if (0 == g_strncmp(cmnd, "list", 5)) - { - cmndList(c); - } - else if (0 == g_strncmp(cmnd, "kill:", 5)) - { - cmndKill(c,s); - } + if (0 == g_strncmp(cmnd, "list", 5)) + { + cmndList(c); + } + else if (0 == g_strncmp(cmnd, "kill:", 5)) + { + cmndKill(c, s); + } - g_tcp_close(sock); - scp_session_destroy(s); - scp_connection_destroy(c); - log_end(); + g_tcp_close(sock); + scp_session_destroy(s); + scp_connection_destroy(c); + log_end(); - return 0; + return 0; } void cmndHelp() { - fprintf(stderr, "sesadmin - a console sesman adminitration tool\n"); - fprintf(stderr, "sysntax: sesadmin [] COMMAND [OPTIONS]\n\n"); - fprintf(stderr, "-u=<username>: username to connect to sesman [MANDATORY]\n"); - fprintf(stderr, "-p=<password>: password to connect to sesman [MANDATORY]\n"); - fprintf(stderr, "-s=<hostname>: sesman host (default is localhost)\n"); - fprintf(stderr, "-i=<port> : sesman port (default 3350)\n"); - fprintf(stderr, "-c=<command> : command to execute on the server [MANDATORY]\n"); - fprintf(stderr, " it can be one of those:\n"); - fprintf(stderr, " LIST\n"); - fprintf(stderr, " KILL:<sid>\n"); + fprintf(stderr, "sesadmin - a console sesman adminitration tool\n"); + fprintf(stderr, "sysntax: sesadmin [] COMMAND [OPTIONS]\n\n"); + fprintf(stderr, "-u=<username>: username to connect to sesman [MANDATORY]\n"); + fprintf(stderr, "-p=<password>: password to connect to sesman [MANDATORY]\n"); + fprintf(stderr, "-s=<hostname>: sesman host (default is localhost)\n"); + fprintf(stderr, "-i=<port> : sesman port (default 3350)\n"); + fprintf(stderr, "-c=<command> : command to execute on the server [MANDATORY]\n"); + fprintf(stderr, " it can be one of those:\n"); + fprintf(stderr, " LIST\n"); + fprintf(stderr, " KILL:<sid>\n"); } -void cmndList(struct SCP_CONNECTION* c) +void cmndList(struct SCP_CONNECTION *c) { - struct SCP_DISCONNECTED_SESSION* dsl; - enum SCP_CLIENT_STATES_E e; - int scnt; - int idx; - - e = scp_v1c_mng_get_session_list(c, &scnt, &dsl); - if ((SCP_CLIENT_STATE_LIST_OK == e) && (scnt > 0)) - { - for (idx = 0; idx < scnt; idx++) + struct SCP_DISCONNECTED_SESSION *dsl; + enum SCP_CLIENT_STATES_E e; + int scnt; + int idx; + + e = scp_v1c_mng_get_session_list(c, &scnt, &dsl); + + if ((SCP_CLIENT_STATE_LIST_OK == e) && (scnt > 0)) { - printf("%d\t%d\t%dx%dx%d\t%d-%d-%d\t%04d/%02d/%02d@%02d:%02d\n", \ - (dsl[idx]).SID, (dsl[idx]).type, (dsl[idx]).width, (dsl[idx]).height, (dsl[idx]).bpp, \ - (dsl[idx]).idle_days, (dsl[idx]).idle_hours, (dsl[idx]).idle_minutes, \ - (dsl[idx]).conn_year, (dsl[idx]).conn_month, (dsl[idx]).conn_day, (dsl[idx]).conn_hour, (dsl[idx]).conn_minute); + for (idx = 0; idx < scnt; idx++) + { + printf("%d\t%d\t%dx%dx%d\t%d-%d-%d\t%04d/%02d/%02d@%02d:%02d\n", \ + (dsl[idx]).SID, (dsl[idx]).type, (dsl[idx]).width, (dsl[idx]).height, (dsl[idx]).bpp, \ + (dsl[idx]).idle_days, (dsl[idx]).idle_hours, (dsl[idx]).idle_minutes, \ + (dsl[idx]).conn_year, (dsl[idx]).conn_month, (dsl[idx]).conn_day, (dsl[idx]).conn_hour, (dsl[idx]).conn_minute); + } + + if (0 != dsl) + { + g_free(dsl); + } } - if (0 != dsl) + else { - g_free(dsl); + printf("No sessions.\n"); } - } - else - { - printf("No sessions.\n"); - } } -void cmndKill(struct SCP_CONNECTION* c, struct SCP_SESSION* s) +void cmndKill(struct SCP_CONNECTION *c, struct SCP_SESSION *s) { } diff --git a/sesman/tools/sesrun.c b/sesman/tools/sesrun.c index f22e5a30..5ad3b5cc 100644 --- a/sesman/tools/sesrun.c +++ b/sesman/tools/sesrun.c @@ -1,28 +1,27 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * * @file sesrun.c * @brief An utility to start a session * @author Jay Sorg, Simone Fedele - * + * */ #include "sesman.h" @@ -34,93 +33,100 @@ struct config_sesman g_cfg; /* config.h */ /******************************************************************************/ int DEFAULT_CC -main(int argc, char** argv) +main(int argc, char **argv) { - int sck; - int code; - int i; - int size; - int version; - int width; - int height; - int bpp; - int display; - struct stream* in_s; - struct stream* out_s; - char* username; - char* password; - long data; + int sck; + int code; + int i; + int size; + int version; + int width; + int height; + int bpp; + int display; + struct stream *in_s; + struct stream *out_s; + char *username; + char *password; + long data; + + if (0 != config_read(&g_cfg)) + { + g_printf("sesrun: error reading config. quitting.\n"); + return 1; + } - if (0 != config_read(&g_cfg)) - { - g_printf("sesrun: error reading config. quitting.\n"); - return 1; - } + g_pid = g_getpid(); - g_pid = g_getpid(); - if (argc == 1) - { - g_printf("xrdp session starter v0.1\n"); - g_printf("\nusage:\n"); - g_printf("sesrun <server> <username> <password> <width> <height> <bpp>\n"); - } - else if (argc == 7) - { - username = argv[2]; - password = argv[3]; - width = g_atoi(argv[4]); - height = g_atoi(argv[5]); - bpp = g_atoi(argv[6]); - make_stream(in_s); - init_stream(in_s, 8192); - make_stream(out_s); - init_stream(out_s, 8192); - sck = g_tcp_socket(); - if (g_tcp_connect(sck, argv[1], g_cfg.listen_port) == 0) + if (argc == 1) { - s_push_layer(out_s, channel_hdr, 8); - out_uint16_be(out_s, 0); /* code */ - i = g_strlen(username); - out_uint16_be(out_s, i); - out_uint8a(out_s, username, i); - i = g_strlen(password); - out_uint16_be(out_s, i); - out_uint8a(out_s, password, i); - out_uint16_be(out_s, width); - out_uint16_be(out_s, height); - out_uint16_be(out_s, bpp); - s_mark_end(out_s); - s_pop_layer(out_s, channel_hdr); - out_uint32_be(out_s, 0); /* version */ - out_uint32_be(out_s, out_s->end - out_s->data); /* size */ - tcp_force_send(sck, out_s->data, out_s->end - out_s->data); - if (tcp_force_recv(sck, in_s->data, 8) == 0) - { - in_uint32_be(in_s, version); - in_uint32_be(in_s, size); + g_printf("xrdp session starter v0.1\n"); + g_printf("\nusage:\n"); + g_printf("sesrun <server> <username> <password> <width> <height> <bpp>\n"); + } + else if (argc == 7) + { + username = argv[2]; + password = argv[3]; + width = g_atoi(argv[4]); + height = g_atoi(argv[5]); + bpp = g_atoi(argv[6]); + make_stream(in_s); init_stream(in_s, 8192); - if (tcp_force_recv(sck, in_s->data, size - 8) == 0) + make_stream(out_s); + init_stream(out_s, 8192); + sck = g_tcp_socket(); + + if (g_tcp_connect(sck, argv[1], g_cfg.listen_port) == 0) { - if (version == 0) - { - in_uint16_be(in_s, code); - if (code == 3) + s_push_layer(out_s, channel_hdr, 8); + out_uint16_be(out_s, 0); /* code */ + i = g_strlen(username); + out_uint16_be(out_s, i); + out_uint8a(out_s, username, i); + i = g_strlen(password); + out_uint16_be(out_s, i); + out_uint8a(out_s, password, i); + out_uint16_be(out_s, width); + out_uint16_be(out_s, height); + out_uint16_be(out_s, bpp); + s_mark_end(out_s); + s_pop_layer(out_s, channel_hdr); + out_uint32_be(out_s, 0); /* version */ + out_uint32_be(out_s, out_s->end - out_s->data); /* size */ + tcp_force_send(sck, out_s->data, out_s->end - out_s->data); + + if (tcp_force_recv(sck, in_s->data, 8) == 0) { - in_uint16_be(in_s, data); - in_uint16_be(in_s, display); - g_printf("ok %d display %d\n", data, display); + in_uint32_be(in_s, version); + in_uint32_be(in_s, size); + init_stream(in_s, 8192); + + if (tcp_force_recv(sck, in_s->data, size - 8) == 0) + { + if (version == 0) + { + in_uint16_be(in_s, code); + + if (code == 3) + { + in_uint16_be(in_s, data); + in_uint16_be(in_s, display); + g_printf("ok %d display %d\n", data, display); + } + } + } } - } } - } - } - else - { - g_printf("connect error\n"); + else + { + g_printf("connect error\n"); + } + + g_tcp_close(sck); + free_stream(in_s); + free_stream(out_s); } - g_tcp_close(sck); - free_stream(in_s); - free_stream(out_s); - } - return 0; + + return 0; } diff --git a/sesman/tools/sestest.c b/sesman/tools/sestest.c index c0784ba3..f2823eb6 100644 --- a/sesman/tools/sestest.c +++ b/sesman/tools/sestest.c @@ -12,205 +12,217 @@ #include <stdio.h> -int inputSession(struct SCP_SESSION* s); +int inputSession(struct SCP_SESSION *s); unsigned int menuSelect(unsigned int choices); -int main(int argc, char** argv) +int main(int argc, char **argv) { - char buf[256]; - struct SCP_SESSION* s; - struct SCP_CONNECTION* c; - /*struct SCP_DISCONNECTED_SESSION ds;*/ - struct SCP_DISCONNECTED_SESSION* dsl; - enum SCP_CLIENT_STATES_E e; - struct log_config log; - int end; - int scnt; - int idx; - int sel; - int sock; - - log.enable_syslog=0; - log.log_level=99; - log.program_name=g_strdup("sestest"); - log.log_file=g_strdup("sestest.log"); - log_start_from_param(&log); - scp_init(&log); - - sock=g_tcp_socket(); - s = scp_session_create(); - c = scp_connection_create(sock); - - if (0!=g_tcp_connect(sock, "localhost", "3350")) - { - g_printf("error connecting"); - return 1; - } - - g_printf("001 - send connect request\n"); - - scp_session_set_type(s, SCP_SESSION_TYPE_XVNC); - scp_session_set_version(s, 1); - scp_session_set_height(s, 600); - scp_session_set_width(s, 800); - scp_session_set_bpp(s, 16); - scp_session_set_rsr(s, 0); - scp_session_set_locale(s, "it_IT"); - scp_session_set_username(s, "prog"); - scp_session_set_password(s, "prog"); - scp_session_set_hostname(s, "odin"); -// scp_session_set_addr(s, SCP_ADDRESS_TYPE_IPV4, "127.0.0.1"); -// scp_session_set_display(struct SCP_SESSION* s, SCP_DISPLAY display); -// scp_session_set_errstr(struct SCP_SESSION* s, char* str); - - /*s.type=SCP_SESSION_TYPE_XVNC; - s.version=1; - s.height=600; - s.width=800; - s.bpp=8; - s.rsr=0; - g_strncpy(s.locale,"it_IT 0123456789",18); - s.username=g_malloc(256, 1); - g_strncpy(s.username,"prog",255); - s.password=g_malloc(256,1); - g_strncpy(s.password, "prog", 255); - g_printf("%s - %s\n", s.username, s.password); - s.hostname=g_malloc(256,1); - g_strncpy(s.hostname, "odin", 255); - s.addr_type=SCP_ADDRESS_TYPE_IPV4; - s.ipv4addr=0; - s.errstr=0;*/ - - end=0; - e=scp_v1c_connect(c,s); - - while (!end) - { - switch (e) + char buf[256]; + struct SCP_SESSION *s; + struct SCP_CONNECTION *c; + /*struct SCP_DISCONNECTED_SESSION ds;*/ + struct SCP_DISCONNECTED_SESSION *dsl; + enum SCP_CLIENT_STATES_E e; + struct log_config log; + int end; + int scnt; + int idx; + int sel; + int sock; + + log.enable_syslog = 0; + log.log_level = 99; + log.program_name = g_strdup("sestest"); + log.log_file = g_strdup("sestest.log"); + log_start_from_param(&log); + scp_init(&log); + + sock = g_tcp_socket(); + s = scp_session_create(); + c = scp_connection_create(sock); + + if (0 != g_tcp_connect(sock, "localhost", "3350")) { - case SCP_CLIENT_STATE_OK: - g_printf("OK : display is %d\n", (short int)s->display); - end=1; - break; - case SCP_CLIENT_STATE_SESSION_LIST: - g_printf("OK : session list needed\n"); - e=scp_v1c_get_session_list(c, &scnt, &dsl); - break; - case SCP_CLIENT_STATE_LIST_OK: - g_printf("OK : selecting a session:\n"); - for (idx=0; idx <scnt; idx++) - { - printf("Session \t%d - %d - %dx%dx%d - %d %d %d - %4d/%2d/%2d@%2d:%2d\n", \ - (dsl[idx]).SID, (dsl[idx]).type, (dsl[idx]).width, (dsl[idx]).height, (dsl[idx]).bpp, \ - (dsl[idx]).idle_days, (dsl[idx]).idle_hours, (dsl[idx]).idle_minutes, \ - (dsl[idx]).conn_year, (dsl[idx]).conn_month, (dsl[idx]).conn_day, (dsl[idx]).conn_hour, (dsl[idx]).conn_minute); - } - sel = menuSelect(scnt); - e=scp_v1c_select_session(c, s, dsl[sel-1].SID); - g_printf("\n return: %d \n", e); - break; - case SCP_CLIENT_STATE_RESEND_CREDENTIALS: - g_printf("ERR: resend credentials - %s\n", s->errstr); - g_printf(" username:"); - if (scanf("%255s", buf) < 0) - { - g_writeln("error"); - } - scp_session_set_username(s, buf); - g_printf(" password:"); - if (scanf("%255s", buf) < 0) + g_printf("error connecting"); + return 1; + } + + g_printf("001 - send connect request\n"); + + scp_session_set_type(s, SCP_SESSION_TYPE_XVNC); + scp_session_set_version(s, 1); + scp_session_set_height(s, 600); + scp_session_set_width(s, 800); + scp_session_set_bpp(s, 16); + scp_session_set_rsr(s, 0); + scp_session_set_locale(s, "it_IT"); + scp_session_set_username(s, "prog"); + scp_session_set_password(s, "prog"); + scp_session_set_hostname(s, "odin"); + // scp_session_set_addr(s, SCP_ADDRESS_TYPE_IPV4, "127.0.0.1"); + // scp_session_set_display(struct SCP_SESSION* s, SCP_DISPLAY display); + // scp_session_set_errstr(struct SCP_SESSION* s, char* str); + + /*s.type=SCP_SESSION_TYPE_XVNC; + s.version=1; + s.height=600; + s.width=800; + s.bpp=8; + s.rsr=0; + g_strncpy(s.locale,"it_IT 0123456789",18); + s.username=g_malloc(256, 1); + g_strncpy(s.username,"prog",255); + s.password=g_malloc(256,1); + g_strncpy(s.password, "prog", 255); + g_printf("%s - %s\n", s.username, s.password); + s.hostname=g_malloc(256,1); + g_strncpy(s.hostname, "odin", 255); + s.addr_type=SCP_ADDRESS_TYPE_IPV4; + s.ipv4addr=0; + s.errstr=0;*/ + + end = 0; + e = scp_v1c_connect(c, s); + + while (!end) + { + switch (e) { - g_writeln("error"); + case SCP_CLIENT_STATE_OK: + g_printf("OK : display is %d\n", (short int)s->display); + end = 1; + break; + case SCP_CLIENT_STATE_SESSION_LIST: + g_printf("OK : session list needed\n"); + e = scp_v1c_get_session_list(c, &scnt, &dsl); + break; + case SCP_CLIENT_STATE_LIST_OK: + g_printf("OK : selecting a session:\n"); + + for (idx = 0; idx < scnt; idx++) + { + printf("Session \t%d - %d - %dx%dx%d - %d %d %d - %4d/%2d/%2d@%2d:%2d\n", \ + (dsl[idx]).SID, (dsl[idx]).type, (dsl[idx]).width, (dsl[idx]).height, (dsl[idx]).bpp, \ + (dsl[idx]).idle_days, (dsl[idx]).idle_hours, (dsl[idx]).idle_minutes, \ + (dsl[idx]).conn_year, (dsl[idx]).conn_month, (dsl[idx]).conn_day, (dsl[idx]).conn_hour, (dsl[idx]).conn_minute); + } + + sel = menuSelect(scnt); + e = scp_v1c_select_session(c, s, dsl[sel - 1].SID); + g_printf("\n return: %d \n", e); + break; + case SCP_CLIENT_STATE_RESEND_CREDENTIALS: + g_printf("ERR: resend credentials - %s\n", s->errstr); + g_printf(" username:"); + + if (scanf("%255s", buf) < 0) + { + g_writeln("error"); + } + + scp_session_set_username(s, buf); + g_printf(" password:"); + + if (scanf("%255s", buf) < 0) + { + g_writeln("error"); + } + + scp_session_set_password(s, buf); + e = scp_v1c_resend_credentials(c, s); + break; + case SCP_CLIENT_STATE_CONNECTION_DENIED: + g_printf("ERR: connection denied: %s\n", s->errstr); + end = 1; + break; + case SCP_CLIENT_STATE_PWD_CHANGE_REQ: + g_printf("OK : password change required\n"); + break; + /*case SCP_CLIENT_STATE_RECONNECT_SINGLE: + g_printf("OK : reconnect to 1 disconnected session\n"); + e=scp_v1c_retrieve_session(&c, &s, &ds); + g_printf("Session Type: %d on %d\n", ds.type, s.display); + g_printf("Session Screen: %dx%dx%d\n", ds.height, ds.width, ds.bpp);*/ + break; + default: + g_printf("protocol error: %d\n", e); + end = 1; } - scp_session_set_password(s, buf); - e=scp_v1c_resend_credentials(c,s); - break; - case SCP_CLIENT_STATE_CONNECTION_DENIED: - g_printf("ERR: connection denied: %s\n", s->errstr); - end=1; - break; - case SCP_CLIENT_STATE_PWD_CHANGE_REQ: - g_printf("OK : password change required\n"); - break; - /*case SCP_CLIENT_STATE_RECONNECT_SINGLE: - g_printf("OK : reconnect to 1 disconnected session\n"); - e=scp_v1c_retrieve_session(&c, &s, &ds); - g_printf("Session Type: %d on %d\n", ds.type, s.display); - g_printf("Session Screen: %dx%dx%d\n", ds.height, ds.width, ds.bpp);*/ - break; - default: - g_printf("protocol error: %d\n", e); - end=1; } - } - g_tcp_close(sock); - scp_session_destroy(s); - scp_connection_destroy(c); - /*free_stream(c.in_s); - free_stream(c.out_s);*/ + g_tcp_close(sock); + scp_session_destroy(s); + scp_connection_destroy(c); + /*free_stream(c.in_s); + free_stream(c.out_s);*/ - return 0; + return 0; } -int inputSession(struct SCP_SESSION* s) +int inputSession(struct SCP_SESSION *s) { - unsigned int integer; - - g_printf("username: "); - if (scanf("%255s", s->username) < 0) - { - g_writeln("error"); - } - g_printf("password:"); - if (scanf("%255s", s->password) < 0) - { - g_writeln("error"); - } - g_printf("hostname:"); - if (scanf("%255s", s->hostname) < 0) - { - g_writeln("error"); - } - - g_printf("session type:\n"); - g_printf("0: Xvnc\n", SCP_SESSION_TYPE_XVNC); - g_printf("1: x11rdp\n", SCP_SESSION_TYPE_XRDP); - integer=menuSelect(1); - if (integer==1) - { - s->type=SCP_SESSION_TYPE_XRDP; - } - else - { - s->type=SCP_SESSION_TYPE_XVNC; - } - - s->version=1; - s->height=600; - s->width=800; - s->bpp=8; - - /* fixed for now */ - s->rsr=0; - g_strncpy(s->locale,"it_IT 0123456789",18); - - return 0; + unsigned int integer; + + g_printf("username: "); + + if (scanf("%255s", s->username) < 0) + { + g_writeln("error"); + } + + g_printf("password:"); + + if (scanf("%255s", s->password) < 0) + { + g_writeln("error"); + } + + g_printf("hostname:"); + + if (scanf("%255s", s->hostname) < 0) + { + g_writeln("error"); + } + + g_printf("session type:\n"); + g_printf("0: Xvnc\n", SCP_SESSION_TYPE_XVNC); + g_printf("1: x11rdp\n", SCP_SESSION_TYPE_XRDP); + integer = menuSelect(1); + + if (integer == 1) + { + s->type = SCP_SESSION_TYPE_XRDP; + } + else + { + s->type = SCP_SESSION_TYPE_XVNC; + } + + s->version = 1; + s->height = 600; + s->width = 800; + s->bpp = 8; + + /* fixed for now */ + s->rsr = 0; + g_strncpy(s->locale, "it_IT 0123456789", 18); + + return 0; } tui32 menuSelect(tui32 choices) { - tui32 sel; - int ret; + tui32 sel; + int ret; - ret = scanf("%u", &sel); - - while ((ret == 0) || (sel > choices)) - { - g_printf("invalid choice."); ret = scanf("%u", &sel); - } - return sel; + while ((ret == 0) || (sel > choices)) + { + g_printf("invalid choice."); + ret = scanf("%u", &sel); + } + + return sel; } diff --git a/sesman/tools/tcp.c b/sesman/tools/tcp.c index 1cba18d6..c8d01e96 100644 --- a/sesman/tools/tcp.c +++ b/sesman/tools/tcp.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -35,111 +34,113 @@ /*****************************************************************************/ int DEFAULT_CC -tcp_force_recv(int sck, char* data, int len) +tcp_force_recv(int sck, char *data, int len) { - int rcvd; + int rcvd; -//#ifndef LIBSCP_CLIENT -// int block; -// block = lock_fork_critical_section_start(); -//#endif + //#ifndef LIBSCP_CLIENT + // int block; + // block = lock_fork_critical_section_start(); + //#endif - while (len > 0) - { - rcvd = g_tcp_recv(sck, data, len, 0); - if (rcvd == -1) + while (len > 0) { - if (g_tcp_last_error_would_block(sck)) - { - g_sleep(1); - } - else - { -//#ifndef LIBSCP_CLIENT -// lock_fork_critical_section_end(block); -//#endif - return 1; - } + rcvd = g_tcp_recv(sck, data, len, 0); + + if (rcvd == -1) + { + if (g_tcp_last_error_would_block(sck)) + { + g_sleep(1); + } + else + { + //#ifndef LIBSCP_CLIENT + // lock_fork_critical_section_end(block); + //#endif + return 1; + } + } + else if (rcvd == 0) + { + //#ifndef LIBSCP_CLIENT + // lock_fork_critical_section_end(block); + //#endif + return 1; + } + else + { + data += rcvd; + len -= rcvd; + } } - else if (rcvd == 0) - { -//#ifndef LIBSCP_CLIENT -// lock_fork_critical_section_end(block); -//#endif - return 1; - } - else - { - data += rcvd; - len -= rcvd; - } - } -//#ifndef LIBSCP_CLIENT -// lock_fork_critical_section_end(block); -//#endif + //#ifndef LIBSCP_CLIENT + // lock_fork_critical_section_end(block); + //#endif - return 0; + return 0; } /*****************************************************************************/ int DEFAULT_CC -tcp_force_send(int sck, char* data, int len) +tcp_force_send(int sck, char *data, int len) { - int sent; + int sent; -//#ifndef LIBSCP_CLIENT -// int block; -// block = lock_fork_critical_section_start(); -//#endif + //#ifndef LIBSCP_CLIENT + // int block; + // block = lock_fork_critical_section_start(); + //#endif - while (len > 0) - { - sent = g_tcp_send(sck, data, len, 0); - if (sent == -1) - { - if (g_tcp_last_error_would_block(sck)) - { - g_sleep(1); - } - else - { -//#ifndef LIBSCP_CLIENT -// lock_fork_critical_section_end(block); -//#endif - return 1; - } - } - else if (sent == 0) - { -//#ifndef LIBSCP_CLIENT -// lock_fork_critical_section_end(block); -//#endif - return 1; - } - else + while (len > 0) { - data += sent; - len -= sent; + sent = g_tcp_send(sck, data, len, 0); + + if (sent == -1) + { + if (g_tcp_last_error_would_block(sck)) + { + g_sleep(1); + } + else + { + //#ifndef LIBSCP_CLIENT + // lock_fork_critical_section_end(block); + //#endif + return 1; + } + } + else if (sent == 0) + { + //#ifndef LIBSCP_CLIENT + // lock_fork_critical_section_end(block); + //#endif + return 1; + } + else + { + data += sent; + len -= sent; + } } - } -//#ifndef LIBSCP_CLIENT -// lock_fork_critical_section_end(block); -//#endif + //#ifndef LIBSCP_CLIENT + // lock_fork_critical_section_end(block); + //#endif - return 0; + return 0; } /*****************************************************************************/ int DEFAULT_CC -tcp_bind(int sck, char* addr, char* port) +tcp_bind(int sck, char *addr, char *port) { - struct sockaddr_in s; + struct sockaddr_in s; - memset(&s, 0, sizeof(struct sockaddr_in)); - s.sin_family = AF_INET; - s.sin_port = htons(atoi(port)); - s.sin_addr.s_addr = inet_addr(addr); - return bind(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_in)); + memset(&s, 0, sizeof(struct sockaddr_in)); + s.sin_family = AF_INET; + s.sin_port = htons(atoi(port)); + s.sin_addr.s_addr = inet_addr(addr); + return bind(sck, (struct sockaddr *)&s, sizeof(struct sockaddr_in)); } diff --git a/sesman/tools/tcp.h b/sesman/tools/tcp.h index 5de12f18..2fd7963e 100644 --- a/sesman/tools/tcp.h +++ b/sesman/tools/tcp.h @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2010 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * diff --git a/sesman/tools/xcon.c b/sesman/tools/xcon.c index 7a45a1cd..bb715054 100644 --- a/sesman/tools/xcon.c +++ b/sesman/tools/xcon.c @@ -1,35 +1,58 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <X11/Xlib.h> -Display* g_display = 0; +Display *g_display = 0; int g_x_socket = 0; -int main(int argc, char** argv) +int main(int argc, char **argv) { - fd_set rfds; - int i1; - XEvent xevent; - - g_display = XOpenDisplay(0); - if (g_display == 0) - { - printf("XOpenDisplay failed\n"); - return 0; - } - g_x_socket = XConnectionNumber(g_display); - while (1) - { - FD_ZERO(&rfds); - FD_SET(g_x_socket, &rfds); - i1 = select(g_x_socket + 1, &rfds, 0, 0, 0); - if (i1 < 0) + fd_set rfds; + int i1; + XEvent xevent; + + g_display = XOpenDisplay(0); + + if (g_display == 0) { - break; + printf("XOpenDisplay failed\n"); + return 0; } - XNextEvent(g_display, &xevent); - } - return 0; + + g_x_socket = XConnectionNumber(g_display); + + while (1) + { + FD_ZERO(&rfds); + FD_SET(g_x_socket, &rfds); + i1 = select(g_x_socket + 1, &rfds, 0, 0, 0); + + if (i1 < 0) + { + break; + } + + XNextEvent(g_display, &xevent); + } + + return 0; } diff --git a/sesman/verify_user.c b/sesman/verify_user.c index aaa1515c..8765d7c2 100644 --- a/sesman/verify_user.c +++ b/sesman/verify_user.c @@ -1,21 +1,20 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2008 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * @@ -38,77 +37,89 @@ #define SECS_PER_DAY (24L*3600L) #endif -extern struct config_sesman* g_cfg; /* in sesman.c */ +extern struct config_sesman *g_cfg; /* in sesman.c */ static int DEFAULT_CC -auth_crypt_pwd(char* pwd, char* pln, char* crp); +auth_crypt_pwd(char *pwd, char *pln, char *crp); static int DEFAULT_CC -auth_account_disabled(struct spwd* stp); +auth_account_disabled(struct spwd *stp); /******************************************************************************/ /* returns boolean */ long DEFAULT_CC -auth_userpass(char* user, char* pass) +auth_userpass(char *user, char *pass) { - char salt[13] = "$1$"; - char hash[35] = ""; - char* encr = 0; - struct passwd* spw; - struct spwd* stp; - int saltcnt = 0; - - spw = getpwnam(user); - if (spw == 0) - { - return 0; - } - if (g_strncmp(spw->pw_passwd, "x", 3) == 0) - { - /* the system is using shadow */ - stp = getspnam(user); - if (stp == 0) + char salt[13] = "$1$"; + char hash[35] = ""; + char *encr = 0; + struct passwd *spw; + struct spwd *stp; + int saltcnt = 0; + + spw = getpwnam(user); + + if (spw == 0) { - return 0; + return 0; } - if (1==auth_account_disabled(stp)) + + if (g_strncmp(spw->pw_passwd, "x", 3) == 0) { - log_message(&(g_cfg->log), LOG_LEVEL_INFO, "account %s is disabled", user); - return 0; + /* the system is using shadow */ + stp = getspnam(user); + + if (stp == 0) + { + return 0; + } + + if (1 == auth_account_disabled(stp)) + { + log_message(&(g_cfg->log), LOG_LEVEL_INFO, "account %s is disabled", user); + return 0; + } + + g_strncpy(hash, stp->sp_pwdp, 34); } - g_strncpy(hash, stp->sp_pwdp, 34); - } - else - { - /* old system with only passwd */ - g_strncpy(hash, spw->pw_passwd, 34); - } - hash[34] = '\0'; - if (g_strncmp(hash, "$1$", 3) == 0) - { - /* gnu style crypt(); */ - saltcnt = 3; - while ((hash[saltcnt] != '$') && (saltcnt < 11)) + else { - salt[saltcnt] = hash[saltcnt]; - saltcnt++; + /* old system with only passwd */ + g_strncpy(hash, spw->pw_passwd, 34); } - salt[saltcnt] = '$'; - salt[saltcnt + 1] = '\0'; - } - else - { - /* classic two char salt */ - salt[0] = hash[0]; - salt[1] = hash[1]; - salt[2] = '\0'; - } - encr = crypt(pass,salt); - if (g_strncmp(encr, hash, 34) != 0) - { - return 0; - } - return 1; + + hash[34] = '\0'; + + if (g_strncmp(hash, "$1$", 3) == 0) + { + /* gnu style crypt(); */ + saltcnt = 3; + + while ((hash[saltcnt] != '$') && (saltcnt < 11)) + { + salt[saltcnt] = hash[saltcnt]; + saltcnt++; + } + + salt[saltcnt] = '$'; + salt[saltcnt + 1] = '\0'; + } + else + { + /* classic two char salt */ + salt[0] = hash[0]; + salt[1] = hash[1]; + salt[2] = '\0'; + } + + encr = crypt(pass, salt); + + if (g_strncmp(encr, hash, 34) != 0) + { + return 0; + } + + return 1; } /******************************************************************************/ @@ -116,138 +127,144 @@ auth_userpass(char* user, char* pass) int DEFAULT_CC auth_start_session(long in_val, int in_display) { - return 0; + return 0; } /******************************************************************************/ int DEFAULT_CC auth_end(long in_val) { - return 0; + return 0; } /******************************************************************************/ int DEFAULT_CC auth_set_env(long in_val) { - return 0; + return 0; } /******************************************************************************/ int DEFAULT_CC -auth_check_pwd_chg(char* user) +auth_check_pwd_chg(char *user) { - struct passwd* spw; - struct spwd* stp; - int now; - long today; - - spw = getpwnam(user); - if (spw == 0) - { - return AUTH_PWD_CHG_ERROR; - } - if (g_strncmp(spw->pw_passwd, "x", 3) != 0) - { - /* old system with only passwd */ - return AUTH_PWD_CHG_OK; - } + struct passwd *spw; + struct spwd *stp; + int now; + long today; + + spw = getpwnam(user); + + if (spw == 0) + { + return AUTH_PWD_CHG_ERROR; + } + + if (g_strncmp(spw->pw_passwd, "x", 3) != 0) + { + /* old system with only passwd */ + return AUTH_PWD_CHG_OK; + } + + /* the system is using shadow */ + stp = getspnam(user); + + if (stp == 0) + { + return AUTH_PWD_CHG_ERROR; + } - /* the system is using shadow */ - stp = getspnam(user); - if (stp == 0) - { - return AUTH_PWD_CHG_ERROR; - } + /* check if we need a pwd change */ + now = g_time1(); + today = now / SECS_PER_DAY; - /* check if we need a pwd change */ - now=g_time1(); - today=now/SECS_PER_DAY; + if (stp->sp_expire == -1) + { + return AUTH_PWD_CHG_OK; + } + + if (today >= (stp->sp_lstchg + stp->sp_max - stp->sp_warn)) + { + return AUTH_PWD_CHG_CHANGE; + } + + if (today >= (stp->sp_lstchg + stp->sp_max)) + { + return AUTH_PWD_CHG_CHANGE_MANDATORY; + } + + if (today < ((stp->sp_lstchg) + (stp->sp_min))) + { + /* cannot change pwd for now */ + return AUTH_PWD_CHG_NOT_NOW; + } - if (stp->sp_expire == -1) - { return AUTH_PWD_CHG_OK; - } - if (today >= (stp->sp_lstchg + stp->sp_max - stp->sp_warn)) - { - return AUTH_PWD_CHG_CHANGE; - } - - if (today >= (stp->sp_lstchg + stp->sp_max)) - { - return AUTH_PWD_CHG_CHANGE_MANDATORY; - } - - if (today < ((stp->sp_lstchg)+(stp->sp_min))) - { - /* cannot change pwd for now */ - return AUTH_PWD_CHG_NOT_NOW; - } - - return AUTH_PWD_CHG_OK; } int DEFAULT_CC -auth_change_pwd(char* user, char* newpwd) +auth_change_pwd(char *user, char *newpwd) { - struct passwd* spw; - struct spwd* stp; - char hash[35] = ""; - long today; + struct passwd *spw; + struct spwd *stp; + char hash[35] = ""; + long today; - FILE* fd; + FILE *fd; - if (0 != lckpwdf()) - { - return 1; - } + if (0 != lckpwdf()) + { + return 1; + } - /* open passwd */ - spw = getpwnam(user); - if (spw == 0) - { - return 1; - } + /* open passwd */ + spw = getpwnam(user); - if (g_strncmp(spw->pw_passwd, "x", 3) != 0) - { - /* old system with only passwd */ - if (auth_crypt_pwd(spw->pw_passwd, newpwd, hash) != 0) + if (spw == 0) { - ulckpwdf(); - return 1; + return 1; } - spw->pw_passwd=g_strdup(hash); - fd = fopen("/etc/passwd", "rw"); - putpwent(spw, fd); - } - else - { - /* the system is using shadow */ - stp = getspnam(user); - if (stp == 0) + if (g_strncmp(spw->pw_passwd, "x", 3) != 0) { - return 1; + /* old system with only passwd */ + if (auth_crypt_pwd(spw->pw_passwd, newpwd, hash) != 0) + { + ulckpwdf(); + return 1; + } + + spw->pw_passwd = g_strdup(hash); + fd = fopen("/etc/passwd", "rw"); + putpwent(spw, fd); } - - /* old system with only passwd */ - if (auth_crypt_pwd(stp->sp_pwdp, newpwd, hash) != 0) + else { - ulckpwdf(); - return 1; + /* the system is using shadow */ + stp = getspnam(user); + + if (stp == 0) + { + return 1; + } + + /* old system with only passwd */ + if (auth_crypt_pwd(stp->sp_pwdp, newpwd, hash) != 0) + { + ulckpwdf(); + return 1; + } + + stp->sp_pwdp = g_strdup(hash); + today = g_time1() / SECS_PER_DAY; + stp->sp_lstchg = today; + stp->sp_expire = today + stp->sp_max + stp->sp_inact; + fd = fopen("/etc/shadow", "rw"); + putspent(stp, fd); } - stp->sp_pwdp = g_strdup(hash); - today = g_time1() / SECS_PER_DAY; - stp->sp_lstchg = today; - stp->sp_expire = today + stp->sp_max + stp->sp_inact; - fd = fopen("/etc/shadow", "rw"); - putspent(stp, fd); - } - - ulckpwdf(); - return 0; + ulckpwdf(); + return 0; } /** @@ -260,36 +277,38 @@ auth_change_pwd(char* user, char* newpwd) */ static int DEFAULT_CC -auth_crypt_pwd(char* pwd, char* pln, char* crp) +auth_crypt_pwd(char *pwd, char *pln, char *crp) { - char salt[13] = "$1$"; - int saltcnt = 0; - char* encr; - - if (g_strncmp(pwd, "$1$", 3) == 0) - { - /* gnu style crypt(); */ - saltcnt = 3; - while ((pwd[saltcnt] != '$') && (saltcnt < 11)) + char salt[13] = "$1$"; + int saltcnt = 0; + char *encr; + + if (g_strncmp(pwd, "$1$", 3) == 0) + { + /* gnu style crypt(); */ + saltcnt = 3; + + while ((pwd[saltcnt] != '$') && (saltcnt < 11)) + { + salt[saltcnt] = pwd[saltcnt]; + saltcnt++; + } + + salt[saltcnt] = '$'; + salt[saltcnt + 1] = '\0'; + } + else { - salt[saltcnt] = pwd[saltcnt]; - saltcnt++; + /* classic two char salt */ + salt[0] = pwd[0]; + salt[1] = pwd[1]; + salt[2] = '\0'; } - salt[saltcnt] = '$'; - salt[saltcnt + 1] = '\0'; - } - else - { - /* classic two char salt */ - salt[0] = pwd[0]; - salt[1] = pwd[1]; - salt[2] = '\0'; - } - - encr = crypt(pln, salt); - g_strncpy(crp, encr, 34); - - return 0; + + encr = crypt(pln, salt); + g_strncpy(crp, encr, 34); + + return 0; } /** @@ -298,35 +317,35 @@ auth_crypt_pwd(char* pwd, char* pln, char* crp) * */ static int DEFAULT_CC -auth_account_disabled(struct spwd* stp) +auth_account_disabled(struct spwd *stp) { - int today; + int today; - if (0 == stp) - { - /* if an invalid struct was passed we assume a disabled account */ - return 1; - } + if (0 == stp) + { + /* if an invalid struct was passed we assume a disabled account */ + return 1; + } - today = g_time1() / SECS_PER_DAY; + today = g_time1() / SECS_PER_DAY; - LOG_DBG("last %d",stp->sp_lstchg); - LOG_DBG("min %d",stp->sp_min); - LOG_DBG("max %d",stp->sp_max); - LOG_DBG("inact %d",stp->sp_inact); - LOG_DBG("warn %d",stp->sp_warn); - LOG_DBG("expire %d",stp->sp_expire); - LOG_DBG("today %d",today); + LOG_DBG("last %d", stp->sp_lstchg); + LOG_DBG("min %d", stp->sp_min); + LOG_DBG("max %d", stp->sp_max); + LOG_DBG("inact %d", stp->sp_inact); + LOG_DBG("warn %d", stp->sp_warn); + LOG_DBG("expire %d", stp->sp_expire); + LOG_DBG("today %d", today); - if ((stp->sp_expire != -1) && (today >= stp->sp_expire)) - { - return 1; - } + if ((stp->sp_expire != -1) && (today >= stp->sp_expire)) + { + return 1; + } - if (today >= (stp->sp_lstchg+stp->sp_max+stp->sp_inact)) - { - return 1; - } + if (today >= (stp->sp_lstchg + stp->sp_max + stp->sp_inact)) + { + return 1; + } - return 0; + return 0; } diff --git a/sesman/verify_user_kerberos.c b/sesman/verify_user_kerberos.c index 68b232af..c4a7ecde 100644 --- a/sesman/verify_user_kerberos.c +++ b/sesman/verify_user_kerberos.c @@ -1,28 +1,27 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2008 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * * @file verify_user_kerberos.c * @brief Authenticate user using kerberos * @author Jay Sorg - * + * */ #include "arch.h" @@ -34,346 +33,393 @@ typedef enum { INIT_PW, INIT_KT, RENEW, VALIDATE } action_type; struct k_opts { - /* in seconds */ - krb5_deltat starttime; - krb5_deltat lifetime; - krb5_deltat rlife; + /* in seconds */ + krb5_deltat starttime; + krb5_deltat lifetime; + krb5_deltat rlife; - int forwardable; - int proxiable; - int addresses; + int forwardable; + int proxiable; + int addresses; - int not_forwardable; - int not_proxiable; - int no_addresses; + int not_forwardable; + int not_proxiable; + int no_addresses; - int verbose; + int verbose; - char* principal_name; - char* service_name; - char* keytab_name; - char* k5_cache_name; - char* k4_cache_name; + char *principal_name; + char *service_name; + char *keytab_name; + char *k5_cache_name; + char *k4_cache_name; - action_type action; + action_type action; }; struct k5_data { - krb5_context ctx; - krb5_ccache cc; - krb5_principal me; - char* name; + krb5_context ctx; + krb5_ccache cc; + krb5_principal me; + char *name; }; struct user_info { - char* name; - char* pass; + char *name; + char *pass; }; /******************************************************************************/ /* returns boolean */ static int DEFAULT_CC -k5_begin(struct k_opts* opts, struct k5_data* k5, struct user_info* u_info) +k5_begin(struct k_opts *opts, struct k5_data *k5, struct user_info *u_info) { - krb5_error_code code = 0; + krb5_error_code code = 0; + + code = krb5_init_context(&k5->ctx); - code = krb5_init_context(&k5->ctx); - if (code != 0) - { - g_printf("krb5_init_context failed in k5_begin\n"); - return 0; - } - if (opts->k5_cache_name) - { - code = krb5_cc_resolve(k5->ctx, opts->k5_cache_name, &k5->cc); if (code != 0) { - g_printf("krb5_cc_resolve failed in k5_begin\n"); - return 0; + g_printf("krb5_init_context failed in k5_begin\n"); + return 0; } - } - else - { - code = krb5_cc_default(k5->ctx, &k5->cc); - if (code != 0) + + if (opts->k5_cache_name) { - g_printf("krb5_cc_default failed in k5_begin\n"); - return 0; + code = krb5_cc_resolve(k5->ctx, opts->k5_cache_name, &k5->cc); + + if (code != 0) + { + g_printf("krb5_cc_resolve failed in k5_begin\n"); + return 0; + } } - } - if (opts->principal_name) - { - /* Use specified name */ - code = krb5_parse_name(k5->ctx, opts->principal_name, &k5->me); - if (code != 0) + else { - g_printf("krb5_parse_name failed in k5_begin\n"); - return 0; + code = krb5_cc_default(k5->ctx, &k5->cc); + + if (code != 0) + { + g_printf("krb5_cc_default failed in k5_begin\n"); + return 0; + } } - } - else - { - /* No principal name specified */ - if (opts->action == INIT_KT) + + if (opts->principal_name) { - /* Use the default host/service name */ - code = krb5_sname_to_principal(k5->ctx, NULL, NULL, - KRB5_NT_SRV_HST, &k5->me); - if (code != 0) - { - g_printf("krb5_sname_to_principal failed in k5_begin\n"); - return 0; - } + /* Use specified name */ + code = krb5_parse_name(k5->ctx, opts->principal_name, &k5->me); + + if (code != 0) + { + g_printf("krb5_parse_name failed in k5_begin\n"); + return 0; + } } else { - /* Get default principal from cache if one exists */ - code = krb5_cc_get_principal(k5->ctx, k5->cc, &k5->me); - if (code != 0) - { - code = krb5_parse_name(k5->ctx, u_info->name, &k5->me); - if (code != 0) + /* No principal name specified */ + if (opts->action == INIT_KT) { - g_printf("krb5_parse_name failed in k5_begin\n"); - return 0; + /* Use the default host/service name */ + code = krb5_sname_to_principal(k5->ctx, NULL, NULL, + KRB5_NT_SRV_HST, &k5->me); + + if (code != 0) + { + g_printf("krb5_sname_to_principal failed in k5_begin\n"); + return 0; + } + } + else + { + /* Get default principal from cache if one exists */ + code = krb5_cc_get_principal(k5->ctx, k5->cc, &k5->me); + + if (code != 0) + { + code = krb5_parse_name(k5->ctx, u_info->name, &k5->me); + + if (code != 0) + { + g_printf("krb5_parse_name failed in k5_begin\n"); + return 0; + } + } } - } } - } - code = krb5_unparse_name(k5->ctx, k5->me, &k5->name); - if (code != 0) - { - g_printf("krb5_unparse_name failed in k5_begin\n"); - return 0; - } - opts->principal_name = k5->name; - return 1; + + code = krb5_unparse_name(k5->ctx, k5->me, &k5->name); + + if (code != 0) + { + g_printf("krb5_unparse_name failed in k5_begin\n"); + return 0; + } + + opts->principal_name = k5->name; + return 1; } /******************************************************************************/ static void DEFAULT_CC -k5_end(struct k5_data* k5) +k5_end(struct k5_data *k5) { - if (k5->name) - { - krb5_free_unparsed_name(k5->ctx, k5->name); - } - if (k5->me) - { - krb5_free_principal(k5->ctx, k5->me); - } - if (k5->cc) - { - krb5_cc_close(k5->ctx, k5->cc); - } - if (k5->ctx) - { - krb5_free_context(k5->ctx); - } - g_memset(k5, 0, sizeof(struct k5_data)); + if (k5->name) + { + krb5_free_unparsed_name(k5->ctx, k5->name); + } + + if (k5->me) + { + krb5_free_principal(k5->ctx, k5->me); + } + + if (k5->cc) + { + krb5_cc_close(k5->ctx, k5->cc); + } + + if (k5->ctx) + { + krb5_free_context(k5->ctx); + } + + g_memset(k5, 0, sizeof(struct k5_data)); } /******************************************************************************/ static krb5_error_code KRB5_CALLCONV -kinit_prompter(krb5_context ctx, void* data, const char* name, - const char* banner, int num_prompts, krb5_prompt prompts[]) +kinit_prompter(krb5_context ctx, void *data, const char *name, + const char *banner, int num_prompts, krb5_prompt prompts[]) { - int i; - krb5_prompt_type* types; - krb5_error_code rc; - struct user_info* u_info; - - u_info = (struct user_info*)data; - rc = 0; - types = krb5_get_prompt_types(ctx); - for (i = 0; i < num_prompts; i++) - { - if (types[i] == KRB5_PROMPT_TYPE_PASSWORD || - types[i] == KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN) + int i; + krb5_prompt_type *types; + krb5_error_code rc; + struct user_info *u_info; + + u_info = (struct user_info *)data; + rc = 0; + types = krb5_get_prompt_types(ctx); + + for (i = 0; i < num_prompts; i++) { - g_strncpy(prompts[i].reply->data, u_info->pass, 255); + if (types[i] == KRB5_PROMPT_TYPE_PASSWORD || + types[i] == KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN) + { + g_strncpy(prompts[i].reply->data, u_info->pass, 255); + } } - } - return rc; + + return rc; } /******************************************************************************/ /* returns boolean */ static int -k5_kinit(struct k_opts* opts, struct k5_data* k5, struct user_info* u_info) +k5_kinit(struct k_opts *opts, struct k5_data *k5, struct user_info *u_info) { - char* doing; - int notix = 1; - krb5_keytab keytab = 0; - krb5_creds my_creds; - krb5_error_code code = 0; - krb5_get_init_creds_opt options; - krb5_address** addresses; - - krb5_get_init_creds_opt_init(&options); - g_memset(&my_creds, 0, sizeof(my_creds)); - /* - From this point on, we can goto cleanup because my_creds is - initialized. - */ - if (opts->lifetime) - { - krb5_get_init_creds_opt_set_tkt_life(&options, opts->lifetime); - } - if (opts->rlife) - { - krb5_get_init_creds_opt_set_renew_life(&options, opts->rlife); - } - if (opts->forwardable) - { - krb5_get_init_creds_opt_set_forwardable(&options, 1); - } - if (opts->not_forwardable) - { - krb5_get_init_creds_opt_set_forwardable(&options, 0); - } - if (opts->proxiable) - { - krb5_get_init_creds_opt_set_proxiable(&options, 1); - } - if (opts->not_proxiable) - { - krb5_get_init_creds_opt_set_proxiable(&options, 0); - } - if (opts->addresses) - { - addresses = NULL; - code = krb5_os_localaddr(k5->ctx, &addresses); - if (code != 0) + char *doing; + int notix = 1; + krb5_keytab keytab = 0; + krb5_creds my_creds; + krb5_error_code code = 0; + krb5_get_init_creds_opt options; + krb5_address **addresses; + + krb5_get_init_creds_opt_init(&options); + g_memset(&my_creds, 0, sizeof(my_creds)); + + /* + From this point on, we can goto cleanup because my_creds is + initialized. + */ + if (opts->lifetime) { - g_printf("krb5_os_localaddr failed in k5_kinit\n"); - goto cleanup; + krb5_get_init_creds_opt_set_tkt_life(&options, opts->lifetime); } - krb5_get_init_creds_opt_set_address_list(&options, addresses); - } - if (opts->no_addresses) - { - krb5_get_init_creds_opt_set_address_list(&options, NULL); - } - if ((opts->action == INIT_KT) && opts->keytab_name) - { - code = krb5_kt_resolve(k5->ctx, opts->keytab_name, &keytab); - if (code != 0) + + if (opts->rlife) + { + krb5_get_init_creds_opt_set_renew_life(&options, opts->rlife); + } + + if (opts->forwardable) + { + krb5_get_init_creds_opt_set_forwardable(&options, 1); + } + + if (opts->not_forwardable) + { + krb5_get_init_creds_opt_set_forwardable(&options, 0); + } + + if (opts->proxiable) + { + krb5_get_init_creds_opt_set_proxiable(&options, 1); + } + + if (opts->not_proxiable) { - g_printf("krb5_kt_resolve failed in k5_kinit\n"); - goto cleanup; + krb5_get_init_creds_opt_set_proxiable(&options, 0); + } + + if (opts->addresses) + { + addresses = NULL; + code = krb5_os_localaddr(k5->ctx, &addresses); + + if (code != 0) + { + g_printf("krb5_os_localaddr failed in k5_kinit\n"); + goto cleanup; + } + + krb5_get_init_creds_opt_set_address_list(&options, addresses); } - } - switch (opts->action) - { - case INIT_PW: - code = krb5_get_init_creds_password(k5->ctx, &my_creds, k5->me, - 0, kinit_prompter, u_info, - opts->starttime, - opts->service_name, - &options); - break; - case INIT_KT: - code = krb5_get_init_creds_keytab(k5->ctx, &my_creds, k5->me, - keytab, - opts->starttime, - opts->service_name, - &options); - break; - case VALIDATE: - code = krb5_get_validated_creds(k5->ctx, &my_creds, k5->me, k5->cc, - opts->service_name); - break; - case RENEW: - code = krb5_get_renewed_creds(k5->ctx, &my_creds, k5->me, k5->cc, - opts->service_name); - break; - } - if (code != 0) - { - doing = 0; + + if (opts->no_addresses) + { + krb5_get_init_creds_opt_set_address_list(&options, NULL); + } + + if ((opts->action == INIT_KT) && opts->keytab_name) + { + code = krb5_kt_resolve(k5->ctx, opts->keytab_name, &keytab); + + if (code != 0) + { + g_printf("krb5_kt_resolve failed in k5_kinit\n"); + goto cleanup; + } + } + switch (opts->action) { - case INIT_PW: - case INIT_KT: - doing = "getting initial credentials"; - break; - case VALIDATE: - doing = "validating credentials"; - break; - case RENEW: - doing = "renewing credentials"; - break; + case INIT_PW: + code = krb5_get_init_creds_password(k5->ctx, &my_creds, k5->me, + 0, kinit_prompter, u_info, + opts->starttime, + opts->service_name, + &options); + break; + case INIT_KT: + code = krb5_get_init_creds_keytab(k5->ctx, &my_creds, k5->me, + keytab, + opts->starttime, + opts->service_name, + &options); + break; + case VALIDATE: + code = krb5_get_validated_creds(k5->ctx, &my_creds, k5->me, k5->cc, + opts->service_name); + break; + case RENEW: + code = krb5_get_renewed_creds(k5->ctx, &my_creds, k5->me, k5->cc, + opts->service_name); + break; } - if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY) + + if (code != 0) { - g_printf("sesman: Password incorrect while %s in k5_kinit\n", doing); + doing = 0; + + switch (opts->action) + { + case INIT_PW: + case INIT_KT: + doing = "getting initial credentials"; + break; + case VALIDATE: + doing = "validating credentials"; + break; + case RENEW: + doing = "renewing credentials"; + break; + } + + if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY) + { + g_printf("sesman: Password incorrect while %s in k5_kinit\n", doing); + } + else + { + g_printf("sesman: error while %s in k5_kinit\n", doing); + } + + goto cleanup; } - else + + if (!opts->lifetime) + { + /* We need to figure out what lifetime to use for Kerberos 4. */ + opts->lifetime = my_creds.times.endtime - my_creds.times.authtime; + } + + code = krb5_cc_initialize(k5->ctx, k5->cc, k5->me); + + if (code != 0) + { + g_printf("krb5_cc_initialize failed in k5_kinit\n"); + goto cleanup; + } + + code = krb5_cc_store_cred(k5->ctx, k5->cc, &my_creds); + + if (code != 0) { - g_printf("sesman: error while %s in k5_kinit\n", doing); + g_printf("krb5_cc_store_cred failed in k5_kinit\n"); + goto cleanup; } - goto cleanup; - } - if (!opts->lifetime) - { - /* We need to figure out what lifetime to use for Kerberos 4. */ - opts->lifetime = my_creds.times.endtime - my_creds.times.authtime; - } - code = krb5_cc_initialize(k5->ctx, k5->cc, k5->me); - if (code != 0) - { - g_printf("krb5_cc_initialize failed in k5_kinit\n"); - goto cleanup; - } - code = krb5_cc_store_cred(k5->ctx, k5->cc, &my_creds); - if (code != 0) - { - g_printf("krb5_cc_store_cred failed in k5_kinit\n"); - goto cleanup; - } - notix = 0; + + notix = 0; cleanup: - if (my_creds.client == k5->me) - { - my_creds.client = 0; - } - krb5_free_cred_contents(k5->ctx, &my_creds); - if (keytab) - { - krb5_kt_close(k5->ctx, keytab); - } - return notix ? 0 : 1; + + if (my_creds.client == k5->me) + { + my_creds.client = 0; + } + + krb5_free_cred_contents(k5->ctx, &my_creds); + + if (keytab) + { + krb5_kt_close(k5->ctx, keytab); + } + + return notix ? 0 : 1; } /******************************************************************************/ /* returns boolean */ int DEFAULT_CC -auth_userpass(char* user, char* pass) +auth_userpass(char *user, char *pass) { - struct k_opts opts; - struct k5_data k5; - struct user_info u_info; - int got_k5; - int authed_k5; - - g_memset(&opts, 0, sizeof(opts)); - opts.action = INIT_PW; - g_memset(&k5, 0, sizeof(k5)); - g_memset(&u_info, 0, sizeof(u_info)); - u_info.name = user; - u_info.pass = pass; - authed_k5 = 0; - got_k5 = k5_begin(&opts, &k5, &u_info); - if (got_k5) - { - authed_k5 = k5_kinit(&opts, &k5, &u_info); - k5_end(&k5); - } - return authed_k5; + struct k_opts opts; + struct k5_data k5; + struct user_info u_info; + int got_k5; + int authed_k5; + + g_memset(&opts, 0, sizeof(opts)); + opts.action = INIT_PW; + g_memset(&k5, 0, sizeof(k5)); + g_memset(&u_info, 0, sizeof(u_info)); + u_info.name = user; + u_info.pass = pass; + authed_k5 = 0; + got_k5 = k5_begin(&opts, &k5, &u_info); + + if (got_k5) + { + authed_k5 = k5_kinit(&opts, &k5, &u_info); + k5_end(&k5); + } + + return authed_k5; } /******************************************************************************/ @@ -381,19 +427,19 @@ auth_userpass(char* user, char* pass) int DEFAULT_CC auth_start_session(void) { - return 0; + return 0; } /******************************************************************************/ int DEFAULT_CC auth_end(void) { - return 0; + return 0; } /******************************************************************************/ int DEFAULT_CC auth_set_env(void) { - return 0; + return 0; } diff --git a/sesman/verify_user_pam.c b/sesman/verify_user_pam.c index e3d8596e..b81398de 100644 --- a/sesman/verify_user_pam.c +++ b/sesman/verify_user_pam.c @@ -1,28 +1,27 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2008 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * * @file verify_user_pam.c * @brief Authenticate user using pam * @author Jay Sorg - * + * */ #include "arch.h" @@ -33,107 +32,116 @@ struct t_user_pass { - char user[256]; - char pass[256]; + char user[256]; + char pass[256]; }; struct t_auth_info { - struct t_user_pass user_pass; - int session_opened; - int did_setcred; - struct pam_conv pamc; - pam_handle_t* ph; + struct t_user_pass user_pass; + int session_opened; + int did_setcred; + struct pam_conv pamc; + pam_handle_t *ph; }; /******************************************************************************/ static int DEFAULT_CC -verify_pam_conv(int num_msg, const struct pam_message** msg, - struct pam_response** resp, void* appdata_ptr) +verify_pam_conv(int num_msg, const struct pam_message **msg, + struct pam_response **resp, void *appdata_ptr) { - int i; - struct pam_response* reply; - struct t_user_pass* user_pass; - - reply = g_malloc(sizeof(struct pam_response) * num_msg, 1); - for (i = 0; i < num_msg; i++) - { - switch (msg[i]->msg_style) + int i; + struct pam_response *reply; + struct t_user_pass *user_pass; + + reply = g_malloc(sizeof(struct pam_response) * num_msg, 1); + + for (i = 0; i < num_msg; i++) { - case PAM_PROMPT_ECHO_ON: /* username */ - user_pass = appdata_ptr; - reply[i].resp = g_strdup(user_pass->user); - reply[i].resp_retcode = PAM_SUCCESS; - break; - case PAM_PROMPT_ECHO_OFF: /* password */ - user_pass = appdata_ptr; - reply[i].resp = g_strdup(user_pass->pass); - reply[i].resp_retcode = PAM_SUCCESS; - break; - default: - g_printf("unknown in verify_pam_conv\r\n"); - g_free(reply); - return PAM_CONV_ERR; + switch (msg[i]->msg_style) + { + case PAM_PROMPT_ECHO_ON: /* username */ + user_pass = appdata_ptr; + reply[i].resp = g_strdup(user_pass->user); + reply[i].resp_retcode = PAM_SUCCESS; + break; + case PAM_PROMPT_ECHO_OFF: /* password */ + user_pass = appdata_ptr; + reply[i].resp = g_strdup(user_pass->pass); + reply[i].resp_retcode = PAM_SUCCESS; + break; + default: + g_printf("unknown in verify_pam_conv\r\n"); + g_free(reply); + return PAM_CONV_ERR; + } } - } - *resp = reply; - return PAM_SUCCESS; + + *resp = reply; + return PAM_SUCCESS; } /******************************************************************************/ static void DEFAULT_CC -get_service_name(char* service_name) +get_service_name(char *service_name) { - service_name[0] = 0; - if (g_file_exist("/etc/pam.d/xrdp-sesman")) - { - g_strncpy(service_name, "xrdp-sesman", 255); - } - else - { - g_strncpy(service_name, "gdm", 255); - } + service_name[0] = 0; + + if (g_file_exist("/etc/pam.d/xrdp-sesman")) + { + g_strncpy(service_name, "xrdp-sesman", 255); + } + else + { + g_strncpy(service_name, "gdm", 255); + } } /******************************************************************************/ /* returns long, zero is no go */ long DEFAULT_CC -auth_userpass(char* user, char* pass) +auth_userpass(char *user, char *pass) { - int error; - struct t_auth_info* auth_info; - char service_name[256]; - - get_service_name(service_name); - auth_info = g_malloc(sizeof(struct t_auth_info), 1); - g_strncpy(auth_info->user_pass.user, user, 255); - g_strncpy(auth_info->user_pass.pass, pass, 255); - auth_info->pamc.conv = &verify_pam_conv; - auth_info->pamc.appdata_ptr = &(auth_info->user_pass); - error = pam_start(service_name, 0, &(auth_info->pamc), &(auth_info->ph)); - if (error != PAM_SUCCESS) - { - g_printf("pam_start failed: %s\r\n", pam_strerror(auth_info->ph, error)); - g_free(auth_info); - return 0; - } - error = pam_authenticate(auth_info->ph, 0); - if (error != PAM_SUCCESS) - { - g_printf("pam_authenticate failed: %s\r\n", - pam_strerror(auth_info->ph, error)); - g_free(auth_info); - return 0; - } - error = pam_acct_mgmt(auth_info->ph, 0); - if (error != PAM_SUCCESS) - { - g_printf("pam_acct_mgmt failed: %s\r\n", - pam_strerror(auth_info->ph, error)); - g_free(auth_info); - return 0; - } - return (long)auth_info; + int error; + struct t_auth_info *auth_info; + char service_name[256]; + + get_service_name(service_name); + auth_info = g_malloc(sizeof(struct t_auth_info), 1); + g_strncpy(auth_info->user_pass.user, user, 255); + g_strncpy(auth_info->user_pass.pass, pass, 255); + auth_info->pamc.conv = &verify_pam_conv; + auth_info->pamc.appdata_ptr = &(auth_info->user_pass); + error = pam_start(service_name, 0, &(auth_info->pamc), &(auth_info->ph)); + + if (error != PAM_SUCCESS) + { + g_printf("pam_start failed: %s\r\n", pam_strerror(auth_info->ph, error)); + g_free(auth_info); + return 0; + } + + error = pam_authenticate(auth_info->ph, 0); + + if (error != PAM_SUCCESS) + { + g_printf("pam_authenticate failed: %s\r\n", + pam_strerror(auth_info->ph, error)); + g_free(auth_info); + return 0; + } + + error = pam_acct_mgmt(auth_info->ph, 0); + + if (error != PAM_SUCCESS) + { + g_printf("pam_acct_mgmt failed: %s\r\n", + pam_strerror(auth_info->ph, error)); + g_free(auth_info); + return 0; + } + + return (long)auth_info; } /******************************************************************************/ @@ -141,34 +149,40 @@ auth_userpass(char* user, char* pass) int DEFAULT_CC auth_start_session(long in_val, int in_display) { - struct t_auth_info* auth_info; - int error; - char display[256]; - - g_sprintf(display, ":%d", in_display); - auth_info = (struct t_auth_info*)in_val; - error = pam_set_item(auth_info->ph, PAM_TTY, display); - if (error != PAM_SUCCESS) - { - g_printf("pam_set_item failed: %s\r\n", pam_strerror(auth_info->ph, error)); - return 1; - } - error = pam_setcred(auth_info->ph, PAM_ESTABLISH_CRED); - if (error != PAM_SUCCESS) - { - g_printf("pam_setcred failed: %s\r\n", pam_strerror(auth_info->ph, error)); - return 1; - } - auth_info->did_setcred = 1; - error = pam_open_session(auth_info->ph, 0); - if (error != PAM_SUCCESS) - { - g_printf("pam_open_session failed: %s\r\n", - pam_strerror(auth_info->ph, error)); - return 1; - } - auth_info->session_opened = 1; - return 0; + struct t_auth_info *auth_info; + int error; + char display[256]; + + g_sprintf(display, ":%d", in_display); + auth_info = (struct t_auth_info *)in_val; + error = pam_set_item(auth_info->ph, PAM_TTY, display); + + if (error != PAM_SUCCESS) + { + g_printf("pam_set_item failed: %s\r\n", pam_strerror(auth_info->ph, error)); + return 1; + } + + error = pam_setcred(auth_info->ph, PAM_ESTABLISH_CRED); + + if (error != PAM_SUCCESS) + { + g_printf("pam_setcred failed: %s\r\n", pam_strerror(auth_info->ph, error)); + return 1; + } + + auth_info->did_setcred = 1; + error = pam_open_session(auth_info->ph, 0); + + if (error != PAM_SUCCESS) + { + g_printf("pam_open_session failed: %s\r\n", + pam_strerror(auth_info->ph, error)); + return 1; + } + + auth_info->session_opened = 1; + return 0; } /******************************************************************************/ @@ -177,27 +191,31 @@ auth_start_session(long in_val, int in_display) int DEFAULT_CC auth_end(long in_val) { - struct t_auth_info* auth_info; + struct t_auth_info *auth_info; + + auth_info = (struct t_auth_info *)in_val; - auth_info = (struct t_auth_info*)in_val; - if (auth_info != 0) - { - if (auth_info->ph != 0) + if (auth_info != 0) { - if (auth_info->session_opened) - { - pam_close_session(auth_info->ph, 0); - } - if (auth_info->did_setcred) - { - pam_setcred(auth_info->ph, PAM_DELETE_CRED); - } - pam_end(auth_info->ph, PAM_SUCCESS); - auth_info->ph = 0; + if (auth_info->ph != 0) + { + if (auth_info->session_opened) + { + pam_close_session(auth_info->ph, 0); + } + + if (auth_info->did_setcred) + { + pam_setcred(auth_info->ph, PAM_DELETE_CRED); + } + + pam_end(auth_info->ph, PAM_SUCCESS); + auth_info->ph = 0; + } } - } - g_free(auth_info); - return 0; + + g_free(auth_info); + return 0; } /******************************************************************************/ @@ -206,33 +224,39 @@ auth_end(long in_val) int DEFAULT_CC auth_set_env(long in_val) { - struct t_auth_info* auth_info; - char** pam_envlist; - char** pam_env; - char item[256]; - char value[256]; - int eq_pos; - - auth_info = (struct t_auth_info*)in_val; - if (auth_info != 0) - { - /* export PAM environment */ - pam_envlist = pam_getenvlist(auth_info->ph); - if (pam_envlist != NULL) + struct t_auth_info *auth_info; + char **pam_envlist; + char **pam_env; + char item[256]; + char value[256]; + int eq_pos; + + auth_info = (struct t_auth_info *)in_val; + + if (auth_info != 0) { - for (pam_env = pam_envlist; *pam_env != NULL; ++pam_env) - { - eq_pos = g_pos(*pam_env, "="); - if (eq_pos >= 0 && eq_pos < 250) + /* export PAM environment */ + pam_envlist = pam_getenvlist(auth_info->ph); + + if (pam_envlist != NULL) { - g_strncpy(item, *pam_env, eq_pos); - g_strncpy(value, (*pam_env) + eq_pos + 1, 255); - g_setenv(item, value, 1); + for (pam_env = pam_envlist; *pam_env != NULL; ++pam_env) + { + eq_pos = g_pos(*pam_env, "="); + + if (eq_pos >= 0 && eq_pos < 250) + { + g_strncpy(item, *pam_env, eq_pos); + g_strncpy(value, (*pam_env) + eq_pos + 1, 255); + g_setenv(item, value, 1); + } + + g_free(*pam_env); + } + + g_free(pam_envlist); } - g_free(*pam_env); - } - g_free(pam_envlist); } - } - return 0; + + return 0; } diff --git a/sesman/verify_user_pam_userpass.c b/sesman/verify_user_pam_userpass.c index 0075afeb..9fa2d9e5 100644 --- a/sesman/verify_user_pam_userpass.c +++ b/sesman/verify_user_pam_userpass.c @@ -1,28 +1,27 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2005-2008 -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ /** * * @file verify_user_pam_userpass.c * @brief Authenticate user using pam_userpass module * @author Jay Sorg - * + * */ #include "arch.h" @@ -35,43 +34,52 @@ /******************************************************************************/ /* returns boolean */ int DEFAULT_CC -auth_userpass(char* user, char* pass) +auth_userpass(char *user, char *pass) { - pam_handle_t* pamh; - pam_userpass_t userpass; - struct pam_conv conv = {pam_userpass_conv, &userpass}; - const void* template1; - int status; - - userpass.user = user; - userpass.pass = pass; - if (pam_start(SERVICE, user, &conv, &pamh) != PAM_SUCCESS) - { - return 0; - } - status = pam_authenticate(pamh, 0); - if (status != PAM_SUCCESS) - { - pam_end(pamh, status); - return 0; - } - status = pam_acct_mgmt(pamh, 0); - if (status != PAM_SUCCESS) - { - pam_end(pamh, status); - return 0; - } - status = pam_get_item(pamh, PAM_USER, &template1); - if (status != PAM_SUCCESS) - { - pam_end(pamh, status); - return 0; - } - if (pam_end(pamh, PAM_SUCCESS) != PAM_SUCCESS) - { - return 0; - } - return 1; + pam_handle_t *pamh; + pam_userpass_t userpass; + struct pam_conv conv = {pam_userpass_conv, &userpass}; + const void *template1; + int status; + + userpass.user = user; + userpass.pass = pass; + + if (pam_start(SERVICE, user, &conv, &pamh) != PAM_SUCCESS) + { + return 0; + } + + status = pam_authenticate(pamh, 0); + + if (status != PAM_SUCCESS) + { + pam_end(pamh, status); + return 0; + } + + status = pam_acct_mgmt(pamh, 0); + + if (status != PAM_SUCCESS) + { + pam_end(pamh, status); + return 0; + } + + status = pam_get_item(pamh, PAM_USER, &template1); + + if (status != PAM_SUCCESS) + { + pam_end(pamh, status); + return 0; + } + + if (pam_end(pamh, PAM_SUCCESS) != PAM_SUCCESS) + { + return 0; + } + + return 1; } /******************************************************************************/ @@ -79,19 +87,19 @@ auth_userpass(char* user, char* pass) int DEFAULT_CC auth_start_session(void) { - return 0; + return 0; } /******************************************************************************/ int DEFAULT_CC auth_end(void) { - return 0; + return 0; } /******************************************************************************/ int DEFAULT_CC auth_set_env(void) { - return 0; + return 0; } |