adding scp v1 first code, fixed passwd auth for disabled password

ulab-original
ilsimo 18 years ago
parent b681420acc
commit 078b4d3f41

@ -3,7 +3,7 @@ LIBSCPOBJ = libscp_vX.o libscp_v0.o libscp_v1s.o
SESMANOBJ = sesman.o config.o tcp.o sig.o session.o env.o \
os_calls.o d3des.o list.o file.o log.o access.o \
scp.o scp_v0.o thread.o lock.o \
scp.o scp_v0.o scp_v1.o thread.o lock.o \
$(LIBSCPOBJ)
SESRUNOBJ = sesrun.o config.o tcp.o lock.o \
@ -16,7 +16,7 @@ MANDIR = /usr/local/man
DOCDIR = /usr/doc/xrdp
DEFINES = -DSESMAN_CFG_FILE=\"$(CFGDIR)/sesman.ini\" \
-DSESMAN_PID_FILE=\"$(PIDDIR)/sesman.pid\"
-DSESMAN_PID_FILE=\"$(PIDDIR)/sesman.pid\" -DDEBUG
CFLAGS = -Wall -O2 -I../common -I/usr/include/nptl $(DEFINES)
LDFLAGS = -L /usr/gnu/lib -I/usr/include/nptl -L/usr/lib/nptl -lpthread $(DEFINES)
@ -44,15 +44,18 @@ kerberos-base: $(SESMANOBJ) verify_user_kerberos.o
tools: $(SESRUNOBJ)
$(CC) $(LDFLAGS) -o sesrun $(SESRUNOBJ) -ldl
make -C tools
clean:
rm -f $(SESMANOBJ) verify_user.o verify_user_pam.o verify_user_pam_userpass.o sesman sesrun.o sesrun
make -C tools clean
install:
install sesman $(DESTDIR)/sesman
install sesrun $(DESTDIR)/sesrun
install startwm.sh $(DESTDIR)/startwm.sh
install sesman.ini $(CFGDIR)/sesman.ini
make -C tools install
installdeb:
install sesman $(DESTDIRDEB)/usr/lib/xrdp/sesman

@ -32,6 +32,6 @@
#include "libscp_vX.h"
#include "libscp_v0.h"
#include "libscp_v1s.h"
//#include "libscp_v1c.h"
#include "libscp_v1c.h"
#endif

