summaryrefslogtreecommitdiffstats
path: root/sesman
diff options
context:
space:
mode:
authorilsimo <ilsimo>2006-11-24 20:46:45 +0000
committerilsimo <ilsimo>2006-11-24 20:46:45 +0000
commit078b4d3f4127042b020e78bb9d9762196ff070c3 (patch)
tree9d0b7a5b0ffe2c8e2f07b2b45ebd950d43c59533 /sesman
parentb681420acc6297f628d132946f6f9f94f536a358 (diff)
downloadxrdp-proprietary-078b4d3f4127042b020e78bb9d9762196ff070c3.tar.gz
xrdp-proprietary-078b4d3f4127042b020e78bb9d9762196ff070c3.zip
adding scp v1 first code, fixed passwd auth for disabled password
Diffstat (limited to 'sesman')
-rw-r--r--sesman/Makefile7
-rw-r--r--sesman/libscp.h2
-rw-r--r--sesman/libscp_v1c.c249
-rw-r--r--sesman/libscp_v1c.h23
-rw-r--r--sesman/libscp_v1s.c179
-rw-r--r--sesman/libscp_v1s.h30
-rw-r--r--sesman/scp.c5
-rw-r--r--sesman/scp.h3
-rw-r--r--sesman/scp_v1.c192
-rw-r--r--sesman/scp_v1.h42
-rw-r--r--sesman/tools/Makefile40
-rw-r--r--sesman/tools/sestest.c155
-rw-r--r--sesman/verify_user.c101
13 files changed, 982 insertions, 46 deletions
diff --git a/sesman/Makefile b/sesman/Makefile
index 9dd94c45..293f5372 100644
--- a/sesman/Makefile
+++ b/sesman/Makefile
@@ -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
diff --git a/sesman/libscp.h b/sesman/libscp.h
index d4b412ba..a445e98e 100644
--- a/sesman/libscp.h
+++ b/sesman/libscp.h
@@ -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
diff --git a/sesman/libscp_v1c.c b/sesman/libscp_v1c.c
new file mode 100644
index 00000000..f2f6ffee
--- /dev/null
+++ b/sesman/libscp_v1c.c
@@ -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;
+}
diff --git a/sesman/libscp_v1c.h b/sesman/libscp_v1c.h
index b85b7508..1707fb68 100644
--- a/sesman/libscp_v1c.h
+++ b/sesman/libscp_v1c.h
@@ -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
diff --git a/sesman/libscp_v1s.c b/sesman/libscp_v1s.c
index 47f6b376..e0b3058e 100644
--- a/sesman/libscp_v1s.c
+++ b/sesman/libscp_v1s.c
@@ -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;
}
diff --git a/sesman/libscp_v1s.h b/sesman/libscp_v1s.h
index d61392d1..5dc85960 100644
--- a/sesman/libscp_v1s.h
+++ b/sesman/libscp_v1s.h
@@ -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
diff --git a/sesman/scp.c b/sesman/scp.c
index 6631154c..476c3e3a 100644
--- a/sesman/scp.c
+++ b/sesman/scp.c
@@ -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;
diff --git a/sesman/scp.h b/sesman/scp.h
index 8da78b86..145ea5e6 100644
--- a/sesman/scp.h
+++ b/sesman/scp.h
@@ -28,8 +28,9 @@
#ifndef SCP_H
#define SCP_H
+//#include "libscp.h"
#include "scp_v0.h"
-#include "libscp.h"
+#include "scp_v1.h"
/**
*
diff --git a/sesman/scp_v1.c b/sesman/scp_v1.c
new file mode 100644
index 00000000..03461b72
--- /dev/null
+++ b/sesman/scp_v1.c
@@ -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);
+}
+
diff --git a/sesman/scp_v1.h b/sesman/scp_v1.h
new file mode 100644
index 00000000..5f0b41ae
--- /dev/null
+++ b/sesman/scp_v1.h
@@ -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
diff --git a/sesman/tools/Makefile b/sesman/tools/Makefile
new file mode 100644
index 00000000..b4902ad5
--- /dev/null
+++ b/sesman/tools/Makefile
@@ -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
diff --git a/sesman/tools/sestest.c b/sesman/tools/sestest.c
new file mode 100644
index 00000000..62629f3a
--- /dev/null
+++ b/sesman/tools/sestest.c
@@ -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;
+}
diff --git a/sesman/verify_user.c b/sesman/verify_user.c
index 11c6473c..03ecfadb 100644
--- a/sesman/verify_user.c
+++ b/sesman/verify_user.c
@@ -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;
+}
+