Update of /cvsroot/phpshell/phpshell
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25902

Modified Files:
        AUTHORS ChangeLog INSTALL README phpshell.php 
Added Files:
        SECURITY config.php pwhash.php style.css 
Removed Files:
        phpshell.css release.sh valid-xhtml10.png vcss.png 
Log Message:
Imported PHP Shell version 2.1.

--- phpshell.css DELETED ---

Index: ChangeLog
===================================================================
RCS file: /cvsroot/phpshell/phpshell/ChangeLog,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- ChangeLog   13 Jan 2006 17:38:31 -0000      1.6
+++ ChangeLog   13 Jan 2006 17:49:45 -0000      1.7
@@ -1,4 +1,22 @@
-2004-03-27  Martin Geisler  <[EMAIL PROTECTED]>
+2005-12-27  Martin Geisler  <[EMAIL PROTECTED]>
+
+       * phpshell.php:
+       Added code to prevent simple replay attacks by only accepting each
+       login form once.
+       
+2005-12-25  Martin Geisler  <[EMAIL PROTECTED]>
+
+       * INSTALL: Information about the new internal configuration.
+       
+       * phpshell.php: Made authentication internal.
+
+       * SECURITY: New file.
+
+       * config.php: New file.
+
+       * style.css: New file.  Renamed from phpshell.css.
+
+2004-03-27  Martin Geisler  <[EMAIL PROTECTED]>
 
        * phpshell.php 1.29: Removed debug output.
 
@@ -20,13 +38,13 @@
        special cases are taken care of, and simple command substitution using
        aliases have been introduced.
 
-2004-03-24  Martin Geisler  <[EMAIL PROTECTED]>
+2004-03-24  Martin Geisler  <[EMAIL PROTECTED]>
 
        * phpshell.php 1.26:
        Increased year of copyright to 2004.  Fixed the references to the PNG
        images, as pointed out by Michael Z. Bell.
 
-2003-11-11  Martin Geisler  <[EMAIL PROTECTED]>
+2003-11-11  Martin Geisler  <[EMAIL PROTECTED]>
 
        * AUTHORS 1.6:
        Added Wolfgang Dautermann <[EMAIL PROTECTED]>.
@@ -41,7 +59,7 @@
        Also, changing directory through symbolic links now works as expected,
        so that it's possible to go back using 'cd ..'.
 
-2003-04-01  Martin Geisler  <[EMAIL PROTECTED]>
+2003-04-01  Martin Geisler  <[EMAIL PROTECTED]>
 
        * INSTALL 1.4:
        New instructions on how to change the username and password.
@@ -74,7 +92,7 @@
        Applied patch from Michael Zech <[EMAIL PROTECTED]> that made the
        stderr-checkbox remember it's state.
 
-2002-09-18  Martin Geisler  <[EMAIL PROTECTED]>
+2002-09-18  Martin Geisler  <[EMAIL PROTECTED]>
 
        * phpshell.php 1.18:
        Use the directory of phpshell.php as the default working directory.
@@ -84,7 +102,7 @@
        * phpshell.php 1.17:
        PHP Shell now works on PHP 4.2.0 with register_globals turned off.
 
-2002-06-10  Martin Geisler  <[EMAIL PROTECTED]>
+2002-06-10  Martin Geisler  <[EMAIL PROTECTED]>
 
        * INSTALL 1.3: Added a section about Safe Mode in PHP.
 
@@ -92,7 +110,7 @@
        Added a section about Safe Mode in PHP. Also fixed a lot of spelling
        errors.
 
-2002-03-23  Martin Geisler  <[EMAIL PROTECTED]>
+2002-03-23  Martin Geisler  <[EMAIL PROTECTED]>
 
        * README 1.8: Added a version number to the file.
 
@@ -112,7 +130,7 @@
        Added a tip from Jeremy Miller <[EMAIL PROTECTED]> about how to
        use PHP Shell together with Sudo to execute code as another user.
 
-2001-12-10  Martin Geisler  <[EMAIL PROTECTED]>
+2001-12-10  Martin Geisler  <[EMAIL PROTECTED]>
 
        * phpshell.php 1.13:
        I found out that 'ls -F' produced better output than 'ls -p'.
@@ -126,7 +144,7 @@
 
        * README 1.5: Updated the documentation a bit.
 
-2001-02-11  Martin Geisler  <[EMAIL PROTECTED]>
+2001-02-11  Martin Geisler  <[EMAIL PROTECTED]>
 
        * phpshell.php 1.11:
        Another suggestion from Thomas Langen <[EMAIL PROTECTED]>: some
@@ -137,7 +155,7 @@
        Expanded all PHP start-tags (<?) to <?php, as suggested by Thomas
        Langen <[EMAIL PROTECTED]>.
 
-2000-11-20  Martin Geisler  <[EMAIL PROTECTED]>
+2000-11-20  Martin Geisler  <[EMAIL PROTECTED]>
 
        * AUTHORS 1.1: New file.
 
@@ -145,11 +163,11 @@
        Applied a patch from [EMAIL PROTECTED] which fixed a problem with
        accessing the root-directory.
 
-2000-09-24  Martin Geisler  <[EMAIL PROTECTED]>
+2000-09-24  Martin Geisler  <[EMAIL PROTECTED]>
 
        * phpshell.php 1.8: Removed a debug-comment.
 
-2000-09-09  Martin Geisler  <[EMAIL PROTECTED]>
+2000-09-09  Martin Geisler  <[EMAIL PROTECTED]>
 
        * README 1.4: Expanded the brief explanation at the top.
 
@@ -166,18 +184,18 @@
        Removed 'Martin Geisler' from the title, putting my name on the bottom
        of the page ought to be enough :-)
 
-2000-08-06  Martin Geisler  <[EMAIL PROTECTED]>
+2000-08-06  Martin Geisler  <[EMAIL PROTECTED]>
 
        * phpshell.php 1.6:
        Added a link to gimpster.com at the bottom of the page
 
-2000-08-05  Martin Geisler  <[EMAIL PROTECTED]>
+2000-08-05  Martin Geisler  <[EMAIL PROTECTED]>
 
        * phpshell.php 1.5:
        Removed references to php3 - I now use php4 so all my files end with
        just a '.php'
 
-2000-06-21  Martin Geisler  <[EMAIL PROTECTED]>
+2000-06-21  Martin Geisler  <[EMAIL PROTECTED]>
 
        * phpshell.php 1.4:
        Fix - there were still references to the old name: shell.php3.