@ -0,0 +1,249 @@
/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
xrdp: A Remote Desktop Protocol server.
Copyright (C) Jay Sorg 2005-2006
*/
/**
*
* @file libscp_v1c.c
* @brief libscp version 1 client api code
* @author Simone Fedele
*
*/
#include "libscp_v1c.h"
static enum SCP_CLIENT_STATES_E _scp_v1c_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s);
/* client API */
/* 001 */
enum SCP_CLIENT_STATES_E scp_v1c_connect(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
{
unsigned char sz;
uint32_t size;
//uint32_t version;
//uint16_t cmd;
//uint16_t dim;
init_stream(c->out_s, c->out_s->size);
init_stream(c->in_s, c->in_s->size);
size=19+17+4+ g_strlen(s->hostname) + g_strlen(s->username) + g_strlen(s->password);
if (s->addr_type==SCP_ADDRESS_TYPE_IPV4)
{
size=size+4;
}
else
{
size=size+16;
}
/* sending request */
/* header */
out_uint32_be(c->out_s, 1); /* version */
out_uint32_be(c->out_s, size);
out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT);
out_uint16_be(c->out_s, 1);
/* body */
out_uint8(c->out_s, s->type);
out_uint16_be(c->out_s, s->height);
out_uint16_be(c->out_s, s->width);
out_uint8(c->out_s, s->bpp);
out_uint8(c->out_s, s->rsr);
out_uint8p(c->out_s, s->locale, 17);
out_uint8(c->out_s, s->addr_type);
if (s->addr_type==SCP_ADDRESS_TYPE_IPV4)
{
out_uint32_be(c->out_s, s->ipv4addr);
}
else
{
#warning ipv6 address needed
}
sz=g_strlen(s->hostname);
out_uint8(c->out_s, sz);
out_uint8p(c->out_s, s->hostname, sz);
sz=g_strlen(s->username);
out_uint8(c->out_s, sz);
out_uint8p(c->out_s, s->username, sz);
sz=g_strlen(s->password);
out_uint8(c->out_s, sz);
out_uint8p(c->out_s, s->password, sz);
if (0!=tcp_force_send(c->in_sck, c->out_s->data, size))
{
return SCP_CLIENT_STATE_NETWORK_ERR;
}
/* wait for response */
return _scp_v1c_check_response(c, s);
}
/* 004 */
enum SCP_CLIENT_STATES_E scp_v1c_resend_credentials(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
{
unsigned char sz;
uint32_t size;
//uint32_t version;
//uint16_t cmd;
//uint16_t dim;
init_stream(c->out_s, c->out_s->size);
init_stream(c->in_s, c->in_s->size);
size=12+2+g_strlen(s->username)+g_strlen(s->password);
/* sending request */
/* header */
out_uint32_be(c->out_s, 1); /* version */
out_uint32_be(c->out_s, size);
out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT);
out_uint16_be(c->out_s, 4);
/* body */
sz=g_strlen(s->username);
out_uint8(c->out_s, sz);
out_uint8p(c->out_s, s->username, sz);
sz=g_strlen(s->password);
out_uint8(c->out_s, sz);
out_uint8p(c->out_s, s->password, sz);
if (0!=tcp_force_send(c->in_sck, c->out_s->data, size))
{
return SCP_CLIENT_STATE_NETWORK_ERR;
}
/* wait for response */
return _scp_v1c_check_response(c, s);
}
/* 021 */ enum SCP_CLIENT_STATES_E scp_v1c_pwd_change(struct SCP_CONNECTION* c, char* newpass);
/* 022 */ enum SCP_CLIENT_STATES_E scp_v1c_pwd_change_cancel(struct SCP_CONNECTION* c);
/* ... */ enum SCP_CLIENT_STATES_E scp_v1c_get_session_list(struct SCP_CONNECTION* c, int* scount, struct SCP_DISCONNECTED_SESSION** s);
/* 041 */ enum SCP_CLIENT_STATES_E scp_v1c_select_session(struct SCP_CONNECTION* c, SCP_SID sid);
/* 042 */ enum SCP_CLIENT_STATES_E scp_v1c_select_session_cancel(struct SCP_CONNECTION* c);
/* 03x */ enum SCP_CLIENT_STATES_E scp_v1c_retrieve_session(struct SCP_CONNECTION* c, struct SCP_SESSION* s, struct SCP_DISCONNECTED_SESSION* ds);
static enum SCP_CLIENT_STATES_E _scp_v1c_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
{
uint32_t version;
uint32_t size;
uint16_t cmd;
uint16_t dim;
init_stream(c->in_s, c->in_s->size);
if (0!=tcp_force_recv(c->in_sck, c->in_s->data, 8))
{
return SCP_CLIENT_STATE_NETWORK_ERR;
}
in_uint32_be(c->in_s, version);
if (version!=1)
{
return SCP_CLIENT_STATE_VERSION_ERR;
}
in_uint32_be(c->in_s, size);
init_stream(c->in_s, c->in_s->size);
/* read the rest of the packet */
if (0!=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==2) /* connection denied */
{
in_uint16_be(c->in_s, dim);
if (s->errstr!=0)
{
g_free(s->errstr);
}
s->errstr=g_malloc(dim+1,0);
if (s->errstr==0)
{
return SCP_CLIENT_STATE_INTERNAL_ERR;
}
in_uint8a(c->in_s, s->errstr, dim);
(s->errstr)[dim]='\0';
return SCP_CLIENT_STATE_CONNECTION_DENIED;
}
else if (cmd==3) /* resend usr/pwd */
{
in_uint16_be(c->in_s, dim);
if (s->errstr!=0)
{
g_free(s->errstr);
}
s->errstr=g_malloc(dim+1,0);
if (s->errstr==0)
{
return SCP_CLIENT_STATE_INTERNAL_ERR;
}
in_uint8a(c->in_s, s->errstr, dim);
(s->errstr)[dim]='\0';
return SCP_CLIENT_STATE_RESEND_CREDENTIALS;
}
else if (cmd==20) /* password change */
{
in_uint16_be(c->in_s, dim);
if (s->errstr!=0)
{
g_free(s->errstr);
}
s->errstr=g_malloc(dim+1,0);
if (s->errstr==0)
{
return SCP_CLIENT_STATE_INTERNAL_ERR;
}
in_uint8a(c->in_s, s->errstr, dim);
(s->errstr)[dim]='\0';
return SCP_CLIENT_STATE_PWD_CHANGE_REQ;
}
else if (cmd==30) /* display */
{
in_uint16_be(c->in_s, s->display);
return SCP_CLIENT_STATE_OK;
}
else if (cmd==32) /* display of a disconnected session */
{
return SCP_CLIENT_STATE_RECONNECT;
}
else if (cmd==40) /* session list */
{
return SCP_CLIENT_STATE_SESSION_LIST;
}
return SCP_CLIENT_STATE_SEQUENCE_ERR;
}

