/* Created: 03.19.05 11:34:57 by Attila Nagyidai $Id: C\040Console.c,v 1.1.2.1 2003/08/13 00:38:46 neum Exp $ This file is part of IBSH (Iron Bars Shell) , a restricted Unix shell Copyright (C) 2005 Attila Nagyidai 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Author: Attila Nagyidai Email: na@ent.hu Co-Author: Shy Email: shy@cpan.org Co-Author: Witzy Email: stazzz@altern.org URL: http://ibsh.sourceforge.net IRC: irc.freenode.net #ibsh RSS, Statistics, etc: http://sourceforge.net/projects/ibsh/ */ /* Header files */ #include "ibsh.h" /* Main: */ /* Handle arguments, read config files, start command processing. */ /* IBSH doesnt use any command line arguments, but my text editor */ /* uses this code in all new c files to create. And i didnt have the */ /* heart to remove it. ;p */ /* Technical Description: */ /* Get the passwd entry for the user. The uid is easily aquired, since */ /* it is the real user id. After that, grab the passwd file entry upon */ /* the id, and copy the information to the loggedin struct. */ /* Add some signal handlers too. */ /* The infinite loop: */ /* Get the current directory, the full path. Compute the jailpath from that, */ /* that is the directories below the users homedir, which is the jail root. */ /* The jail ceiling if you like. Print some prompt to the user with the jailpath, */ /* and read stdin for incoming commands. Filter out the bad commands, typos, the */ /* not allowed commands. It the command is ok, execute it. If it is a shell builtin, */ /* use our builtin code, otherwise use execve. After execve, check if the user didnt */ /* use the last command to create some illegal content. If yes, erase that. Give the */ /* notice only afterwards. */ int main(int argc, char **argv) { char temp[STRING_SIZE], *buf; struct stat info; uid_t ruid, euid; gid_t rgid, egid; /* setuid protection */ ruid = getuid(); euid = geteuid(); rgid = getgid(); egid = getegid(); if ( (ruid!=euid) || (ruid==0) || (euid==0) || (rgid!=egid) || (rgid==0) || (egid==0) ) { OPENLOG; syslog(LOG_ERR, "setuid/setgid violation!"); CLOSELOG; printf("ibsh: setuid/setgid violation!! exiting...\n"); #ifdef DEBUG printf("ruid: %d;euid: %d;rgid: %d;egid: %d\n", ruid,euid,rgid,egid); #endif exit(0); } /* To Do: The code of your application goes here */ /* First part: */ /* Get essential information about the user who got this shell: */ /* first the username, then the user id. Upon this, retrieve the */ /* user's record in the passwd file. */ bzero(&loggedin, sizeof(loggedin)); loggedin.uid = getuid(); loggedin.record = getpwuid(loggedin.uid); if ( loggedin.record == NULL ) { loggedin.record = getpwnam(loggedin.uname); if ( loggedin.record == NULL ) { openlog(loggedin.uname, LOG_PID, LOG_AUTH); syslog(LOG_ERR, "Can not obtain user information"); closelog(); exit(0); } } strncpy(loggedin.uname, loggedin.record->pw_name, PAM_SIZE); strncpy(loggedin.udir, loggedin.record->pw_dir, STRING_SIZE); /* Second part: */ /* Handle some signal catching. Read the configuration files. */ signal( SIGINT, SIG_IGN ); signal( SIGQUIT, SIG_IGN ); signal( SIGTERM, SIG_IGN ); signal( SIGTSTP, SIG_IGN ); LoadConfig(); /* Command mode */ if(argc == 3) { if ( argv[1][1] == 'c' ) { if ( CommandOK(argv[2], loggedin.udir, "/", filtered_command) == 1) { exitcode = hhsystem(filtered_command); OPENLOG; syslog(LOG_INFO, "command %s ordered, command %s has been executed.", argv[2], filtered_command); CLOSELOG; exit(exitcode); } exit(0); } else { exit(0); } } OPENLOG; syslog(LOG_INFO, "user %s has logged in.", loggedin.uname); CLOSELOG; DelBadFiles(loggedin.udir); chdir (loggedin.udir); /* Third part: */ /* Start reading and processing the user issued commands. */ /* Split the command by the spaces, filter out anything, */ /* that would allow the user to access files outside the */ /* jail. Filter out multiples and pipes as well. No program */ /* will be allowed to run, unless it is mentioned in the */ /* config files. Files that are created with an extension */ /* that is listed in the other config file, must be deleted! */ for ( ; ; ) { /* Where is he ? */ getcwd(real_path, STRING_SIZE); GetPositionInJail(real_path, loggedin.udir, jail_path); if ( (strlen(jail_path)) == 0 ) { strncpy(jail_path, "/", 2); } /* We don't want the user to know where he actually is. */ /* This is the prompt! */ printf("[%s]%% ", jail_path); /* scanf("%s", user_command); */ myscanf(user_command, real_path); /* Command interpretation and execution. */ if ( (CommandOK(user_command, loggedin.udir, jail_path, filtered_command)) == 0 ) { printf("Sorry, can't let you do that!\n"); log_attempt(loggedin.uname); /* v0.2a */ continue; } /* If the user issued command starts with a shell builtin. */ bzero(temp, strlen(temp)); if ( (buf = strstr(filtered_command, "cd")) != NULL ) { if ( (strcmp(buf, filtered_command)) == 0 ) { LTrim3(filtered_command, temp); if ( (strcmp(temp, real_path)) != 0 ) { if ( (strcmp(temp, "..")) == 0 ) { PathMinusOne(jail_path, temp, 1,sizeof(temp)); } if ( (strcmp(temp, "/")) == 0 ) { strncpy(temp, loggedin.udir, LINE_SIZE); } exitcode = chdir(temp); if ( exitcode == -1 ) { printf("ibsh: cd: %s: No such file or directory\n", temp); } } continue; } } else if ( (buf = strstr(filtered_command, "pwd")) != NULL ) { if ( (strcmp(buf, filtered_command)) == 0 ) { printf("%s\n", jail_path); continue; } } else if ( (buf = strstr(filtered_command, "logout")) != NULL ) { if ( (strcmp(buf, filtered_command)) == 0 ) { OPENLOG; syslog(LOG_INFO, "user %s has logged out.", loggedin.uname); CLOSELOG; break; } } else if ( (buf = strstr(filtered_command, "exit")) != NULL ) { if ( (strcmp(buf, filtered_command)) == 0 ) { OPENLOG; syslog(LOG_INFO, "user %s has logged out.", loggedin.uname); CLOSELOG; break; } } else { exitcode = hhsystem(filtered_command); if ( exitcode < 0 ) { printf("%s\n", strerror(errno)); } } getcwd(real_path, STRING_SIZE); DelBadFiles(loggedin.udir); chdir (real_path); } return 0; }