Index: AUTHORS
===================================================================
RCS file: /cvsroot/phpshell/phpshell/AUTHORS,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- AUTHORS     13 Jan 2006 17:34:25 -0000      1.5
+++ AUTHORS     13 Jan 2006 17:49:45 -0000      1.6
@@ -1,4 +1,9 @@
-Main author: Martin Geisler <[EMAIL PROTECTED]>         -*- text -*-
+AUTHORS file for PHP Shell 2.1
+Copyright (C) 2000-2004 Martin Geisler <[EMAIL PROTECTED]>
+Licensed under the GNU GPL.  See the file COPYING for details.
+
+
+Main author: Martin Geisler <[EMAIL PROTECTED]>
 
 Thanks goes to all these persons who have helped:
 
@@ -17,7 +22,7 @@
 
     http://www.courtesan.com/sudo/
 
-  to let PhpShell execute code with different privileges than the
+  to let PHP Shell execute code with different privileges than the
   webserver.
 
 Michael Zech <[EMAIL PROTECTED]>

--- vcss.png DELETED ---

Index: README
===================================================================
RCS file: /cvsroot/phpshell/phpshell/README,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- README      13 Jan 2006 17:38:31 -0000      1.6
+++ README      13 Jan 2006 17:49:45 -0000      1.7
@@ -1,120 +1,126 @@
-README for PhpShell 2.0
-Copyright (C) 2000-2004 Martin Geisler <[EMAIL PROTECTED]>
+README file for PHP Shell 2.1
+Copyright (C) 2000-2005 Martin Geisler <[EMAIL PROTECTED]>
 Licensed under the GNU GPL.  See the file COPYING for details.
 
-What is PhpShell?
-------------------
-PhpShell is a shell wrapped in a PHP script.  It's a tool you can use
-to execute arbitrary shell-commands or browse the filesystem on your
-remote webserver.  This replaces, to a degree, a normal
-telnet-connection.  You can use it for transferring your site as a
-compressed file, and then unpack it on the webserver, administration
-and maintenance of your website using commands like ps, free, du, df
-etc...
+What is PHP Shell?
+==================
+
+PHP Shell is a shell wrapped in a PHP script.  It's a tool you can use to
+execute arbitrary shell-commands or browse the filesystem on your remote
+webserver.  This replaces, to a degree, a normal telnet-connection.
+
+You use it for administration and maintenance of your website, which is often
+much easier to do if you can work directly on the server.  For example, you
+could use PHP Shell to unpack and move big files around.  All the normal
+command line programs like ps, free, du, df, etc... can be used.
  
 
 Limitations
------------
-There are some limitations on what kind of programs you can run.  It
-won't do no good if you start something like Netscape or even vi.  All
-programs have to be strictly command-line programs, and they will have
-no chance of getting user input after they have been lunched.  They
-probably also have to terminate within 30 seconds, as this is the
-default time-limit imposed unto all PHP scripts, to prevent them from
-running in an infinite loop.  Your ISP may have set this time-limit to
-something else.
+===========
 
-But you can rely on all the normal shell-functionality, like pipes,
-output and input redirection, etc...  (There is no <tab>-completion,
-though :-)
+There are some limitations on what kind of programs you can run.  It won't do
+no good if you start a graphical program like Firefox or even a console based
+one like vi.  All programs have to be strictly command line programs, and they
+will have no chance of getting user input after they have been lunched.
 
+They probably also have to terminate within 30 seconds, as this is the default
+time-limit imposed unto all PHP scripts, to prevent them from running in an
+infinite loop.  Your ISP may have set this time-limit to something else.
 
-Safe Mode
----------
-If PHP is running in Safe Mode, then you cannot use PhpShell ---
-sorry.  Safe Mode restricts the commands that can be executed using
-the shell_exec() call in PHP, and it also restricts the files and
-directories that can be accessed using other calls in PHP.
+But you can rely on all the normal shell-functionality, like pipes, output and
+input redirection, etc...  (There is no <tab>-completion, though :-)
 
-The effect is, that PhpShell simply doesn't work --- you cannot
-change directory and you cannot execute any commands.
 
-Safe Mode is often used on servers that host several websites for
-different users to limit the users ability to peek at each others
-files.
+Safe Mode
+=========
+
+Safe Mode is the nemisis of PHP Shell.  If PHP is running in Safe Mode then
+PHP Shell will normally not work --- sorry.  Please read the detailed
+explaination in the SECURITY file.
 
 
 Who am I?
----------
+=========
+
 (Well, my name is Martin, but that's not the point :-)
 
-You may not be the same user when using PhpShell, as you are when you
-upload your files with ftp.  On some systems you will be 'nobody', on
-other systems you will become 'httpd' or 'www-data'.  This is a rather
-dangerous "feature" of PhpShell! So use it at your own risk and
-remember to choose a good password as described in the INSTALL file.
+You may not be the same user when using PHP Shell, as you are when you upload
+your files with FTP.  On some systems you will be ``nobody``, on other systems
+you will become ``httpd`` or ``www-data``.  This is a rather dangerous
+"feature" of the way PHP is run by the webserver.  A possible effect of this
+is that you might end up creating files using PHP Shell which you cannot
+delete afterwards using FTP and maybe not even using PHP Shell.  Strange, but
+true :-)
 
-If you want to execute code as different user, then it's possible to
-do so by using the Sudo program available from this address:
+If you want to execute code as different user, then it's possible to do so by
+using the Sudo program available from this address:
 
   http://www.courtesan.com/sudo/
 
-The trick is to configure Sudo to allow the user running the webserver
-to execute certain commands as a more privileged user.  Please refer
-to the documentation for Sudo for further information about doing
-this.
+The trick is to configure Sudo to allow the user running the webserver to
+execute certain commands as a more privileged user.  This will have to be done
+by the administrator of the server.  Please refer to the documentation for
+Sudo for further information about doing this.
 
 
 How to Use It
--------------
-When you point your browser at PhpShell and types in your password
-(see the file INSTALL for more information on how to change the
-password), you'll be presented with a rather simple page containing
-nothing much except a big window with the cursor blinking at the
-bottom, signaling that it's ready to obey your commands.
+=============
+
+When you point your browser at PHP Shell you will be asked to authenticate
+yourself.  By default no username/password will work, so please go read
+INSTALL for information about adding a user.
+
+You're back?  Good.  Enter your username and password and press "Login".
+
+You will then be presented with a rather simple page containing nothing much
+except a big window with the cursor blinking at the bottom, signaling that
+it's ready to obey your commands.
 
 Write a command and press RET --- or alternatively, press the 'Execute
-Command' button if you insist.  The command will be executed and the
-result will be shows in the terminal.  You can now enter another
-command.
+Command' button if you really want.  The command will be executed and the
+result will be shows in the terminal.  You can now enter another command.
 
-To be more precise: the terminal is updated with the command line you
-have just executed, the output of the command to standard out (stdout)
-and following that any error output sent to stderr.
+To be more precise: the terminal is updated with the command line you have
+just executed, the output of the command to standard out (stdout), and
+following that any error output sent to stderr.
 
