diff --git a/sesman/Makefile b/sesman/Makefile index 62b2eb25..b9bb0e06 100644 --- a/sesman/Makefile +++ b/sesman/Makefile @@ -1,6 +1,6 @@ # sesman makefile SESMANOBJ = sesman.o config.o tcp.o sig.o session.o env.o \ - os_calls.o d3des.o list.o file.o log.o + os_calls.o d3des.o list.o file.o log.o access.o SESRUNOBJ = sesrun.o config.o tcp.o \ os_calls.o d3des.o list.o file.o log.o @@ -15,7 +15,7 @@ DEFINES = -DSESMAN_CFG_FILE=\"$(CFGDIR)/sesman.ini\" \ -DSESMAN_PID_FILE=\"$(PIDDIR)/sesman.pid\" CFLAGS = -Wall -O2 -I../common $(DEFINES) -LDFLAGS = -L /usr/gnu/lib +LDFLAGS = -L /usr/gnu/lib $(DEFINES) C_OS_FLAGS = $(CFLAGS) -c CC = gcc diff --git a/sesman/access.c b/sesman/access.c new file mode 100644 index 00000000..594120d6 --- /dev/null +++ b/sesman/access.c @@ -0,0 +1,86 @@ +/* + 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 + + authenticate user + +*/ + +#include "sesman.h" + +#define _XOPEN_SOURCE +#include +#include +#include +//#include +//#include + +extern struct config_sesman g_cfg; + +/******************************************************************************/ +int DEFAULT_CC +access_login_allowed(char* user) +{ + int i; + struct group* groups; + struct passwd* pwd; + + if ((0==g_strncmp(user, "root",5)) && (0==g_cfg.sec.allow_root)) + { + log_message(LOG_LEVEL_WARNING, "ROOT login attempted, but root login is disabled"); + return 0; + } + + if (0==g_cfg.sec.ts_users_enable) + { + LOG_DBG("Terminal Server Users group is disabled, allowing authentication",1); + return 1; + } + + groups = getgrgid(g_cfg.sec.ts_users); + + if (0==groups) + { + log_message(LOG_LEVEL_ERROR,"Cannot read group info! - login denied"); + return 0; + } + + pwd = getpwnam(user); + if (0==pwd) + { + log_message(LOG_LEVEL_ERROR, "Cannot read user info! - login denied"); + return 0; + } + + if (g_cfg.sec.ts_users==pwd->pw_gid) + { + LOG_DBG("ts_users is user's primary group",1); + return 1; + } + + i=0; + while (0!=groups->gr_mem[i]) + { + LOG_DBG("user: %s", groups->gr_mem[i]); + if (0==strcmp(groups->gr_mem[i], user)) return 1; + i++; + } + + log_message(LOG_LEVEL_INFO, "login denied for user %s", user); + + return 0; +} diff --git a/sesman/access.h b/sesman/access.h new file mode 100644 index 00000000..342431d5 --- /dev/null +++ b/sesman/access.h @@ -0,0 +1,33 @@ +/* + 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 + + session manager - access control header +*/ + +#ifndef ACCESS_H +#define ACCESS_H + +/** + * + * + * + */ +int DEFAULT_CC +access_login_allowed(char* user); + +#endif diff --git a/sesman/config.c b/sesman/config.c index 3861e413..d96bb45a 100644 --- a/sesman/config.c +++ b/sesman/config.c @@ -19,6 +19,9 @@ session manager - read config file */ +#include "sys/types.h" +#include "grp.h" + #include "arch.h" #include "list.h" #include "file.h" @@ -68,6 +71,9 @@ config_read(struct config_sesman* cfg) /* read logging config */ config_read_logging(fd, &(cfg->log), param_n, param_v); + /* read security config */ + config_read_security(fd, &(cfg->sec), param_n, param_v); + /* cleanup */ list_delete(sec); list_delete(param_v); @@ -85,6 +91,12 @@ config_read_globals(int file, struct config_sesman* cf, struct list* param_n, list_clear(param_v); list_clear(param_n); + + /* resetting the struct */ + cf->listen_port[0]='\0'; + cf->enable_user_wm=0; + cf->user_wm[0]='\0'; + cf->default_wm[0]='\0'; file_read_section(file, SESMAN_CFG_GLOBALS, param_n, param_v); for (i = 0; i < param_n->count; i++) @@ -108,6 +120,21 @@ config_read_globals(int file, struct config_sesman* cf, struct list* param_n, } } + /* checking for missing required parameters */ + if ('\0'==cf->listen_port[0]) + { + g_strncpy(cf->listen_port, "3350", 5); + } + if ('\0'==cf->user_wm[0]) + { + cf->enable_user_wm=0; + } + if ('\0'==cf->default_wm[0]) + { + g_strncpy(cf->default_wm, "startwm.sh", 11); + } + + /* showing read config */ g_printf("sesman config:\r\n"); g_printf("\tListenPort: %s\r\n", cf->listen_port); g_printf("\tEnableUserWindowManager: %i\r\n", cf->enable_user_wm); @@ -158,6 +185,11 @@ config_read_logging(int file, struct log_config* lc, struct list* param_n, } } + if (0==lc->log_file) + { + lc->log_file=g_strdup("./sesman.log"); + } + g_printf("logging configuration:\r\n"); g_printf("\tLogFile: %s\r\n",lc->log_file); g_printf("\tLogLevel: %i\r\n", lc->log_level); @@ -167,3 +199,62 @@ config_read_logging(int file, struct log_config* lc, struct list* param_n, return 0; } +/******************************************************************************/ +int DEFAULT_CC +config_read_security(int file, struct config_security* sc, struct list* param_n, + struct list* param_v) +{ + int i; + char* buf; + + list_clear(param_v); + list_clear(param_n); + + /* setting defaults */ + sc->allow_root=0; + sc->ts_users_enable=0; + sc->ts_admins_enable=0; + + file_read_section(file, SESMAN_CFG_SECURITY, param_n, param_v); + for (i = 0; i < param_n->count; i++) + { + buf = (char*)list_get_item(param_n, i); + if (0 == g_strncasecmp(buf, SESMAN_CFG_SEC_ALLOW_ROOT, 20)) + { + sc->allow_root = text2bool((char*)list_get_item(param_v, i)); + } + if (0 == g_strncasecmp(buf, SESMAN_CFG_SEC_USR_GROUP, 20)) + { + sc->ts_users_enable=1; + sc->ts_users=(getgrnam((char*)list_get_item(param_v, i))->gr_gid); + } + if (0 == g_strncasecmp(buf, SESMAN_CFG_SEC_ADM_GROUP, 20)) + { + sc->ts_admins_enable=1; + sc->ts_admins=(getgrnam((char*)list_get_item(param_v, i))->gr_gid); + } + } + + /* printing security config */ + g_printf("security configuration:\r\n"); + g_printf("\tAllowRootLogin: %i\r\n",sc->allow_root); + if (sc->ts_users_enable) + { + g_printf("\tTSUsersGroup: %i\r\n", sc->ts_users); + } + else + { + g_printf("\tNo TSUsersGroup defined\r\n"); + } + if (sc->ts_admins_enable) + { + g_printf("\tTSAdminsGroup: %i\r\n", sc->ts_admins); + } + else + { + g_printf("\tNo TSAdminsGroup defined\r\n"); + } + + return 0; +} + diff --git a/sesman/config.h b/sesman/config.h index 81a54959..c73d35da 100644 --- a/sesman/config.h +++ b/sesman/config.h @@ -22,6 +22,7 @@ #ifndef CONFIG_H #define CONFIG_H +#include "sys/types.h" #include "arch.h" #include "list.h" #include "log.h" @@ -41,6 +42,7 @@ #define SESMAN_CFG_PORT "ListenPort" #define SESMAN_CFG_ENABLE_USERWM "EnableUserWindowManager" #define SESMAN_CFG_USERWM "UserWindowManager" +#define SESMAN_CFG_MAX_SESSION "MaxSessions" #define SESMAN_CFG_LOGGING "Logging" #define SESMAN_CFG_LOG_FILE "LogFile" @@ -48,6 +50,47 @@ #define SESMAN_CFG_LOG_ENABLE_SYSLOG "EnableSyslog" #define SESMAN_CFG_LOG_SYSLOG_LEVEL "SyslogLevel" +#define SESMAN_CFG_SECURITY "Security" +#define SESMAN_CFG_SEC_ALLOW_ROOT "AllowRootLogin" +#define SESMAN_CFG_SEC_USR_GROUP "TerminalServerUsers" +#define SESMAN_CFG_SEC_ADM_GROUP "TerminalServerAdmins" + +#define SESMAN_CFG_SESSIONS "Sessions" +#define SESMAN_CFG_SESS_MAX "MaxSessions" +#define SESMAN_CFG_SESS_KILL_DISC "KillDisconnected" +#define SESMAN_CFG_SESS_IDLE_LIMIT "IdleTimeLimit" + +/** + * + * @struct config_sesman + * @brief \t struct that contains \t sesman configuration + * + * This \t struct contains all of \t sesman configuration parameters\n + * Every parameter in \t [globals] is a member of this struct, other + * sections options are embedded in this \t struct as member structures + * + */ +struct config_security +{ + /** + * @var allow_root + * @brief + */ + int allow_root; + /** + * @var ts_users + * @brief Terminal Server Users group + */ + int ts_users_enable; + gid_t ts_users; + /** + * @var ts_admins + * @brief Terminal Server Adminnistrators group + */ + int ts_admins_enable; + gid_t ts_admins; +}; + /** * * @struct config_sesman @@ -85,6 +128,11 @@ struct config_sesman * @brief Log configuration \t struct */ struct log_config log; + /** + * @var sec + * @brief Security configuration options \t struct + */ + struct config_security sec; }; /** @@ -123,4 +171,16 @@ config_read_globals(int file, struct config_sesman* cf, struct list* param_n, st int DEFAULT_CC config_read_logging(int file, struct log_config* lc, struct list* param_n, struct list* param_v); +/** + * + * @brief Reads sesman [iSecurity] configuration section + * + * @param cfg pointer to configuration object to be replaced + * + * @return 0 on success, 1 on failure + * + */ +int DEFAULT_CC +config_read_security(int file, struct config_security* sc, struct list* param_n, struct list* param_v); + #endif diff --git a/sesman/sesman.c b/sesman/sesman.c index 3ee2ce55..30cbd44f 100644 --- a/sesman/sesman.c +++ b/sesman/sesman.c @@ -142,8 +142,17 @@ sesman_main_loop() } else { - display = session_start(width, height, bpp, user, pass, - data); + g_printf("pre auth"); + if (1==access_login_allowed(user)) + { + log_message(LOG_LEVEL_INFO, "granted TS access to user %s", user); + display = session_start(width, height, bpp, user, pass, + data); + } + else + { + display=0; + } } if (display == 0) { @@ -227,7 +236,7 @@ main(int argc, char** argv) /* check if sesman is running */ if (!g_file_exist(SESMAN_PID_FILE)) { - g_printf("sesman is not running (pid file not found)\n"); + g_printf("sesman is not running (pid file not found - %s)\n", SESMAN_PID_FILE); g_exit(1); } @@ -247,6 +256,10 @@ main(int argc, char** argv) { g_printf("error killing sesman: %s\n", strerror(errno)); } + else + { + g_file_delete(SESMAN_PID_FILE); + } g_exit(error); } @@ -260,7 +273,6 @@ main(int argc, char** argv) } - if (g_file_exist(SESMAN_PID_FILE)) { g_printf("sesman is already running.\n"); @@ -338,7 +350,10 @@ main(int argc, char** argv) sesman_main_loop(); - log_end(); + if (!daemon) + { + log_end(); + } return 0; } diff --git a/sesman/sesman.h b/sesman/sesman.h index ebdec77d..8dd95226 100644 --- a/sesman/sesman.h +++ b/sesman/sesman.h @@ -33,6 +33,7 @@ #include "tcp.h" #include "sig.h" #include "session.h" +#include "access.h" #ifndef SESMAN_PID_FILE #define SESMAN_PID_FILE "./sesman.pid" diff --git a/sesman/verify_user.c b/sesman/verify_user.c index 4ec94dac..5e9203c2 100644 --- a/sesman/verify_user.c +++ b/sesman/verify_user.c @@ -20,18 +20,19 @@ */ -#include "arch.h" -#include "os_calls.h" +#include "sesman.h" #define _XOPEN_SOURCE -#include -#include +#include +#include #include #include +extern struct config_sesman g_cfg; + /******************************************************************************/ /* returns boolean */ -int DEFAULT_CC +long DEFAULT_CC auth_userpass(char* user, char* pass) { char salt[13] = "$1$"; @@ -46,7 +47,7 @@ auth_userpass(char* user, char* pass) { return 0; } - if (strncmp(spw->pw_passwd, "x", 3) == 0) + if (g_strncmp(spw->pw_passwd, "x", 3) == 0) { /* the system is using shadow */ stp = getspnam(user); @@ -54,15 +55,15 @@ auth_userpass(char* user, char* pass) { return 0; } - strncpy(hash, stp->sp_pwdp, 34); + g_strncpy(hash, stp->sp_pwdp, 34); } else { /* old system with only passwd */ - strncpy(hash, spw->pw_passwd, 34); + g_strncpy(hash, spw->pw_passwd, 34); } hash[34] = '\0'; - if (strncmp(hash, "$1$", 3) == 0) + if (g_strncmp(hash, "$1$", 3) == 0) { /* gnu style crypt(); */ saltcnt = 3; @@ -82,7 +83,7 @@ auth_userpass(char* user, char* pass) salt[2] = '\0'; } encr = crypt(pass,salt); - if (strncmp(encr, hash, 34) != 0) + if (g_strncmp(encr, hash, 34) != 0) { return 0; } @@ -92,21 +93,22 @@ auth_userpass(char* user, char* pass) /******************************************************************************/ /* returns error */ int DEFAULT_CC -auth_start_session(void) +auth_start_session(long in_val, int in_display) { return 0; } /******************************************************************************/ int DEFAULT_CC -auth_end(void) +auth_end(long in_val) { return 0; } /******************************************************************************/ int DEFAULT_CC -auth_set_env(void) +auth_set_env(long in_val) { return 0; } +