@ -30,24 +30,15 @@
#include "libscp_types.h"
enum SCP_CLIENt_STATES_E
{
SCP_CLIENT_STATE_NO,
SCP_CLIENT_STATE_WRONGPWD,
SCP_CLIENT_STATE_PWDCHG_REQ,
SCP_CLIENT_STATE_PWDCHG_CANCEL,
SCP_CLIENT_STATE_
};
/* client API */
/* 001 */ SCP_CLIENT_STATES_E scp_v1c_connect(struct SCP_CONNECTION* c, struct SCP_SESSION* s);
/* 004 */ SCP_CLIENT_STATES_E scp_v1c_resend_credentials(struct SCP_CONNECTION* c, struct SCP_SESSION* s);
/* 001 */ enum SCP_CLIENT_STATES_E scp_v1c_connect(struct SCP_CONNECTION* c, struct SCP_SESSION* s);
/* 004 */ enum SCP_CLIENT_STATES_E scp_v1c_resend_credentials(struct SCP_CONNECTION* c, struct SCP_SESSION* s);
/* 021 */ SCP_CLIENT_STATES_E scp_v1c_pwd_change(struct SCP_CONNECTION* c, char* newpass);
/* 022 */ SCP_CLIENT_STATES_E scp_v1c_pwd_change_cancel(struct SCP_CONNECTION* c);
/* 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);
/* ... */ SCP_CLIENT_STATES_E scp_v1c_get_session_list(struct SCP_CONNECTION* c, int* scount, struct SCP_DISCONNECTED_SESSION** s);
/* 041 */ SCP_CLIENT_STATES_E scp_v1c_select_session(struct SCP_CONNECTION* c, SCP_SID sid);
/* 042 */ SCP_CLIENT_STATES_E scp_v1c_select_session_cancel(struct SCP_CONNECTION* c);
/* ... */ enum SCP_CLIENT_STATES_E scp_v1c_get_session_list(struct SCP_CONNECTION* c, int* scount, struct SCP_DISCONNECTED_SESSION** s);
/* 041 */ enum SCP_CLIENT_STATES_E scp_v1c_select_session(struct SCP_CONNECTION* c, SCP_SID sid);
/* 042 */ enum SCP_CLIENT_STATES_E scp_v1c_select_session_cancel(struct SCP_CONNECTION* c);
#endif