-The commands are executed relative to a current working directory,
-which is written at the top.  You change this by the normal 'cd'
-command.
+The commands are executed relative to a current working directory, which is
+written at the top.  You change this by the normal 'cd' command.
 
 
 Download
---------
-You can download PhpShell from http://www.gimpster.com/wiki/PhpShell.
+========
+
+You can download the newest version of PHP Shell from
+
+  http://mgeisler.net/php-shell/
+
 The tarball/zipfile contains these files:
 
 phpshell.php
-  This is the script you run when you use PhpShell.
+  This is the script you run when you use PHP Shell.
 
 ChangeLog
-  This file describe the changes I've made to PhpShell.  By reading
-  it you'll always know when I've added a new feature or made a
-  bugfix, and the nature of the feature/bugfix.
+  This file describe the changes I've made to PHP Shell.  By reading it you'll
+  always know when I've added a new feature or made a bugfix, and the nature
+  of the feature/bugfix.
 
 README
-  This file :-)
+  This file! :-)
 
 INSTALL
-  Tells you how to install PhpShell.  Amoung other things, it
-  explains how to change the password protection so that you can use
-  PhpShell.
+  Tells you how to install PHP Shell.  Amoung other things, it explains how to
+  change the password protection so that you can use PHP Shell.
 
-  Remember that it's very important to have PhpShell password
-  protected, or else everybody will be able so snoop into your files
-  and perhaps also be able to delete them!  I've already seen one site
-  that were using PhpShell without password-protection --- I was able
-  so quickly find their config.inc.php file from phpMyAdmin, and read
-  the password to the database!  So please take the time to protect
-  PhpShell.
+  Remember that it's very important to have PHP Shell password protected, or
+  else everybody will be able so snoop into your files and perhaps also be
+  able to delete them!  Please take the time to protect your installation of
+  PHP Shell.
+
+SECURITY
+  A separate guide about security with PHP in general and PHP Shell in
+  particular.  Be sure to read this too, especially if you are getting strange
+  errors back from PHP Shell.
 
 COPYING
-  Standard GNU disclaimer.
+  Standard GNU GPL.

--- NEW FILE: config.php ---
; <?php die('Forbidden'); ?>
; Do not remove the above line, it prevents this file from being downloaded.
;
; config.php file for PHP Shell 2.1
; Copyright (C) 2005 Martin Geisler <[EMAIL PROTECTED]>
; Licensed under the GNU GPL.  See the file COPYING for details.

; This ini-file has three parts:
;
; * [users] where you add usernames and passwords to give users access to PHP
;   Shell.
;
; * [aliases] where you can configure shell aliases.
;
; * [settings] where general settings are placed.


[users]

; The default configuration has no users defined, you have to add your own
; (choose good passwords!).  Add uses as simple 'username = "password"' lines.
; Please quote your password using double-quotes as shown.  The semi-colon ':'
; is a reserved character, so do *not* use that in your passwords.
;
; For improved security it is *strongly suggested* that you the pwhash.php
; script to generate a hashed password and store that instead of the normal
; clear text password.  Keeping your passwords in hashed form ensures that
; they cannot be found, even if this file is disclosed.  The passwords are
; still visible in clear text during the login, though.  Please follow the
; instructions given in pwhash.php.



[aliases]

; Alias expansion.  Change the two examples as needed and add your own
; favorites --- feel free to suggest more defaults!  The command line you
; enter will only be expanded on the very first token and only once, so having
; 'ls' expand into 'ls -CvhF' does not cause an infinite recursion.

ls = "ls -CvhF"
ll = "ls -lvhF"



[settings]

; General settings for PHP Shell.

; Home directory.  PHP Shell will change to this directory upon startup and
; whenever a bare 'cd' command is given.  This can be an absolute path or a
; path relative to the PHP Shell installation directory.

home-directory = "."

--- NEW FILE: style.css ---
/* style.css file for PHP Shell 2.1
 * Copyright (C) 2003-2005 Martin Geisler <[EMAIL PROTECTED]>
 * Licensed under the GNU GPL.  See the file COPYING for details.
 */

body {
  font-family: sans-serif;
  color: black;
  background: white;
}

h1 {
  color: red;
  background: white;
}

img {
  border: none;
}

div#terminal {
  border: inset 2px red;
  padding: 2px;
  margin-top: 0.5em;
}

div#terminal textarea { 
  font-size: 100%;
  width: 100%;
  border: none;
}

p {
  margin-top: 0.5em;
  margin-bottom: 0.5em;
}

p#prompt {
  font-family: monospace;
  margin: 0px;
}

p#prompt input {
  border: none;
  font-family: monospace;
}

legend {
  padding-right: 0.5em;
}

fieldset {
  padding: 0.5em;
}

.error {
  color: red;
}
Index: INSTALL
===================================================================
RCS file: /cvsroot/phpshell/phpshell/INSTALL,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- INSTALL     13 Jan 2006 17:38:31 -0000      1.5
+++ INSTALL     13 Jan 2006 17:49:45 -0000      1.6
@@ -1,76 +1,96 @@
-Installation instructions for PhpShell 2.0
-Copyright (C) 2000-2004 Martin Geisler <[EMAIL PROTECTED]>
+INSTALL file for PHP Shell 2.1
+Copyright (C) 2000-2005 Martin Geisler <[EMAIL PROTECTED]>
 Licensed under the GNU GPL.  See the file COPYING for details.
 
 
-Getting the Tarball
--------------------
-You can always get the latest version of PhpShell from my homepage:
+Downloading PHP Shell
+=====================
+
+You can always get the latest version of PHP Shell from my homepage:
+
+  http://mgeisler.net/php-shell/
 
-  http://www.gimpster.com/wiki/PhpShell
 
 
 Installation
-------------
-Installation is easy: first unpack the tarball or zipfile downloaded
-from the above website into your webserver.  This will create a
-subdirectory called phpweather-2.0 for PhpShell version 2.0.
+============
 
-If you're using PhpShell on an Apache webserver running PHP as a
-module, then PhpShell wont work until you've edited phpshell.php.  You
-can see this when you try and load the file phpshell.php from the
-directory just created --- you should get a prompt from your browser
-asking you to authenticate you.  In the default setup, no username or
-password will authenticate you, this what you'll have to change next.
+Installation is easy: first unpack the tarball or zipfile downloaded from the
+above website into your webserver.  This will create a subdirectory called
+phpweather-2.1 for PHP Shell version 2.1.
 
-In the phpshell.php file you'll find comments near the top that
-explains how to enable access for a username with a password. In
-short, you'll simply add the pair as an entry in the $passwd array
-like this:
+Try loading the file ``phpshell.php`` in your browser and check that you are
+served a page that asks you to authenticate yourself with a username and a
+password.  If you do not see such a page, then please check that you have
+entered the URL correctly and that PHP is working on your server.
 
