Remove SCP V0 and V1 files

This commit is contained in:
matt335672 2022-02-14 20:17:31 +00:00
parent bb820cca87
commit 1746ac2f79
29 changed files with 0 additions and 5099 deletions

View File

@ -493,7 +493,6 @@ AC_CONFIG_FILES([
pkgconfig/xrdp.pc
pkgconfig/xrdp-uninstalled.pc
sesman/chansrv/Makefile
sesman/libscp/Makefile
sesman/Makefile
sesman/tools/Makefile
tests/Makefile

View File

@ -1,42 +0,0 @@
AM_CPPFLAGS = \
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
-DXRDP_SBIN_PATH=\"${sbindir}\" \
-DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
-DXRDP_PID_PATH=\"${localstatedir}/run\" \
-I$(top_srcdir)/common
module_LTLIBRARIES = \
libscp.la
libscp_la_SOURCES = \
libscp.h \
libscp_commands.h \
libscp_commands_mng.h \
libscp_connection.c \
libscp_connection.h \
libscp_init.c \
libscp_init.h \
libscp_lock.c \
libscp_lock.h \
libscp_session.c \
libscp_session.h \
libscp_tcp.c \
libscp_tcp.h \
libscp_types.h \
libscp_types_mng.h \
libscp_v0.c \
libscp_v0.h \
libscp_v1c.c \
libscp_v1c.h \
libscp_v1c_mng.c \
libscp_v1c_mng.h \
libscp_v1s.c \
libscp_v1s.h \
libscp_v1s_mng.c \
libscp_v1s_mng.h \
libscp_vX.c \
libscp_vX.h
libscp_la_LIBADD = \
$(top_builddir)/common/libcommon.la \
-lpthread

View File

@ -1,46 +0,0 @@
/**
* 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.h
* @brief libscp main header
* @author Simone Fedele
*
*/
#ifndef LIBSCP_H
#define LIBSCP_H
#include "libscp_types.h"
#include "libscp_commands.h"
#include "libscp_connection.h"
#include "libscp_session.h"
#include "libscp_init.h"
#include "libscp_tcp.h"
#include "libscp_lock.h"
#include "libscp_vX.h"
#include "libscp_v0.h"
#include "libscp_v1s.h"
#include "libscp_v1c.h"
#include "libscp_v1s_mng.h"
#include "libscp_v1c_mng.h"
#endif

View File

@ -1,55 +0,0 @@
/**
* 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_commands.h
* @brief libscp data types definitions
* @author Simone Fedele
*
*/
#ifndef LIBSCP_COMMANDS_H
#define LIBSCP_COMMANDS_H
#include "libscp_commands_mng.h"
/* Message numbers
* SCP_CMD_* are client to server, SCP_REPLY_* are server to client */
/* Login sequence */
#define SCP_CMD_LOGIN 1
#define SCP_REPLY_LOGIN_DENIED 2
#define SCP_REPLY_REREQUEST_CREDS 3
#define SCP_CMD_RESEND_CREDS 4
#define SCP_REPLY_CHANGE_PASSWD 20
#define SCP_REPLY_NEW_SESSION 30
#define SCP_REPLY_USER_SESSIONS_EXIST 40
/* List sessions */
#define SCP_CMD_GET_SESSION_LIST 41
#define SCP_REPLY_SESSIONS_INFO 42
#define SCP_CMD_SELECT_SESSION 43
#define SCP_CMD_SELECT_SESSION_CANCEL 44
/* Other */
#define SCP_CMD_FORCE_NEW_CONN 45
#define SCP_REPLY_SESSION_RECONNECTED 46
#define SCP_REPLY_CMD_CONN_ERROR 0xFFFF
#endif

View File

@ -1,38 +0,0 @@
/**
* 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_commands_mng.h
* @brief libscp data types definitions
* @author Simone Fedele
*
*/
#ifndef LIBSCP_COMMANDS_MNG_H
#define LIBSCP_COMMANDS_MNG_H
#define SCP_CMD_MNG_LOGIN 0x0001
#define SCP_CMD_MNG_LOGIN_ALLOW 0x0002
#define SCP_CMD_MNG_LOGIN_DENY 0x0003
#define SCP_CMD_MNG_CMD_ERROR 0x0004
#define SCP_CMD_MNG_LIST_REQ 0x0005
#define SCP_CMD_MNG_LIST 0x0006
#define SCP_CMD_MNG_ACTION 0x0007
#endif

View File

@ -1,138 +0,0 @@
/**
* 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.c
* @brief SCP_CONNECTION handling code
* @author Simone Fedele
*
*/
#if defined(HAVE_CONFIG_H)
#include <config_ac.h>
#endif
#include "libscp_connection.h"
#include "string_calls.h"
#include "trans.h"
/*****************************************************************************/
struct trans *
scp_connect(const char *host, const char *port,
tis_term term_func,
ttrans_data_in data_in_func,
void *callback_data)
{
struct trans *t = trans_create(TRANS_MODE_TCP, 8192, 8192);
int index;
if (host == NULL)
{
host = "localhost";
}
if (port == NULL)
{
port = "3350";
}
t->is_term = term_func;
t->trans_data_in = data_in_func;
t->header_size = 8;
t->no_stream_init_on_data_in = 1;
t->callback_data = callback_data;
/* try to connect up to 4 times
*
* term_func can be NULL, so check before calling it */
index = 4;
while (trans_connect(t, host, port, 3000) != 0 &&
!(term_func && term_func()) &&
--index > 0)
{
g_sleep(1000);
LOG_DEVEL(LOG_LEVEL_DEBUG, "Connect failed. Trying again...");
}
if (t->status != TRANS_STATUS_UP)
{
trans_delete(t);
t = NULL;
}
return t;
}
/*****************************************************************************/
const char *
scp_client_state_to_str(enum SCP_CLIENT_STATES_E e)
{
const char *result = "SCP_CLIENT_STATE_????";
/* Some compilers will warn if this switch is missing states */
switch (e)
{
case SCP_CLIENT_STATE_OK:
result = "SCP_CLIENT_STATE_OK";
break;
case SCP_CLIENT_STATE_NETWORK_ERR:
result = "SCP_CLIENT_STATE_NETWORK_ERR";
break;
case SCP_CLIENT_STATE_VERSION_ERR:
result = "SCP_CLIENT_STATE_VERSION_ERR";
break;
case SCP_CLIENT_STATE_SEQUENCE_ERR:
result = "SCP_CLIENT_STATE_SEQUENCE_ERR";
break;
case SCP_CLIENT_STATE_SIZE_ERR:
result = "SCP_CLIENT_STATE_SIZE_ERR";
break;
case SCP_CLIENT_STATE_INTERNAL_ERR:
result = "SCP_CLIENT_STATE_INTERNAL_ERR";
break;
case SCP_CLIENT_STATE_SESSION_LIST:
result = "SCP_CLIENT_STATE_SESSION_LIST";
break;
case SCP_CLIENT_STATE_LIST_OK:
result = "SCP_CLIENT_STATE_LIST_OK";
break;
case SCP_CLIENT_STATE_RESEND_CREDENTIALS:
result = "SCP_CLIENT_STATE_RESEND_CREDENTIALS";
break;
case SCP_CLIENT_STATE_CONNECTION_DENIED:
result = "SCP_CLIENT_STATE_CONNECTION_DENIED";
break;
case SCP_CLIENT_STATE_PWD_CHANGE_REQ:
result = "SCP_CLIENT_STATE_PWD_CHANGE_REQ";
break;
case SCP_CLIENT_STATE_RECONNECT_SINGLE:
result = "SCP_CLIENT_STATE_RECONNECT_SINGLE";
break;
case SCP_CLIENT_STATE_SELECTION_CANCEL:
result = "SCP_CLIENT_STATE_SELECTION_CANCEL";
break;
case SCP_CLIENT_STATE_END:
result = "SCP_CLIENT_STATE_END";
break;
}
return result;
}

View File

@ -1,61 +0,0 @@
/**
* 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
#define LIBSCP_CONNECTION_H
#include "libscp.h"
/**
*
* @brief creates a new SCP connection
* @param host Hostname to connect to (NULL for default)
* @param port Port to connect to (NULL for default)
* @param term_func Transport termination function (or NULL)
* @param data_in_func Transport 'data in' function
* @param callback_data Closure data for data in function
*
* Returned object can be freed with trans_delete()
*
* @return a struct trans* object on success, NULL otherwise
*
*/
struct trans *
scp_connect(const char *host, const char *port,
tis_term term_func,
ttrans_data_in data_in_func,
void *callback_data);
/**
* @brief Maps SCP_CLIENT_TYPES_E to a string
* @param e
*
* @return Pointer to a string
*
*/
const char *scp_client_state_to_str(enum SCP_CLIENT_STATES_E e);
#endif

View File

@ -1,53 +0,0 @@
/**
* 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.c
* @brief libscp initialization code
* @author Simone Fedele
*
*/
#if defined(HAVE_CONFIG_H)
#include <config_ac.h>
#endif
#include "libscp_init.h"
//struct log_config* s_log;
/* server API */
int
scp_init(void)
{
/*
if (0 == log)
{
return 1;
}
*/
//s_log = log;
scp_lock_init();
LOG(LOG_LEVEL_DEBUG, "libscp initialized");
return 0;
}

View File

@ -1,46 +0,0 @@
/**
* 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
#define LIBSCP_INIT_H
#include "log.h"
#include "libscp.h"
/**
*
* @brief version neutral server accept function
* @param c connection descriptor
* @param s session descriptor pointer address.
* it will return a newly allocated descriptor.
* It this memory needs to be g_free()d
*
*/
int
scp_init(void);
#endif

View File

@ -1,152 +0,0 @@
/**
* 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
*/
#if defined(HAVE_CONFIG_H)
#include <config_ac.h>
#endif
#include "libscp_lock.h"
#include "thread_calls.h"
#include <pthread.h>
pthread_mutex_t lock_fork; /* this lock protects the counters */
pthread_mutexattr_t lock_fork_attr; /* mutex attributes */
tbus lock_fork_req; /* semaphore on which the process that are going to fork suspend on */
tbus lock_fork_wait; /* semaphore on which the suspended process wait on */
int lock_fork_forkers_count; /* threads that want to fork */
int lock_fork_blockers_count; /* threads that are blocking fork */
int lock_fork_waiting_count; /* threads suspended until the fork finishes */
void
scp_lock_init(void)
{
/* initializing fork lock */
pthread_mutexattr_init(&lock_fork_attr);
pthread_mutex_init(&lock_fork, &lock_fork_attr);
lock_fork_req = tc_sem_create(0);
lock_fork_wait = tc_sem_create(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
scp_lock_fork_request(void)
{
/* lock mutex */
pthread_mutex_lock(&lock_fork);
if (lock_fork_blockers_count == 0)
{
/* if no one is blocking fork(), then we're allowed to fork */
tc_sem_inc(lock_fork_req);
}
lock_fork_forkers_count++;
pthread_mutex_unlock(&lock_fork);
/* we wait to be allowed to fork() */
tc_sem_dec(lock_fork_req);
}
/******************************************************************************/
void
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)
{
tc_sem_inc(lock_fork_req);
}
for (; lock_fork_waiting_count > 0; lock_fork_waiting_count--)
{
/* waking up the other processes */
tc_sem_inc(lock_fork_wait);
}
pthread_mutex_unlock(&lock_fork);
}
/******************************************************************************/
void
scp_lock_fork_critical_section_end(int blocking)
{
//LOG_DEVEL(LOG_LEVEL_DEBUG, "lock_fork_critical_section_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))
{
tc_sem_inc(lock_fork_req);
}
pthread_mutex_unlock(&lock_fork);
}
/******************************************************************************/
int
scp_lock_fork_critical_section_start(void)
{
//LOG_DEVEL(LOG_LEVEL_DEBUG, "lock_fork_critical_section_start()",0);
do
{
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 */
tc_sem_dec(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;
}
}
while (1);
/* we'll never get here */
return LIBSCP_LOCK_FORK_WAITING;
}

View File

@ -1,73 +0,0 @@
/**
* 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
#include "libscp_types.h"
#define LIBSCP_LOCK_FORK_BLOCKER 1
#define LIBSCP_LOCK_FORK_WAITING 0
/**
*
* @brief initializes all the locks
*
*/
void
scp_lock_init(void);
/**
*
* @brief requires to fork a new child process
*
*/
void
scp_lock_fork_request(void);
/**
*
* @brief releases a fork() request
*
*/
void
scp_lock_fork_release(void);
/**
*
* @brief starts a section that is critical for forking
*
* starts a section that is critical for forking, that is no one can fork()
* while I'm in a critical section. But if someone wanted to fork we have
* to wait until he finishes with lock_fork_release()
*
* @return
*
*/
int
scp_lock_fork_critical_section_start(void);
/**
*
* @brief closes the critical section
*
*/
void
scp_lock_fork_critical_section_end(int blocking);
#endif

View File

@ -1,485 +0,0 @@
/**
* 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_session.c
* @brief SCP_SESSION handling code
* @author Simone Fedele
*
*/
#if defined(HAVE_CONFIG_H)
#include <config_ac.h>
#endif
#include "libscp_session.h"
#include "string_calls.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
//extern struct log_config* s_log;
/*******************************************************************/
struct SCP_SESSION *
scp_session_create(void)
{
struct SCP_SESSION *s;
s = (struct SCP_SESSION *)g_malloc(sizeof(struct SCP_SESSION), 1);
if (0 == s)
{
LOG(LOG_LEVEL_ERROR, "[session:%d] session create: malloc error", __LINE__);
return 0;
}
return s;
}
/*******************************************************************/
int
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_SESSION_TYPE_XORG:
s->type = SCP_SESSION_TYPE_XORG;
break;
case SCP_GW_AUTHENTICATION:
s->type = SCP_GW_AUTHENTICATION;
break;
case SCP_SESSION_TYPE_MANAGE:
s->type = SCP_SESSION_TYPE_MANAGE;
break;
default:
LOG(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)
{
switch (version)
{
case 0:
s->version = 0;
break;
case 1:
s->version = 1;
break;
default:
LOG(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)
{
s->height = h;
return 0;
}
/*******************************************************************/
int
scp_session_set_width(struct SCP_SESSION *s, tui16 w)
{
s->width = w;
return 0;
}
/*******************************************************************/
int
scp_session_set_bpp(struct SCP_SESSION *s, tui8 bpp)
{
switch (bpp)
{
case 8:
case 15:
case 16:
case 24:
case 32:
s->bpp = bpp;
break;
default:
return 1;
}
return 0;
}
/*******************************************************************/
int
scp_session_set_rsr(struct SCP_SESSION *s, tui8 rsr)
{
if (s->rsr)
{
s->rsr = 1;
}
else
{
s->rsr = 0;
}
return 0;
}
/*******************************************************************/
int
scp_session_set_locale(struct SCP_SESSION *s, const char *str)
{
if (0 == str)
{
LOG(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, const char *str)
{
if (0 == str)
{
LOG(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(LOG_LEVEL_WARNING, "[session:%d] set_username: strdup error", __LINE__);
return 1;
}
return 0;
}
/*******************************************************************/
int
scp_session_set_password(struct SCP_SESSION *s, const char *str)
{
if (0 == str)
{
LOG(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(LOG_LEVEL_WARNING, "[session:%d] set_password: strdup error", __LINE__);
return 1;
}
return 0;
}
/*******************************************************************/
int
scp_session_set_domain(struct SCP_SESSION *s, const char *str)
{
if (0 == str)
{
LOG(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(LOG_LEVEL_WARNING, "[session:%d] set_domain: strdup error", __LINE__);
return 1;
}
return 0;
}
/*******************************************************************/
int
scp_session_set_program(struct SCP_SESSION *s, const char *str)
{
if (0 == str)
{
LOG(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(LOG_LEVEL_WARNING, "[session:%d] set_program: strdup error", __LINE__);
return 1;
}
return 0;
}
/*******************************************************************/
int
scp_session_set_directory(struct SCP_SESSION *s, const char *str)
{
if (0 == str)
{
LOG(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(LOG_LEVEL_WARNING, "[session:%d] set_directory: strdup error", __LINE__);
return 1;
}
return 0;
}
/*******************************************************************/
int
scp_session_set_connection_description(struct SCP_SESSION *s, const char *str)
{
if (0 == str)
{
LOG(LOG_LEVEL_WARNING, "[session:%d] set_connection_description: null description", __LINE__);
return 1;
}
if (0 != s->connection_description)
{
g_free(s->connection_description);
}
s->connection_description = g_strdup(str);
if (0 == s->connection_description)
{
LOG(LOG_LEVEL_WARNING, "[session:%d] set_connection_description: strdup error", __LINE__);
return 1;
}
return 0;
}
/*******************************************************************/
int
scp_session_set_hostname(struct SCP_SESSION *s, const char *str)
{
if (0 == str)
{
LOG(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(LOG_LEVEL_WARNING, "[session:%d] set_hostname: strdup error", __LINE__);
return 1;
}
return 0;
}
/*******************************************************************/
int
scp_session_set_errstr(struct SCP_SESSION *s, const char *str)
{
if (0 == str)
{
LOG(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(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)
{
s->display = display;
return 0;
}
/*******************************************************************/
int
scp_session_set_addr(struct SCP_SESSION *s, int type, const void *addr)
{
switch (type)
{
case SCP_ADDRESS_TYPE_IPV4:
g_memcpy(&(s->ipv4addr), addr, 4);
break;
#ifdef IN6ADDR_ANY_INIT
case SCP_ADDRESS_TYPE_IPV6:
g_memcpy(s->ipv6addr, addr, 16);
break;
#endif
default:
return 1;
}
return 0;
}
/*******************************************************************/
int
scp_session_set_guid(struct SCP_SESSION *s, const struct guid *guid)
{
if (0 == guid)
{
LOG(LOG_LEVEL_WARNING, "[session:%d] set_guid: null guid", __LINE__);
return 1;
}
s->guid = *guid;
return 0;
}
/*******************************************************************/
void
scp_session_destroy(struct SCP_SESSION *s)
{
if (s != NULL)
{
g_free(s->username);
g_free(s->password);
g_free(s->hostname);
g_free(s->domain);
g_free(s->program);
g_free(s->directory);
g_free(s->connection_description);
g_free(s->errstr);
g_free(s);
}
}
/*******************************************************************/
struct SCP_SESSION *
scp_session_clone(const struct SCP_SESSION *s)
{
struct SCP_SESSION *result = NULL;
if (s != NULL && (result = g_new(struct SCP_SESSION, 1)) != NULL)
{
/* Duplicate all the scalar variables */
g_memcpy(result, s, sizeof(*s));
/* Now duplicate all the strings */
result->username = g_strdup(s->username);
result->password = g_strdup(s->password);
result->hostname = g_strdup(s->hostname);
result->errstr = g_strdup(s->errstr);
result->domain = g_strdup(s->domain);
result->program = g_strdup(s->program);
result->directory = g_strdup(s->directory);
result->connection_description = g_strdup(s->connection_description);
/* Did all the string copies succeed? */
if ((s->username != NULL && result->username == NULL) ||
(s->password != NULL && result->password == NULL) ||
(s->hostname != NULL && result->hostname == NULL) ||
(s->errstr != NULL && result->errstr == NULL) ||
(s->domain != NULL && result->domain == NULL) ||
(s->program != NULL && result->program == NULL) ||
(s->directory != NULL && result->directory == NULL) ||
(s->connection_description != NULL && result->connection_description == NULL))
{
scp_session_destroy(result);
result = NULL;
}
}
return result;
}

View File

@ -1,114 +0,0 @@
/**
* 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_session.h
* @brief SCP_SESSION handling code
* @author Simone Fedele
*
*/
#ifndef LIBSCP_SESSION_H
#define LIBSCP_SESSION_H
#include "libscp.h"
/**
*
* @brief creates a new connection
* @param sck the connection socket
*
* @return a struct SCP_SESSION* object on success, NULL otherwise
*
*/
struct SCP_SESSION *
scp_session_create(void);
/*
* Makes a copy of a struct SCP_SESSION object
* @param s Object to clone
* @return a copy of s, or NULL if no memory
*/
struct SCP_SESSION *
scp_session_clone(const struct SCP_SESSION *s);
int
scp_session_set_type(struct SCP_SESSION *s, tui8 type);
int
scp_session_set_version(struct SCP_SESSION *s, tui32 version);
int
scp_session_set_height(struct SCP_SESSION *s, tui16 h);
int
scp_session_set_width(struct SCP_SESSION *s, tui16 w);
int
scp_session_set_bpp(struct SCP_SESSION *s, tui8 bpp);
int
scp_session_set_rsr(struct SCP_SESSION *s, tui8 rsr);
int
scp_session_set_locale(struct SCP_SESSION *s, const char *str);
int
scp_session_set_username(struct SCP_SESSION *s, const char *str);
int
scp_session_set_password(struct SCP_SESSION *s, const char *str);
int
scp_session_set_domain(struct SCP_SESSION *s, const char *str);
int
scp_session_set_program(struct SCP_SESSION *s, const char *str);
int
scp_session_set_directory(struct SCP_SESSION *s, const char *str);
int
scp_session_set_connection_description(struct SCP_SESSION *s, const char *str);
int
scp_session_set_hostname(struct SCP_SESSION *s, const char *str);
int
scp_session_set_addr(struct SCP_SESSION *s, int type, const void *addr);
int
scp_session_set_display(struct SCP_SESSION *s, SCP_DISPLAY display);
int
scp_session_set_errstr(struct SCP_SESSION *s, const char *str);
int
scp_session_set_guid(struct SCP_SESSION *s, const struct guid *guid);
/**
*
* @brief destroys a session object
* @param s the object to be destroyed
*
*/
void
scp_session_destroy(struct SCP_SESSION *s);
#endif

View File

@ -1,126 +0,0 @@
/**
* 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 tcp.c
* @brief Tcp stream functions
* @author Jay Sorg, Simone Fedele
*
*/
#if defined(HAVE_CONFIG_H)
#include <config_ac.h>
#endif
#include "libscp_tcp.h"
extern struct log_config *s_log;
/*****************************************************************************/
int
scp_tcp_force_recv(int sck, char *data, int len)
{
int rcvd;
int block;
LOG_DEVEL(LOG_LEVEL_DEBUG, "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)
{
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;
}
}
scp_lock_fork_critical_section_end(block);
return 0;
}
/*****************************************************************************/
int
scp_tcp_force_send(int sck, char *data, int len)
{
int sent;
int block;
LOG_DEVEL(LOG_LEVEL_DEBUG, "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)
{
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;
}
}
scp_lock_fork_critical_section_end(block);
return 0;
}
/*****************************************************************************/
int
scp_tcp_bind(int sck, char *addr, char *port)
{
return g_tcp_bind_address(sck, port, addr);
}

View File

@ -1,68 +0,0 @@
/**
* 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_tcp.h
* @brief Tcp stream functions declarations
* @author Jay Sorg, Simone Fedele
*
*/
#ifndef LIBSCP_TCP_H
#define LIBSCP_TCP_H
#include "libscp.h"
/**
*
* @brief Force receiving data from tcp stream
* @param sck The socket to read from
* @param data Data buffer
* @param len Data buffer size
* @return 0 on success, 1 on error
*
*/
int
scp_tcp_force_recv(int sck, char *data, int len);
/**
*
* @brief Force sending data to tcp stream
* @param sck the socket to write to
* @param data Data buffer
* @param len Data buffer size
* @return 0 on success, 1 on error
*
*/
int
scp_tcp_force_send(int sck, char *data, int len);
/**
*
* @brief Binds the listening socket
* @param sck Listening socket
* @param addr Listening address
* @param port Listening port
* @return 0 on success, -1 on error
*
*/
int
scp_tcp_bind(int sck, char *addr, char *port);
#endif

View File

@ -1,153 +0,0 @@
/**
* 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_types.h
* @brief libscp data types definitions
* @author Simone Fedele
*
*/
#ifndef LIBSCP_TYPES_H
#define LIBSCP_TYPES_H
#include "os_calls.h"
#include "parse.h"
#include "arch.h"
#include "guid.h"
#include "log.h"
#include "trans.h"
#define SCP_SID tui32
#define SCP_DISPLAY tui16
#define SCP_RESOURCE_SHARING_REQUEST_YES 0x01
#define SCP_RESOURCE_SHARING_REQUEST_NO 0x00
#define SCP_SESSION_TYPE_XVNC 0x00
#define SCP_SESSION_TYPE_XRDP 0x01
#define SCP_SESSION_TYPE_MANAGE 0x02
#define SCP_SESSION_TYPE_XORG 0x03
/* 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
* to use the gateway */
#define SCP_GW_AUTHENTICATION 0x04
#define SCP_ADDRESS_TYPE_IPV4 0x00
#define SCP_ADDRESS_TYPE_IPV6 0x01
#define SCP_COMMAND_SET_DEFAULT 0x0000
#define SCP_COMMAND_SET_MANAGE 0x0001
#define SCP_COMMAND_SET_RSR 0x0002
#define SCP_SERVER_MAX_LIST_SIZE 100
#include "libscp_types_mng.h"
/* Max server incoming and outgoing message size, used to stop memory
exhaustion attempts (CVE-2020-4044) */
#define SCP_MAX_MESSAGE_SIZE 8192
struct SCP_SESSION
{
tui8 type;
tui32 version;
tui16 height;
tui16 width;
tui8 bpp;
tui8 rsr;
char locale[18];
char *username;
char *password;
char *hostname;
tui8 addr_type;
tui32 ipv4addr;
tui8 ipv6addr[16];
SCP_DISPLAY display;
char *errstr;
char *domain;
char *program;
char *directory;
char *connection_description;
struct guid guid;
/* added for state */
int current_cmd;
int return_sid;
int retries;
int current_try;
};
struct SCP_DISCONNECTED_SESSION
{
tui32 SID;
tui8 type;
tui8 status;
tui16 height;
tui16 width;
tui8 bpp;
tui8 idle_days;
tui8 idle_hours;
tui8 idle_minutes;
tui16 conn_year;
tui8 conn_month;
tui8 conn_day;
tui8 conn_hour;
tui8 conn_minute;
tui8 addr_type;
tui32 ipv4addr;
tui8 ipv6addr[16];
};
enum SCP_CLIENT_STATES_E
{
SCP_CLIENT_STATE_OK,
SCP_CLIENT_STATE_NETWORK_ERR,
SCP_CLIENT_STATE_VERSION_ERR,
SCP_CLIENT_STATE_SEQUENCE_ERR,
SCP_CLIENT_STATE_SIZE_ERR,
SCP_CLIENT_STATE_INTERNAL_ERR,
SCP_CLIENT_STATE_SESSION_LIST,
SCP_CLIENT_STATE_LIST_OK,
SCP_CLIENT_STATE_RESEND_CREDENTIALS,
SCP_CLIENT_STATE_CONNECTION_DENIED,
SCP_CLIENT_STATE_PWD_CHANGE_REQ,
SCP_CLIENT_STATE_RECONNECT_SINGLE,
SCP_CLIENT_STATE_SELECTION_CANCEL,
SCP_CLIENT_STATE_END
};
enum SCP_SERVER_STATES_E
{
SCP_SERVER_STATE_OK,
SCP_SERVER_STATE_VERSION_ERR,
SCP_SERVER_STATE_NETWORK_ERR,
SCP_SERVER_STATE_SEQUENCE_ERR,
SCP_SERVER_STATE_INTERNAL_ERR,
SCP_SERVER_STATE_SESSION_TYPE_ERR,
SCP_SERVER_STATE_SIZE_ERR,
SCP_SERVER_STATE_SELECTION_CANCEL,
/*SCP_SERVER_STATE_FORCE_NEW,*/
SCP_SERVER_STATE_START_MANAGE,
SCP_SERVER_STATE_MNG_LISTREQ,
SCP_SERVER_STATE_MNG_ACTION,
SCP_SERVER_STATE_END
};
#endif

View File

@ -1,47 +0,0 @@
/**
* 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_types_mng.h
* @brief libscp data types definitions
* @author Simone Fedele
*
*/
#ifndef LIBSCP_TYPES_MNG_H
#define LIBSCP_TYPES_MNG_H
#include "os_calls.h"
#include "parse.h"
#include "arch.h"
#include "log.h"
enum SCP_MNG_COMMAND
{
SCP_MNG_CMD_KILL,
SCP_MNG_CMD_DISCONNECT
};
struct SCP_MNG_DATA
{
enum SCP_MNG_COMMAND cmd;
SCP_SID sid;
};
#endif

View File

@ -1,591 +0,0 @@
/**
* 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_v0.c
* @brief libscp version 0 code
* @author Simone Fedele
*
*/
#if defined(HAVE_CONFIG_H)
#include <config_ac.h>
#endif
#include "libscp_v0.h"
#include "os_calls.h"
#include "string_calls.h"
extern struct log_config *s_log;
/** Maximum length of a string (two bytes + len), excluding the terminator
*
* Practially this is limited by [MS-RDPBCGR] TS_INFO_PACKET
* */
#define STRING16_MAX_LEN 512
/**
* Reads a big-endian uint16 followed by a string into a buffer
*
* Buffer is null-terminated on success
*
* @param s Input stream
* @param [out] str Output buffer (must be >= (STRING16_MAX_LEN+1) chars)
* @param prefix Logging prefix for errors
* @return != 0 if string read OK
*/
static
int in_string16(struct stream *s, char str[], const char *prefix)
{
int result;
unsigned int sz;
if ((result = s_check_rem_and_log(s, 2, prefix)) != 0)
{
in_uint16_be(s, sz);
if (sz > STRING16_MAX_LEN)
{
LOG(LOG_LEVEL_ERROR, "%s input string too long (%u chars)",
prefix, sz);
result = 0;
}
else if ((result = s_check_rem_and_log(s, sz, prefix)) != 0)
{
in_uint8a(s, str, sz);
str[sz] = '\0';
}
}
return result;
}
/**
* Writes a big-endian uint16 followed by a string into a buffer
*
* @param s Output stream
* @param[in] str output string (must be <= (STRING16_MAX_LEN+1) chars)
* @param param Parameter we're sending
* @return != 0 if string written OK
*/
static
int out_string16(struct stream *out_s, const char *str, const char *prefix)
{
int result;
unsigned int sz = g_strlen(str);
if (sz > STRING16_MAX_LEN)
{
LOG(LOG_LEVEL_WARNING, "%s String too long (%u chars)", prefix, sz);
result = 0;
}
else if ((result = s_check_rem_out_and_log(out_s, 2 + sz, prefix)) != 0)
{
out_uint16_be(out_s, sz);
out_uint8a(out_s, str, sz);
}
return result;
}
/***
* Terminates a V0 request, adds the header and sends it.
*
* On entry, channel_hdr on the transport output stream is expected to
* contain the location for the SCP header
*
* @param atrans Transport for the message
* @return error code
*/
static enum SCP_CLIENT_STATES_E
terminate_and_send_v0_request(struct trans *atrans)
{
enum SCP_CLIENT_STATES_E e;
struct stream *s = atrans->out_s;
s_mark_end(s);
s_pop_layer(s, channel_hdr);
/* version */
out_uint32_be(s, 0);
/* size */
out_uint32_be(s, s->end - s->data);
if (trans_force_write_s(atrans, s) == 0)
{
e = SCP_CLIENT_STATE_OK;
}
else
{
LOG(LOG_LEVEL_ERROR, "connection aborted: network error");
e = SCP_CLIENT_STATE_NETWORK_ERR;
}
return e;
}
/* client API */
/******************************************************************************/
enum SCP_CLIENT_STATES_E
scp_v0c_create_session_request(struct trans *atrans,
const char *username,
const char *password,
unsigned short code,
unsigned short width,
unsigned short height,
unsigned short bpp,
const char *domain,
const char *shell,
const char *directory,
const char *client_ip)
{
enum SCP_CLIENT_STATES_E e;
struct stream *s = trans_get_out_s(atrans, 8192);
s_push_layer(s, channel_hdr, 8);
out_uint16_be(s, code);
if (!out_string16(s, username, "Session username") ||
!out_string16(s, password, "Session passwd"))
{
e = SCP_CLIENT_STATE_SIZE_ERR;
}
else
{
out_uint16_be(s, width);
out_uint16_be(s, height);
out_uint16_be(s, bpp);
if (!out_string16(s, domain, "Session domain") ||
!out_string16(s, shell, "Session shell") ||
!out_string16(s, directory, "Session directory") ||
!out_string16(s, client_ip, "Session client IP"))
{
e = SCP_CLIENT_STATE_SIZE_ERR;
}
else
{
e = terminate_and_send_v0_request(atrans);
}
}
return e;
}
enum SCP_CLIENT_STATES_E
scp_v0c_gateway_request(struct trans *atrans,
const char *username,
const char *password)
{
enum SCP_CLIENT_STATES_E e;
struct stream *s = trans_get_out_s(atrans, 500);
s_push_layer(s, channel_hdr, 8);
out_uint16_be(s, SCP_GW_AUTHENTICATION);
if (!out_string16(s, username, "Gateway username") ||
!out_string16(s, password, "Gateway passwd"))
{
e = SCP_CLIENT_STATE_SIZE_ERR;
}
else
{
e = terminate_and_send_v0_request(atrans);
}
return e;
}
/**************************************************************************//**
* Is a reply available from the other end?
*
* Returns true if it is, or if an error has occurred which needs handling.
*
* @param trans Transport to be polled
* @return True if scp_v0c_get_reply() should be called
*/
int
scp_v0c_reply_available(struct trans *trans)
{
int result = 1;
if (trans != NULL && trans->status == TRANS_STATUS_UP)
{
/* Have we read enough data from the stream? */
if ((trans->in_s->end - trans->in_s->data) < trans->header_size)
{
result = 0;
}
else if (trans->extra_flags == 0)
{
int version;
int size;
/* We've read the header only */
in_uint32_be(trans->in_s, version);
in_uint32_be(trans->in_s, size);
if (version != 0)
{
LOG(LOG_LEVEL_ERROR, "Unexpected version number %d from SCP",
version);
trans->status = TRANS_STATUS_DOWN;
}
else if (size <= 8 || size > trans->in_s->size)
{
LOG(LOG_LEVEL_ERROR,
"Invalid V0 message length %d from SCP",
size);
trans->status = TRANS_STATUS_DOWN;
}
else
{
/* Read the rest of the message */
trans->header_size = size;
trans->extra_flags = 1;
result = 0;
}
}
}
return result;
}
/**************************************************************************//**
* Get a reply from the V0 transport
*
* Only call this once scp_v0c_reply_available() has returned true
*
* After a successful call, the transport is ready to be used for the
* next incoming message
*
* @param trans Transport containing the reply
* @param[out] reply, provided result is SCP_CLIENT_STATE_OK
* @return SCP client state
*/
enum SCP_CLIENT_STATES_E
scp_v0c_get_reply(struct trans *trans, struct scp_v0_reply_type *reply)
{
enum SCP_CLIENT_STATES_E e;
if (trans == NULL || trans->status != TRANS_STATUS_UP)
{
e = SCP_CLIENT_STATE_NETWORK_ERR;
}
else if (!s_check_rem_and_log(trans->in_s, 6, "SCPV0 reply"))
{
trans->status = TRANS_STATUS_DOWN;
e = SCP_CLIENT_STATE_NETWORK_ERR;
}
else
{
int word1;
int word2;
int word3;
in_uint16_be(trans->in_s, word1);
in_uint16_be(trans->in_s, word2);
in_uint16_be(trans->in_s, word3);
if (word1 == SCP_GW_AUTHENTICATION)
{
reply->is_gw_auth_response = 1;
reply->auth_result = word2;
reply->display = 0;
guid_clear(&reply->guid);
}
else
{
reply->is_gw_auth_response = 0;
reply->auth_result = word2;
reply->display = word3;
if (s_check_rem(trans->in_s, GUID_SIZE))
{
in_uint8a(trans->in_s, reply->guid.g, GUID_SIZE);
}
else
{
guid_clear(&reply->guid);
}
}
e = SCP_CLIENT_STATE_OK;
/* Reset the input stream for the next message */
trans->header_size = 8;
trans->extra_flags = 0;
init_stream(trans->in_s, 0);
}
return e;
}
/* server API */
/**
* Initialises a V0 session object
*
* At the time of the call, the version has been read from the connection
*
* @param c Connection
* @param [out] session pre-allocated session object
* @return SCP_SERVER_STATE_OK for success
*/
enum SCP_SERVER_STATES_E
scp_v0s_accept(struct trans *atrans, struct SCP_SESSION *session)
{
tui16 height;
tui16 width;
tui16 bpp;
tui32 code = 0;
char buf[STRING16_MAX_LEN + 1];
struct stream *in_s = atrans->in_s;
int session_type = -1;
scp_session_set_version(session, 0);
if (!s_check_rem(in_s, 6))
{
return SCP_SERVER_STATE_SIZE_ERR;
}
in_uint8s(in_s, 4); /* size */
in_uint16_be(in_s, code);
if ((code == 0) || (code == 10) || (code == 20))
{
if (code == 0)
{
session_type = SCP_SESSION_TYPE_XVNC;
}
else if (code == 10)
{
session_type = SCP_SESSION_TYPE_XRDP;
}
else
{
session_type = SCP_SESSION_TYPE_XORG;
}
scp_session_set_type(session, session_type);
/* reading username */
if (!in_string16(in_s, buf, "Session username"))
{
return SCP_SERVER_STATE_SIZE_ERR;
}
if (0 != scp_session_set_username(session, buf))
{
LOG(LOG_LEVEL_WARNING, "connection aborted: error setting username");
return SCP_SERVER_STATE_INTERNAL_ERR;
}
/* reading password */
if (!in_string16(in_s, buf, "Session passwd"))
{
return SCP_SERVER_STATE_SIZE_ERR;
}
if (0 != scp_session_set_password(session, buf))
{
LOG(LOG_LEVEL_WARNING, "connection aborted: error setting password");
return SCP_SERVER_STATE_INTERNAL_ERR;
}
/* width + height + bpp */
if (!s_check_rem(in_s, 2 + 2 + 2))
{
LOG(LOG_LEVEL_WARNING, "connection aborted: width+height+bpp missing");
return SCP_SERVER_STATE_SIZE_ERR;
}
in_uint16_be(in_s, width);
scp_session_set_width(session, width);
in_uint16_be(in_s, height);
scp_session_set_height(session, height);
in_uint16_be(in_s, bpp);
if (session_type == SCP_SESSION_TYPE_XORG)
{
/* Client value is ignored */
bpp = 24;
}
if (0 != scp_session_set_bpp(session, (tui8)bpp))
{
LOG(LOG_LEVEL_WARNING,
"connection aborted: unsupported bpp: %d", (tui8)bpp);
return SCP_SERVER_STATE_INTERNAL_ERR;
}
if (s_check_rem(in_s, 2))
{
/* reading domain */
if (!in_string16(in_s, buf, "Session domain"))
{
return SCP_SERVER_STATE_SIZE_ERR;
}
if (buf[0] != '\0')
{
scp_session_set_domain(session, buf);
}
}
if (s_check_rem(in_s, 2))
{
/* reading program */
if (!in_string16(in_s, buf, "Session program"))
{
return SCP_SERVER_STATE_SIZE_ERR;
}
if (buf[0] != '\0')
{
scp_session_set_program(session, buf);
}
}
if (s_check_rem(in_s, 2))
{
/* reading directory */
if (!in_string16(in_s, buf, "Session directory"))
{
return SCP_SERVER_STATE_SIZE_ERR;
}
if (buf[0] != '\0')
{
scp_session_set_directory(session, buf);
}
}
if (s_check_rem(in_s, 2))
{
/* reading client IP address */
if (!in_string16(in_s, buf, "connection description"))
{
return SCP_SERVER_STATE_SIZE_ERR;
}
if (buf[0] != '\0')
{
scp_session_set_connection_description(session, buf);
}
}
}
else if (code == SCP_GW_AUTHENTICATION)
{
scp_session_set_type(session, SCP_GW_AUTHENTICATION);
/* reading username */
if (!in_string16(in_s, buf, "Session username"))
{
return SCP_SERVER_STATE_SIZE_ERR;
}
if (0 != scp_session_set_username(session, buf))
{
LOG(LOG_LEVEL_WARNING, "connection aborted: error setting username");
return SCP_SERVER_STATE_INTERNAL_ERR;
}
/* reading password */
if (!in_string16(in_s, buf, "Session passwd"))
{
return SCP_SERVER_STATE_SIZE_ERR;
}
if (0 != scp_session_set_password(session, buf))
{
LOG(LOG_LEVEL_WARNING, "connection aborted: error setting password");
return SCP_SERVER_STATE_INTERNAL_ERR;
}
}
else
{
LOG(LOG_LEVEL_WARNING, "connection aborted: sequence error");
return SCP_SERVER_STATE_SEQUENCE_ERR;
}
return SCP_SERVER_STATE_OK;
}
/******************************************************************************/
enum SCP_SERVER_STATES_E
scp_v0s_allow_connection(struct trans *atrans, SCP_DISPLAY d,
const struct guid *guid)
{
int msg_size;
struct stream *out_s;
out_s = trans_get_out_s(atrans, 0);
msg_size = guid_is_set(guid) ? 14 + GUID_SIZE : 14;
out_uint32_be(out_s, 0); /* version */
out_uint32_be(out_s, msg_size); /* size */
out_uint16_be(out_s, 3); /* cmd */
out_uint16_be(out_s, 1); /* data */
out_uint16_be(out_s, d); /* data */
if (msg_size > 14)
{
out_uint8a(out_s, guid->g, GUID_SIZE);
}
s_mark_end(out_s);
if (0 != trans_write_copy(atrans))
{
LOG(LOG_LEVEL_WARNING, "connection aborted: network error");
return SCP_SERVER_STATE_NETWORK_ERR;
}
LOG_DEVEL(LOG_LEVEL_DEBUG, "connection terminated (allowed)");
return SCP_SERVER_STATE_OK;
}
/******************************************************************************/
enum SCP_SERVER_STATES_E
scp_v0s_deny_connection(struct trans *atrans)
{
struct stream *out_s;
out_s = trans_get_out_s(atrans, 0);
out_uint32_be(out_s, 0); /* version */
out_uint32_be(out_s, 14); /* size */
out_uint16_be(out_s, 3); /* cmd */
out_uint16_be(out_s, 0); /* data = 0 - means NOT ok*/
out_uint16_be(out_s, 0); /* reserved for display number*/
s_mark_end(out_s);
if (0 != trans_write_copy(atrans))
{
LOG(LOG_LEVEL_WARNING, "connection aborted: network error");
return SCP_SERVER_STATE_NETWORK_ERR;
}
LOG_DEVEL(LOG_LEVEL_DEBUG, "connection terminated (denied)");
return SCP_SERVER_STATE_OK;
}
/******************************************************************************/
enum SCP_SERVER_STATES_E
scp_v0s_replyauthentication(struct trans *atrans, unsigned short int value)
{
struct stream *out_s;
out_s = trans_get_out_s(atrans, 0);
out_uint32_be(out_s, 0); /* version */
out_uint32_be(out_s, 14); /* size */
/* cmd SCP_GW_AUTHENTICATION means authentication reply */
out_uint16_be(out_s, SCP_GW_AUTHENTICATION);
out_uint16_be(out_s, value); /* reply code */
out_uint16_be(out_s, 0); /* dummy data */
s_mark_end(out_s);
if (0 != trans_write_copy(atrans))
{
LOG(LOG_LEVEL_WARNING, "connection aborted: network error");
return SCP_SERVER_STATE_NETWORK_ERR;
}
LOG_DEVEL(LOG_LEVEL_DEBUG, "connection terminated (scp_v0s_deny_authentication)");
return SCP_SERVER_STATE_OK;
}

View File

@ -1,124 +0,0 @@
/**
* 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_v0.h
* @brief libscp version 0 declarations
* @author Simone Fedele
*
*/
#ifndef LIBSCP_V0_H
#define LIBSCP_V0_H
#include "libscp.h"
#include "guid.h"
/* client API */
struct scp_v0_reply_type
{
/**
* True if this is a reply to a gateway authentication request
*/
int is_gw_auth_response;
/**
* Authentication result. PAM code for gateway request, boolean otherwise
*/
int auth_result;
/**
* Display number for successful non-gateway requests
*/
int display;
/**
* GUID for successful non-gateway requests
*/
struct guid guid;
};
enum SCP_CLIENT_STATES_E
scp_v0c_gateway_request(struct trans *atrans,
const char *username,
const char *password);
/*
* Note client bpp is ignored by the sesman for Xorg sessions
*/
enum SCP_CLIENT_STATES_E
scp_v0c_create_session_request(struct trans *atrans,
const char *username,
const char *password,
unsigned short code,
unsigned short width,
unsigned short height,
unsigned short bpp,
const char *domain,
const char *shell,
const char *directory,
const char *client_ip);
int
scp_v0c_reply_available(struct trans *atrans);
enum SCP_CLIENT_STATES_E
scp_v0c_get_reply(struct trans *atrans, struct scp_v0_reply_type *reply);
/* server API */
/**
*
* @brief processes the stream using scp version 0
* @param atrans connection trans
* @param s session descriptor
*
*/
enum SCP_SERVER_STATES_E
scp_v0s_accept(struct trans *atrans, struct SCP_SESSION *s);
/**
*
* @brief allows the connection to TS, returning the display port
* @param atrans connection trans
*
*/
enum SCP_SERVER_STATES_E
scp_v0s_allow_connection(struct trans *atrans, SCP_DISPLAY d,
const struct guid *guid);
/**
*
* @brief denies the connection to TS
* @param atrans connection trans
*
*/
enum SCP_SERVER_STATES_E
scp_v0s_deny_connection(struct trans *atrans);
/**
* @brief send reply to an authentication request
* @param atrans connection trans
* @param value the reply code 0 means ok
* @return
*/
enum SCP_SERVER_STATES_E
scp_v0s_replyauthentication(struct trans *atrans, unsigned short int value);
#endif

View File

@ -1,516 +0,0 @@
/**
* 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_v1c.c
* @brief libscp version 1 client api code
* @author Simone Fedele
*
*/
#if defined(HAVE_CONFIG_H)
#include <config_ac.h>
#endif
#include "libscp_v1c.h"
#include "string_calls.h"
#include <stdlib.h>
#include <stdio.h>
static enum SCP_CLIENT_STATES_E
_scp_v1c_check_response(struct trans *t, struct SCP_SESSION *s);
/* client API */
enum SCP_CLIENT_STATES_E
scp_v1c_connect(struct trans *t, struct SCP_SESSION *s)
{
tui8 sz;
int size;
struct stream *out_s = t->out_s;
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;
}
init_stream(out_s, size);
/* sending request */
/* header */
out_uint32_be(out_s, 1); /* version */
out_uint32_be(out_s, size);
out_uint16_be(out_s, SCP_COMMAND_SET_DEFAULT);
out_uint16_be(out_s, SCP_CMD_LOGIN);
/* body */
out_uint8(out_s, s->type);
out_uint16_be(out_s, s->height);
out_uint16_be(out_s, s->width);
out_uint8(out_s, s->bpp);
out_uint8(out_s, s->rsr);
out_uint8p(out_s, s->locale, 17);
out_uint8(out_s, s->addr_type);
if (s->addr_type == SCP_ADDRESS_TYPE_IPV4)
{
out_uint32_be(out_s, s->ipv4addr);
}
else if (s->addr_type == SCP_ADDRESS_TYPE_IPV6)
{
out_uint8p(out_s, s->ipv6addr, 16);
}
sz = g_strlen(s->hostname);
out_uint8(out_s, sz);
out_uint8p(out_s, s->hostname, sz);
sz = g_strlen(s->username);
out_uint8(out_s, sz);
out_uint8p(out_s, s->username, sz);
sz = g_strlen(s->password);
out_uint8(out_s, sz);
out_uint8p(out_s, s->password, sz);
s_mark_end(out_s);
if (0 != trans_force_write(t))
{
return SCP_CLIENT_STATE_NETWORK_ERR;
}
/* wait for response */
return _scp_v1c_check_response(t, s);
}
enum SCP_CLIENT_STATES_E
scp_v1c_resend_credentials(struct trans *t, struct SCP_SESSION *s)
{
struct stream *out_s = t->out_s;
tui8 sz;
int size;
size = 12 + 2 + g_strlen(s->username) + g_strlen(s->password);
init_stream(out_s, size);
/* sending request */
/* header */
out_uint32_be(out_s, 1); /* version */
out_uint32_be(out_s, size);
out_uint16_be(out_s, SCP_COMMAND_SET_DEFAULT);
out_uint16_be(out_s, SCP_CMD_RESEND_CREDS);
/* body */
sz = g_strlen(s->username);
out_uint8(out_s, sz);
out_uint8p(out_s, s->username, sz);
sz = g_strlen(s->password);
out_uint8(out_s, sz);
out_uint8p(out_s, s->password, sz);
s_mark_end(out_s);
if (0 != trans_force_write(t))
{
return SCP_CLIENT_STATE_NETWORK_ERR;
}
/* wait for response */
return _scp_v1c_check_response(t, s);
}
enum SCP_CLIENT_STATES_E
scp_v1c_get_session_list(struct trans *t, int *scount,
struct SCP_DISCONNECTED_SESSION **s)
{
struct stream *in_s = t->in_s;
struct stream *out_s = t->out_s;
tui32 version = 1;
int size = 12;
tui16 cmd = SCP_CMD_GET_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;
init_stream(out_s, 64);
/* we request session list */
out_uint32_be(out_s, version); /* version */
out_uint32_be(out_s, size); /* size */
out_uint16_be(out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */
out_uint16_be(out_s, cmd); /* cmd */
s_mark_end(out_s);
if (0 != trans_force_write(t))
{
return SCP_CLIENT_STATE_NETWORK_ERR;
}
do
{
/* then we wait for server response */
init_stream(in_s, 8);
if (0 != trans_force_read(t, 8))
{
g_free(ds);
return SCP_CLIENT_STATE_NETWORK_ERR;
}
in_uint32_be(t->in_s, version);
if (version != 1)
{
g_free(ds);
return SCP_CLIENT_STATE_VERSION_ERR;
}
in_uint32_be(t->in_s, size);
if (size < 12)
{
g_free(ds);
return SCP_CLIENT_STATE_SIZE_ERR;
}
init_stream(t->in_s, size - 8);
if (0 != trans_force_read(t, size - 8))
{
g_free(ds);
return SCP_CLIENT_STATE_NETWORK_ERR;
}
in_uint16_be(in_s, cmd);
if (cmd != SCP_COMMAND_SET_DEFAULT)
{
g_free(ds);
return SCP_CLIENT_STATE_SEQUENCE_ERR;
}
in_uint16_be(in_s, cmd);
if (cmd != SCP_REPLY_SESSIONS_INFO)
{
g_free(ds);
return SCP_CLIENT_STATE_SEQUENCE_ERR;
}
if (firstpkt)
{
firstpkt = 0;
in_uint32_be(in_s, sescnt);
sestmp = sescnt;
ds = g_new(struct SCP_DISCONNECTED_SESSION, sescnt);
if (ds == 0)
{
return SCP_CLIENT_STATE_INTERNAL_ERR;
}
}
else
{
in_uint32_be(in_s, sestmp);
}
in_uint8(in_s, continued);
in_uint8(in_s, pktcnt);
for (idx = 0; idx < pktcnt; idx++)
{
in_uint32_be(in_s, (ds[totalcnt]).SID); /* session id */
in_uint8(in_s, (ds[totalcnt]).type);
in_uint16_be(in_s, (ds[totalcnt]).height);
in_uint16_be(in_s, (ds[totalcnt]).width);
in_uint8(in_s, (ds[totalcnt]).bpp);
in_uint8(in_s, (ds[totalcnt]).idle_days);
in_uint8(in_s, (ds[totalcnt]).idle_hours);
in_uint8(in_s, (ds[totalcnt]).idle_minutes);
in_uint16_be(in_s, (ds[totalcnt]).conn_year);
in_uint8(in_s, (ds[totalcnt]).conn_month);
in_uint8(in_s, (ds[totalcnt]).conn_day);
in_uint8(in_s, (ds[totalcnt]).conn_hour);
in_uint8(in_s, (ds[totalcnt]).conn_minute);
in_uint8(in_s, (ds[totalcnt]).addr_type);
if ((ds[totalcnt]).addr_type == SCP_ADDRESS_TYPE_IPV4)
{
in_uint32_be(in_s, (ds[totalcnt]).ipv4addr);
}
else if ((ds[totalcnt]).addr_type == SCP_ADDRESS_TYPE_IPV6)
{
in_uint8a(in_s, (ds[totalcnt]).ipv6addr, 16);
}
totalcnt++;
}
}
while (continued);
printf("fine\n");
/* return data... */
(*scount) = sescnt;
(*s) = ds;
return SCP_CLIENT_STATE_LIST_OK;
}
enum SCP_CLIENT_STATES_E
scp_v1c_select_session(struct trans *t, struct SCP_SESSION *s,
SCP_SID sid)
{
struct stream *in_s = t->in_s;
struct stream *out_s = t->out_s;
tui32 version = 1;
int size = 16;
tui16 cmd = SCP_CMD_SELECT_SESSION;
init_stream(out_s, 64);
/* sending our selection */
out_uint32_be(out_s, version); /* version */
out_uint32_be(out_s, size); /* size */
out_uint16_be(out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */
out_uint16_be(out_s, cmd); /* cmd */
out_uint32_be(out_s, sid);
s_mark_end(out_s);
if (0 != trans_force_write(t))
{
return SCP_CLIENT_STATE_NETWORK_ERR;
}
/* waiting for response.... */
init_stream(in_s, 8);
if (0 != trans_force_read(t, 8))
{
return SCP_CLIENT_STATE_NETWORK_ERR;
}
in_uint32_be(in_s, version);
if (version != 1)
{
return SCP_CLIENT_STATE_VERSION_ERR;
}
in_uint32_be(in_s, size);
if (size < 12)
{
return SCP_CLIENT_STATE_SIZE_ERR;
}
init_stream(in_s, size - 8);
/* read the rest of the packet */
if (0 != trans_force_read(t, size - 8))
{
return SCP_CLIENT_STATE_NETWORK_ERR;
}
in_uint16_be(in_s, cmd);
if (cmd != SCP_COMMAND_SET_DEFAULT)
{
return SCP_CLIENT_STATE_SEQUENCE_ERR;
}
in_uint16_be(in_s, cmd);
if (cmd != SCP_REPLY_SESSION_RECONNECTED)
{
return SCP_CLIENT_STATE_SEQUENCE_ERR;
}
/* session display */
in_uint16_be(in_s, (s->display));
/*we don't need to return any data other than the display */
/*because we already sent that */
return SCP_CLIENT_STATE_OK;
}
enum SCP_CLIENT_STATES_E
scp_v1c_select_session_cancel(struct trans *t)
{
struct stream *out_s = t->out_s;
tui32 version = 1;
tui32 size = 12;
tui16 cmd = SCP_CMD_SELECT_SESSION_CANCEL;
init_stream(out_s, 64);
/* sending our selection */
out_uint32_be(out_s, version); /* version */
out_uint32_be(out_s, size); /* size */
out_uint16_be(out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */
out_uint16_be(out_s, cmd); /* cmd */
s_mark_end(out_s);
if (0 != trans_force_write(t))
{
return SCP_CLIENT_STATE_NETWORK_ERR;
}
return SCP_CLIENT_STATE_END;
}
static enum SCP_CLIENT_STATES_E
_scp_v1c_check_response(struct trans *t, struct SCP_SESSION *s)
{
struct stream *in_s = t->in_s;
tui32 version;
int size;
tui16 cmd;
tui16 dim;
init_stream(in_s, 64);
if (0 != trans_force_read(t, 8))
{
return SCP_CLIENT_STATE_NETWORK_ERR;
}
in_uint32_be(in_s, version);
if (version != 1)
{
return SCP_CLIENT_STATE_VERSION_ERR;
}
in_uint32_be(in_s, size);
init_stream(in_s, size - 8);
/* read the rest of the packet */
if (0 != trans_force_read(t, size - 8))
{
return SCP_CLIENT_STATE_NETWORK_ERR;
}
in_uint16_be(in_s, cmd);
if (cmd != SCP_COMMAND_SET_DEFAULT)
{
return SCP_CLIENT_STATE_SEQUENCE_ERR;
}
in_uint16_be(in_s, cmd);
if (cmd == SCP_REPLY_LOGIN_DENIED)
{
in_uint16_be(in_s, dim);
if (s->errstr != 0)
{
g_free(s->errstr);
}
s->errstr = g_new(char, dim + 1);
if (s->errstr == 0)
{
return SCP_CLIENT_STATE_INTERNAL_ERR;
}
in_uint8a(in_s, s->errstr, dim);
(s->errstr)[dim] = '\0';
return SCP_CLIENT_STATE_CONNECTION_DENIED;
}
else if (cmd == SCP_REPLY_REREQUEST_CREDS)
{
in_uint16_be(in_s, dim);
if (s->errstr != 0)
{
g_free(s->errstr);
}
s->errstr = g_new(char, dim + 1);
if (s->errstr == 0)
{
return SCP_CLIENT_STATE_INTERNAL_ERR;
}
in_uint8a(in_s, s->errstr, dim);
(s->errstr)[dim] = '\0';
return SCP_CLIENT_STATE_RESEND_CREDENTIALS;
}
else if (cmd == SCP_REPLY_CHANGE_PASSWD)
{
in_uint16_be(in_s, dim);
if (s->errstr != 0)
{
g_free(s->errstr);
}
s->errstr = g_new(char, dim + 1);
if (s->errstr == 0)
{
return SCP_CLIENT_STATE_INTERNAL_ERR;
}
in_uint8a(in_s, s->errstr, dim);
(s->errstr)[dim] = '\0';
return SCP_CLIENT_STATE_PWD_CHANGE_REQ;
}
else if (cmd == SCP_REPLY_NEW_SESSION)
{
in_uint16_be(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 == SCP_REPLY_USER_SESSIONS_EXIST) /* session list */
{
return SCP_CLIENT_STATE_SESSION_LIST;
}
return SCP_CLIENT_STATE_SEQUENCE_ERR;
}

View File

@ -1,63 +0,0 @@
/**
* 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_v1c.h
* @brief libscp version 1 client api declarations
* @author Simone Fedele
*
*/
#ifndef LIBSCP_V1C_H
#define LIBSCP_V1C_H
#include "libscp.h"
/* client API */
/* 001 */
enum SCP_CLIENT_STATES_E
scp_v1c_connect(struct trans *t, struct SCP_SESSION *s);
/* 004 */
enum SCP_CLIENT_STATES_E
scp_v1c_resend_credentials(struct trans *t, struct SCP_SESSION *s);
/* 021 */
enum SCP_CLIENT_STATES_E
scp_v1c_pwd_change(struct trans *t, char *newpass);
/* 022 */
enum SCP_CLIENT_STATES_E
scp_v1c_pwd_change_cancel(struct trans *t);
/* 041 */
enum SCP_CLIENT_STATES_E
scp_v1c_get_session_list(struct trans *t, int *scount,
struct SCP_DISCONNECTED_SESSION **s);
/* 043 */
enum SCP_CLIENT_STATES_E
scp_v1c_select_session(struct trans *t, struct SCP_SESSION *s,
SCP_SID sid);
/* 044 */
enum SCP_CLIENT_STATES_E
scp_v1c_select_session_cancel(struct trans *t);
#endif

View File

@ -1,434 +0,0 @@
/**
* 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_v1c_mng.c
* @brief libscp version 1 client api code - session management
* @author Simone Fedele
*
*/
#if defined(HAVE_CONFIG_H)
#include <config_ac.h>
#endif
#include "libscp_v1c_mng.h"
#include "string_calls.h"
#include <stdlib.h>
#include <stdio.h>
//extern struct log_config* s_log;
static enum SCP_CLIENT_STATES_E
_scp_v1c_mng_check_response(struct trans *t, struct SCP_SESSION *s);
/* client API */
/* 001 */
enum SCP_CLIENT_STATES_E
scp_v1c_mng_connect(struct trans *t, struct SCP_SESSION *s)
{
struct stream *out_s = t->out_s;
tui8 sz;
int 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;
}
init_stream(out_s, size);
/* sending request */
/* header */
out_uint32_be(out_s, 1); /* version */
out_uint32_be(out_s, size);
out_uint16_be(out_s, SCP_COMMAND_SET_MANAGE);
out_uint16_be(out_s, SCP_CMD_MNG_LOGIN);
/* data */
sz = g_strlen(s->username);
out_uint8(out_s, sz);
out_uint8p(out_s, s->username, sz);
sz = g_strlen(s->password);
out_uint8(out_s, sz);
out_uint8p(out_s, s->password, sz);
/* address */
out_uint8(out_s, s->addr_type);
if (s->addr_type == SCP_ADDRESS_TYPE_IPV4)
{
out_uint32_be(out_s, s->ipv4addr);
}
else
{
out_uint8p(out_s, s->ipv6addr, 16);
}
/* hostname */
sz = g_strlen(s->hostname);
out_uint8(out_s, sz);
out_uint8p(out_s, s->hostname, sz);
s_mark_end(out_s);
if (0 != trans_force_write(t))
{
LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
return SCP_CLIENT_STATE_NETWORK_ERR;
}
/* wait for response */
return _scp_v1c_mng_check_response(t, s);
}
/* 004 */
enum SCP_CLIENT_STATES_E
scp_v1c_mng_get_session_list(struct trans *t, int *scount,
struct SCP_DISCONNECTED_SESSION **s)
{
struct stream *in_s = t->in_s;
struct stream *out_s = t->out_s;
tui32 version = 1;
int 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(out_s, 64);
/* we request session list */
out_uint32_be(out_s, version); /* version */
out_uint32_be(out_s, size); /* size */
out_uint16_be(out_s, SCP_COMMAND_SET_MANAGE); /* cmdset */
out_uint16_be(out_s, cmd); /* cmd */
s_mark_end(out_s);
if (0 != trans_force_write(t))
{
LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
return SCP_CLIENT_STATE_NETWORK_ERR;
}
do
{
/* then we wait for server response */
init_stream(in_s, 8);
if (0 != trans_force_read(t, 8))
{
LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
g_free(ds);
return SCP_CLIENT_STATE_NETWORK_ERR;
}
in_uint32_be(in_s, version);
if (version != 1)
{
LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: version error", __LINE__);
g_free(ds);
return SCP_CLIENT_STATE_VERSION_ERR;
}
in_uint32_be(in_s, size);
if (size < 12)
{
LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: size error", __LINE__);
g_free(ds);
return SCP_CLIENT_STATE_SIZE_ERR;
}
init_stream(in_s, size);
if (0 != trans_force_read(t, size - 8))
{
LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
g_free(ds);
return SCP_CLIENT_STATE_NETWORK_ERR;
}
in_uint16_be(in_s, cmd);
if (cmd != SCP_COMMAND_SET_MANAGE)
{
LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__);
g_free(ds);
return SCP_CLIENT_STATE_SEQUENCE_ERR;
}
in_uint16_be(in_s, cmd);
if (cmd != SCP_CMD_MNG_LIST) /* session list */
{
LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__);
g_free(ds);
return SCP_CLIENT_STATE_SEQUENCE_ERR;
}
if (firstpkt)
{
firstpkt = 0;
in_uint32_be(in_s, sescnt);
sestmp = sescnt;
if (0 == sescnt)
{
/* return data... */
(*scount) = sescnt;
(*s) = NULL;
LOG_DEVEL(LOG_LEVEL_DEBUG, "[v1c_mng] end list - no session on TS");
return SCP_CLIENT_STATE_LIST_OK;
}
ds = g_new(struct SCP_DISCONNECTED_SESSION, sescnt);
if (ds == 0)
{
LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: internal error", __LINE__);
return SCP_CLIENT_STATE_INTERNAL_ERR;
}
}
else
{
in_uint32_be(in_s, sestmp);
}
in_uint8(in_s, continued);
in_uint8(in_s, pktcnt);
for (idx = 0; idx < pktcnt; idx++)
{
in_uint32_be(in_s, (ds[totalcnt]).SID); /* session id */
in_uint8(in_s, (ds[totalcnt]).type);
in_uint16_be(in_s, (ds[totalcnt]).height);
in_uint16_be(in_s, (ds[totalcnt]).width);
in_uint8(in_s, (ds[totalcnt]).bpp);
in_uint8(in_s, (ds[totalcnt]).idle_days);
in_uint8(in_s, (ds[totalcnt]).idle_hours);
in_uint8(in_s, (ds[totalcnt]).idle_minutes);
in_uint16_be(in_s, (ds[totalcnt]).conn_year);
in_uint8(in_s, (ds[totalcnt]).conn_month);
in_uint8(in_s, (ds[totalcnt]).conn_day);
in_uint8(in_s, (ds[totalcnt]).conn_hour);
in_uint8(in_s, (ds[totalcnt]).conn_minute);
in_uint8(in_s, (ds[totalcnt]).addr_type);
if ((ds[totalcnt]).addr_type == SCP_ADDRESS_TYPE_IPV4)
{
in_uint32_be(in_s, (ds[totalcnt]).ipv4addr);
}
if ((ds[totalcnt]).addr_type == SCP_ADDRESS_TYPE_IPV6)
{
in_uint8a(in_s, (ds[totalcnt]).ipv6addr, 16);
}
totalcnt++;
}
}
while (continued);
/* return data... */
(*scount) = sescnt;
(*s) = ds;
LOG_DEVEL(LOG_LEVEL_DEBUG, "[v1c_mng] end list");
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 = 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;
}
in_uint16_be(c->in_s, cmd);
if (cmd != 46)
{
return SCP_CLIENT_STATE_SEQUENCE_ERR;
}
/ * session display * /
in_uint16_be(c->in_s, (s->display));
/ *we don't need to return any data other than the display * /
/ *because we already sent that * /
return SCP_CLIENT_STATE_OK;
}*/
/* 044 * /
enum SCP_CLIENT_STATES_E
scp_v1c_select_session_cancel(struct SCP_CONNECTION* c)
{
tui32 version = 1;
tui32 size = 12;
tui16 cmd = 44;
init_stream(c->out_s, c->out_s->size);
/ * sending our selection * /
out_uint32_be(c->out_s, version); / * version * /
out_uint32_be(c->out_s, size); / * size * /
out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); / * cmdset * /
out_uint16_be(c->out_s, cmd); / * cmd * /
if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size))
{
return SCP_CLIENT_STATE_NETWORK_ERR;
}
return SCP_CLIENT_STATE_END;
}*/
static enum SCP_CLIENT_STATES_E
_scp_v1c_mng_check_response(struct trans *t, struct SCP_SESSION *s)
{
struct stream *in_s = t->in_s;
tui32 version;
int size;
tui16 cmd;
tui8 dim;
char buf[257];
init_stream(in_s, 8);
if (0 != trans_force_read(t, 8))
{
LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
return SCP_CLIENT_STATE_NETWORK_ERR;
}
in_uint32_be(in_s, version);
if (version != 1)
{
LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: version error", __LINE__);
return SCP_CLIENT_STATE_VERSION_ERR;
}
in_uint32_be(in_s, size);
init_stream(in_s, size - 8);
/* read the rest of the packet */
if (0 != trans_force_read(t, size - 8))
{
LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
return SCP_CLIENT_STATE_NETWORK_ERR;
}
in_uint16_be(in_s, cmd);
if (cmd != SCP_COMMAND_SET_MANAGE)
{
LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__);
return SCP_CLIENT_STATE_SEQUENCE_ERR;
}
in_uint16_be(in_s, cmd);
if (cmd == SCP_CMD_MNG_LOGIN_ALLOW) /* connection ok */
{
LOG(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(in_s, dim);
buf[dim] = '\0';
in_uint8a(in_s, buf, dim);
scp_session_set_errstr(s, buf);
LOG(LOG_LEVEL_INFO, "[v1c_mng:%d] connection denied: %s", __LINE__, s->errstr);
return SCP_CLIENT_STATE_CONNECTION_DENIED;
}
LOG(LOG_LEVEL_WARNING, "[v1c-mng:%d] connection aborted: sequence error", __LINE__);
return SCP_CLIENT_STATE_SEQUENCE_ERR;
}

View File

@ -1,55 +0,0 @@
/**
* 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_v1c_mng.h
* @brief libscp version 1 client api declarations - session management
* @author Simone Fedele
*
*/
#ifndef LIBSCP_V1C_MNG_H
#define LIBSCP_V1C_MNG_H
#include "libscp.h"
/* client API */
/* 001 */
enum SCP_CLIENT_STATES_E
scp_v1c_mng_connect(struct trans *t, struct SCP_SESSION *s);
/* 004 * /
enum SCP_CLIENT_STATES_E
scp_v1c_resend_credentials(struct SCP_CONNECTION* c, struct SCP_SESSION* s);
/ * 021 * /
enum SCP_CLIENT_STATES_E
scp_v1c_pwd_change(struct SCP_CONNECTION* c, char* newpass);
/ * 022 * /
enum SCP_CLIENT_STATES_E
scp_v1c_pwd_change_cancel(struct SCP_CONNECTION* c);
*/
/* 041 */
enum SCP_CLIENT_STATES_E
scp_v1c_mng_get_session_list(struct trans *t, int *scount,
struct SCP_DISCONNECTED_SESSION **s);
#endif

View File

@ -1,892 +0,0 @@
/**
* 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_v1s.c
* @brief libscp version 1 server api code
* @author Simone Fedele
*
*/
#if defined(HAVE_CONFIG_H)
#include <config_ac.h>
#endif
#ifndef LIBSCP_V1S_C
#define LIBSCP_V1S_C
#include "libscp_v1s.h"
#include "string_calls.h"
//extern struct log_config* s_log;
/**
* Reads a uint8 followed by a string into a buffer
*
* Buffer is null-terminated on success
*
* @param s Input stream
* @param [out] Output buffer (must be >= 256 chars)
* @param param Parameter we're reading
* @param line Line number reference
* @return != 0 if string read OK
*
* @todo
* This needs to be merged with the func of the same name in
* libscp_v1s_mng.c
*/
static
int in_string8(struct stream *s, char str[], const char *param, int line)
{
int result;
if (!s_check_rem(s, 1))
{
LOG(LOG_LEVEL_WARNING,
"[v1s:%d] connection aborted: %s len missing",
line, param);
result = 0;
}
else
{
unsigned int sz;
in_uint8(s, sz);
result = s_check_rem(s, sz);
if (!result)
{
LOG(LOG_LEVEL_WARNING,
"[v1s:%d] connection aborted: %s data missing",
line, param);
}
else
{
in_uint8a(s, str, sz);
str[sz] = '\0';
}
}
return result;
}
/**
* Initialises a V1 session object
*
* This is called after the V1 header, command set and command have been read
*
* @param c Connection
* @param [out] session pre-allocated session object
* @return SCP_SERVER_STATE_OK for success
*/
static enum SCP_SERVER_STATES_E
scp_v1s_init_session(struct trans *t, struct SCP_SESSION *session)
{
tui8 type;
tui16 height;
tui16 width;
tui8 bpp;
tui8 sz;
char buf[256];
struct stream *in_s = t->in_s;
scp_session_set_version(session, 1);
/* Check there's data for the session type, the height, the width, the
* bpp, the resource sharing indicator and the locale */
if (!s_check_rem(in_s, 1 + 2 + 2 + 1 + 1 + 17))
{
LOG(LOG_LEVEL_WARNING,
"[v1s:%d] connection aborted: short packet",
__LINE__);
return SCP_SERVER_STATE_SIZE_ERR;
}
in_uint8(in_s, type);
if ((type != SCP_SESSION_TYPE_XVNC) && (type != SCP_SESSION_TYPE_XRDP))
{
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: unknown session type", __LINE__);
return SCP_SERVER_STATE_SESSION_TYPE_ERR;
}
scp_session_set_type(session, type);
in_uint16_be(in_s, height);
scp_session_set_height(session, height);
in_uint16_be(in_s, width);
scp_session_set_width(session, width);
in_uint8(in_s, bpp);
if (0 != scp_session_set_bpp(session, bpp))
{
LOG(LOG_LEVEL_WARNING,
"[v1s:%d] connection aborted: unsupported bpp: %d",
__LINE__, bpp);
return SCP_SERVER_STATE_INTERNAL_ERR;
}
in_uint8(in_s, sz);
scp_session_set_rsr(session, sz);
in_uint8a(in_s, buf, 17);
buf[17] = '\0';
scp_session_set_locale(session, buf);
/* Check there's enough data left for at least an IPv4 address (+len) */
if (!s_check_rem(in_s, 1 + 4))
{
LOG(LOG_LEVEL_WARNING,
"[v1s:%d] connection aborted: IP addr len missing",
__LINE__);
return SCP_SERVER_STATE_SIZE_ERR;
}
in_uint8(in_s, sz);
if (sz == SCP_ADDRESS_TYPE_IPV4)
{
tui32 ipv4;
in_uint32_be(in_s, ipv4);
scp_session_set_addr(session, sz, &ipv4);
}
else if (sz == SCP_ADDRESS_TYPE_IPV6)
{
if (!s_check_rem(in_s, 16))
{
LOG(LOG_LEVEL_WARNING,
"[v1s:%d] connection aborted: IP addr missing",
__LINE__);
return SCP_SERVER_STATE_SIZE_ERR;
}
in_uint8a(in_s, buf, 16);
scp_session_set_addr(session, sz, buf);
}
/* reading hostname */
if (!in_string8(in_s, buf, "hostname", __LINE__))
{
return SCP_SERVER_STATE_SIZE_ERR;
}
if (0 != scp_session_set_hostname(session, buf))
{
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
return SCP_SERVER_STATE_INTERNAL_ERR;
}
/* reading username */
if (!in_string8(in_s, buf, "username", __LINE__))
{
return SCP_SERVER_STATE_SIZE_ERR;
}
if (0 != scp_session_set_username(session, buf))
{
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
return SCP_SERVER_STATE_INTERNAL_ERR;
}
/* reading password */
if (!in_string8(in_s, buf, "passwd", __LINE__))
{
return SCP_SERVER_STATE_SIZE_ERR;
}
if (0 != scp_session_set_password(session, buf))
{
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
return SCP_SERVER_STATE_INTERNAL_ERR;
}
return SCP_SERVER_STATE_OK;
}
/* server API */
enum SCP_SERVER_STATES_E
scp_v1s_accept(struct trans *t, struct SCP_SESSION *s)
{
tui32 size;
tui16 cmdset;
tui16 cmd;
struct stream *in_s = t->in_s;
enum SCP_SERVER_STATES_E result;
in_uint32_be(in_s, size);
/* Check the message is big enough for the header, the command set, and
* the command (but not too big) */
if (size < (8 + 2 + 2) || size > SCP_MAX_MESSAGE_SIZE)
{
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__);
return SCP_SERVER_STATE_SIZE_ERR;
}
/* reading command set */
in_uint16_be(in_s, cmdset);
/* if we are starting a management session */
if (cmdset == SCP_COMMAND_SET_MANAGE)
{
LOG(LOG_LEVEL_DEBUG, "[v1s:%d] requested management connection", __LINE__);
/* should return SCP_SERVER_STATE_START_MANAGE */
return scp_v1s_mng_accept(t, s);
}
/* if we started with resource sharing... */
if (cmdset == SCP_COMMAND_SET_RSR)
{
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
return SCP_SERVER_STATE_SEQUENCE_ERR;
}
/* reading command */
in_uint16_be(in_s, cmd);
switch (cmd)
{
case SCP_CMD_LOGIN:
s->current_cmd = cmd;
result = scp_v1s_init_session(t, s);
break;
case SCP_CMD_RESEND_CREDS:
result = scp_v1s_accept_password_reply(t, s);
s->current_cmd = SCP_CMD_LOGIN; /* Caller re-parses credentials */
break;
default:
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence "
"error. Unrecognised cmd %d", __LINE__, cmd);
result = SCP_SERVER_STATE_SEQUENCE_ERR;
}
return result;
}
enum SCP_SERVER_STATES_E
scp_v1s_deny_connection(struct trans *t, const char *reason)
{
struct stream *out_s;
int rlen;
/* forcing message not to exceed 64k */
rlen = g_strlen(reason);
if (rlen > 65535)
{
rlen = 65535;
}
out_s = trans_get_out_s(t, rlen + 14);
out_uint32_be(out_s, 1); /* version */
/* packet size: 4 + 4 + 2 + 2 + 2 + strlen(reason) */
/* version + size + cmdset + cmd + msglen + msg */
out_uint32_be(out_s, rlen + 14);
out_uint16_be(out_s, SCP_COMMAND_SET_DEFAULT);
out_uint16_be(out_s, SCP_REPLY_LOGIN_DENIED);
out_uint16_be(out_s, rlen);
out_uint8p(out_s, reason, rlen);
s_mark_end(out_s);
if (0 != trans_force_write(t))
{
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
return SCP_SERVER_STATE_END;
}
enum SCP_SERVER_STATES_E
scp_v1s_request_password(struct trans *t, struct SCP_SESSION *s,
const char *reason)
{
struct stream *out_s;
int rlen;
/* forcing message not to exceed 64k */
rlen = g_strlen(reason);
if (rlen > 65535)
{
rlen = 65535;
}
out_s = trans_get_out_s(t, rlen + 14);
out_uint32_be(out_s, 1); /* version */
/* packet size: 4 + 4 + 2 + 2 + 2 + strlen(reason) */
/* version + size + cmdset + cmd + msglen + msg */
out_uint32_be(out_s, rlen + 14);
out_uint16_be(out_s, SCP_COMMAND_SET_DEFAULT);
out_uint16_be(out_s, SCP_REPLY_REREQUEST_CREDS);
out_uint16_be(out_s, rlen);
out_uint8p(out_s, reason, rlen);
s_mark_end(out_s);
if (0 != trans_force_write(t))
{
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
return SCP_SERVER_STATE_OK;
}
enum SCP_SERVER_STATES_E
scp_v1s_accept_password_reply(struct trans *t, struct SCP_SESSION *s)
{
struct stream *in_s;
char buf[257];
in_s = t->in_s;
buf[256] = '\0';
/* reading username */
if (!in_string8(in_s, buf, "username", __LINE__))
{
return SCP_SERVER_STATE_SIZE_ERR;
}
if (0 != scp_session_set_username(s, buf))
{
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error",
__LINE__);
return SCP_SERVER_STATE_INTERNAL_ERR;
}
/* reading password */
if (!in_string8(in_s, buf, "passwd", __LINE__))
{
return SCP_SERVER_STATE_SIZE_ERR;
}
if (0 != scp_session_set_password(s, buf))
{
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error",
__LINE__);
return SCP_SERVER_STATE_INTERNAL_ERR;
}
return SCP_SERVER_STATE_OK;
}
enum SCP_SERVER_STATES_E
scp_v1s_request_pwd_change(struct trans *t, char *reason, char *npw)
{
return SCP_SERVER_STATE_INTERNAL_ERR;
}
enum SCP_SERVER_STATES_E
scp_v1s_pwd_change_error(struct trans *t, char *error, int retry, char *npw)
{
return SCP_SERVER_STATE_INTERNAL_ERR;
}
enum SCP_SERVER_STATES_E
scp_v1s_connect_new_session(struct trans *t, SCP_DISPLAY d)
{
struct stream *out_s;
out_s = trans_get_out_s(t, 14);
out_uint32_be(out_s, 1); /* version */
/* packet size: 4 + 4 + 2 + 2 + 2 */
/* version + size + cmdset + cmd + msglen + msg */
out_uint32_be(out_s, 14);
out_uint16_be(out_s, SCP_COMMAND_SET_DEFAULT);
out_uint16_be(out_s, SCP_REPLY_NEW_SESSION);
out_uint16_be(out_s, d);
s_mark_end(out_s);
if (0 != trans_force_write(t))
{
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
return SCP_SERVER_STATE_OK;
}
enum SCP_SERVER_STATES_E
scp_v1s_connection_error(struct trans *t, const char *error)
{
struct stream *out_s;
tui16 len;
len = g_strlen(error);
if (len > 8192 - 12)
{
len = 8192 - 12;
}
out_s = trans_get_out_s(t, 12 + len);
out_uint32_be(out_s, 1); /* version */
/* packet size: 4 + 4 + 2 + 2 + len */
/* version + size + cmdset + cmd */
out_uint32_be(out_s, 12 + len);
out_uint16_be(out_s, SCP_COMMAND_SET_DEFAULT);
out_uint16_be(out_s, SCP_REPLY_CMD_CONN_ERROR);
out_uint8a(out_s, error, len);
s_mark_end(out_s);
if (0 != trans_force_write(t))
{
return SCP_SERVER_STATE_NETWORK_ERR;
}
return SCP_SERVER_STATE_END;
}
#if 0
enum SCP_SERVER_STATES_E
scp_v1s_list_sessions(struct SCP_CONNECTION *c, int sescnt, struct SCP_DISCONNECTED_SESSION *ds, SCP_SID *sid)
{
tui32 version = 1;
int 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(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
/* then we wait for client ack */
/*
* Maybe this message could say if the session should be resized on
* 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(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(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__);
return SCP_SERVER_STATE_VERSION_ERR;
}
in_uint32_be(c->in_s, size);
/* Check the message is big enough for the header, the command set, and
* the command (but not too big) */
if (size < (8 + 2 + 2) || size > SCP_MAX_MESSAGE_SIZE)
{
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__);
return SCP_SERVER_STATE_SIZE_ERR;
}
init_stream(c->in_s, size - 8);
if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, (size - 8)))
{
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
c->in_s->end = c->in_s->data + (size - 8);
in_uint16_be(c->in_s, cmd);
if (cmd != SCP_COMMAND_SET_DEFAULT)
{
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
return SCP_SERVER_STATE_SEQUENCE_ERR;
}
in_uint16_be(c->in_s, cmd);
if (cmd != 41)
{
LOG(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(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(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(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__);
return SCP_SERVER_STATE_VERSION_ERR;
}
in_uint32_be(c->in_s, size);
/* Check the message is big enough for the header, the command set, and
* the command (but not too big) */
if (size < (8 + 2 + 2) || size > SCP_MAX_MESSAGE_SIZE)
{
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__);
return SCP_SERVER_STATE_SIZE_ERR;
}
/* rest of the packet */
init_stream(c->in_s, size - 8);
if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, (size - 8)))
{
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
c->in_s->end = c->in_s->data + (size - 8);
in_uint16_be(c->in_s, cmd);
if (cmd != SCP_COMMAND_SET_DEFAULT)
{
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
return SCP_SERVER_STATE_SEQUENCE_ERR;
}
in_uint16_be(c->in_s, cmd);
if (cmd == 43)
{
if (!s_check_rem(c->in_s, 4))
{
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: missing session", __LINE__);
return SCP_SERVER_STATE_SIZE_ERR;
}
/* 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(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error (no such session in list)", __LINE__);
return SCP_SERVER_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(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
return SCP_SERVER_STATE_SEQUENCE_ERR;
}
return SCP_SERVER_STATE_OK;
}
#endif
enum SCP_SERVER_STATES_E
scp_v1s_list_sessions40(struct trans *t)
{
struct stream *out_s;
out_s = trans_get_out_s(t, 12);
/* send a notice that we have some disconnected sessions */
out_uint32_be(out_s, 1); /* version */
out_uint32_be(out_s, 12); /* size */
out_uint16_be(out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */
out_uint16_be(out_s, SCP_REPLY_USER_SESSIONS_EXIST);/* cmd */
s_mark_end(out_s);
if (0 != trans_force_write(t))
{
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
return SCP_SERVER_STATE_OK;
}
enum SCP_SERVER_STATES_E
scp_v1s_list_sessions42(struct trans *t, int sescnt, struct SCP_DISCONNECTED_SESSION *ds)
{
int pktcnt;
int idx;
int sidx;
int pidx;
int size;
struct stream *out_s;
struct SCP_DISCONNECTED_SESSION *cds;
/* calculating the number of packets to send */
pktcnt = sescnt / SCP_SERVER_MAX_LIST_SIZE;
if ((sescnt % SCP_SERVER_MAX_LIST_SIZE) != 0)
{
pktcnt++;
}
for (idx = 0; idx < pktcnt; idx++)
{
out_s = trans_get_out_s(t, 8192);
/* size: ver+size+cmdset+cmd+sescnt+continue+count */
size = 4 + 4 + 2 + 2 + 4 + 1 + 1;
/* header */
s_push_layer(out_s, channel_hdr, 8);
out_uint16_be(out_s, SCP_COMMAND_SET_DEFAULT);
out_uint16_be(out_s, SCP_REPLY_SESSIONS_INFO);
/* session count */
out_uint32_be(out_s, sescnt);
/* setting the continue flag */
if ((idx + 1) * SCP_SERVER_MAX_LIST_SIZE >= sescnt)
{
out_uint8(out_s, 0);
/* setting session count for this packet */
pidx = sescnt - (idx * SCP_SERVER_MAX_LIST_SIZE);
out_uint8(out_s, pidx);
}
else
{
out_uint8(out_s, 1);
/* setting session count for this packet */
pidx = SCP_SERVER_MAX_LIST_SIZE;
out_uint8(out_s, pidx);
}
/* adding session descriptors */
for (sidx = 0; sidx < pidx; sidx++)
{
/* shortcut to the current session to send */
cds = ds + (idx * SCP_SERVER_MAX_LIST_SIZE) + sidx;
/* session data */
out_uint32_be(out_s, cds->SID); /* session id */
out_uint8(out_s, cds->type);
out_uint16_be(out_s, cds->height);
out_uint16_be(out_s, cds->width);
out_uint8(out_s, cds->bpp);
out_uint8(out_s, cds->idle_days);
out_uint8(out_s, cds->idle_hours);
out_uint8(out_s, cds->idle_minutes);
size += 13;
out_uint16_be(out_s, cds->conn_year);
out_uint8(out_s, cds->conn_month);
out_uint8(out_s, cds->conn_day);
out_uint8(out_s, cds->conn_hour);
out_uint8(out_s, cds->conn_minute);
out_uint8(out_s, cds->addr_type);
size += 7;
if (cds->addr_type == SCP_ADDRESS_TYPE_IPV4)
{
in_uint32_be(out_s, cds->ipv4addr);
size += 4;
}
else if (cds->addr_type == SCP_ADDRESS_TYPE_IPV6)
{
in_uint8a(out_s, cds->ipv6addr, 16);
size += 16;
}
}
s_mark_end(out_s);
s_pop_layer(out_s, channel_hdr);
out_uint32_be(out_s, 1); /* version */
out_uint32_be(out_s, size);
if (0 != trans_force_write(t))
{
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
}
return SCP_SERVER_STATE_OK;
}
// TODO
enum SCP_SERVER_STATES_E
scp_v1s_accept_list_sessions_reply(int cmd, struct trans *t)
{
struct SCP_SESSION *s;
struct stream *in_s;
s = (struct SCP_SESSION *) (t->callback_data);
if (s == NULL)
{
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
return SCP_SERVER_STATE_INTERNAL_ERR;
}
s->current_cmd = cmd;
in_s = t->in_s;
switch (cmd)
{
case SCP_CMD_GET_SESSION_LIST:
break;
case SCP_CMD_SELECT_SESSION:
in_uint32_be(in_s, s->return_sid);
break;
case SCP_CMD_SELECT_SESSION_CANCEL:
break;
case SCP_CMD_FORCE_NEW_CONN:
break;
default:
break;
}
return SCP_SERVER_STATE_OK;
}
enum SCP_SERVER_STATES_E
scp_v1s_reconnect_session(struct trans *t, SCP_DISPLAY d)
{
struct stream *out_s;
/* ok, we send session data and display */
out_s = trans_get_out_s(t, 14);
/* header */
out_uint32_be(out_s, 1); /* version */
out_uint32_be(out_s, 14); /* size */
out_uint16_be(out_s, SCP_COMMAND_SET_DEFAULT);
out_uint16_be(out_s, SCP_REPLY_SESSION_RECONNECTED); /* cmd */
/* session data */
out_uint16_be(out_s, d); /* session display */
s_mark_end(out_s);
/*out_uint8(c->out_s, ds->type);
out_uint16_be(c->out_s, ds->height);
out_uint16_be(c->out_s, ds->width);
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 != trans_force_write(t))
{
LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
return SCP_SERVER_STATE_OK;
}
#endif

View File

@ -1,99 +0,0 @@
/**
* 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_v1s.h
* @brief libscp version 1 server api declarations
* @author Simone Fedele
*
*/
#ifndef LIBSCP_V1S_H
#define LIBSCP_V1S_H
#include "libscp.h"
/* server API */
/**
*
* @brief processes the stream using scp version 1
* @param trans connection trans
* @param s pointer to session descriptor pointer
*
* this function places in *s the address of a newly allocated SCP_SESSION structure
* that should be free()d
*/
enum SCP_SERVER_STATES_E
scp_v1s_accept(struct trans *t, struct SCP_SESSION *s);
/**
*
* @brief denies connection to sesman
* @param c connection descriptor
* @param reason pointer to a string containing the reason for denying connection
*
*/
/* 002 */
enum SCP_SERVER_STATES_E
scp_v1s_deny_connection(struct trans *t, const char *reason);
enum SCP_SERVER_STATES_E
scp_v1s_request_password(struct trans *t, struct SCP_SESSION *s,
const char *reason);
enum SCP_SERVER_STATES_E
scp_v1s_accept_password_reply(struct trans *t, struct SCP_SESSION *s);
enum SCP_SERVER_STATES_E
scp_v1s_accept_list_sessions_reply(int cmd, struct trans *t);
/* 020 */
enum SCP_SERVER_STATES_E
scp_v1s_request_pwd_change(struct trans *t, char *reason, char *npw);
/* 023 */
enum SCP_SERVER_STATES_E
scp_v1s_pwd_change_error(struct trans *t, char *error, int retry, char *npw);
/* 030 */
enum SCP_SERVER_STATES_E
scp_v1s_connect_new_session(struct trans *t, SCP_DISPLAY d);
/* 032 */
enum SCP_SERVER_STATES_E
scp_v1s_connection_error(struct trans *t, const char *error);
/* 040 */
#if 0
enum SCP_SERVER_STATES_E
scp_v1s_list_sessions(struct SCP_CONNECTION *c, int sescnt,
struct SCP_DISCONNECTED_SESSION *ds, SCP_SID *sid);
#endif
enum SCP_SERVER_STATES_E
scp_v1s_list_sessions40(struct trans *t);
enum SCP_SERVER_STATES_E
scp_v1s_list_sessions42(struct trans *t, int sescnt, struct SCP_DISCONNECTED_SESSION *ds);
/* 046 was: 031 struct SCP_DISCONNECTED_SESSION* ds, */
enum SCP_SERVER_STATES_E
scp_v1s_reconnect_session(struct trans *t, SCP_DISPLAY d);
#endif

View File

@ -1,451 +0,0 @@
/**
* 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_v1s_mng.c
* @brief libscp version 1 server api code - session management
* @author Simone Fedele
*
*/
#if defined(HAVE_CONFIG_H)
#include <config_ac.h>
#endif
#ifndef LIBSCP_V1S_MNG_C
#define LIBSCP_V1S_MNG_C
#include "libscp_v1s_mng.h"
#include "string_calls.h"
//extern struct log_config* s_log;
static enum SCP_SERVER_STATES_E
_scp_v1s_mng_check_response(struct trans *t, struct SCP_SESSION *s);
/**
* Reads a uint8 followed by a string into a buffer
*
* Buffer is null-terminated on success
*
* @param s Input stream
* @param [out] Output buffer (must be >= 256 chars)
* @param param Parameter we're reading
* @param line Line number reference
* @return != 0 if string read OK
*
* @todo
* This needs to be merged with the func of the same name in
* libscp_v1s.c
*/
static
int in_string8(struct stream *s, char str[], const char *param, int line)
{
int result;
if (!s_check_rem(s, 1))
{
LOG(LOG_LEVEL_WARNING,
"[v1s_mng:%d] connection aborted: %s len missing",
line, param);
result = 0;
}
else
{
unsigned int sz;
in_uint8(s, sz);
result = s_check_rem(s, sz);
if (!result)
{
LOG(LOG_LEVEL_WARNING,
"[v1s_mng:%d] connection aborted: %s data missing",
line, param);
}
else
{
in_uint8a(s, str, sz);
str[sz] = '\0';
}
}
return result;
}
/**
* Initialises a V1 management session object
*
* At call time, the command set value has been read from the wire, and
* the command still needs to be processed.
*
* @param c Connection
* @param [out] session pre-allocated session object
* @return SCP_SERVER_STATE_START_MANAGE for success
*/
enum SCP_SERVER_STATES_E
scp_v1s_mng_accept(struct trans *atrans, struct SCP_SESSION *session)
{
tui32 ipaddr;
tui16 cmd;
tui8 sz;
char buf[256];
struct stream *in_s = atrans->in_s;
scp_session_set_version(session, 1);
scp_session_set_type(session, SCP_SESSION_TYPE_MANAGE);
/* reading command */
if (!s_check_rem(in_s, 2))
{
/* Caller should have checked this */
return SCP_SERVER_STATE_SIZE_ERR;
}
in_uint16_be(in_s, cmd);
if (cmd != 1) /* manager login */
{
return SCP_SERVER_STATE_SEQUENCE_ERR;
}
/* reading username */
if (!in_string8(in_s, buf, "username", __LINE__))
{
return SCP_SERVER_STATE_SIZE_ERR;
}
if (0 != scp_session_set_username(session, buf))
{
return SCP_SERVER_STATE_INTERNAL_ERR;
}
/* reading password */
if (!in_string8(in_s, buf, "passwd", __LINE__))
{
return SCP_SERVER_STATE_SIZE_ERR;
}
if (0 != scp_session_set_password(session, buf))
{
return SCP_SERVER_STATE_INTERNAL_ERR;
}
/* reading remote address
* Check there's enough data left for at least an IPv4 address (+len) */
if (!s_check_rem(in_s, 1 + 4))
{
LOG(LOG_LEVEL_WARNING,
"[v1s_mng:%d] connection aborted: IP addr len missing",
__LINE__);
return SCP_SERVER_STATE_SIZE_ERR;
}
in_uint8(in_s, sz);
if (sz == SCP_ADDRESS_TYPE_IPV4)
{
in_uint32_be(in_s, ipaddr);
scp_session_set_addr(session, sz, &ipaddr);
}
else if (sz == SCP_ADDRESS_TYPE_IPV6)
{
if (!s_check_rem(in_s, 16))
{
LOG(LOG_LEVEL_WARNING,
"[v1s_mng:%d] connection aborted: IP addr missing",
__LINE__);
return SCP_SERVER_STATE_SIZE_ERR;
}
in_uint8a(in_s, buf, 16);
scp_session_set_addr(session, sz, buf);
}
/* reading hostname */
if (!in_string8(in_s, buf, "hostname", __LINE__))
{
return SCP_SERVER_STATE_SIZE_ERR;
}
if (0 != scp_session_set_hostname(session, buf))
{
return SCP_SERVER_STATE_INTERNAL_ERR;
}
return SCP_SERVER_STATE_START_MANAGE;
}
/* 002 */
enum SCP_SERVER_STATES_E
scp_v1s_mng_allow_connection(struct trans *t, struct SCP_SESSION *s)
{
struct stream *out_s = t->out_s;
init_stream(out_s, 64);
out_uint32_be(out_s, 1);
/* packet size: 4 + 4 + 2 + 2 */
/* version + size + cmdset + cmd */
out_uint32_be(out_s, 12);
out_uint16_be(out_s, SCP_COMMAND_SET_MANAGE);
out_uint16_be(out_s, SCP_CMD_MNG_LOGIN_ALLOW);
s_mark_end(out_s);
if (0 != trans_force_write(t))
{
return SCP_SERVER_STATE_NETWORK_ERR;
}
return _scp_v1s_mng_check_response(t, s);
}
/* 003 */
enum SCP_SERVER_STATES_E
scp_v1s_mng_deny_connection(struct trans *t, const char *reason)
{
int rlen;
struct stream *out_s = t->out_s;
/* forcing message not to exceed 64k */
rlen = g_strlen(reason);
if (rlen > 65535 - 64)
{
rlen = 65535 - 64;
}
init_stream(out_s, rlen + 64);
out_uint32_be(out_s, 1);
/* packet size: 4 + 4 + 2 + 2 + 2 + strlen(reason)*/
/* version + size + cmdset + cmd + msglen + msg */
out_uint32_be(out_s, rlen + 14);
out_uint16_be(out_s, SCP_COMMAND_SET_MANAGE);
out_uint16_be(out_s, SCP_CMD_MNG_LOGIN_DENY);
out_uint16_be(out_s, rlen);
out_uint8p(out_s, reason, rlen);
s_mark_end(out_s);
if (0 != trans_force_write(t))
{
return SCP_SERVER_STATE_NETWORK_ERR;
}
return SCP_SERVER_STATE_END;
}
/* 006 */
enum SCP_SERVER_STATES_E
scp_v1s_mng_list_sessions(struct trans *t, 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;
struct stream *out_s = t->out_s;
/* calculating the number of packets to send */
if (sescnt == 0)
{
pktcnt = 1;
}
else
{
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(out_s, 64 + (SCP_SERVER_MAX_LIST_SIZE * 40));
/* size: ver+size+cmdset+cmd+sescnt+continue+count */
size = 4 + 4 + 2 + 2 + 4 + 1 + 1;
/* header */
s_push_layer(out_s, channel_hdr, 8);
out_uint16_be(out_s, SCP_COMMAND_SET_MANAGE);
out_uint16_be(out_s, cmd);
/* session count */
out_uint32_be(out_s, sescnt);
/* setting the continue flag */
if ((idx + 1)*SCP_SERVER_MAX_LIST_SIZE >= sescnt)
{
out_uint8(out_s, 0);
/* setting session count for this packet */
pidx = sescnt - (idx * SCP_SERVER_MAX_LIST_SIZE);
out_uint8(out_s, pidx);
}
else
{
out_uint8(out_s, 1);
/* setting session count for this packet */
pidx = SCP_SERVER_MAX_LIST_SIZE;
out_uint8(out_s, pidx);
}
/* adding session descriptors */
for (sidx = 0; sidx < pidx; sidx++)
{
/* shortcut to the current session to send */
cds = ds + ((idx) * SCP_SERVER_MAX_LIST_SIZE) + sidx;
/* session data */
out_uint32_be(out_s, cds->SID); /* session id */
out_uint8(out_s, cds->type);
out_uint16_be(out_s, cds->height);
out_uint16_be(out_s, cds->width);
out_uint8(out_s, cds->bpp);
out_uint8(out_s, cds->idle_days);
out_uint8(out_s, cds->idle_hours);
out_uint8(out_s, cds->idle_minutes);
size += 13;
out_uint16_be(out_s, cds->conn_year);
out_uint8(out_s, cds->conn_month);
out_uint8(out_s, cds->conn_day);
out_uint8(out_s, cds->conn_hour);
out_uint8(out_s, cds->conn_minute);
out_uint8(out_s, cds->addr_type);
size += 7;
if (cds->addr_type == SCP_ADDRESS_TYPE_IPV4)
{
out_uint32_be(out_s, cds->ipv4addr);
size += 4;
}
else if (cds->addr_type == SCP_ADDRESS_TYPE_IPV6)
{
out_uint8a(out_s, cds->ipv6addr, 16);
size += 16;
}
}
s_mark_end(out_s);
s_pop_layer(out_s, channel_hdr);
out_uint32_be(out_s, version);
out_uint32_be(out_s, size);
if (0 != trans_force_write(t))
{
LOG(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
}
return _scp_v1s_mng_check_response(t, s);
}
static enum SCP_SERVER_STATES_E
_scp_v1s_mng_check_response(struct trans *t, struct SCP_SESSION *s)
{
tui32 version;
int size;
tui16 cmd;
// tui8 dim;
// char buf[257];
struct stream *in_s = t->in_s;
init_stream(in_s, 64);
if (0 != trans_force_read(t, 8))
{
LOG(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
in_uint32_be(in_s, version);
if (version != 1)
{
LOG(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: version error", __LINE__);
return SCP_SERVER_STATE_VERSION_ERR;
}
in_uint32_be(in_s, size);
/* Check the message is big enough for the header, the command set, and
* the command (but not too big) */
if (size < (8 + 2 + 2) || size > SCP_MAX_MESSAGE_SIZE)
{
LOG(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: size error", __LINE__);
return SCP_SERVER_STATE_SIZE_ERR;
}
init_stream(in_s, size - 8);
/* read the rest of the packet */
if (0 != trans_force_read(t, size - 8))
{
LOG(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
in_uint16_be(in_s, cmd);
if (cmd != SCP_COMMAND_SET_MANAGE)
{
LOG(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: sequence error", __LINE__);
return SCP_SERVER_STATE_SEQUENCE_ERR;
}
in_uint16_be(in_s, cmd);
if (cmd == SCP_CMD_MNG_LIST_REQ) /* request session list */
{
LOG(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(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(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: sequence error", __LINE__);
return SCP_SERVER_STATE_SEQUENCE_ERR;
}
#endif

View File

@ -1,75 +0,0 @@
/**
* 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_v1s_mng.h
* @brief libscp version 1 server api declarations - session management
* @author Simone Fedele
*
*/
#ifndef LIBSCP_V1S_MNG_H
#define LIBSCP_V1S_MNG_H
#include "libscp.h"
/* server API */
/**
*
* @brief processes the stream using scp version 1
* @param atrans connection descriptor
* @param s session descriptor pointer
*/
enum SCP_SERVER_STATES_E
scp_v1s_mng_accept(struct trans *atrans, struct SCP_SESSION *s);
/**
*
* @brief allows connection to sesman
* @param c connection descriptor
*
*/
/* 002 */
enum SCP_SERVER_STATES_E
scp_v1s_mng_allow_connection(struct trans *atrans, struct SCP_SESSION *s);
/**
*
* @brief denies connection to sesman
* @param c connection descriptor
* @param reason pointer to a string containing the reason for denying connection
*
*/
/* 003 */
enum SCP_SERVER_STATES_E
scp_v1s_mng_deny_connection(struct trans *atrans, const char *reason);
/**
*
* @brief sends session list
* @param c connection descriptor
*
*/
/* 006 */
enum SCP_SERVER_STATES_E
scp_v1s_mng_list_sessions(struct trans *atrans, struct SCP_SESSION *s,
int sescnt, struct SCP_DISCONNECTED_SESSION *ds);
// SCP_SID* sid);
#endif

View File

@ -1,55 +0,0 @@
/**
* 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.c
* @brief libscp version neutral code
* @author Simone Fedele
*
*/
#if defined(HAVE_CONFIG_H)
#include <config_ac.h>
#endif
#include "libscp_vX.h"
/******************************************************************************/
enum SCP_SERVER_STATES_E
scp_vXs_accept(struct trans *atrans, struct SCP_SESSION *s)
{
struct stream *in_s;
int version;
in_s = atrans->in_s;
if (!s_check_rem(in_s, 4))
{
return SCP_SERVER_STATE_INTERNAL_ERR;
}
in_uint32_be(in_s, version);
if (version == 0)
{
return scp_v0s_accept(atrans, s);
}
else if (version == 1)
{
return scp_v1s_accept(atrans, s);
}
return SCP_SERVER_STATE_VERSION_ERR;
}

View File

@ -1,46 +0,0 @@
/**
* 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
#define LIBSCP_VX_H
#include "libscp_types.h"
#include "libscp_v0.h"
#include "libscp_v1s.h"
/* server API */
/**
*
* @brief version neutral server accept function
* @param atrans connection trans
* @param s session descriptor
*
*/
enum SCP_SERVER_STATES_E
scp_vXs_accept(struct trans *atrans, struct SCP_SESSION *s);
#endif