@ -56,8 +56,13 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SES
return SCP_SERVER_STATE_NETWORK_ERR;
}
}
else
{
version=1;
}
in_uint32_be(c->in_s, size);
LOG_DBG("size: %d",size);
if (size<12)
{
return SCP_SERVER_STATE_SIZE_ERR;
@ -71,6 +76,7 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SES
/* reading command set */
in_uint16_be(c->in_s, cmdset);
LOG_DBG("command set: %d",cmdset);
/* if we are starting a management session */
if (cmdset==SCP_COMMAND_SET_MANAGE)
@ -86,13 +92,18 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SES
/* reading command */
in_uint16_be(c->in_s, cmd);
if (cmd != 0)
LOG_DBG("command: %d",cmd);
if (cmd != 1)
{
return SCP_SERVER_STATE_SEQUENCE_ERR;
}
session = g_malloc(sizeof(struct SCP_SESSION),1);
if (0 == session) return SCP_SERVER_STATE_INTERNAL_ERR;
if (0 == session)
{
return SCP_SERVER_STATE_INTERNAL_ERR;
}
session->version=1;
in_uint8(c->in_s, session->type);
if ((session->type != SCP_SESSION_TYPE_XVNC) && (session->type != SCP_SESSION_TYPE_XRDP))
@ -107,6 +118,8 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SES
in_uint8(c->in_s, session->rsr);
in_uint8a(c->in_s, session->locale, 17);
session->locale[17]='\0';
LOG_DBG("locale: %s\n", session->locale);
in_uint8(c->in_s, session->addr_type);
if (session->addr_type==SCP_ADDRESS_TYPE_IPV4)
@ -117,9 +130,12 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SES
{
#warning how to handle ipv6 addresses?
}
LOG_DBG("rest: %d\n",(unsigned char)*((c->in_s->p)+2));
/* reading hostname */
in_uint8(c->in_s, sz);
LOG_DBG("size read: %d", sz);
session->hostname=g_malloc(sz+1,1);
if (0==session->hostname)
{
@ -143,6 +159,7 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SES
/* reading password */
in_uint8(c->in_s, sz);
LOG_DBG("size read: %d", sz);
session->password=g_malloc(sz+1,1);
if (0==session->password)
{
@ -154,15 +171,20 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SES
session->password[sz]='\0';
in_uint8a(c->in_s, session->password, sz);
LOG_DBG("password: %s - size: %d - pointer: %x", session->password, sz, session->password);
/* returning the struct */
*s=session;
(*s)=session;
return SCP_SERVER_STATE_OK;
}
enum SCP_SERVER_STATES_E scp_v1s_deny_connection(struct SCP_CONNECTION* c, char* reason)
enum SCP_SERVER_STATES_E
scp_v1s_deny_connection(struct SCP_CONNECTION* c, char* reason)
{
int rlen;
init_stream(c->out_s,c->out_s->size);
/* forcing message not to exceed 64k */
rlen = g_strlen(reason);
@ -188,7 +210,8 @@ enum SCP_SERVER_STATES_E scp_v1s_deny_connection(struct SCP_CONNECTION* c, char*
return SCP_SERVER_STATE_END;
}
enum SCP_SERVER_STATES_E scp_v1s_request_password(struct SCP_CONNECTION* c, struct SCP_SESSION* s, char* reason)
enum SCP_SERVER_STATES_E
scp_v1s_request_password(struct SCP_CONNECTION* c, struct SCP_SESSION* s, char* reason)
{
unsigned char sz;
char *ubuf;
@ -233,11 +256,18 @@ enum SCP_SERVER_STATES_E scp_v1s_request_password(struct SCP_CONNECTION* c, stru
{
return SCP_SERVER_STATE_NETWORK_ERR;
}
#warning check version
in_uint32_be(c->in_s, version);
if (version!=1)
{
LOG_DBG("version: %d",version);
return SCP_SERVER_STATE_VERSION_ERR;
}
in_uint32_be(c->in_s, size);
if (size<12)
{
LOG_DBG("size: %d",size);
return SCP_SERVER_STATE_SIZE_ERR;
}
@ -282,32 +312,151 @@ enum SCP_SERVER_STATES_E scp_v1s_request_password(struct SCP_CONNECTION* c, stru
}
/* 020 */
enum SCP_SERVER_STATES_E scp_v1s_request_pwd_change(struct SCP_CONNECTION* c, char* reason, char* npw)
enum SCP_SERVER_STATES_E
scp_v1s_request_pwd_change(struct SCP_CONNECTION* c, char* reason, char* npw)
{
return SCP_SERVER_STATE_INTERNAL_ERR;
}
/* 023 */
enum SCP_SERVER_STATES_E scp_v1s_pwd_change_error(struct SCP_CONNECTION* s, char* error, int retry, char* npw)
enum SCP_SERVER_STATES_E
scp_v1s_pwd_change_error(struct SCP_CONNECTION* c, char* error, int retry, char* npw)
{
return SCP_SERVER_STATE_INTERNAL_ERR;
}
/* 030 */
enum SCP_SERVER_STATES_E scp_v1s_connect_new_session(struct SCP_CONNECTION* s, SCP_DISPLAY d)
enum SCP_SERVER_STATES_E
scp_v1s_connect_new_session(struct SCP_CONNECTION* c, SCP_DISPLAY d)
{
return SCP_SERVER_STATE_INTERNAL_ERR;
/* send password request */
uint32_t version=1;
uint32_t size=14;
uint16_t cmd=30;
init_stream(c->out_s, c->out_s->size);
out_uint32_be(c->out_s, version); /* version */
out_uint32_be(c->out_s, size); /* size */
out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */
out_uint16_be(c->out_s, cmd); /* cmd */
out_uint16_be(c->out_s, d); /* display */
if (0!=tcp_force_send(c->in_sck, c->out_s->data, 14))
{
return SCP_SERVER_STATE_NETWORK_ERR;
}
return SCP_SERVER_STATE_OK;
}
/* 031 */
enum SCP_SERVER_STATES_E scp_v1s_reconnect_session(struct SCP_CONNECTION* s, SCP_DISPLAY d)
enum SCP_SERVER_STATES_E
scp_v1s_reconnect_session(struct SCP_CONNECTION* c, struct SCP_DISCONNECTED_SESSION* ds,
SCP_DISPLAY d)
{
return SCP_SERVER_STATE_INTERNAL_ERR;
uint32_t version=1;
uint32_t size=12;
uint16_t cmd=32;
#warning FIXME check this command code
/* first we send a notice that we're reconnecting to an existing session */
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!=tcp_force_send(c->in_sck, c->out_s->data, 14))
{
return SCP_SERVER_STATE_NETWORK_ERR;
}
/* then we wait for client ack */
#warning maybe this message could say if the session should be resized on
#warning server side or client side
if (0!=tcp_force_recv(c->in_sck, c->in_s->data, 8))
{
return SCP_SERVER_STATE_NETWORK_ERR;
}
in_uint32_be(c->in_s, version);
if (version!=1)
{
return SCP_SERVER_STATE_VERSION_ERR;
}
in_uint32_be(c->in_s, size);
if (size<12)
{
return SCP_SERVER_STATE_SIZE_ERR;
}
init_stream(c->in_s, c->in_s->size);
if (0!=tcp_force_recv(c->in_sck, c->in_s->data, (size-8)))
{
return SCP_SERVER_STATE_NETWORK_ERR;
}
in_uint16_be(c->in_s, cmd);
if (cmd != SCP_COMMAND_SET_DEFAULT)
{
return SCP_SERVER_STATE_SEQUENCE_ERR;
}
in_uint16_be(c->in_s, cmd);
#warning FIXME check this command code
if (cmd != 33)
{
return SCP_SERVER_STATE_SEQUENCE_ERR;
}
/* ok, we send session data and display */
init_stream(c->out_s, c->out_s->size);
/* size */
size=4+4+2+2+ \
2+1+2+2+1+1+1+1;
/* header */
cmd=31;
out_uint32_be(c->out_s, version);
out_uint32_be(c->out_s, size);
out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT);
out_uint16_be(c->out_s, cmd);
/* session data */
out_uint16_be(c->out_s, d); /* session display */
out_uint8(c->out_s, ds->type);
out_uint16_be(c->out_s, ds->height);
out_uint16_be(c->out_s, ds->width);
out_uint8(c->out_s, ds->bpp);
out_uint8(c->out_s, ds->idle_days);
out_uint8(c->out_s, ds->idle_hours);
out_uint8(c->out_s, ds->idle_minutes);
/* these last three are not really needed... */
if (0!=tcp_force_send(c->in_sck, c->out_s->data, size))
{
return SCP_SERVER_STATE_NETWORK_ERR;
}
return SCP_SERVER_STATE_OK;
}
/* 032 */
enum SCP_SERVER_STATES_E scp_v1s_connection_error(struct SCP_CONNECTION* s, char* error)
enum SCP_SERVER_STATES_E
scp_v1s_connection_error(struct SCP_CONNECTION* c, char* error)
{
return SCP_SERVER_STATE_INTERNAL_ERR;
return SCP_SERVER_STATE_END;
}
/* 040 */
enum SCP_SERVER_STATES_E scp_v1s_list_sessions(struct SCP_CONNECTION* s, int sescnt, struct SCP_DISCONNECTED_SESSION** ds, SCP_SID* sid)
enum SCP_SERVER_STATES_E
scp_v1s_list_sessions(struct SCP_CONNECTION* c, int sescnt, struct SCP_DISCONNECTED_SESSION* ds, SCP_SID* sid)
{
return SCP_SERVER_STATE_INTERNAL_ERR;
}

@ -42,7 +42,8 @@
* this function places in *s the address of a newely allocated SCP_SESSION structure
* that should be free()d
*/
enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk);
enum SCP_SERVER_STATES_E
scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk);
/**
*
@ -51,25 +52,36 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SES
* @param reason pointer to a string containinge the reason for denying connection
*/
/* 002 */
enum SCP_SERVER_STATES_E scp_v1s_deny_connection(struct SCP_CONNECTION* c, char* reason);
enum SCP_SERVER_STATES_E
scp_v1s_deny_connection(struct SCP_CONNECTION* c, char* reason);
enum SCP_SERVER_STATES_E
scp_v1s_request_password(struct SCP_CONNECTION* c, struct SCP_SESSION* s, char* reason);
/* 020 */
enum SCP_SERVER_STATES_E scp_v1s_request_pwd_change(struct SCP_CONNECTION* c, char* reason, char* npw);
enum SCP_SERVER_STATES_E
scp_v1s_request_pwd_change(struct SCP_CONNECTION* c, char* reason, char* npw);
/* 023 */
enum SCP_SERVER_STATES_E scp_v1s_pwd_change_error(struct SCP_CONNECTION* s, char* error, int retry, char* npw);
enum SCP_SERVER_STATES_E
scp_v1s_pwd_change_error(struct SCP_CONNECTION* c, char* error, int retry, char* npw);
/* 030 */
enum SCP_SERVER_STATES_E scp_v1s_connect_new_session(struct SCP_CONNECTION* s, SCP_DISPLAY d);
enum SCP_SERVER_STATES_E
scp_v1s_connect_new_session(struct SCP_CONNECTION* c, SCP_DISPLAY d);
/* 031 */
enum SCP_SERVER_STATES_E scp_v1s_reconnect_session(struct SCP_CONNECTION* s, SCP_DISPLAY d);
enum SCP_SERVER_STATES_E
scp_v1s_reconnect_session(struct SCP_CONNECTION* c, struct SCP_DISCONNECTED_SESSION* ds,
SCP_DISPLAY d);
/* 032 */
enum SCP_SERVER_STATES_E scp_v1s_connection_error(struct SCP_CONNECTION* s, char* error);
enum SCP_SERVER_STATES_E
scp_v1s_connection_error(struct SCP_CONNECTION* c, char* error);
/* 040 */
enum SCP_SERVER_STATES_E scp_v1s_list_sessions(struct SCP_CONNECTION* s, int sescnt, struct
SCP_DISCONNECTED_SESSION** ds, SCP_SID* sid);
enum SCP_SERVER_STATES_E
scp_v1s_list_sessions(struct SCP_CONNECTION* c, int sescnt, struct SCP_DISCONNECTED_SESSION* ds,
SCP_SID* sid);
#endif

@ -58,11 +58,14 @@ scp_process_start(void* sck)
if (sdata->version == 0)
{
/* starts processing an scp v0 connection */
LOG_DBG("accept ok, go on with scp v0\n",0);
scp_v0_process(&scon, sdata);
}
else
{
//scp_v1_process();
LOG_DBG("accept ok, go on with scp v1\n",0);
LOG_DBG("user: %s\npass: %s",sdata->username, sdata->password);
scp_v1_process(&scon, sdata);
}
break;

@ -28,8 +28,9 @@
#ifndef SCP_H
#define SCP_H
//#include "libscp.h"
#include "scp_v0.h"
#include "libscp.h"
#include "scp_v1.h"
/**
*

@ -0,0 +1,192 @@
/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
xrdp: A Remote Desktop Protocol server.
Copyright (C) Jay Sorg 2005-2006
*/
/**
*
* @file scp_v1.c
* @brief scp version 1 implementation
* @author Jay Sorg, Simone Fedele
*
*/
#include "sesman.h"
//#include "libscp_types.h"
#include "libscp.h"
extern struct config_sesman g_cfg;
/******************************************************************************/
void DEFAULT_CC
scp_v1_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
{
long data;
int display;
int retries;
int current_try;
enum SCP_SERVER_STATES_E e;
struct SCP_DISCONNECTED_SESSION* slist;
struct session_item* sitem;
int scount;
SCP_SID sid;
retries=g_cfg.sec.login_retry;
current_try=retries;
data=auth_userpass(s->username, s->password);
LOG_DBG("user: %s\npass: %s", s->username, s->password);
while ((!data) && ((retries==0) || (current_try>0)))
{
LOG_DBG("data %d - retry %d - currenttry %d - expr %d", data, retries, current_try, ((!data) && ((retries==0) || (current_try>0))));
e=scp_v1s_request_password(c,s,"Wrong username and/or password");
switch (e)
{
case SCP_SERVER_STATE_OK:
/* all ok, we got new username and password */
data=auth_userpass(s->username, s->password);
/* one try less */
if (current_try>0)
{
current_try--;
}
break;
case SCP_SERVER_STATE_VERSION_ERR:
LOG_DBG("version error",0)
case SCP_SERVER_STATE_SIZE_ERR:
/* an unknown scp version was requested, so we shut down the */
/* connection (and log the fact) */
log_message(LOG_LEVEL_WARNING,"protocol violation. connection closed.");
return;
case SCP_SERVER_STATE_NETWORK_ERR:
log_message(LOG_LEVEL_WARNING,"libscp network error.");
return;
case SCP_SERVER_STATE_SEQUENCE_ERR:
log_message(LOG_LEVEL_WARNING,"libscp sequence error.");
return;
case SCP_SERVER_STATE_INTERNAL_ERR:
/* internal error occurred (eg. malloc() error, ecc.) */
log_message(LOG_LEVEL_ERROR, "libscp internal error occurred.");
return;
default:
/* dummy: scp_v1s_request_password won't generate any other */
/* error other than the ones before */
log_message(LOG_LEVEL_ALWAYS, "unknown return from scp_v1s_request_password()");
return;
}
}
if (!data)
{
scp_v1s_deny_connection(c,"Login failed");
log_message(LOG_LEVEL_INFO,"Login failed for user %s. Connection terminated", s->username);
free_session(s);
return;
}
/* testing if login is allowed*/
if (0==access_login_allowed(s->username))
{
scp_v1s_deny_connection(c,"Access to Terminal Server not allowed.");
log_message(LOG_LEVEL_INFO,"User %s not allowed on TS. Connection terminated", s->username);
free_session(s);
return;
}
//check if we need password change
/* list disconnected sessions */
slist=session_get_byuser(s->username, &scount);
if (scount==0)
{
#warning FIXME we should check for MaxSessions
/* no disconnected sessions - start a new one */
log_message(LOG_LEVEL_INFO, "granted TS access to user %s", s->username);
if (SCP_SESSION_TYPE_XVNC == s->type)
{
log_message(LOG_LEVEL_INFO, "starting Xvnc session...");
display = session_start(s->width, s->height, s->bpp, s->username, s->password,
data, SESMAN_SESSION_TYPE_XVNC);
}
else
{
log_message(LOG_LEVEL_INFO, "starting Xrdp session...");
display = session_start(s->width, s->height, s->bpp, s->username, s->password,
data, SESMAN_SESSION_TYPE_XRDP);
}
e=scp_v1s_connect_new_session(c, display);
switch (e)
{
case SCP_SERVER_STATE_OK:
/* all ok, we got new username and password */
break;
case SCP_SERVER_STATE_NETWORK_ERR:
log_message(LOG_LEVEL_WARNING,"libscp network error.");
return;
default:
return;
}
}
else if (scount==1)
{
/* there's only one session - returning that */
sitem=session_get_bypid(slist->SID);
#warning FIXME session_get_by*() should return a malloc()ated struct
#warning FIXME or at least lock the chain
if (0==sitem)
{
e=scp_v1s_connection_error(c, "Internal error");
log_message(LOG_LEVEL_INFO, "Cannot find session item on the chain");
}
else
{
display=sitem->display;
e=scp_v1s_reconnect_session(c, slist, display);
log_message(LOG_LEVEL_INFO, "User %s reconnected to session %d on port %d", \
s->username, sitem->pid, display);
}
g_free(slist);
}
else
{
/* 2 or more disconnected sessions - listing */
//max session x packet = 100 => pkt size = 1300 (13x100)
e=scp_v1s_list_sessions(c, scount, slist, &sid);
//CHECK RETURN
g_free(slist);
}
/* resource management */
if ((e==SCP_SERVER_STATE_OK) && (s->rsr))
{
/* here goes scp resource sharing code */
}
/* cleanup */
free_session(s);
auth_end(data);
}

@ -0,0 +1,42 @@
/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
xrdp: A Remote Desktop Protocol server.
Copyright (C) Jay Sorg 2005-2006
*/
/**
*
* @file scp_v1.h
* @brief scp version 1 declarations
* @author Simone Fedele
*
*/
#ifndef SCP_V1_H
#define SCP_V1_H
/**
*
* @brief processes the stream using scp version 1
* @param in_sck connection socket
* @param in_s input stream
* @param out_s output stream
*
*/
void DEFAULT_CC
scp_v1_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s);
#endif