-  $passwd = array('username' => 'password');
 
-This can be expanded to multiple users with their own passwords in a
-very simple way:
 
-  $passwd = array('username_1' => 'password_1',
-                  'username_2' => 'password_2',
-                  // ...
-                  'username_n' => 'password_n');
+Configuration
+=============
 
-It is important that you password-protect PhpShell with a good
-password.  If someone is able to guess your password, then they'll
-have access to your webserver over the Internet, and they might be
-able to erase your files, and perhaps even shutdown the webserver!  So
-be careful with this and remember that you can always find the usual
-disclaimer in the file LICENSE.
+All configuration happens in the ``config.php`` file.  This is an ini-file
+dispite its name.  Ini-files consist of a number of sections, each containing
+a number of 'key = "value"' pairs.  PHP Shell has tree sections: '[users]' for
+configuring usernames and passwords, '[aliases]' for configuring shell
+aliases, and '[settings]' for general settings.
+
+
+Setting Usernames and Passwords
+-------------------------------
+
+As a security precaution PHP Shell has no default username and password
+(people often forget to change them...).  To add the user "alice" with
+password "secret" you simply add
+
+  [users]
+  alice = "secret"
+
+to the file.  Note that you can add as many users as you want by simply adding
+more lines like this.
+
+This system works, but there is a better way --- a way so that the password
+does not appear in clear text in the file.  For that you use the supplied
+script ``pwhash.php`` to generate a hashed password.  Please see the
+instructions given in ``pwhash.php``.
+
+With the above example the result could look like
+
+  [users]
+  alice    = "md5:7ea3b59e:eb271c4459253eaa163fcac2a119f225"
+
+You will not get exactly the same line if you try it out, this is a feature of
+the system which means that both "alice" and "bob" could have "secret" as
+their password, and you would not be able to tell from just looking at
+``config.php``.
 
 
 Shell Aliases
 -------------
 
-As in a normal shell, PhpShell supports a simple form of aliases.
-Simply edit the $aliases array at the top of phpshell.php.  The keys
-in the array are substituted for their corresponding values before the
-commands are executed --- a couple of convenient aliases are already
-defined:
+As in a normal shell, PHP Shell supports alias expansion, albeit in a simple
+form.  Aliases are defined by 'key = "value"' pairs in the '[aliases]'
+section.  The "key" will be matched against the first token of the command
+line and substituted with the "value" given.
 
-  $aliases = array('ls' => 'ls -CvhF',
-                   'll' => 'ls -lvhF');
+Two convenient aliases are already defined:
 
+  [aliases]
+  ls = "ls -CvhF"
+  ll = "ls -lvhF"
 
-Safe Mode
----------
-PhpShell doesn't work if PHP is running in Safe Mode.  There is
-nothing I can do about this --- Safe Mode was made to prevent scripts
-just like PhpShell.  So if you're worried that people will be able to
-destroy your website using a tool like PhpShell, then tell your
-provider to enable Safe Mode as this makes PHP much less evil.
 
+General Settings
+----------------
 
-Bugs?
------
-If you find a bug or miss something in PhpShell, please don't hesitate
-to mail me at <[EMAIL PROTECTED]>!
+PHP has just one other setting right now --- the home directory.  Change this
+in the '[settings]' section.
 
-Enjoy! - Martin Geisler <[EMAIL PROTECTED]>
+
+
+Bugs?  Comments?
+================
+
+If you find a bug or miss something in PHP Shell, please don't hesitate to
+mail me at <[EMAIL PROTECTED]>!  Or you could drop by and leave a comment
+at http://mgeisler.net/php-shell/.

--- NEW FILE: pwhash.php ---
<?php
/*
 * pwhash.php file for PHP Shell 2.1
 * Copyright (C) 2005 Martin Geisler <[EMAIL PROTECTED]>
 * Licensed under the GNU GPL.  See the file COPYING for details.
 */

function stripslashes_deep($value) {
    if (is_array($value))
        return array_map('stripslashes_deep', $value);
    else
        return stripslashes($value);
}

if (get_magic_quotes_gpc())
    $_POST = stripslashes_deep($_POST);

$username = isset($_POST['username']) ? $_POST['username'] : '';
$password = isset($_POST['password']) ? $_POST['password'] : '';

?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd";>
<html>
<head>
  <title>Password Hasher for PHP Shell 2.1</title>
  <link rel="stylesheet" href="style.css" type="text/css">
</head>

<body>

<h1>Password Hasher for PHP Shell 2.1</h1>

<form action="<?php $_SERVER['PHP_SELF']; ?>" method="POST">

<fieldset>
  <legend>Username</legend>
  <input name="username" type="text" value="<?php echo $username ?>">
</fieldset>

<fieldset>
  <legend>Password</legend>
  <input name="password" type="text" value="<?php echo $password ?>">
</fieldset>

<fieldset>
  <legend>Result</legend>

<?php
if ($username == '' || $password == '') {
  echo "  <p><i>Enter a username and a password and update.</i></p>\n";
} else {

    $u = strtolower($username);

    if (preg_match('/[[ |&~!()]/', $u) || $u == 'null' ||
        $u == 'yes' || $u == 'no' || $u == 'true' || $u == 'false') {

        echo '  <p class="error">Your username cannot contain any of the 
following reserved
  word: "<tt>null</tt>", "<tt>yes</tt>", "<tt>no</tt>", "<tt>true</tt>", or
  "<tt>false</tt>".  The following characters are also prohibited:
  "<tt>&nbsp;</tt>" (space), "<tt>[</tt>" (left bracket), "<tt>|</tt>" (pipe),
  "<tt>&</tt>" (ampersand), "<tt>~</tt>" (tilde), "<tt>!</tt>" (exclamation
  mark), "<tt>(</tt>" (left parenthesis), or "<tt>)</tt>" (right
  parenthesis).</p>' . "\n";

        echo '  <p>Please choose another username and try again.</p>' . "\n";

    } else {
        echo "  <p>Write the following line into <tt>config.php</tt> " .
            "in the <tt>users</tt> section:</p>\n";

        $fkt = 'md5'; // Change to sha1 is you feel like it...
        $salt = dechex(mt_rand());

        $hash = $fkt . ':' . $salt . ':' . $fkt($salt . $password);

        echo "<pre>\n";
        echo htmlentities(str_pad($username, 8) . ' = "' . $hash . '"') . "\n";
        echo "</pre>\n";
    }
}
?>

<p><input type="submit" value="Update"></p>

</fieldset>

</form>


<hr>

<address>
Copyright &copy; 2005, <a href="mailto:[EMAIL PROTECTED]">Martin Geisler</a>. 
Get the
latest version at <a 
href="http://mgeisler.net/php-shell/";>mgeisler.net/php-shell/</a>.
</address>

</body>
</html>