@ -0,0 +1,40 @@
# sesman makefile
SESTESTOBJ = sestest.o tcp.o \
os_calls.o d3des.o list.o file.o \
libscp_v1c.o
DEFINES = -DLIBSCP_CLIENT
CFLAGS = -Wall -O2 -I../../common -I../ -I/usr/include/nptl $(DEFINES)
LDFLAGS = -L /usr/gnu/lib -I/usr/include/nptl -L/usr/lib/nptl -lpthread -ldl $(DEFINES)
C_OS_FLAGS = $(CFLAGS) -c
CC = gcc
all: sestest
sestest: $(SESTESTOBJ)
$(CC) $(LDFLAGS) -o sestest $(SESTESTOBJ)
os_calls.o: ../../common/os_calls.c
$(CC) $(C_OS_FLAGS) ../../common/os_calls.c
d3des.o: ../../common/d3des.c
$(CC) $(C_OS_FLAGS) ../../common/d3des.c
list.o: ../../common/list.c
$(CC) $(C_OS_FLAGS) ../../common/list.c
file.o: ../../common/file.c
$(CC) $(C_OS_FLAGS) ../../common/file.c
tcp.o: ../tcp.c
$(CC) $(C_OS_FLAGS) ../tcp.c
libscp_v1c.o: ../libscp_v1c.c
$(CC) $(C_OS_FLAGS) ../libscp_v1c.c
clean:
rm $(SESTESTOBJ) sestest
install:
#install:wq

@ -0,0 +1,155 @@
#include "arch.h"
#include "tcp.h"
#include "libscp.h"
#include "parse.h"
#include <stdio.h>
int inputSession(struct SCP_SESSION* s);
unsigned int menuSelect(unsigned int choices);
int main(int argc, char** argv)
{
struct SCP_SESSION s;
struct SCP_CONNECTION c;
enum SCP_CLIENT_STATES_E e;
int end;
make_stream(c.in_s);
init_stream(c.in_s, 8192);
make_stream(c.out_s);
init_stream(c.out_s, 8192);
c.in_sck = g_tcp_socket();
if (0!=g_tcp_connect(c.in_sck, "localhost", "3350"))
{
g_printf("error connecting");
return 1;
}
g_printf("001 - send connect request\n");
/*struct SCP_SESSION
{
uint16_t display;
char* errstr;
};*/
s.type=SCP_SESSION_TYPE_XVNC;
s.version=1;
s.height=600;
s.width=800;
s.bpp=8;
s.rsr=0;
g_strncpy(s.locale,"it_IT 0123456789",18);
s.username=g_malloc(256, 1);
g_strncpy(s.username,"prog",255);
s.password=g_malloc(256,1);
g_strncpy(s.password, "prog", 255);
g_printf("%s - %s\n", s.username, s.password);
s.hostname=g_malloc(256,1);
g_strncpy(s.hostname, "odin", 255);
s.addr_type=SCP_ADDRESS_TYPE_IPV4;
s.ipv4addr=0;
s.errstr=0;
end=0;
e=scp_v1c_connect(&c,&s);
while (!end)
{
switch (e)
{
case SCP_CLIENT_STATE_OK:
g_printf("OK : display is %d\n", (int)s.display);
end=1;
break;
case SCP_CLIENT_STATE_SESSION_LIST:
g_printf("OK : session list needed\n");
break;
case SCP_CLIENT_STATE_RESEND_CREDENTIALS:
g_printf("ERR: resend credentials - %s\n", s.errstr);
g_printf(" username:");
scanf("%255s", s.username);
g_printf(" password:");
scanf("%255s", s.password);
e=scp_v1c_resend_credentials(&c,&s);
break;
case SCP_CLIENT_STATE_CONNECTION_DENIED:
g_printf("ERR: connection denied: %s\n", s.errstr);
end=1;
break;
case SCP_CLIENT_STATE_PWD_CHANGE_REQ:
g_printf("OK : password change required\n");
break;
default:
g_printf("protocol error: %d\n", e);
end=1;
}
}
g_tcp_close(c.in_sck);
free_stream(c.in_s);
free_stream(c.out_s);
return 0;
}
int inputSession(struct SCP_SESSION* s)
{
unsigned int integer;
g_printf("username: ");
scanf("%255s", s->username);
g_printf("password:");
scanf("%255s", s->password);
g_printf("hostname:");
scanf("%255s", s->hostname);
g_printf("session type:\n");
g_printf("0: Xvnc\n", SCP_SESSION_TYPE_XVNC);
g_printf("1: x11rdp\n", SCP_SESSION_TYPE_XRDP);
integer=menuSelect(1);
if (integer==1)
{
s->type=SCP_SESSION_TYPE_XRDP;
}
else
{
s->type=SCP_SESSION_TYPE_XVNC;
}
s->version=1;
s->height=600;
s->width=800;
s->bpp=8;
/* fixed for now */
s->rsr=0;
g_strncpy(s->locale,"it_IT 0123456789",18);
return 0;
}
unsigned int menuSelect(unsigned int choices)
{
unsigned int sel;
int ret;
ret=scanf("%u", &sel);
while ((ret==0) || (sel > choices))
{
g_printf("invalid choice.");
scanf("%u", &sel);
}
return sel;
}