Index: phpshell.php
===================================================================
RCS file: /cvsroot/phpshell/phpshell/phpshell.php,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- phpshell.php        13 Jan 2006 17:38:31 -0000      1.6
+++ phpshell.php        13 Jan 2006 17:49:45 -0000      1.7
@@ -3,15 +3,14 @@
 /*
 
   **************************************************************
-  *                      PhpShell 2.0                          *
+  *                     PHP Shell 2.1                          *
   **************************************************************
-  $Id$
 
-  PhpShell is an interactive PHP script that will execute any command
-  entered. See the files README and INSTALL or
-  http://www.gimpster.com/wiki/PhpShell for further information.
+  PHP Shell is an interactive PHP script that will execute any command
+  entered.  See the files README, INSTALL, and SECURITY or
+  http://mgeisler.net/php-shell/ for further information.
 
-  Copyright (C) 2000-2004 Martin Geisler <[EMAIL PROTECTED]>
+  Copyright (C) 2000-2005 Martin Geisler <[EMAIL PROTECTED]>
 
   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License
@@ -30,157 +29,253 @@
   
 */
 
-/* Set your usernames and passwords like this:
+/* There are no user-configurable settings in this file anymore, please see
+ * config.php instead. */
 
-   $passwd = array('username' => 'password');
 
-   You can add several pairs of usernames and passwords to the array
-   to give several different people access to PhpShell.
+/* This error handler will turn all notices, warnings, and errors into fatal
+ * errors, unless they have been suppressed with the @-operator. */
+function error_handler($errno, $errstr, $errfile, $errline, $errcontext) {
+    /* The @-opertor (used with chdir() below) temporarely makes
+     * error_reporting() return zero, and we don't want to die in that case.
+     * We do note the error in the output, though. */
+    if (error_reporting() == 0) {
+        $_SESSION['output'] .= $errstr . "\n";
+    } else {
+        die('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+   "http://www.w3.org/TR/html4/strict.dtd";>
+<html>
+<head>
+  <title>PHP Shell 2.1</title>
+  <link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body>
+  <h1>Fatal Error!</h1>
+  <p><b>' . $errstr . '</b></p>
+  <p>in <b>' . $errfile . '</b>, line <b>' . $errline . '</b>.</p>
 
-   $passwd = array('username_1' => 'password_1',
-                   'username_2' => 'password_2',
-                   // ...
-                   'username_n' => 'password_n');
+  <hr>
 
-*/
-$passwd = array();
+  <p>Please consult the <a href="README">README</a>, <a
+  href="INSTALL">INSTALL</a>, and <a href="SECURITY">SECURITY</a> files for
+  instruction on how to use PHP Shell.</p>
 
-/* Set your aliases here.  Each key in the array will be substituted
- * with the corresponding value before the commands are executed. */
-$aliases = array('ls' => 'ls -CvhF',
-                 'll' => 'ls -lvhF');
+  <hr>
 
-if (!isset($_SERVER['PHP_AUTH_USER']) ||
-    !isset($_SERVER['PHP_AUTH_PW']) ||
-    !isset($passwd[$_SERVER['PHP_AUTH_USER']]) ||
-    $passwd[$_SERVER['PHP_AUTH_USER']] != $_SERVER['PHP_AUTH_PW']) {
-  header('WWW-Authenticate: Basic realm="PhpShell 2.0"');
-  header('HTTP/1.0 401 Unauthorized');
-  $authenticated = false;
-} else {
-  $authenticated = true;
+  <address>
+  Copyright &copy; 2000&ndash;2005, <a
+  href="mailto:[EMAIL PROTECTED]">Martin Geisler</a>. Get the latest
+  version at <a
+  href="http://mgeisler.net/php-shell/";>mgeisler.net/php-shell/</a>.
+  </address>
 
-  /* We now start the session. */
-  session_start();
-  
-  /* Initialize the session variables. */
-  if (empty($_SESSION['cwd']) || !empty($_REQUEST['reset'])) {
-    $_SESSION['cwd'] = getcwd();
-    $_SESSION['history'] = array();
-    $_SESSION['output'] = '';
-  }
-  
-  if (!empty($_REQUEST['command'])) {
-    if (get_magic_quotes_gpc()) {
-      /* We don't want to add the commands to the history in the
-       * escaped form, so we remove the backslashes now. */
-      $_REQUEST['command'] = stripslashes($_REQUEST['command']);
+</body>
+</html>');
     }
+}
 
-    /* Save the command for late use in the JavaScript.  If the
-     * command is already in the history, then the old entry is
-     * removed before the new entry is put into the list at the
-     * front. */
-    if (($i = array_search($_REQUEST['command'], $_SESSION['history'])) !== 
false)
-      unset($_SESSION['history'][$i]);
-    
-    array_unshift($_SESSION['history'], $_REQUEST['command']);
+/* Installing our error handler makes PHP die on even the slightest problem.
+ * This is what we want in a security critical application like this. */
+set_error_handler('error_handler');
+
+
+function logout() {
+    /* Empty the session data, except for the 'authenticated' entry which the
+     * rest of the code needs to be able to check. */
+    $_SESSION = array('authenticated' => false);
+
+    /* Unset the client's cookie, if it has one. */
+//    if (isset($_COOKIE[session_name()]))
+//        setcookie(session_name(), '', time()-42000, '/');
+
+    /* Destroy the session data on the server.  This prevents the simple
+     * replay attach where one uses the back button to re-authenticate using
+     * the old POST data since the server wont know the session then.*/
+//    session_destroy();
+}
+
+
+function stripslashes_deep($value) {
+    if (is_array($value))
+        return array_map('stripslashes_deep', $value);
+    else
+        return stripslashes($value);
+}
+
+if (get_magic_quotes_gpc())
+    $_POST = stripslashes_deep($_POST);
+
+/* Initialize some variables we need again and again. */
+$username = isset($_POST['username']) ? $_POST['username'] : '';
+$password = isset($_POST['password']) ? $_POST['password'] : '';
+$nounce   = isset($_POST['nounce'])   ? $_POST['nounce']   : '';
+
+$command  = isset($_POST['command'])  ? $_POST['command']  : '';
+$rows     = isset($_POST['rows'])     ? $_POST['rows']     : 24;
+$columns  = isset($_POST['columns'])  ? $_POST['columns']  : 80;
+
+
+/* Load the configuration. */
+$ini = parse_ini_file('config.php', true);
+
+if (empty($ini['settings']))
+    $ini['settings'] = array();
+
+/* Default settings --- these settings should always be set to something. */
+$default_settings = array('home-directory'   => '.');
+
+/* Merge settings. */
+$ini['settings'] = array_merge($default_settings, $ini['settings']);
+
+
+session_start();
+
+/* Delete the session data if the user requested a logout.  This leaves the
+ * session cookie at the user, but this is not important since we
+ * authenticates on $_SESSION['authenticated']. */
+if (isset($_POST['logout']))
+    logout();
+
+/* Attempt authentication. */
+if (isset($_SESSION['nounce']) && $nounce == $_SESSION['nounce'] && 
+    isset($ini['users'][$username])) {
+    if (strchr($ini['users'][$username], ':') === false) {
+        // No seperator found, assume this is a password in clear text.
+        $_SESSION['authenticated'] = ($ini['users'][$username] == $password);
+    } else {
+        list($fkt, $salt, $hash) = explode(':', $ini['users'][$username]);
+        $_SESSION['authenticated'] = ($fkt($salt . $password) == $hash);
+    }
+}
+
+
+/* Enforce default non-authenticated state if the above code didn't set it
+ * already. */
+if (!isset($_SESSION['authenticated']))
+    $_SESSION['authenticated'] = false;
+
+
+if ($_SESSION['authenticated']) {  
+    /* Initialize the session variables. */
+    if (empty($_SESSION['cwd'])) {
+        $_SESSION['cwd'] = realpath($ini['settings']['home-directory']);
+        $_SESSION['history'] = array();
+        $_SESSION['output'] = '';
+    }
   
-    /* Now append the commmand to the output. */
-    $_SESSION['output'] .= '$ ' . $_REQUEST['command'] . "\n";
+    if (!empty($command)) {
+        /* Save the command for late use in the JavaScript.  If the command is
+         * already in the history, then the old entry is removed before the
+         * new entry is put into the list at the front. */
+        if (($i = array_search($command, $_SESSION['history'])) !== false)
+            unset($_SESSION['history'][$i]);
+        
+        array_unshift($_SESSION['history'], $command);
+  
+        /* Now append the commmand to the output. */
+        $_SESSION['output'] .= '$ ' . $command . "\n";
 
-    /* Initialize the current working directory. */
-    if (ereg('^[[:blank:]]*cd[[:blank:]]*$', $_REQUEST['command'])) {
-      $_SESSION['cwd'] = dirname(__FILE__);
-    } elseif (ereg('^[[:blank:]]*cd[[:blank:]]+([^;]+)$', 
$_REQUEST['command'], $regs)) {
-      /* The current command is a 'cd' command which we have to handle
-       * as an internal shell command. */
+        /* Initialize the current working directory. */
+        if (ereg('^[[:blank:]]*cd[[:blank:]]*$', $command)) {
+            $_SESSION['cwd'] = realpath($ini['settings']['home-directory']);
+        } elseif (ereg('^[[:blank:]]*cd[[:blank:]]+([^;]+)$', $command, 
$regs)) {
+            /* The current command is a 'cd' command which we have to handle
+             * as an internal shell command. */
 
-      if ($regs[1][0] == '/') {
-        /* Absolute path, we use it unchanged. */
-        $new_dir = $regs[1];
-      } else {
-        /* Relative path, we append it to the current working
-         * directory. */
-        $new_dir = $_SESSION['cwd'] . '/' . $regs[1];
-      }
+            if ($regs[1]{0} == '/') {
+                /* Absolute path, we use it unchanged. */
+                $new_dir = $regs[1];
+            } else {
+                /* Relative path, we append it to the current working
+                 * directory. */
+                $new_dir = $_SESSION['cwd'] . '/' . $regs[1];
+            }
       
-      /* Transform '/./' into '/' */
-      while (strpos($new_dir, '/./') !== false)
-        $new_dir = str_replace('/./', '/', $new_dir);
+            /* Transform '/./' into '/' */
+            while (strpos($new_dir, '/./') !== false)
+                $new_dir = str_replace('/./', '/', $new_dir);
 
-      /* Transform '//' into '/' */
-      while (strpos($new_dir, '//') !== false)
-        $new_dir = str_replace('//', '/', $new_dir);
+            /* Transform '//' into '/' */
+            while (strpos($new_dir, '//') !== false)
+                $new_dir = str_replace('//', '/', $new_dir);
 
-      /* Transform 'x/..' into '' */
-      while (preg_match('|/\.\.(?!\.)|', $new_dir))
-        $new_dir = preg_replace('|/?[^/]+/\.\.(?!\.)|', '', $new_dir);
+            /* Transform 'x/..' into '' */
+            while (preg_match('|/\.\.(?!\.)|', $new_dir))
+                $new_dir = preg_replace('|/?[^/]+/\.\.(?!\.)|', '', $new_dir);
       
-      if ($new_dir == '') $new_dir = '/';
+            if ($new_dir == '') $new_dir = '/';
       
-      /* Try to change directory. */
-      if (@chdir($new_dir)) {
-        $_SESSION['cwd'] = $new_dir;
-      } else {
-        $_SESSION['output'] .= "cd: could not change to: $new_dir\n";
-      }
+            /* Try to change directory. */
+            if (@chdir($new_dir)) {
+                $_SESSION['cwd'] = $new_dir;
+            } else {
+                $_SESSION['output'] .= "cd: could not change to: $new_dir\n";
+            }
       
-    } else {
-      /* The command is not a 'cd' command, so we execute it after
-       * changing the directory and save the output. */
-      chdir($_SESSION['cwd']);
+        } elseif (trim($command) == 'exit') {
+            logout();
+        } else {
 
-      /* Alias expansion. */
-      $length = strcspn($_REQUEST['command'], " \t");
-      $token = substr($_REQUEST['command'], 0, $length);
-      if (isset($aliases[$token]))
-        $_REQUEST['command'] = $aliases[$token] . substr($_REQUEST['command'], 
$length);
+            /* The command is not an internal command, so we execute it after
+             * changing the directory and save the output. */
+            chdir($_SESSION['cwd']);
+
+            // We canot use putenv() in safe mode.
+            if (!ini_get('safe_mode')) {
+                // Advice programs (ls for example) of the terminal size.
+                putenv('ROWS=' . $rows);
+                putenv('COLUMNS=' . $columns);
+            }
+
+            /* Alias expansion. */
+            $length = strcspn($command, " \t");
+            $token = substr($command, 0, $length);
+            if (isset($ini['aliases'][$token]))
+                $command = $ini['aliases'][$token] . substr($command, $length);
     
-      $p = proc_open($_REQUEST['command'],
-                     array(1 => array('pipe', 'w'),
-                           2 => array('pipe', 'w')),
-                     $io);
+            $io = array();
+            $p = proc_open($command,
+                           array(1 => array('pipe', 'w'),
+                                 2 => array('pipe', 'w')),
+                           $io);
 
-      /* Read output sent to stdout. */
-      while (!feof($io[1])) {
-        $_SESSION['output'] .= htmlspecialchars(fgets($io[1]),
-                                                ENT_COMPAT, 'UTF-8');
-      }
-      /* Read output sent to stderr. */
-      while (!feof($io[2])) {
-        $_SESSION['output'] .= htmlspecialchars(fgets($io[2]),
-                                                ENT_COMPAT, 'UTF-8');
-      }
-      
-      fclose($io[1]);
-      fclose($io[2]);
-      proc_close($p);
+            /* Read output sent to stdout. */
+            while (!feof($io[1])) {
+                $_SESSION['output'] .= htmlspecialchars(fgets($io[1]),
+                                                        ENT_COMPAT, 'UTF-8');
+            }
+            /* Read output sent to stderr. */
+            while (!feof($io[2])) {
+                $_SESSION['output'] .= htmlspecialchars(fgets($io[2]),
+                                                        ENT_COMPAT, 'UTF-8');
+            }
+            
+            fclose($io[1]);
+            fclose($io[2]);
+            proc_close($p);
+        }
     }
-  }
 
-  /* Build the command history for use in the JavaScript */
-  if (empty($_SESSION['history'])) {
-    $js_command_hist = '""';
-  } else {
-    $escaped = array_map('addslashes', $_SESSION['history']);
-    $js_command_hist = '"", "' . implode('", "', $escaped) . '"';
-  }
+    /* Build the command history for use in the JavaScript */
+    if (empty($_SESSION['history'])) {
+        $js_command_hist = '""';
+    } else {
+        $escaped = array_map('addslashes', $_SESSION['history']);
+        $js_command_hist = '"", "' . implode('", "', $escaped) . '"';
+    }
 }
 
-header('Content-Type: text/html; charset=UTF-8');
-/* Since most installations still operate with short_open_tag enabled,
- * we have to echo this string from within PHP: */
-echo '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
 ?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd";>
-<html xmlns="http://www.w3.org/1999/xhtml"; xml:lang="en" lang="en">
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+   "http://www.w3.org/TR/html4/strict.dtd";>
+<html>
 <head>
-  <title>PhpShell 2.0</title>
-  <link rel="stylesheet" href="phpshell.css" type="text/css" />
+  <title>PHP Shell 2.1</title>
+  <link rel="stylesheet" href="style.css" type="text/css">
+
+  <script type="text/javascript">
+  <?php if ($_SESSION['authenticated']) { ?>
 
-  <script type="text/javascript" language="JavaScript">
   var current_line = 0;
   var command_hist = new Array(<?php echo $js_command_hist ?>);
   var last = 0;
@@ -202,86 +297,112 @@
 
   }
 
-function init() {
-  document.shell.setAttribute("autocomplete", "off");
-  document.shell.output.scrollTop = document.shell.output.scrollHeight;
-  document.shell.command.focus();
-}
+  function init() {
+    document.shell.setAttribute("autocomplete", "off");
+    document.shell.output.scrollTop = document.shell.output.scrollHeight;
+    document.shell.command.focus();
+  }
+
+  <?php } else { ?>
 
+  function init() {
+    document.shell.username.focus();
+  }
+
+  <?php } ?>
   </script>
 </head>
 
 <body onload="init()">
 
-<h1>PhpShell 2.0</h1>
+<h1>PHP Shell 2.1</h1>
 
-<?php if (!$authenticated) { ?>
-<p>You failed to authenticate yourself to PhpShell. You can <a
-href="<?php echo $_SERVER['PHP_SELF'] ?>">reload</a> to try again.</p>
+<form name="shell" action="<?php echo $_SERVER['PHP_SELF'] ?>" method="post">
 
-<p>Try reading the <a href="INSTALL">INSTALL</a> file if you're having
-problems with installing PhpShell.</p>
+<?php
+if (!$_SESSION['authenticated']) {
+    /* Genereate a new nounce every time we preent the login page.  This binds
+     * each login to a unique hit on the server and prevents the simple replay
+     * attack where one uses the back button in the browser to replay the POST
+     * data from a login. */
+    $_SESSION['nounce'] = mt_rand();
 
-</body>
-</html>
+?>
 
-<?php // ' <-- fix syntax highlight in Emacs
-  exit;
-}
+<fieldset>
+  <legend>Authentication</legend>
 
-error_reporting (E_ALL);
+  <?php
+  if (!empty($username))
+      echo '  <p class="error">Login failed, please try again:</p>' . "\n";
+  else
+      echo "  <p>Please login:</p>\n";
+  ?>
 
-if (empty($_REQUEST['rows'])) $_REQUEST['rows'] = 24;
+  <p>Username: <input name="username" type="text" value="<?php echo $username
+  ?>"></p>
 
-?>
+  <p>Password: <input name="password" type="password"></p>
 
-<p>Current Working Directory: <code><?php echo $_SESSION['cwd'] ?></code></p>
+  <p><input type="submit" value="Login"></p>
 
-<form name="shell" action="<?php echo $_SERVER['PHP_SELF'] ?>" method="post">
-<div>
-<textarea name="output" readonly="readonly" cols="80" rows="<?php echo 
$_REQUEST['rows'] ?>">
+  <input name="nounce" type="hidden" value="<?php echo $_SESSION['nounce']; 
?>">
+
+</fieldset>
+
+<?php } else { /* Authenticated. */ ?>
+
+<fieldset>
+  <legend>Current Working Directory: <code><?php
+     echo  htmlspecialchars($_SESSION['cwd'], ENT_COMPAT, 'UTF-8');
+    ?></code></legend>
+
+
+<div id="terminal">
+<textarea name="output" readonly="readonly" cols="<?php echo $columns ?>" 
rows="<?php echo $rows ?>">
 <?php
 $lines = substr_count($_SESSION['output'], "\n");
-$padding = str_repeat("\n", max(0, $_REQUEST['rows']+1 - $lines));
+$padding = str_repeat("\n", max(0, $rows+1 - $lines));
 echo rtrim($padding . $_SESSION['output']);
 ?>
 </textarea>
-<p class="prompt">
-  $&nbsp;<input class="prompt" name="command" type="text"
-                onkeyup="key(event)" size="78" tabindex="1">
+<p id="prompt">
+  $&nbsp;<input name="command" type="text"
+                onkeyup="key(event)" size="<?php echo $columns-2 ?>" 
tabindex="1">
 </p>
 </div>
+
 <p>
-  <input type="submit" value="Execute Command" />
-  <input type="submit" name="reset" value="Reset" />
-  Rows: <input type="text" name="rows" value="<?php echo $_REQUEST['rows'] ?>" 
/>
+  <span style="float: right">Size: <input type="text" name="rows" size="2"
+  maxlength="3" value="<?php echo $rows ?>"> &times; <input type="text"
+  name="columns" size="2" maxlength="3" value="<?php echo $columns
+  ?>"></span>
+  
+<input type="submit" value="Execute Command">
+  <input type="submit" name="logout" value="Logout">
 </p>
+
+</fieldset>
+
+<?php } ?>
+
 </form>
 
-<hr />
 
-<p>Please consult the <a href="README">README</a> and <a
-href="INSTALL">INSTALL</a> files for instruction on how to use
-PhpShell.</p>
+<hr>
 
-<hr />
+<p>Please consult the <a href="README">README</a>, <a
+href="INSTALL">INSTALL</a>, and <a href="SECURITY">SECURITY</a> files for
+instruction on how to use PHP Shell.</p>
+
+<hr>
 
 <address>
-Copyright &copy; 2000&ndash;2004, <a
-href="mailto:[EMAIL PROTECTED]">Martin Geisler</a>. Get the
+Copyright &copy; 2000&ndash;2005, <a
+href="mailto:[EMAIL PROTECTED]">Martin Geisler</a>. Get the
 latest version at <a
-href="http://www.gimpster.com/wiki/PhpShell";>www.gimpster.com/wiki/PhpShell</a>.
+href="http://mgeisler.net/php-shell/";>mgeisler.net/php-shell/</a>.
 </address>
 
-<p>
-  <a href="http://validator.w3.org/check/referer";>
-    <img src="valid-xhtml10.png" alt="Valid XHTML 1.0 Strict!"
-         height="31" width="88" />
-  </a>
-  <a href="http://jigsaw.w3.org/css-validator/check/referer";>
-    <img src="vcss.png" alt="Valid CSS!" width="88" height="31" />
-  </a>
-</p>
-
 </body>
 </html>

--- NEW FILE: SECURITY ---
SECURITY file for PHP Shell 2.1
Copyright (C) 2005 Martin Geisler <[EMAIL PROTECTED]>
Licensed under the GNU GPL.  See the file COPYING for details.


PHP Security
============

Installing PHP on your server is an inheriently dangerous thing to do,
somewhat similar to the danger one faces when one buys a car: it might kill
you if you have an accident.  On the other hand a car makes so many things so
much more convenient, so most people are willing to accept the risk of
accidents.

Likewise, PHP is a powerful tool which will let you build your webpages easier
and faster than without.  But it is a *very* powerful tool --- PHP is a full
programming language which can be used for general purpose programming and not
just to format HTML for display in a browser.

So PHP has support for reading and writing files on the filesystem.  But PHP
also has support for *deleting* files.  PHP even has support for executing
other programs.  In other words, PHP has lots of support for interacting with
the rest of the computer it runs on.  This interaction is potentially much
more powerful than you want it to, and this can be a problem if this power
ends up in the wrong hands.


What about Safe Mode?
---------------------

As they note in the PHP manual, Safe Mode is an inherently wrong way to secure
PHP, but is nevertheless used in many installations.  Turning Safe Mode on in
PHP basically tries to restrict the language and its functions to make it
"safe".

This involves a strict check on file ownership so that PHP wont operate on
files and directories which are not owned by the owner of the current script.
Other restrictions in Safe Mode include limits on which files can be executed
and includes (thus making a primitive form of chroot or jail around the PHP
script).

PHP Shell is made mostly useless with Safe Mode since it restricts the two
commands that PHP Shell uses: ``chdir()`` and ``proc_open()``:

* With Safe Mode you cannot change to a directory unless you are the owner of
  that directory.  This means that you cannot change to, say, ``/etc`` since
  ``root`` own that directory.

  You'll see this when 'cd /etc' results in this error from PHP Shell:

    chdir(): SAFE MODE Restriction in effect.  The script whose uid is 500 is
    not allowed to access /etc owned by uid 0
    cd: could not change to: /etc

* When Safe Mode is active, PHP forces the argument to ``proc_open()`` to be
  escaped, which means that you cannot use normal shell wildcards, pipes or
  any such stuff.

  So if you enter 'ls *.txt' in a directory where you know for certain that
  there is a text file ending in '.txt', you will get the following error:

    /bin/ls: *.txt: No such file or directory

  This is because PHP has silently changed the command into 'ls \*.txt' to
  disable the wildcard.

* You cannot execute programs unless they are placed in a directory listed in
  ``safe_mode_exec_dir``.  Say you want to execute the program ``tr`` (which
  translates between sets of characters) and you get this strange messages
  back:

    sh: line 1: /bin/tr: No such file or directory

  Then you have a problem with the ``safe_mode_exec_dir`` setting.  In this
  case ``safe_mode_exec_dir`` is set to just ``/bin`` and so PHP has forced
  the shell to execute ``/bin/tr`` and since ``tr`` is installed in
  ``/usr/bin`` it could not be found.

  If you have write access to a directory listed in ``safe_mode_exec_dir``,
  then try copying the wanted program there first.  Executing it should now
  work.


Even without enabling Safe Mode some functions might have been disabled via
the ``disabled_functions`` setting.  If the ``proc_open()`` function used by
PHP Shell has been disabled, then you will see an error like this:

    Fatal Error!

    proc_open() has been disabled for security reasons

    in /path/to/your/installation/phpshell.php, line 221.



PHP Shell Security
==================

As noted above, PHP is a powerful tool --- how does PHP Shell fit into this?
PHP Shell is actually quite simple and does one thing: it uses the standard
PHP function ``proc_open()`` to execute programs.

Executing other programs is probably the most powerful thing you can do in
PHP, and so PHP Shell gives you a convenient interface to this the most
powerful feature of PHP.  Nothing more.


Is PHP Shell Dangerous?
-----------------------

Short answer: *yes*!  PHP Shell has been used in the past by people with
not-so-good intentions to destroy valuable content on servers.

The longer answer is that installing PHP Shell is like building a new door in
your house --- if you leave it unlocked, then people can (and probably will!)
walk into it and steal your posessions.  So you want to lock it, and make sure
you use a good lock.

With PHP Shell that is equivalent of using a secure password.  A secure
password is one which is hard to guess (make it long, make it random, and put
both numbers, special characters and normal letters in it).

  Remember that guessing the password is all that stands between the crackers
  and your files!

If you use a good password, then PHP Shell does not make your system any more
unsecure than it already was.  Security is always a matter of finding the
weakest link in the chain: if you use FTP with a simple password for updating
your site, then it would be much easier for the crackers to attack that
instead of trying to guess your super-hard PHP Shell password.  So make sure
that you tighten security on all fronts you know of.


If you have suggestions for improvements to this little guide in system
security, then please do not hesitate to contact <[EMAIL PROTECTED]>.

--- release.sh DELETED ---

--- valid-xhtml10.png DELETED ---



-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems?  Stop!  Download the new AJAX search engine that makes
searching your log files as easy as surfing the  web.  DOWNLOAD SPLUNK!
http://ads.osdn.com/?ad_id=7637&alloc_id=16865&op=click
_______________________________________________
phpshell-commits mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/phpshell-commits

Reply via email to