@ -21,7 +21,7 @@
*
* @file verify_user.c
* @brief Authenticate user using standard unix passwd/shadow system
* @author Jay Sorg
* @author Jay Sorg, Simone Fedele
*
*/
@ -34,8 +34,15 @@
#include <shadow.h>
#include <pwd.h>
#ifndef SECS_PER_DAY
#define SECS_PER_DAY (24L*3600L)
#endif
extern struct config_sesman g_cfg;
static int DEFAULT_CC
auth_account_disabled(struct spwd* stp);
/******************************************************************************/
/* returns boolean */
long DEFAULT_CC
@ -61,6 +68,11 @@ auth_userpass(char* user, char* pass)
{
return 0;
}
if (1==auth_account_disabled(stp))
{
log_message(LOG_LEVEL_INFO, "account %s is disabled", user);
return 0;
}
g_strncpy(hash, stp->sp_pwdp, 34);
}
else
@ -118,3 +130,90 @@ auth_set_env(long in_val)
return 0;
}
#define AUTH_NO_PWD_CHANGE 0
#define AUTH_PWD_CHANGE 1
/******************************************************************************/
int DEFAULT_CC
auth_check_pwd_chg(char* user)
{
struct passwd* spw;
struct spwd* stp;
int now;
long today;
spw = getpwnam(user);
if (spw == 0)
{
return AUTH_NO_PWD_CHANGE;
}
if (g_strncmp(spw->pw_passwd, "x", 3) != 0)
{
/* old system with only passwd */
return AUTH_NO_PWD_CHANGE;
}
/* the system is using shadow */
stp = getspnam(user);
if (stp == 0)
{
return AUTH_NO_PWD_CHANGE;
}
/* check if we need a pwd change */
now=g_time1();
today=now/SECS_PER_DAY;
if (today >= (stp->sp_lstchg + stp->sp_max - stp->sp_warn))
{
return AUTH_PWD_CHANGE;
}
if (today < ((stp->sp_lstchg)+(stp->sp_min)))
{
/* cannot change pwd for now */
return AUTH_NO_PWD_CHANGE;
}
return AUTH_NO_PWD_CHANGE;
}
/**
*
* @return 1 if the account is disabled, 0 otherwise
*
*/
static int DEFAULT_CC
auth_account_disabled(struct spwd* stp)
{
int today;
if (0==stp)
{
/* if an invalid struct was passed we assume a disabled account */
return 1;
}
today=g_time1()/SECS_PER_DAY;
LOG_DBG("last %d",stp->sp_lstchg);
LOG_DBG("min %d",stp->sp_min);
LOG_DBG("max %d",stp->sp_max);
LOG_DBG("inact %d",stp->sp_inact);
LOG_DBG("warn %d",stp->sp_warn);
LOG_DBG("expire %d",stp->sp_expire);
LOG_DBG("today %d",today);
if ((stp->sp_expire != -1) && (today >= stp->sp_expire))
{
return 1;
}
if (today >= (stp->sp_lstchg+stp->sp_max+stp->sp_inact))
{
return 1;
}
return 0;
}

Loading…
Cancel
Save