Commiting Kastalia
authorAndre Pawlowski <sqall@h4des.org>
Thu, 11 Jun 2009 17:59:38 +0000 (19:59 +0200)
committerAndre Pawlowski <sqall@h4des.org>
Thu, 11 Jun 2009 17:59:38 +0000 (19:59 +0200)
a secure filesharing application for Horde 3

39 files changed:
kastalia/COPYING [new file with mode: 0644]
kastalia/LICENSE.ASL [new file with mode: 0644]
kastalia/LICENSE.BSDL [new file with mode: 0755]
kastalia/README [new file with mode: 0644]
kastalia/config/.htaccess [new file with mode: 0644]
kastalia/config/conf.php [new file with mode: 0644]
kastalia/config/conf.xml [new file with mode: 0755]
kastalia/datastore/.htaccess [new file with mode: 0644]
kastalia/decrypt_menu.php [new file with mode: 0644]
kastalia/docs/CHANGES [new file with mode: 0644]
kastalia/docs/CREDITS [new file with mode: 0644]
kastalia/docs/INSTALL [new file with mode: 0644]
kastalia/docs/RELEASE_NOTES [new file with mode: 0755]
kastalia/docs/TODO [new file with mode: 0644]
kastalia/download.php [new file with mode: 0755]
kastalia/encrypt_decrypt_files.php [new file with mode: 0644]
kastalia/index.php [new file with mode: 0755]
kastalia/lib/Block/tree_menu.php [new file with mode: 0644]
kastalia/lib/Kastalia.php [new file with mode: 0755]
kastalia/lib/base.php [new file with mode: 0755]
kastalia/lib/version.php [new file with mode: 0755]
kastalia/list.php [new file with mode: 0755]
kastalia/locale/en_US/help.xml [new file with mode: 0755]
kastalia/main.php [new file with mode: 0755]
kastalia/po/README [new file with mode: 0644]
kastalia/temp/.htaccess [new file with mode: 0644]
kastalia/templates/common-footer.inc [new file with mode: 0644]
kastalia/templates/common-header.inc [new file with mode: 0755]
kastalia/templates/menu.inc [new file with mode: 0755]
kastalia/themes/graphics/directory_closed.gif [new file with mode: 0755]
kastalia/themes/graphics/directory_open.gif [new file with mode: 0644]
kastalia/themes/graphics/file.gif [new file with mode: 0644]
kastalia/themes/graphics/file_enc.gif [new file with mode: 0644]
kastalia/themes/graphics/kastalia.png [new file with mode: 0755]
kastalia/themes/graphics/loader.gif [new file with mode: 0644]
kastalia/themes/graphics/menu/upload.png [new file with mode: 0644]
kastalia/themes/screen.css [new file with mode: 0755]
kastalia/upload.php [new file with mode: 0644]
kastalia/upload_menu.php [new file with mode: 0644]

diff --git a/kastalia/COPYING b/kastalia/COPYING
new file mode 100644 (file)
index 0000000..5a965fb
--- /dev/null
@@ -0,0 +1,280 @@
+                   GNU GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+\f
+                   GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+\f
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+\f
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+\f
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                           NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
diff --git a/kastalia/LICENSE.ASL b/kastalia/LICENSE.ASL
new file mode 100644 (file)
index 0000000..e0b7a13
--- /dev/null
@@ -0,0 +1,48 @@
+Version 1.0
+
+Copyright (c) 2006 The Horde Project. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+
+3. The end-user documentation included with the redistribution, if
+any, must include the following acknowledgment:
+
+   "This product includes software developed by the Horde Project
+    (http://www.horde.org/)."
+
+Alternately, this acknowledgment may appear in the software itself, if
+and wherever such third-party acknowledgments normally appear.
+
+4. The names "Horde", "The Horde Project", and "Skeleton" must not be
+used to endorse or promote products derived from this software without
+prior written permission. For written permission, please contact
+core@horde.org.
+
+5. Products derived from this software may not be called "Horde" or
+"Skeleton", nor may "Horde" or "Skeleton" appear in their name, without
+prior written permission of the Horde Project.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE HORDE PROJECT OR ITS CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+This software consists of voluntary contributions made by many
+individuals on behalf of the Horde Project. For more information on
+the Horde Project, please see <http://www.horde.org/>.
diff --git a/kastalia/LICENSE.BSDL b/kastalia/LICENSE.BSDL
new file mode 100755 (executable)
index 0000000..e2b4fbf
--- /dev/null
@@ -0,0 +1,24 @@
+Copyright (c) 2006 The Horde Project.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HORDE PROJECT
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/kastalia/README b/kastalia/README
new file mode 100644 (file)
index 0000000..fa02ccf
--- /dev/null
@@ -0,0 +1,59 @@
+What is Kastalia?
+=================
+
+:Last update:   $Date: 2008-09-16 10:02:53 $
+:Revision:      $Revision: 1.0 $
+
+.. contents:: Contents
+.. section-numbering::
+
+Kastalia is a Horde Framework application for secure file sharing. Every uploaded 
+file can be encrypted by Kastalia and stored secure in the datastore. The user 
+does not need any additional program for the encryption/decryption.
+
+Obtaining Kastalia
+------------------
+
+Further information on Kastalia and the latest version can be obtained at
+
+  http://h4des.org/index.php?inhalt=kastalia
+
+
+Documentation
+-------------
+
+The following documentation is available in the Kastalia distribution:
+
+:README_:            This file
+:COPYING_:           Copyright and license information
+:LICENSE_:           Copyright and license information
+:`docs/CHANGES`_:    Changes by release
+:`docs/CREDITS`_:    Project developers
+:`docs/INSTALL`_:    Installation instructions and notes
+:`docs/TODO`_:       Development TODO list
+:`docs/UPGRADING`_:  Pointers on upgrading from previous Kastalia versions
+
+
+Installation
+------------
+
+Instructions for installing Kastalia can be found in the file INSTALL_ in the
+``docs/`` directory of the Kastalia distribution.
+
+
+Assistance
+----------
+
+If you encounter problems with Kastalia, help is available! Please contact the 
+author of Kastalia.
+
+
+Licensing
+---------
+
+For licensing and copyright information, please see the file COPYING_/LICENSE_
+in the Kastalia distribution.
+
+Thanks,
+
+the Kastalia team
\ No newline at end of file
diff --git a/kastalia/config/.htaccess b/kastalia/config/.htaccess
new file mode 100644 (file)
index 0000000..3a42882
--- /dev/null
@@ -0,0 +1 @@
+Deny from all
diff --git a/kastalia/config/conf.php b/kastalia/config/conf.php
new file mode 100644 (file)
index 0000000..8828037
--- /dev/null
@@ -0,0 +1,13 @@
+<?php
+/* CONFIG START. DO NOT CHANGE ANYTHING IN OR AFTER THIS LINE. */
+// $Horde: kastalia/config/conf.xml,v 1.0 2008/09/16 09:43:44 sqall Exp $
+$conf['datastore']['location'] = '/home/sqall/projekte/www/horde/kastalia/datastore';
+$conf['datastore']['directoryexcludes'] = array('lost+found', 'testordner', 'testordner2');
+$conf['upload']['uploadenabled'] = true;
+$conf['upload']['maxfilesize'] = 134217728;
+$conf['upload']['tempdir'] = '/home/sqall/projekte/www/horde/kastalia/temp';
+$conf['upload']['tempctime'] = 10;
+$conf['upload']['securestore'] = true;
+$conf['upload']['memorysize'] = 3145728;
+$conf['upload']['refreshcycle'] = 1;
+/* CONFIG END. DO NOT CHANGE ANYTHING IN OR BEFORE THIS LINE. */
\ No newline at end of file
diff --git a/kastalia/config/conf.xml b/kastalia/config/conf.xml
new file mode 100755 (executable)
index 0000000..a0a8436
--- /dev/null
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+<!-- $Horde: kastalia/config/conf.xml,v 1.0 2008/09/16 09:43:44 sqall Exp $ -->
+<configuration>
+ <configsection name="datastore">
+  <configheader>Kastalia Datastore Settings</configheader>
+  <configstring name="location" desc="The absolute path to the Kastalia Datastore. Default is the directory kastalia/datastore. You can also use a directory outside of the webroot with read-permission for the webserver.">
+  /absolute/path/to/horde/kastalia/datastore
+  </configstring>
+  <configlist name="directoryexcludes" desc="Directories and their content which should not be shown on the download page (lost+found, secretdir, etc.). &lt;strong&gt;WARNING:&lt;/strong&gt; the directories and their content are just hidden on the download page. The Content can still be downloaded by manually modifying the URL." required="false">
+  lost+found
+  </configlist>
+ </configsection>
+ <configsection name="upload">
+  <configheader>Kastalia Upload Settings</configheader>
+  <configboolean name="uploadenabled" desc="Should we enable uploads?">
+  false
+  </configboolean>
+  <configinteger name="maxfilesize" desc="The maximum size (in bytes) of each file that users can upload. &lt;strong&gt;NOTICE:&lt;/strong&gt; the values upload_max_filesize and post_max_size in php.ini have to be greater than or equal to this value.">
+  0
+  </configinteger>
+  <configstring name="tempdir" desc="The absolute path to the Kastalia temporary folder. Default is the directory kastalia/temp. You can also use a directory outside of the webroot with write-permission for the webserver. This temporary folder will be used for the encryption/decryption of uploaded files.">
+         /absolute/path/to/horde/kastalia/temp
+  </configstring>
+  <configinteger name="tempctime" desc="How long (in minutes) should Kastalia keep a temporary file? Normally a temporary file will be deleted after its use. Because of connection termination or user error during the encryption/decryption an unencrypted temporary file might be stored in the temporary directory. &lt;strong&gt;WARNING:&lt;/strong&gt; a short time can delete a temporary file during the encryption/decryption and will lead to errors. A too long time will delete an unencrypted file late and can lead to a breach of security.">
+  10
+  </configinteger>
+  <configboolean name="securestore" desc="Should we enable Kastalia to store files encrypted? &lt;strong&gt;WARNING:&lt;/strong&gt; This can cause high CPU load by the webserver.">
+         false
+  </configboolean>
+  <configinteger name="memorysize" desc="The memory size which can be used for the encryption/decryption. This value cannot be greater than the memory_limit value in php.ini. If the value is set too large, you will get a php error message. &lt;strong&gt;WARNING:&lt;/strong&gt; This value is important for the encryption/decryption. If you change this value and you already have files encrypted by Kastalia, these files can only be decrypted with the old memory size value.">
+  0
+  </configinteger>
+  <configinteger name="refreshcycle" desc="The refresh cycle of the browser in seconds during the encryption/decryption. A large value increase the waiting till the encryption/decryption will be done. A small value (and a higher number of users) can lead to many requests to the webserver and slow it down.">
+  1
+  </configinteger>
+ </configsection>
+</configuration>
diff --git a/kastalia/datastore/.htaccess b/kastalia/datastore/.htaccess
new file mode 100644 (file)
index 0000000..3a42882
--- /dev/null
@@ -0,0 +1 @@
+Deny from all
diff --git a/kastalia/decrypt_menu.php b/kastalia/decrypt_menu.php
new file mode 100644 (file)
index 0000000..ce35e03
--- /dev/null
@@ -0,0 +1,104 @@
+<?php
+/**
+ *
+ * This product includes software developed by the Horde Project (http://www.horde.org/).
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author  Andre Pawlowski aka sqall <sqall@h4des.org>
+ */
+
+//das absolute Kastalia directory wird als Konstante definiert
+//um damit config Dateien zu includieren
+@define('KASTALIA_BASE', dirname(__FILE__));  
+
+//die Basis von Kastalia wird includiert
+//um die Anmeldung zu ueberpruefen
+require_once(KASTALIA_BASE . '/lib/base.php');
+//die Konfigurationsdatei von Kastalia wird includiert
+//um alle Kastalia Einstellungen in diesem Skript nutzen zu koennen
+require(KASTALIA_BASE . '/config/conf.php');
+//das Menu von Kastalia wird includiert
+//damit das Menu dem Benutzer angezeigt wird
+require_once(KASTALIA_BASE . '/list.php');
+
+echo "<div class=\"header\">Kastalia Datastore - Decryption Password</div>\n";
+echo "<p><b>notice:</b> cookies and javascripts must be enabled to download files!</p>\n";
+
+//nun wird ueberprueft, ob das verschluesseln/entschluesseln von Dateien aktiviert wurde
+//falls nicht, wird eine Meldung ausgegeben und das Skript beendet
+if(!$conf['upload']['securestore']) {
+    echo "Encryption/Decryption is disabled!";
+    exit(0);
+}
+
+//hier wird ueberprueft, ob die zu herunterladende Datei ueberhaupt
+//uebergeben wurde, damit Manipulation verhindert wird und um Fehler zu vermeiden
+if(isset($_GET['kastalia_filename'])) {
+    //hier wird ueber GET der Dateiname ermittelt
+    $kastalia_filename = $_GET['kastalia_filename'];
+    //hier wird ueberprueft, ob es sich bei der zu herunterladenden Datei um eine ".htaccess" Datei
+    //handelt. Dabei werden allerdings auch Dateien herausgefiltert, die die Endung ".htaccess" haben.
+    if(substr($kastalia_filename, -9) == ".htaccess") {
+        echo "Error: Downloading .htaccess files out of the datastore not allowed!";
+        exit(1);
+    }
+    //Ueberpruefung nach den Zeichenfolgen "/." und "./" damit
+    //durch das Manipulieren der Variable kastalia_filename
+    //keiner aus dem kastalia Datastore entkommen kann (durch Nutzung von "../")
+    if(strpos($kastalia_filename,'/.') === false && strpos($kastalia_filename,'./') === false) {
+        //hier wird ueberprueft, ob die zu entschluesselnde Datei existiert oder lesbar ist
+        if(!is_readable($conf['datastore']['location'] . "/" . $kastalia_filename)) {
+            echo "Error: File $kastalia_filename doesn't exist or is not readable!";
+            exit(1);
+        }
+        //hier wird ueberprueft ob es sich bei dem Download um eine von Kastalia verschluesselte Datei handelt (Endung ".kastaliaenc")
+        //falls es sich nicht um die von Kastalia verwendete Endung handelt, wird ein Fehler ausgegeben
+        if(substr($kastalia_filename, -12) != ".kastaliaenc") {
+           echo "Error: File doesn't have the Kastalia file extension!";
+           exit(1);
+        }
+    }
+    else {
+        echo "Error: \$kastalia_filename in decrypt_menu.php contains illegal characters!";
+        exit(1);
+    }
+}
+else {
+    echo "Error: \$kastalia_filename in decrypt_menu.php is not set!"; 
+    exit(1);
+}
+?>
+
+<!-- hier werden die JavaScripte zum erzeugen des sha-1 hashes includiert //-->
+<script src="js/sha1.js" type="text/javascript" language="JavaScript"></script>
+
+<script type="text/javascript" language="JavaScript">
+<!--
+//diese function ueberprueft die Werte des Formulars
+function FormularCheck() {
+    //hier wird ueberprueft ob das Passworteingabefeld leer nicht ist
+    if(document.forms['decryptpassword'].elements['kastalia_password'].value != "") {
+        //das eingegebene Passwort wird vor dem abschicken durch den sha-1 hash vom Passwort ersetzt
+        //damit das Passwort nie im Klartext uebertragen wird, sondern nur der sha-1 hash zum ver/entschluesseln benutzt wird
+        document.forms['decryptpassword'].elements['kastalia_password'].value = hex_sha1(document.forms['decryptpassword'].elements['kastalia_password'].value);
+        return true;
+    }
+    else {
+        alert('Error: Empty passwords not allowed!');
+        return false;
+    }
+}
+//-->
+</script>
+
+<form name="decryptpassword" method="post" action="download.php?kastalia_filename=<?php echo $kastalia_filename;?>" onsubmit="return FormularCheck()">
+<input name="kastalia_password" type="password" />
+<input type="submit" value="send" />
+</form>
+
+<?php
+//der footer wird includiert
+require KASTALIA_TEMPLATES . '/common-footer.inc';
+?>
\ No newline at end of file
diff --git a/kastalia/docs/CHANGES b/kastalia/docs/CHANGES
new file mode 100644 (file)
index 0000000..fe2b861
--- /dev/null
@@ -0,0 +1,37 @@
+---
+v1.0.1
+---
+
+[sqall] Fixed a problem with the filesize on the download page.
+[sqall] Alphabetic sorted file list.
+[sqall] Added fake upload loading bar.
+[sqall] w3c conformable HTML output.
+[sqall] JavaScript upload bug with IE 6 solved.
+[sqall] JavaScript bug with unreadable temp dir/disabled encryption solved.
+
+
+---
+v1.0
+---
+
+[sqall] Added file encryption feature.
+
+---
+v0.9.1
+---
+
+[sqall] Generate new filenames if file already exists
+        (existing files cannot be overwritten).
+[sqall] Forbid uploading .htaccess files due to security reasons.
+
+---
+v0.9
+---
+
+[sqall] Added upload feature.
+
+---
+v0.8
+---
+
+[sqall] Finished application.
\ No newline at end of file
diff --git a/kastalia/docs/CREDITS b/kastalia/docs/CREDITS
new file mode 100644 (file)
index 0000000..545e0e9
--- /dev/null
@@ -0,0 +1,9 @@
+===========================
+ Kastalia Development Team
+===========================
+
+
+Core Developers
+===============
+
+- Andre Pawlowski aka sqall <sqall@h4des.org>
\ No newline at end of file
diff --git a/kastalia/docs/INSTALL b/kastalia/docs/INSTALL
new file mode 100644 (file)
index 0000000..82578bb
--- /dev/null
@@ -0,0 +1,180 @@
+=========================
+ Installing Kastalia 1.0
+=========================
+
+:Last update:   $Date: 2008-11-03 12:25:48 $
+:Revision:      $Revision: 1.0 $
+
+.. contents:: Contents
+.. section-numbering::
+
+This document contains instructions for installing the Kastalia download application
+
+For information on the capabilities and features of Kastalia, see the file
+README_ in the top-level directory of the Kastalia distribution.
+
+
+Obtaining Kastalia
+==================
+
+Kastalia can be obtained from the authors website
+
+   http://h4des.org/index.php?inhalt=kastalia
+
+
+Prerequisites
+=============
+
+To function properly, Kastalia **requires** the following:
+
+1. A working Horde installation.
+
+   Kastalia runs within the `Horde Application Framework`_, a set of common
+   tools for Web applications written in PHP. You must install Horde before
+   installing Kastalia.
+
+   .. Important:: Kastalia 1.0 requires version 3.0+ of the Horde Framework -
+                  earlier versions of Horde will **not** work.
+
+   .. _`Horde Application Framework`: http://www.horde.org/horde/
+
+   The Horde Framework can be obtained from the Horde website and FTP server,
+   at
+
+      http://www.horde.org/horde/
+
+      ftp://ftp.horde.org/pub/horde/
+
+   Many of Kastalia's prerequisites are also Horde prerequisites.
+
+   .. Important:: Be sure to have completed all of the steps in the
+                  `horde/docs/INSTALL`_ file for the Horde Framework before
+                  installing Kastalia.
+
+2. Install the MCrypt module for php. (optional)
+
+   Kastalia uses the MCrypt module for php to encrypt/decrypt files on the 
+   server. If you want to store files encrypted on the server you have to
+   install this module.
+
+   For further informations and to get MCrypt take a look at
+
+   http://mcrypt.sourceforge.net/
+
+   and
+
+   http://php.net/manual/en/mcrypt.setup.php
+
+
+Installing Kastalia
+===================
+
+Kastalia is written in PHP, and must be installed in a web-accessible
+directory. The precise location of this directory will differ from system to
+system. Kastalia must be installed directly underneath Horde in the
+web server's document tree.
+
+Since Kastalia is written in PHP, there is no compilation necessary; simply
+expand the distribution where you want it to reside and rename the root
+directory of the distribution to whatever you wish to appear in the URL. For
+example, with the Apache web server's default document root of
+``/usr/local/apache/htdocs``, you would type::
+
+   cd /usr/local/apache/htdocs/horde
+   tar zxvf /path/to/kastalia-1.0.tar.gz
+   mv kastalia-1.0 kastalia
+
+and would then find Kastalia at the URL::
+
+   http://your-server/horde/kastalia/
+
+
+Configuring Kastalia
+====================
+
+1. Configuring Horde for Kastalia
+
+   Register the application
+
+      In ``horde/config/registry.php``, add the following lines:
+
+      $this->applications['kastalia'] = array(
+          'fileroot' => dirname(__FILE__) . '/../kastalia',
+          'webroot' => $this->applications['horde']['webroot'] . '/kastalia',
+          'name' => _("Datastore"),
+          'status' => 'active',
+      );
+
+      $this->applications['kastalia-menu'] = array(
+          'status' => 'block',
+          'app' => 'kastalia',
+          'blockname' => 'tree_menu',
+          'menu_parent' => 'kastalia',
+      );
+
+2. Configuring Kastalia
+
+   You must login to Horde as a Horde Administrator to finish the
+   configuration of Kastalia. Use the Horde ``Administration`` menu item to
+   get to the administration page, and then click on the ``Configuration``
+   icon to get the configuration page. Select ``Datastore`` from the
+   selection list of applications. Fill in or change any configuration values
+   as needed. When done click on ``Generate Kastalia Name Configuration`` to
+   generate the ``conf.php`` file. If your web server doesn't have write
+   permissions to the Kastalia configuration directory or file, it will not be
+   able to write the file. In this case, go back to ``Configuration`` and
+   choose one of the other methods to create the configuration file
+   ``kastalia/config/conf.php``.
+
+   Note for international users: Kastalia uses GNU gettext to provide local
+   translations of text displayed by applications; the translations are found
+   in the ``po/`` directory. If a translation is not yet available for your
+   locale (and you wish to create one), see the ``horde/po/README`` file, or
+   if you're having trouble using a provided translation, please see the
+   `horde/docs/TRANSLATIONS`_ file for instructions.
+
+3. Securing Kastalia
+
+   Before you can secure Kastalia, you need a secure Horde installation.  Please
+   read the file in `horde/docs/SECURITY`_ for Horde security information
+   before proceeding.
+
+   First you have to realize that every directory bellow your chosen Kastalia
+   datastore will be downloadable with Kastalia. So if you choose the directory
+   ``/`` every authorized Horde user can download everything readable
+   from your server. The next point to secure your datastore is to place it
+   outside the webroot for example ``/srv/kastalia/datastore``. If you
+   do so, make the directory readable by the webserver and the files owned by
+   ``root``. If your webserver runs as ``www.www``, do as follows:
+
+      chown root:www kastalia/datastore/*
+      chmod 440 kastalia/datastore/*
+
+   An additional approach is to make Kastalia's configuration files owned by the
+   user ``root`` and by a group which only the webserver user belongs to, and
+   then making them readable only to owner and group.  For example, if your
+   webserver runs as ``www.www``, do as follows:
+
+      chown root.www config/*
+      chmod 440 config/*
+
+   To ensure you have a secure file sharing application you should use _https_
+   instead of http. We also recomment to use the option to store files encrypted 
+   (Prerequisites: 2. Install the MCrypt module for php).
+
+5. Testing Kastalia
+
+   Once you have configured Kastalia, you can click on the ``Datastore`` link
+   in the Horde menu. Kastalia will immediately list every file in the configured
+   datastore. Clicking on a file will start the download.
+
+
+Obtaining Support
+=================
+
+If you encounter problems with Kastalia, help is available! Please contact the 
+author of Kastalia.
+
+Thanks for using Kastalia!
+
+The Kastalia team
diff --git a/kastalia/docs/RELEASE_NOTES b/kastalia/docs/RELEASE_NOTES
new file mode 100755 (executable)
index 0000000..b2f3c91
--- /dev/null
@@ -0,0 +1,14 @@
+<?php
+/**
+ * Release focus. Possible values:
+ * 0 - N/A
+ * 1 - Initial freshmeat announcement
+ * 2 - Documentation
+ * 3 - Code cleanup
+ * 4 - Minor feature enhancements
+ * 5 - Major feature enhancements
+ * 6 - Minor bugfixes
+ * 7 - Major bugfixes
+ * 8 - Minor security fixes
+ * 9 - Major security fixes
+ */
diff --git a/kastalia/docs/TODO b/kastalia/docs/TODO
new file mode 100644 (file)
index 0000000..3297fae
--- /dev/null
@@ -0,0 +1,8 @@
+================================
+ Kastalia Development TODO List
+================================
+
+:Last update:   $Date: 2008-09-16 12:24:14 $
+:Revision:      $Revision: 1.0 $
+
+-permission management
diff --git a/kastalia/download.php b/kastalia/download.php
new file mode 100755 (executable)
index 0000000..1a4fa3e
--- /dev/null
@@ -0,0 +1,160 @@
+<?php
+/**
+ *
+ * This product includes software developed by the Horde Project (http://www.horde.org/).
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author  Andre Pawlowski aka sqall <sqall@h4des.org>
+ */
+
+//das absolute Kastalia directory wird als Konstante definiert
+//um damit config Dateien zu includieren
+@define('KASTALIA_BASE', dirname(__FILE__));
+
+//die Konfigurationsdatei von Kastalia wird includiert
+//um alle Kastalia Einstellungen in diesem Skript nutzen zu koennen
+require(KASTALIA_BASE . '/config/conf.php');
+
+//bei dem download.php Skript macht ein includieren von base.php Probleme
+//und kann zu Fehlerhaften Downloads fuehren, deshalb wird ein manueller Anmeldecheck durchgefuehrt
+//################### <MANUELLER ANMELDE CHECK (WENN base.php NICHT INCLUDIERT WIRD)> ###################
+// Check for a prior definition of HORDE_BASE (perhaps by an auto_prepend_file
+// definition for site customization).
+if (!defined('HORDE_BASE')) {
+    @define('HORDE_BASE', dirname(__FILE__) . '/..');
+}
+
+// Load the Horde Framework core, and set up inclusion paths.
+require_once HORDE_BASE . '/lib/core.php';
+
+// Registry.
+$registry = &Registry::singleton();
+if (is_a(($pushed = $registry->pushApp('kastalia', !defined('AUTH_HANDLER'))), 'PEAR_Error')) {
+    if ($pushed->getCode() == 'permission_denied') {
+        Horde::authenticationFailureRedirect();
+    }
+    Horde::fatal($pushed, __FILE__, __LINE__, false);
+}
+//################### </MANUELLER ANMELDE CHECK (WENN base.php NICHT INCLUDIERT WIRD)> ###################
+
+//als erstes wird ueberprueft, ob die zu herunterladende Datei durch
+//eine dafuer vorgesehenen SESSION Variable definiert wurde
+//(diese SESSION Variable ist fuer downloads aus dem temporaeren Verzeichnis vorgesehen)
+if(isset($_SESSION['kastalia_temp_download'])) {
+    $kastalia_filename = $_SESSION['kastalia_temp_download'];
+    //nachdem die SESSION Variable in eine fuer das Skript lokalen Variable gespeichert worden ist
+    //wird die SESSION Variable aus Sicherheits- und Konfliktgruenden geloescht
+    unset($_SESSION['kastalia_temp_download']);
+    //hier wird ueberprueft, ob es sich bei der zu herunterladenden Datei um eine ".htaccess" Datei
+    //handelt. Dabei werden allerdings auch Dateien herausgefiltert, die die Endung ".htaccess" haben.
+    if(substr($kastalia_filename, -9) == ".htaccess") {
+        echo "Error: Downloading .htaccess files out of the temporary directory not allowed!";
+        exit(1);
+    }
+    //hier wird ueberprueft, ob das verschluesselte speichern von Dateien aktiviert ist...
+    if($conf['upload']['securestore']) {
+        //... falls ja, werden weitere Pruefungen durchgefuerht
+        //Ueberpruefung nach den Zeichenfolgen "/." und "./" damit
+        //durch das Manipulieren der Variable kastalia_filename
+        //keiner aus dem temporaeren Verzeichnis entkommen kann (durch Nutzung von "../")
+        if(strpos($kastalia_filename,'/.') === false && strpos($kastalia_filename,'./') === false) {
+            //nun wird der Download aus dem temporaeren Verzeichnis gestartet
+            DownloadFile($conf['upload']['tempdir'], $kastalia_filename);
+            //nachdem die Datei heruntergeladen wurde, muss sie geloescht werden,
+            //damit keiner mehr Zugriff auf sie erhaelt
+            if(!unlink($conf['upload']['tempdir'] . "/" . $kastalia_filename)) {
+                echo "Error: Unable to delete temporary file after downloading!";
+                exit(1);
+            }
+        }
+        else {
+            echo "Error: \$kastalia_filename in download.php contains illegal characters!";
+            exit(1);
+        }
+    }
+    else {
+        //... ansonsten wird mit einer Meldung abgebrochen
+        echo "Encryption/Decryption is disabled!";
+        exit(0);
+    }
+}
+//falls die SESSION Variable nicht gesetzt wurde...
+else {
+    //...wird hier ueberprueft, ob mittels GET der Dateiname gesetzt worden ist
+    if(isset($_GET['kastalia_filename'])) {
+        //hier wird ueber GET der Dateiname ermittelt
+        $kastalia_filename = $_GET['kastalia_filename'];
+        //hier wird ueberprueft, ob es sich bei der zu herunterladenden Datei um eine ".htaccess" Datei
+        //handelt. Dabei werden allerdings auch Dateien herausgefiltert, die die Endung ".htaccess" haben.
+        if(substr($kastalia_filename, -9) == ".htaccess") {
+            echo "Error: Downloading .htaccess files out of the datastore not allowed!";
+            exit(1);
+        }
+        //Ueberpruefung nach den Zeichenfolgen "/." und "./" damit
+        //durch das Manipulieren der Variable kastalia_filename
+        //keiner aus dem kastalia Datastore entkommen kann (durch Nutzung von "../")
+        if(strpos($kastalia_filename,'/.') === false && strpos($kastalia_filename,'./') === false) {
+            //hier wird ueberprueft ob es sich bei dem Download um eine von Kastalia verschluesselte Datei handelt (Endung ".kastaliaenc")
+            if(substr($kastalia_filename, -12) == ".kastaliaenc") { //SECURE STORED
+                //hier wird serverseitig ueberprueft, ob ein leeres Passwort uebergeben wurde
+                //falls ja, wird mit einem Error abgebrochen, da leere Passwoerter verboten sind
+                if($_POST['kastalia_password'] == "") {
+                    echo "Error: Empty passwords not allowed!";
+                    exit(1);
+                }
+                //hier wird ueberprueft, ob das verschluesselte speichern von Dateien aktiviert ist
+                if($conf['upload']['securestore']) {
+                    $_SESSION['kastalia_mode'] = "decrypt"; //diese Variable gibt den Modus an in welchem das Skript encrypt_decrypt_files.php ausgefuehrt werden soll
+                    $_SESSION['kastalia_input_name'] = substr($conf['datastore']['location'] . "/" . $kastalia_filename, 0, -12); //diese Variable gibt die zu entschluesselnde Datei an (ohne die Endung ".kastaliaenc")
+                    $_SESSION['kastalia_output_name'] = substr($conf['upload']['tempdir'] . "/" . basename($kastalia_filename), 0, -12); //diese Variable gibt den Ort fuer die entschluesselte Zieldatei an (der temporaere Ordner von Kastalia, das "basename" ist hier wichtig, da ansonsten auch die unterordner vom datastore im Dateinamen stecken)
+                    $_SESSION['kastalia_part_number'] = 0; //diese Variable gibt die aktuelle Entschluesselungsrunde an (die Beginnrunde ist immer 0)
+                    $_SESSION['kastalia_key'] = $_POST['kastalia_password']; //diese Variable gibt den Schluessel zum entschluesseln der Datei an
+                    //mit der encrypt_decrypt_files.php wird die Entschluesselung fuer die Datei ausgefuehrt
+                    //(diese besteht aus mehreren Teilschritten wobei der Browser automatisch das Skript in Intervallen neu aufruft)
+                    include('encrypt_decrypt_files.php');
+                }
+                else {
+                    //falls es deaktiviert ist, wird mit einer Meldung abgebrochen
+                    echo "Encryption/Decryption is disabled!";
+                    exit(0);
+                }
+            }
+            //falls die zu herunterladende Datei keine von Kastalia verschluesselte Datei ist
+            //wird der Download einfach gestartet
+            else { //UNSECURE STORED
+                DownloadFile($conf['datastore']['location'], $kastalia_filename);
+            }
+        }
+        else {
+            echo "Error: \$kastalia_filename in download.php contains illegal characters!";
+            exit(1);
+        }
+    }
+    //falls der Dateiname nicht gesetzt wurde, wird mit einer Fehlermeldung abgebrochen
+    else{
+        echo "Error: \$kastalia_filename in download.php is not set!"; 
+        exit(1);
+    }
+}
+
+//diese Funktion setzt die Header zum Download der Datei
+//und gibt die Datei an den Browser
+function DownloadFile($file_location,$file_name) {
+    //Ueberpruefung ob Datei existiert und lesbar ist
+    if(is_readable($file_location . '/' . $file_name)) {
+        header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
+        header('Content-Description: File Transfer');
+        header('Content-Type: application/octet-stream');
+        header('Content-Length: ' . filesize($file_location . '/' . $file_name));
+        header('Content-Disposition: attachment; filename=' . basename($file_name));
+        flush();
+        readfile($file_location . '/' . $file_name);
+    }
+    else {
+        echo "Error: File $file_name doesn't exist or is not readable!";
+        exit(1);
+    }
+}
+?>
\ No newline at end of file
diff --git a/kastalia/encrypt_decrypt_files.php b/kastalia/encrypt_decrypt_files.php
new file mode 100644 (file)
index 0000000..f689e5e
--- /dev/null
@@ -0,0 +1,383 @@
+<?php
+/**
+ *
+ * This product includes software developed by the Horde Project (http://www.horde.org/).
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author  Andre Pawlowski aka sqall <sqall@h4des.org>
+ */
+
+//das absolute Kastalia directory wird als Konstante definiert
+//um damit config Dateien zu includieren
+@define('KASTALIA_BASE', dirname(__FILE__)); 
+
+//die Basis von Kastalia wird includiert
+//um die Anmeldung zu ueberpruefen
+require_once(KASTALIA_BASE . '/lib/base.php');
+//die Konfigurationsdatei von Kastalia wird includiert
+//um alle Kastalia Einstellungen in diesem Skript nutzen zu koennen
+require(KASTALIA_BASE . '/config/conf.php');
+//das Menu von Kastalia wird includiert
+//damit das Menu dem Benutzer angezeigt wird
+require_once(KASTALIA_BASE . '/list.php');
+
+echo "<div class=\"header\">Kastalia Datastore - Encryption/Decryption</div>\n";
+echo "<br />\n";
+
+//nun wird ueberprueft, ob das verschluesseln/entschluesseln von Dateien aktiviert wurde
+//falls nicht, wird eine Meldung ausgegeben und das Skript beendet
+if(!$conf['upload']['securestore']) {
+    //mit dieser Funktion werden aus Sicherheitsgruenden nach der Verschluesselung
+    //alle SESSION Variablen die damit zu tun haben geloescht
+    UnsetSessionVars();
+    echo "Encryption/Decryption is disabled!";
+    exit(0);
+}
+
+//hier werden die fuer die Weiterverarbeitung noetigen SESSION und config Variablen in lokalen Variablen gespeichert
+$kastalia_mode = $_SESSION['kastalia_mode']; //diese Variable legt fest, ob ver- oder entschluesselt werden soll
+$input_name = $_SESSION['kastalia_input_name']; //gibt den Namen + Ort der Quelldatei an
+$output_name = $_SESSION['kastalia_output_name']; //gibt den Namen + Ort der Zieldatei an
+$kastalia_part_number = $_SESSION['kastalia_part_number']; //gibt die aktuelle ver/entschluesselungsrunde an
+$key = $_SESSION['kastalia_key']; //gibt den key zum ver/entschluesseln an
+$kastalia_memory_size = $conf['upload']['memorysize']; //gibt die groesse des zu Verfuegung stehenden Speichers an, mit diesem Wert wird die groesse des zu ver/entschluesselnden Teiles berechnet
+$refresh_cycle = $conf['upload']['refreshcycle']; //gibt an, wie lange nach Beendigung einer Ver/Entschluesselungsrunde der naechste Aufruf vom Browser gestartet wird
+
+//hier wird ueberprueft, ob der Schluessel fuer die Ver/Entschluesselung gesetzt wurde
+//falls nicht, wird abgebrochen
+if($key == "") {
+    echo "Error: \$key in encrypt_decrypt_files.php is empty!<br />\n";
+    //falls es sich um die Verschluesselung einer Datei handelt, muss die temporaere unverschluesselte Datei
+    //unbedingt geloescht werden. Hier wird ueberprueft ob die Datei verschluesselt werden sollte
+    if($kastalia_mode == "encrypt") {
+        echo "deleting temporary file...<br />\n";
+        //hier wird nun die temporaere Datei geloescht, falls ein Fehler auftreten sollte, wird ein Error ausgegeben
+            if(!unlink($input_name)) {
+            echo "Error: Unable to delete temporary file!<br />\n";
+            echo "This constitutes a <b>breach of security</b> because the content of the uploaded file stored unencrypted.<br />\n";
+            echo "Please contact the administrator to have the temporary file " . $input_name . " deleted.\n";
+        }
+        else {
+            echo "...done.\n";
+        }
+    }
+    //mit dieser Funktion werden aus Sicherheitsgruenden nach der Verschluesselung
+    //alle SESSION Variablen die damit zu tun haben geloescht
+    UnsetSessionVars();
+    exit(1);
+}
+
+//in dieser switch-case Anweisung wird durch kastalia_mode entschieden ob ver- oder entschluesselt werden soll
+switch($kastalia_mode) {
+    case "encrypt": //######################################### SPLIT AND ENCRYPT FILE #########################################
+        //hier wird die Anzahl der Dateiteile berechnet, die auch gleichzeitig die Anzahl der Verschluesselungsrunden angibt
+        $max_parts = ceil(filesize($input_name) / $kastalia_memory_size);
+        //hier wird ueberprueft, ob alle Verschluesselungsrunden durchlaufen wurden...
+        if($kastalia_part_number < $max_parts) {
+            //... falls nein, wird die naechste Verschluesselungsrunde eingeleitet
+            //mit dieser Funktion wird die Datei in Stuecken ausgelesen und verschluesselt wieder zusammengesetzt
+            //je ein Stueck pro Verschluesselungsrunde
+            SplitAndEncryptFile($input_name, $conf['upload']['tempdir'] . "/" . basename($output_name), $kastalia_part_number, $max_parts, $key);
+            //hier werden die Variablen fuer das weitere vorgehen des Skriptes wieder in die SESSION Variablen gespeichert
+            $_SESSION['kastalia_mode'] = "encrypt"; //diese Variable legt fest, ob ver- oder entschluesselt werden soll
+            $_SESSION['kastalia_input_name'] = $input_name; //gibt den Namen + Ort der Quelldatei an
+            $_SESSION['kastalia_output_name'] = $output_name; //gibt den Namen + Ort der Zieldatei an
+            $_SESSION['kastalia_part_number'] = $kastalia_part_number + 1; //gibt die aktuelle ver/entschluesselungsrunde an (+1)
+            $_SESSION['kastalia_key'] = $key; //gibt den key zum ver/entschluesseln an
+
+            //##################### <HTML HEADER MANIPULATION> #####################
+            //Header Manipulation zum aufrufen der naechsten Verschluesselungsrunde
+            echo "<head>\n";
+            echo "<meta http-equiv=\"refresh\" content=\"" . $refresh_cycle . "; URL=encrypt_decrypt_files.php\">\n";
+            echo "</head>\n";
+            echo "<body>\n";
+            echo "<p>\n";
+            echo "encrypting part " . ($kastalia_part_number + 1) . " of " . $max_parts . "<br />";
+            echo "please wait...<br />";
+            echo "</p>\n";
+            echo "</body>\n";
+            //##################### </HTML HEADER MANIPULATION> #####################
+
+        }
+        else {
+            //... falls ja, werden die letzten Schritte nach der Verschluesselung durchgefuert
+            //mit dieser Funktion werden aus Sicherheitsgruenden nach der Verschluesselung
+            //alle SESSION Variablen die damit zu tun haben geloescht
+            UnsetSessionVars();
+            //hier wird die temporaere verschluesselte Datei an die richtige finale Stelle verschoben,
+            //damit sie heruntergeladen werden kann
+            if(!rename($conf['upload']['tempdir'] . "/" . basename($output_name) . ".kastaliaenc", $output_name . ".kastaliaenc")) {
+                //sollte ein Fehler beim verschieben der temporaeren verschluesselten Datei auftreten
+                //wird eine Fehlermeldung ausgegeben, aber nicht abgebrochen, da die nachfolgenden Befehle noch abgearbeitet werden muessen
+                echo "Error: Encrypted file couldn't be moved to final position " . $output_name . ".kastaliaenc<br />\n";
+            }
+            echo "Encryption done...<br />\n";
+            echo "File successfully stored under <b>" . substr($output_name, strlen($conf['datastore']['location'] . "/")) . "</b> !\n";
+            //hier wird nun die temporaere unverschluesselte Datei geloescht (Wichtig: sollte hier ein Fehler auftreten
+            //liegt eine unverschluesselte Version der Datei in dem temporaeren Verzeichnis!)
+            if(!unlink($input_name)) {
+                echo "Error: Unable to delete temporary file after encryption!<br />\n";
+                echo "This constitutes a <b>breach of security</b> because the content of the uploaded file still stored unencrypted.<br />\n";
+                echo "Please contact the administrator to have the temporary file " . $input_name . " deleted.\n";
+                exit(1);
+            }
+        }
+        break;
+    case "decrypt": //######################################### DECRYPT AND MERGE FILES #########################################
+        //hier wird die Endung ".kastaliaenc" an den input_name gesetzt, da die von Kastalia verschluesselten
+        //Dateien immer diese Endung besitzen
+        $temp_input_name = $input_name . ".kastaliaenc";
+        //hier wird die Anzahl der Dateiteile berechnet, die auch gleichzeitig die Anzahl der Entschluesselungsrunden angibt
+        $max_parts = ceil(filesize($temp_input_name) / $kastalia_memory_size);
+        //hier wird ueberprueft, ob alle Entschluesselungsrunden durchlaufen wurden...
+        if($kastalia_part_number < $max_parts) {
+            //... falls nein, wird die naechste Entschluesselungsrunde eingeleitet
+            //mit dieser Funktion wird die Datei in Stuecken ausgelesen und entschluesselt wieder zusammengesetzt
+            //je ein Stueck pro Entschluesselungsrunde
+            MergeAndDecryptFile($input_name, $output_name, $kastalia_part_number, $max_parts, $key);
+            //hier werden die Variablen fuer das weitere vorgehen des Skriptes wieder in die SESSION Variablen gespeichert
+            $_SESSION['kastalia_mode'] = "decrypt"; //diese Variable legt fest, ob ver- oder entschluesselt werden soll
+            $_SESSION['kastalia_input_name'] = $input_name; //gibt den Namen + Ort der Quelldatei an
+            $_SESSION['kastalia_output_name'] = $output_name; //gibt den Namen + Ort der Zieldatei an
+            $_SESSION['kastalia_part_number'] = $kastalia_part_number + 1; //gibt die aktuelle ver/entschluesselungsrunde an (+1)
+            $_SESSION['kastalia_key'] = $key; //gibt den key zum ver/entschluesseln an
+
+            //##################### <HTML HEADER MANIPULATION> #####################
+            //Header Manipulation zum aufrufen der naechsten Entschluesselungsrunde
+            echo "<head>\n";
+            echo "<meta http-equiv=\"refresh\" content=\"" . $refresh_cycle . "; URL=encrypt_decrypt_files.php\">\n";
+            echo "</head>\n";
+            echo "<body>\n";
+            echo "<p>\n";
+            echo "decrypting part " . ($kastalia_part_number + 1) . " of " . $max_parts . "<br />";
+            echo "please wait...<br />";
+            echo "</p>\n";
+            echo "</body>\n";
+            //##################### </HTML HEADER MANIPULATION> #####################
+
+        }
+        else {
+            //... falls ja, werden die letzten Schritte nach der Entschluesselung durchgefuert
+            //mit dieser Funktion werden aus Sicherheitsgruenden nach der Entschluesselung
+            //alle SESSION Variablen die damit zu tun haben geloescht
+            UnsetSessionVars();
+            //diese Variable gibt fuer das download.php Skript den Dateinamen zum herunterladen an
+            $_SESSION['kastalia_temp_download'] = basename($output_name);
+
+            //##################### <HTML HEADER MANIPULATION> #####################
+            //Header Manipulation zum aufrufen des Downloadskriptes
+            echo "<head>\n";
+            echo "<meta http-equiv=\"refresh\" content=\"" . $refresh_cycle . "; URL=download.php\">\n";
+            echo "</head>\n";
+            echo "<body>\n";
+            echo "<p>\n";
+            echo "starting download<br />";
+            echo "please wait...<br />";
+            echo "</p>\n";
+            echo "</body>\n";
+            //##################### </HTML HEADER MANIPULATION> #####################
+
+        }
+        break;
+    default:
+        //falls der Modus weder "encrypt" noch "decrypt" ist, ist ein unerwarteter Fehler aufgetreten
+        echo "Error: Unexpected value of \$kastalia_mode in encrypt_decrypt_files.php!";
+        //mit dieser Funktion werden aus Sicherheitsgruenden beim Abbruch
+        //alle SESSION Variablen die mit der Ver/Entschluesselung zu tun haben geloescht
+        UnsetSessionVars();
+        exit(1);
+        break;
+}
+
+//diese Funktion verschluesselt die errechneten Dateiteile und fuegt sie in eine Datei an die richtige Stelle
+function SplitAndEncryptFile($input_file_name, $output_name, $part_number, $max_parts, $key) {
+    //hier wird der Name fuer die verschluesselte Datei mit der Endung ".kastaliaenc" versehen
+    $output_file_name = $output_name . ".kastaliaenc";
+    //hier wird ueberprueft ob die verschluesselte Enddatei schon existiert und es die erste Verschluesselungsrunde ist 
+    //(damit die gerade zu verschluesselnde und erstellte Datei nicht mit in die Pruefung einbezogen wird) 
+    //falls ja wird mit einem Error abgebrochen
+    if($part_number == 0 && file_exists($output_file_name)) {
+        echo "Error: File " . $output_file_name . " already exists! Stopping encryption!<br />";
+        //wenn die verschluesselte Datei schon existiert, wird die temporaere unverschluesselte Datei
+        //geloescht damit diese nicht auf dem Server unverschluesselt gespeichert bleibt
+        echo "deleting temporary file...<br />\n";
+        //hier wird nun die temporaere Datei geloescht, falls ein Fehler auftreten sollte, wird ein Error ausgegeben
+        if(!unlink($input_file_name)) {
+            echo "Error: Unable to delete temporary file!<br />\n";
+            echo "This constitutes a <b>breach of security</b> because the content of the uploaded file stored unencrypted.<br />\n";
+            echo "Please contact the administrator to have the temporary file " . $input_file_name . " deleted.\n";
+        }
+        else {
+            echo "...done.\n";
+        }
+        //mit dieser Funktion werden aus Sicherheitsgruenden beim Abbruch
+        //alle SESSION Variablen die mit der Ver/Entschluesselung zu tun haben geloescht
+        UnsetSessionVars();
+        exit(1);
+    }
+    //hier wird die zu verschluesselnde Datei fuer das Lesen geoeffnet
+    if($input_file_handle = fopen($input_file_name, 'rb')) {
+        $input_file_size = filesize($input_file_name);
+        //hier wird die groesse (in Bytes) fuer die einzelnen zu verschluesselnden Datenteile berrechnet
+        $parts_size = floor($input_file_size/$max_parts);
+        //da durch die Groessenberechnung fuer die einzelnen Datenteile (durch die Nutzung von "floor")
+        //ein Rest entstehen kann, wird dieser hier berrechnet um ihn an den letzten Datenteil anzuhaengen
+        //damit kein Datenverlust entstehen kann
+        $last_bytes = $input_file_size % $max_parts;
+        //nun wird die Datei in die die verschluesselten Daten geschrieben werden sollen geoeffnet
+        //(der Dateizeiger zeigt in diesem Modus auf das Ende der Datei)
+        if($output_file_handle = fopen($output_file_name ,'ab')) {
+            //hier wird der Dateizeiger an die richtige Position gesetzt um die Daten fuer die jetzige Verschluesselungsrunde zu lesen
+            fseek($input_file_handle, $part_number * $parts_size, SEEK_SET);
+            //hier wird ueberprueft, ob es sich um die letzte Verschluesselungsrunde handelt
+            if($part_number == ($max_parts-1) ) {
+                //die groesse des letzten Datenteils wird um den Rest ($last_bytes) der Groessenberechnung erhoeht
+                fwrite($output_file_handle, EncryptData($key, fread($input_file_handle, $parts_size + $last_bytes)));
+            }
+            else {
+                fwrite($output_file_handle, EncryptData($key, fread($input_file_handle, $parts_size)));
+            }
+            //die verschluesselte Zieldatei wird geschlossen
+            fclose($output_file_handle);
+        }
+        else {
+            echo "Error: Can't open file " . $output_file_name . "!";
+            //mit dieser Funktion werden aus Sicherheitsgruenden beim Abbruch
+            //alle SESSION Variablen die mit der Ver/Entschluesselung zu tun haben geloescht
+            UnsetSessionVars();
+            exit(1);
+        }
+        //die zu verschluesselnde Datei wird geschlossen
+        fclose($input_file_handle);
+    }
+    else {
+        echo "Error: Can't open file " . $input_file_name . "!";
+        //mit dieser Funktion werden aus Sicherheitsgruenden beim Abbruch
+        //alle SESSION Variablen die mit der Ver/Entschluesselung zu tun haben geloescht
+        UnsetSessionVars();
+        exit(1);
+    }
+    return true;
+}
+
+//diese Funktion entschluesselt die errechneten Dateiteile und fuegt sie in eine Datei an die richtige Stelle
+function MergeAndDecryptFile($input_name, $output_file_name, $part_number, $max_parts, $key) {
+    //die Konfigurationsdatei von Kastalia wird includiert
+    //um alle Kastalia Einstellungen in dieser function nutzen zu koennen
+    require(KASTALIA_BASE . '/config/conf.php');
+    //hier wird ueberprueft ob die entschluesselte Enddatei schon existiert (dies kann passieren wenn 
+    //jemand die Datei gerade entschluesselt um sie herunterzuladen) und es die erste Entschluesselungsrunde ist 
+    //(damit die gerade zu entschluesselnde und erstellte Datei nicht mit in die Pruefung einbezogen wird) 
+    //falls ja wird mit einem Error abgebrochen
+    if(file_exists($output_file_name) && $part_number == 0) {
+        echo "Error: File " . $output_file_name . " already exists! Stopping decryption!<br />\n";
+        //mit dieser Funktion werden aus Sicherheitsgruenden beim Abbruch
+        //alle SESSION Variablen die mit der Ver/Entschluesselung zu tun haben geloescht
+        UnsetSessionVars();
+        //hier wird die ctime von der schon existierenden Datei ermittelt um zu berechnen
+        //wann Kastalia spaetestens diese Date iloeschen wird und es dem Nutzer mitzuteilen
+        if($file_ctime = filectime($output_file_name)) {
+            //hier wird berechnet wie lange die Datei noch laengstens bestehen wird bevor sie von Kastalia geloescht wird
+            $file_ctime = $file_ctime + (60 * $conf['upload']['tempctime']) - time();
+            //sollte die Zeitrechnung negativ werden, ist ein Fehler aufgetreten und eine andere Nachricht wird ausgegeben 
+            if($file_ctime >= 0) {
+                //die Angabe in Minuten wird auf 2 stellen hinter dem Komma gerundet
+                echo "Kastalia will delete the file in about " . round($file_ctime / 60, 2) . " minutes at the latest. Then try again.\n";
+            }
+            else {
+                //wird ausgegeben wenn die Zeitrechnung negativ wird
+                //und somit die automatische Loeschung nicht funktioniert hat
+                echo "Please contact the administrator to have the file deleted.";
+            }
+        }
+        else {
+            //wird ausgegeben wenn die ctime Ermittlung erfolglos war und dementsprechend die automatische
+            //Loeschung auch nicht erfolgen wird
+            echo "Please contact the administrator to have the file deleted.";
+        }
+        exit(1);
+    }
+    //hier wird der Name fuer die verschluesselte Datei mit der Endung ".kastaliaenc" versehen
+    //da sie so auf dem Dateisystem gespeichert wurde
+    $input_file_name = $input_name . ".kastaliaenc";
+    //die Datei wird zum schreiben geoeffnet mit dem Dateizeiger auf das Ende der Datei
+    if($input_file_handle = fopen($input_file_name, 'rb')) {
+        $input_file_size = filesize($input_file_name);
+        //hier wird die groesse (in Bytes) fuer die einzelnen zu entschluesselnden Datenteile berrechnet
+        $parts_size = floor($input_file_size/$max_parts);
+        //da durch die Groessenberechnung fuer die einzelnen Datenteile (durch die Nutzung von "floor")
+        //ein Rest entstehen kann, wird dieser hier berrechnet um ihn an den letzten Datenteil anzuhaengen
+        //damit kein Datenverlust entstehen kann
+        $last_bytes = $input_file_size % $max_parts;
+        //nun wird die Datei in die die entschluesselten Daten geschrieben werden sollen geoeffnet
+        //(der Dateizeiger zeigt in diesem Modus auf das Ende der Datei)
+        if($output_file_handle = fopen($output_file_name, 'ab')) {
+            //hier wird der Dateizeiger an die richtige Position gesetzt um die Daten fuer die jetzige Entschluesselungsrunde zu lesen
+            fseek($input_file_handle, $part_number * $parts_size, SEEK_SET);
+            //hier wird ueberprueft, ob es sich um die letzte Entschluesselungsrunde handelt
+            if($part_number == ($max_parts-1) ) {
+                //die groesse des letzten Datenteils wird um den Rest ($last_bytes) der Groessenberechnung erhoeht
+                fwrite($output_file_handle, DecryptData($key, fread($input_file_handle, $parts_size + $last_bytes)));
+            }
+            else {
+                fwrite($output_file_handle, DecryptData($key, fread($input_file_handle, $parts_size)));
+            }
+            //der entschluesselte Zieldatei wird geschlossen
+            fclose($output_file_handle);
+        }
+        else {
+            echo "Error: Can't open file " . $output_file_name . "!";
+            //mit dieser Funktion werden aus Sicherheitsgruenden beim Abbruch
+            //alle SESSION Variablen die mit der Ver/Entschluesselung zu tun haben geloescht
+            UnsetSessionVars();
+            exit(1);
+        }
+        //die zu entschluesselnde Datei wird geschlossen
+        fclose($input_file_handle);
+    }
+    else {
+        echo "Error: Can't open file " . $input_file_name . "!";
+        //mit dieser Funktion werden aus Sicherheitsgruenden beim Abbruch
+        //alle SESSION Variablen die mit der Ver/Entschluesselung zu tun haben geloescht
+        UnsetSessionVars();
+        exit(1);
+    }
+    return true; 
+}
+
+//diese Funktion verschluesselt die uebergebenden Daten mit den uebergebenden key
+//und gibt die verschluesselten Daten zurueck
+function EncryptData($key, $plaintext) {
+//erstellt den initialisierungsvektor in der groesse des ausgewaehlten algorithmuses
+//aus der md5 summe des uebergebenden keys
+$iv = substr(md5($key), 0, mcrypt_get_iv_size(MCRYPT_BLOWFISH,MCRYPT_MODE_CFB));
+//verschluesselt die Daten mit dem angegebenen Modus und Algorithmuses
+return mcrypt_cfb(MCRYPT_BLOWFISH, $key, $plaintext, MCRYPT_ENCRYPT, $iv);
+}
+
+//diese Funktion entschluesselt die uebergebenden Daten mit den uebergebenden key
+//und gibt die entschluesselten Daten zurueck
+function DecryptData($key, $ciphertext) {
+//erstellt den initialisierungsvektor in der groesse des ausgewaehlten algorithmuses
+//aus der md5 summe des uebergebenden keys
+$iv = substr(md5($key), 0, mcrypt_get_iv_size(MCRYPT_BLOWFISH,MCRYPT_MODE_CFB));
+//entschluesselt die Daten mit dem angegebenen Modus und Algorithmuses
+return mcrypt_cfb(MCRYPT_BLOWFISH, $key, $ciphertext, MCRYPT_DECRYPT, $iv);
+}
+
+//diese Funktion loescht alle SESSION Variablen die mit der Ver/Entschluesselung zu tun haben
+function UnsetSessionVars() {
+    unset($_SESSION['kastalia_mode']);
+    unset($_SESSION['kastalia_input_name']);
+    unset($_SESSION['kastalia_output_name']);
+    unset($_SESSION['kastalia_part_number']);
+    unset($_SESSION['kastalia_key']);
+}
+?>
+
+<?php
+//der footer wird includiert
+require KASTALIA_TEMPLATES . '/common-footer.inc';
+?>
\ No newline at end of file
diff --git a/kastalia/index.php b/kastalia/index.php
new file mode 100755 (executable)
index 0000000..2a9e0ac
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+/**
+ *
+ * This product includes software developed by the Horde Project (http://www.horde.org/).
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author  Andre Pawlowski aka sqall <sqall@h4des.org>
+ */
+
+@define('KASTALIA_BASE', dirname(__FILE__));
+$kastalia_configured = (is_readable(KASTALIA_BASE . '/config/conf.php'));
+
+if (!$kastalia_configured) {
+    require KASTALIA_BASE . '/../lib/Test.php';
+    Horde_Test::configFilesMissing('Kastalia', KASTALIA_BASE,
+                                   array('conf.php'));
+}
+
+require KASTALIA_BASE . '/list.php';
+require KASTALIA_BASE . '/main.php';
diff --git a/kastalia/lib/Block/tree_menu.php b/kastalia/lib/Block/tree_menu.php
new file mode 100644 (file)
index 0000000..7e854c2
--- /dev/null
@@ -0,0 +1,36 @@
+<?php
+/**
+ *
+ * This product includes software developed by the Horde Project (http://www.horde.org/).
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author  Andre Pawlowski aka sqall <sqall@h4des.org> 
+ * @package Tree_Menu
+ */
+
+$block_name = _("Menu List");
+$block_type = 'tree';
+
+class Horde_Block_kastalia_tree_menu extends Horde_Block {
+
+    var $_app = 'kastalia';
+
+    function _buildTree(&$tree, $indent = 0, $parent = null)
+    {
+        global $registry;
+
+        require_once dirname(__FILE__) . '/../base.php';
+
+        $tree->addNode($parent . '__upload',
+                       $parent,
+                       _("Upload"),
+                       $indent + 1,
+                       false,
+                       array('icon' => 'menu/upload.png',
+                             'icondir' => $registry->getImageDir('kastalia'),
+                             'url' => Horde::applicationUrl('upload_menu.php')));
+    }
+
+}
diff --git a/kastalia/lib/Kastalia.php b/kastalia/lib/Kastalia.php
new file mode 100755 (executable)
index 0000000..c7915d5
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Kastalia Base Class.
+ *
+ *
+ * This product includes software developed by the Horde Project (http://www.horde.org/).
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author  Andre Pawlowski aka sqall <sqall@h4des.org>
+ * @package Kastalia
+ */
+class Kastalia {
+
+    /**
+     * Build Kastalia's list of menu items.
+     */
+    function getMenu($returnType = 'object')
+    {
+        global $conf, $registry, $browser, $print_link;
+
+        require_once 'Horde/Menu.php';
+
+        $menu = new Menu(HORDE_MENU_MASK_ALL);
+
+        $menu->add(Horde::applicationUrl('upload_menu.php'), _("Upload"), 'menu/upload.png', $registry->getImageDir('kastalia'));
+
+
+        if ($returnType == 'object') {
+            return $menu;
+        } else {
+            return $menu->render();
+        }
+    }
+
+    //diese Funktion entfernt aus einem String alle hier angegebenen Sonderzeichen
+    function ReplaceSpecialChars($text) {
+        $charstochange = array("Ü","Ö","Ä","ä","ü","ö","ß"," ","'","\\","+","/");
+        $changetochars = array("Ue","Oe","Ae","ae","ue","oe","ss","_","_","_","_","_");
+        $text = str_replace($charstochange,$changetochars,$text);
+        return $text;
+    }
+
+    //diese Funktion entfernt aus einem String alle hier angegebenen Sonderzeichen
+    function ConvertToUriString($text) {
+        $charstochange = array(" ");
+        $changetochars = array("%20");
+        $text = str_replace($charstochange,$changetochars,$text);
+        return $text;
+    }
+}
diff --git a/kastalia/lib/base.php b/kastalia/lib/base.php
new file mode 100755 (executable)
index 0000000..bbf2e9e
--- /dev/null
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Kastalia base application file.
+ *
+ * This product includes software developed by the Horde Project (http://www.horde.org/).
+ *
+ * This file brings in all of the dependencies that every Kastalia script will
+ * need, and sets up objects that all scripts use.
+ *
+ * @author  Andre Pawlowski aka sqall <sqall@h4des.org>
+ */
+
+// Check for a prior definition of HORDE_BASE (perhaps by an auto_prepend_file
+// definition for site customization).
+if (!defined('HORDE_BASE')) {
+    @define('HORDE_BASE', dirname(__FILE__) . '/../..');
+}
+
+// Load the Horde Framework core, and set up inclusion paths.
+require_once HORDE_BASE . '/lib/core.php';
+
+// Registry.
+$registry = &Registry::singleton();
+if (is_a(($pushed = $registry->pushApp('kastalia', !defined('AUTH_HANDLER'))), 'PEAR_Error')) {
+    if ($pushed->getCode() == 'permission_denied') {
+        Horde::authenticationFailureRedirect();
+    }
+    Horde::fatal($pushed, __FILE__, __LINE__, false);
+}
+$conf = &$GLOBALS['conf'];
+@define('KASTALIA_TEMPLATES', $registry->get('templates'));
+
+// Notification system.
+$notification = &Notification::singleton();
+$notification->attach('status');
+
+// Define the base file path of Kastalia.
+@define('KASTALIA_BASE', dirname(__FILE__) . '/..');
+
+// Kastalia base library
+require_once KASTALIA_BASE . '/lib/Kastalia.php';
+
+// Start output compression.
+Horde::compressOutput();
diff --git a/kastalia/lib/version.php b/kastalia/lib/version.php
new file mode 100755 (executable)
index 0000000..1977071
--- /dev/null
@@ -0,0 +1 @@
+<?php define('KASTALIA_VERSION', '1.0.1') ?>
\ No newline at end of file
diff --git a/kastalia/list.php b/kastalia/list.php
new file mode 100755 (executable)
index 0000000..1c4f40a
--- /dev/null
@@ -0,0 +1,18 @@
+<?php
+/**
+ *
+ * This product includes software developed by the Horde Project (http://www.horde.org/).
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author  Andre Pawlowski aka sqall <sqall@h4des.org>
+ */
+
+@define('KASTALIA_BASE', dirname(__FILE__));
+require_once KASTALIA_BASE . '/lib/base.php';
+
+$title = _("List");
+
+require KASTALIA_TEMPLATES . '/common-header.inc';
+require KASTALIA_TEMPLATES . '/menu.inc';
diff --git a/kastalia/locale/en_US/help.xml b/kastalia/locale/en_US/help.xml
new file mode 100755 (executable)
index 0000000..8c7b613
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version='1.0'?>
+<help>
+
+<entry id="kastalia-overview">
+    <title>Kastalia Overview</title>
+
+    <heading>What is Kastalia?</heading>
+    <para>Use this module as a secure file sharing application for the Horde Framework.
+    Every uploaded file can be encrypted by Kastalia and stored secure in the datastore.
+    The user does not need any additional program for the encryption/decryption.</para>
+</entry>
+
+</help>
diff --git a/kastalia/main.php b/kastalia/main.php
new file mode 100755 (executable)
index 0000000..5ddd34e
--- /dev/null
@@ -0,0 +1,236 @@
+<?php
+/**
+ *
+ * This product includes software developed by the Horde Project (http://www.horde.org/).
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author  Andre Pawlowski aka sqall <sqall@h4des.org>
+ */
+
+//das absolute Kastalia directory wird als Konstante definiert
+//um damit config Dateien zu includieren
+@define('KASTALIA_BASE', dirname(__FILE__));
+
+//die Basis von Kastalia wird includiert
+//um die Anmeldung zu ueberpruefen
+require_once(KASTALIA_BASE . '/lib/base.php');
+//die Konfigurationsdatei von Kastalia wird includiert
+//um alle Kastalia Einstellungen in diesem Skript nutzen zu koennen
+require(KASTALIA_BASE . '/config/conf.php');
+
+
+
+
+echo Auth::getAuth();
+
+echo $registry->hasPermission(Auth::getAuth(), PERMS_EDIT);
+if($registry->hasPermission(Auth::getAuth(), PERMS_EDIT)) {
+   echo "TASTA";
+   exit(0);
+}
+
+?>
+
+<script type="text/javascript" language="JavaScript">
+<!--
+//diese function ist fuer das auf und zuklappen der Dateiauswahl zustaendig
+function OpenCloseMenu(div_name,img_name){
+    //falls der Ordner zugeklappt (Auswahlliste ausgeblendet) ist, wird dieser aufgeklappt (Auswahlliste eingeblendet)
+    //ansonsten ist er aufgeklappt (Auswahlliste eingeblendet) und wird zugeklappt (Auswahlliste ausgeblendet)
+    if (document.getElementById(div_name).style.display=='none') {
+        document.getElementById(div_name).style.display='block'; 
+        document.getElementById(img_name).src='themes/graphics/directory_open.gif';
+    }
+    else {
+        document.getElementById(div_name).style.display='none';
+        document.getElementById(img_name).src='themes/graphics/directory_closed.gif';
+    }
+}
+//-->>
+</script>
+
+<div class="header">Kastalia Datastore - Download</div>
+<p><b>notice:</b> cookies and javascripts must be enabled to download files!</p>
+
+<?php
+//die function die den temporaeren Ordner ausliest und alle temporaeren Dateien
+//loescht die zu lange existieren wird aufgerufen. Dies geschieht, da durch 
+//Benutzer seitige Fehler (z.B. schliessen des Browsers beim verschluesseln der Datei)
+//unverschluesselte temporaere Dateien gespeichert bleiben
+CleanDirectory($conf['upload']['tempdir']);
+
+//die function die den Ordner ausliest und ausgibt wird aufgerufen
+ScanDirectory($conf['datastore']['location']);
+
+//diese function liest das Datastore rekursiv aus
+//und gibt den Inhalt aus
+function ScanDirectory($dir_name) {
+   //die Konfigurationsdatei von Kastalia wird includiert
+   //damit die Konfigurationen auch innerhalb dieser Funktion benutzt werden koennen
+   require(KASTALIA_BASE . '/config/conf.php');
+   if ($dir_handle = opendir($dir_name)) {
+      echo "<ul class=\"kastalia_root\">\n";
+      //diese beiden Arrays werden dazu benoetigt, die Ordner- bzw
+      //Dateinamen zwischen zu speichern und zu sortieren
+      $directory_array = array();
+      $file_array = array();
+      //der Inhalt des Ordners wird in dieser Schleife durchgegangen und jedes Element bearbeitet
+      //falls es sich um einen Ordner handelt, wird dieser wieder rekursiv geoeffnet und die Elemente bearbeitet
+      while(false !== ($file = readdir($dir_handle))) {
+         //Ueberpruefung ob es sich bei dem Element um einen Ordner handelt
+         //und ob dieser nicht in der Liste der Ordner ist, die nicht angezeigt werden sollen
+         //falls ja, wird der Name in einem Array gespeichert
+         if($file != "." && $file != ".." && is_dir($dir_name . '/' . $file) && !in_array($file, $conf['datastore']['directoryexcludes'])) { //SAVE DIRECTORYNAMES
+            $directory_array[] = $file;
+         }
+         //Ueberpruefung ob es sich bei dem Element um eine Datei handelt (und keine .htaccess Datei)
+         //falls ja, wird dieses Element in einem Array gespeichert
+         if($file != "." && $file != ".." && $file != ".htaccess" && is_file($dir_name . '/' . $file)) { //SAVE FILENAMES
+            $file_array[] = $file;
+         }
+      }
+      //die Arrays mit den Ordnernamen und den Dateinamen werden sortiert
+      asort($directory_array);
+      asort($file_array);
+      //in dieser Schleife werden die Ordnernamen aus dem sortierten Array
+      //ausgegeben und deren Inhalt jeweils noch einmal
+      //mit Aufruf dieser Funktion ausgelesen
+      foreach($directory_array as $directory_element) { //PRINT DIRECTORY
+         //hier wird der eindeutige Elementname fuer das JavaScript Menu festgelegt 
+         //(der Pfad zu dem Ordner mit entfernten Sonderzeichen wie z.B. '/', da dieser einmalig)
+         $tempscriptname = Kastalia::ReplaceSpecialChars(substr($dir_name . '/' . $directory_element, strlen($conf['datastore']['location'] . '/')));
+         echo "<li class=\"kastalia_directory\">\n";
+         echo "<a class=\"kastalia_directory\" href=\"javascript:OpenCloseMenu('". $tempscriptname . "_div','" . $tempscriptname . "_img');\">\n";
+         echo "<img id=\"" . $tempscriptname . "_img\" src=\"themes/graphics/directory_closed.gif\" class=\"kastalia_picture\" alt=\"directory image\" />\n";
+         echo $directory_element;
+         echo "\n</a>\n";
+         echo "</li>\n";
+         echo "<li style=\"list-style: none; display: inline\">\n";
+         echo "<div id=\"". $tempscriptname . "_div\" class=\"kastalia_filelist\" style=\"display: none;\">\n";
+         //der Ordner wird nun mit einem erneuten aufrufen der Funktion ausgelesen und der Inhalt bearbeitet
+         ScanDirectory($dir_name . '/' . $directory_element);
+         echo "</div>\n";
+         echo "</li>\n";
+      }
+      //in dieser Schleife werden die dateinamen aus dem sortierten Array
+      //ausgegeben und jeweils nochmal ueberprueft
+      //ob diese Dateien mit Kastalia verschluesselt wurden oder nicht
+      foreach($file_array as $file_element) {
+         //hier wird ueberprueft, ob die Datei von Kastalia verschluesselt wurde (die Endung ".kastaliaenc" wird dafuer benutzt)
+         if(substr($file_element, -12) == ".kastaliaenc") { //PRINT ENCRYPTED FILE DOWNLOAD
+            echo "<li class=\"kastalia_file_enc\">\n";
+            //hier wird der Link fuer das Entschluesselungs Menu fuer diese Datei zusammengesetzt
+            //aus dem Link werden vorher alle Zeichen die in der URI nicht stehen duerfen ersetzt (bsp. " " mit "%20")
+            echo "<a href=\"decrypt_menu.php?kastalia_filename=" . Kastalia::ConvertToUriString(substr($dir_name . '/' . $file_element, strlen($conf['datastore']['location'] . '/'))) . "\">\n";
+            //hier wird bei der Ausgabe des Dateinamens die Endung .kastaliaenc entfernt
+            echo substr($file_element, 0, -12);
+            //Nutzerfreundliche Ausgabe der Dateigroesse (auf 2 stellen hinter dem Komma gerundet)
+            $tempfilesize = filesize($dir_name . "/" . $file_element) / 1024 / 1024;
+            if($tempfilesize < 1) {
+               //hier wird ueberprueft, ob die ermittelte Dateigroesse negativ ist
+               //dies kann passieren, wenn die Datei groesser als 2GB ist und der 32Bit signed integer
+               //Wert der Rueckgabe von filesize() zu gross ist
+               if($tempfilesize < 0) {
+                  echo " (>2GB)";
+               }
+               else {
+                  echo " (" . round(filesize($dir_name . "/" . $file_element) / 1024, 2) . "kB)";
+               }
+            }
+            else {
+               echo " (" . round($tempfilesize, 2) . "MB)";
+            }
+            echo "</a>\n";
+            echo "</li>\n";
+         }
+         //falls es sich nicht um eine von Kastalia verschluesselte Datei handelt
+         else { //PRINT UNENCRYPTED FILE DOWNLOAD
+            echo "<li class=\"kastalia_file\">\n";
+            //hier wird der Link fuer das herunterladen der Datei zusammengesetzt
+            //aus dem Link werden vorher alle Zeichen die in der URI nicht stehen duerfen ersetzt (bsp. " " mit "%20")
+            echo "<a href=\"download.php?kastalia_filename=" . Kastalia::ConvertToUriString(substr($dir_name . '/' . $file_element, strlen($conf['datastore']['location'] . '/'))) . "\">\n";
+            echo $file_element;
+            //Nutzerfreundliche Ausgabe der Dateigroesse (auf 2 stellen hinter dem Komma gerundet)
+            $tempfilesize = filesize($dir_name . "/" . $file_element) / 1024 / 1024;
+            if($tempfilesize < 1) {
+               //hier wird ueberprueft, ob die ermittelte Dateigroesse negativ ist
+               //dies kann passieren, wenn die Datei groesser als 2GB ist und der 32Bit signed integer
+               //Wert der Rueckgabe von filesize() zu gross ist
+               if($tempfilesize < 0) {
+                  echo " (>2GB)";
+               }
+               else {
+                  echo " (" . round(filesize($dir_name . "/" . $file_element) / 1024, 2) . "kB)";
+               }
+            }
+            else {
+               echo " (" . round($tempfilesize, 2) . "MB)";
+            }
+            echo "</a>\n";
+            echo "</li>\n";
+         }
+      }
+      echo "</ul>\n";
+      //nachdem der Ordner vollstaendig ausgelesen wurde, wird dieser geschlossen
+      closedir($dir_handle);
+   }
+   else {
+      echo "Error: Can't open directory \"$dir_name\"!";
+   }
+}
+
+//diese Funktion liest den temporaeren Ordner von Kastalia aus
+//und loescht alle Dateien die zu lange existieren
+function CleanDirectory($dir_name) {
+    //die Konfigurationsdatei von Kastalia wird includiert
+    //damit die Konfigurationen auch innerhalb dieser Funktion benutzt werden koennen
+    require(KASTALIA_BASE . '/config/conf.php');
+    if($dir_handle = opendir($dir_name)) {
+        //der Inhalt des Ordners wird in dieser Schleife durchgegangen und jedes Element bearbeitet
+        //falls es sich um eine Datei handelt, wird die ctime von dieser Datei ermittelt
+        while(false !== ($file = readdir($dir_handle))) {
+            //Ueberpruefung ob es sich bei dem Element um eine Datei handelt (und keine .htaccess Datei)
+            if($file != "." && $file != ".." && $file != ".htaccess" && is_file($dir_name . '/' . $file)) {
+                //hier wird die ctime der Datei fuer weitere Pruefungen ermittelt
+                if($file_ctime = filectime($dir_name . '/' . $file)) {
+                    //die ctime der Datei (wird angegeben in Sekunden seit January 1 1970 00:00:00 GMT)
+                    //wird mit der in der Config angegebenen Dauer (in Minuten)
+                    //wie lange eine temporaere Datei existieren darf addiert...
+                    $file_ctime = $file_ctime + (60 * $conf['upload']['tempctime']);
+                    //... um zu ueberpruefen, ob die aktuelle Zeit in Sekunden seit der Unix Epoche
+                    //(January 1 1970 00:00:00 GMT) groesser oder gleich der errechneten Zeit ist
+                    //die eine temporaere Datei existieren darf
+                    if($file_ctime <= time()) {
+                        //wenn die aktuelle Zeit in Sekunden seit der Unix Epoche groesser ist
+                        //wird die temporaere Datei geloescht
+                        if(!unlink($dir_name . '/' . $file)) {
+                            //falls ein Fehler beim loeschen auftritt, wird eine Error Nachricht ausgegeben
+                            //aber das Skript nicht abgebrochen, da der Rest noch abgearbeitet werden soll
+                            echo "Error: Unable to delete temporary file!<br />\n";
+                            echo "This constitutes a <b>breach of security</b> because the content of the uploaded file stored unencrypted.<br />\n";
+                            echo "Please contact the administrator to have the temporary file " . $dir_name . '/' . $file . " deleted.\n";
+                        }
+                    }
+                }
+                else {
+                    //falls die ctime der Datei nicht ermittelt werden kann, wird eine Nachricht ausgegeben
+                    //aber nicht abgebrochen, da der Rest des Skriptes noch abgearbeitet werden soll
+                    echo "Error: Unable to get the ctime of the file: " . $dir_name . '/' . $file . "!<br />";
+                    echo "This constitutes a <b>breach of security</b> because the uploaded file will not be deleted and the content stored unencrypted.<br />\n";
+                    echo "Please contact the administrator to have the file deleted.\n";
+                }
+            }
+        }
+    }
+    else {
+        echo "Error: Can't open directory \"$dir_name\"!";
+    }
+}
+?>
+
+<?php
+//der footer wird includiert
+require KASTALIA_TEMPLATES . '/common-footer.inc';
+?>
\ No newline at end of file
diff --git a/kastalia/po/README b/kastalia/po/README
new file mode 100644 (file)
index 0000000..a985e94
--- /dev/null
@@ -0,0 +1 @@
+see horde/po/README
diff --git a/kastalia/temp/.htaccess b/kastalia/temp/.htaccess
new file mode 100644 (file)
index 0000000..3a42882
--- /dev/null
@@ -0,0 +1 @@
+Deny from all
diff --git a/kastalia/templates/common-footer.inc b/kastalia/templates/common-footer.inc
new file mode 100644 (file)
index 0000000..fffa1d9
--- /dev/null
@@ -0,0 +1,17 @@
+<script language="JavaScript1.5" type="text/javascript">
+<!--
+var _setHordeTitle = 1;
+try {
+    if (document.title && parent.frames.horde_main) parent.document.title = document.title;
+} catch (e) {
+}
+// -->
+</script>
+<script type="text/javascript">
+<!--
+if (typeof(_setHordeTitle) == 'undefined' && document.title && parent.frames.horde_main) parent.document.title = document.title;
+// -->
+</script>
+<?php if (isset($GLOBALS['notification'])) $GLOBALS['notification']->notify(array('listeners' => array('audio', 'javascript'))); ?>
+</body>
+</html>
diff --git a/kastalia/templates/common-header.inc b/kastalia/templates/common-header.inc
new file mode 100755 (executable)
index 0000000..4241186
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+if (isset($language)) {
+    header('Content-type: text/html; charset=' . NLS::getCharset());
+    header('Vary: Accept-Language');
+}
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">
+<!-- Kastalia: Copyright 2009 Andre Pawlowski  -->
+<!--     Horde Project: http://www.horde.org/ | Kastalia: http://h4des.org/index.php?inhalt=kastalia     -->
+<!--                 Horde Licenses: http://www.horde.org/licenses/                       -->
+<?php echo !empty($language) ? '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="' . strtr($language, '_', '-') . '" lang="' . strtr($language, '_', '-') . '">' : '<html>' ?>
+
+
+<head>
+
+<?php
+
+$page_title = $registry->get('name');
+if (!empty($title)) $page_title .= ' :: ' . $title;
+if (!empty($refresh_time) && ($refresh_time > 0) && !empty($refresh_url)) {
+    echo "<meta http-equiv=\"refresh\" content=\"$refresh_time;url=$refresh_url\">\n";
+}
+
+Horde::includeScriptFiles();
+
+?>
+<title><?php echo htmlspecialchars($page_title) ?></title>
+<link href="<?php echo $GLOBALS['registry']->getImageDir()?>/favicon.ico" rel="SHORTCUT ICON" />
+<?php echo Horde::stylesheetLink('kastalia') ?>
+</head>
+
+<body<?php if ($bc = Util::nonInputVar('bodyClass')) echo ' class="' . $bc . '"' ?><?php if ($bi = Util::nonInputVar('bodyId')) echo ' id="' . $bi . '"'; ?>>
diff --git a/kastalia/templates/menu.inc b/kastalia/templates/menu.inc
new file mode 100755 (executable)
index 0000000..dc4aabd
--- /dev/null
@@ -0,0 +1,4 @@
+<div id="menu">
+ <?php echo Kastalia::getMenu('string') ?>
+</div>
+<?php $GLOBALS['notification']->notify(array('listeners' => 'status')) ?>
diff --git a/kastalia/themes/graphics/directory_closed.gif b/kastalia/themes/graphics/directory_closed.gif
new file mode 100755 (executable)
index 0000000..c4f1138
Binary files /dev/null and b/kastalia/themes/graphics/directory_closed.gif differ
diff --git a/kastalia/themes/graphics/directory_open.gif b/kastalia/themes/graphics/directory_open.gif
new file mode 100644 (file)
index 0000000..09755aa
Binary files /dev/null and b/kastalia/themes/graphics/directory_open.gif differ
diff --git a/kastalia/themes/graphics/file.gif b/kastalia/themes/graphics/file.gif
new file mode 100644 (file)
index 0000000..b430f1e
Binary files /dev/null and b/kastalia/themes/graphics/file.gif differ
diff --git a/kastalia/themes/graphics/file_enc.gif b/kastalia/themes/graphics/file_enc.gif
new file mode 100644 (file)
index 0000000..8bd8bac
Binary files /dev/null and b/kastalia/themes/graphics/file_enc.gif differ
diff --git a/kastalia/themes/graphics/kastalia.png b/kastalia/themes/graphics/kastalia.png
new file mode 100755 (executable)
index 0000000..99460f9
Binary files /dev/null and b/kastalia/themes/graphics/kastalia.png differ
diff --git a/kastalia/themes/graphics/loader.gif b/kastalia/themes/graphics/loader.gif
new file mode 100644 (file)
index 0000000..a77150e
Binary files /dev/null and b/kastalia/themes/graphics/loader.gif differ
diff --git a/kastalia/themes/graphics/menu/upload.png b/kastalia/themes/graphics/menu/upload.png
new file mode 100644 (file)
index 0000000..1e22825
Binary files /dev/null and b/kastalia/themes/graphics/menu/upload.png differ
diff --git a/kastalia/themes/screen.css b/kastalia/themes/screen.css
new file mode 100755 (executable)
index 0000000..a219ca1
--- /dev/null
@@ -0,0 +1,44 @@
+a.kastalia_directory {
+    text-decoration: none;
+    font-weight: bold;
+    color: #000000;
+}
+
+div.kastalia_filelist {
+    margin-left: 0px;
+}
+
+img.kastalia_picture {
+    border: 0px;
+    margin-right: 2px;
+}
+
+li.kastalia_directory {
+    list-style: none;
+    display: block;
+    padding-top: 5px;
+    padding-left: 4px;
+}
+
+li.kastalia_file {
+/*    list-style: none;*/
+    list-style-image: url('graphics/file.gif');
+    padding-left: 4px;
+}
+
+li.kastalia_file_enc {
+/*    list-style: none;*/
+    list-style-image: url('graphics/file_enc.gif');
+    padding-left: 4px;
+}
+
+select.kastalia_upload {
+    width: 300px;
+}
+
+ul.kastalia_root {
+    list-style-position: inside;
+    margin-left: 5px;
+    padding-left: 10px;
+    vertical-align: middle;
+}
\ No newline at end of file
diff --git a/kastalia/upload.php b/kastalia/upload.php
new file mode 100644 (file)
index 0000000..e82ecbc
--- /dev/null
@@ -0,0 +1,207 @@
+<?php
+/**
+ *
+ * This product includes software developed by the Horde Project (http://www.horde.org/).
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author  Andre Pawlowski aka sqall <sqall@h4des.org>
+ */
+
+//das absolute Kastalia directory wird als Konstante definiert
+//um damit config Dateien zu includieren
+@define('KASTALIA_BASE', dirname(__FILE__));  
+
+//die Basis von Kastalia wird includiert
+//um die Anmeldung zu ueberpruefen
+require_once(KASTALIA_BASE . '/lib/base.php');
+//die Konfigurationsdatei von Kastalia wird includiert
+//um alle Kastalia Einstellungen in diesem Skript nutzen zu koennen
+require(KASTALIA_BASE . '/config/conf.php');
+//das Menu von Kastalia wird includiert
+//damit das Menu dem Benutzer angezeigt wird
+require_once(KASTALIA_BASE . '/list.php');
+
+echo "<div class=\"header\">Kastalia Datastore - Upload</div>\n";
+echo "<br />\n";
+
+//nun wird ueberprueft, ob das hochladen von Dateien ueberhaupt erlaubt ist
+//falls nicht, wird eine Meldung ausgegeben und das Skript beendet
+if(!$conf['upload']['uploadenabled']) {
+    echo "File uploads are disabled!";
+    exit(0);
+}
+
+//hier wird ueberprueft, ob der Zielordner zum hochladen gesetzt ist
+if(isset($_POST['kastalia_targetlocation'])) {
+    //hier wird mittels POST der uploadzielordner ermittelt
+    $kastalia_targetlocation = $_POST['kastalia_targetlocation'];
+    //Ueberpruefung nach den Zeichenfolgen "/." und "./" damit
+    //durch das Manipulieren der Variable kastalia_targetlocation
+    //keiner aus dem kastalia Datastore entkommen kann (durch Nutzung von "../")
+    if(strpos($kastalia_targetlocation,'/.') === false && strpos($kastalia_targetlocation,'./') === false) {
+        //ueberpruefung ob die Datei eine ".htaccess" ist, falls ja wird zur Sicherheit abgebrochen, damit niemand diese
+        //ueberschreiben kann oder damit regeln fuer den webserver festlegen kann 
+        if(Kastalia::ReplaceSpecialChars($_FILES['userfile']['name']) != ".htaccess") {
+            //hier wird serverseitig ueberprueft, ob die hochgeladene Datei die Endung ".kastaliaenc" besitzt
+            //falls ja wird mit einem Fehler abgebrochen, da diese intern von Kastalia verwendet wird
+            //um von Kastalia verschluesselte Dateien ausfindig zu machen
+            if(substr(Kastalia::ReplaceSpecialChars($_FILES['userfile']['name']), -12) == ".kastaliaenc") {
+                echo "Error: File extension \".kastaliaenc\" not allowed!";
+                exit(1);
+            }
+            //hier wird der absolute Pfad mit Dateiname (Sonderzeichen werden entfernt) zusammengesetzt
+            //wohin die Datei hochgeladen werden soll
+            $target_directory = $conf['datastore']['location'] . $kastalia_targetlocation;
+            $target_location = $target_directory . "/" . Kastalia::ReplaceSpecialChars($_FILES['userfile']['name']);
+            //diese Funktion fuehrt den Upload aus
+            UploadFile($target_location);
+        }
+        else {
+            echo "Error: .htaccess files not allowed for upload!";
+            exit(1);
+        }
+    }
+    else {
+        echo "Error: \$kastalia_targetlocation in upload.php contains illegal characters!";
+        exit(1);
+    }
+}
+//falls der Dateiname nicht gesetzt wurde, wird mit einer Fehlermeldung abgebrochen
+else {
+    echo "Error: \$kastalia_targetlocation in upload.php is not set!"; 
+    exit(1);
+}
+
+//diese Funktion ueberprueft Fehler die beim upload vorkommen koennen
+//und fuehrt den upload durch
+function UploadFile($upload_target) {
+    //die Konfigurationsdatei von Kastalia wird includiert
+    require(KASTALIA_BASE . '/config/conf.php');
+    if(!empty($_FILES)) {
+        switch ($_FILES['userfile']['error']) {
+            case 0: //UPLOAD_ERR_OK
+                //hier wird die in der Config eingestellte maximale Dateigroesse mit
+                //der Dateigroesse der hochgeladenen Datei abgeglichen
+                if($_FILES['userfile']['size'] <= $conf['upload']['maxfilesize']) {
+                    //Sicherheitsueberpruefung ob Datei mittels HTTP POST hochgeladen wurde
+                    //und nicht eine andere Datei weiterbearbeitet wird
+                    if(is_uploaded_file($_FILES['userfile']['tmp_name'])) {
+                        //hier wird ueberprueft ob der Upload verschluesselt gespeichert werden soll
+                        if(isset($_POST['kastalia_secure_store']) && $_POST['kastalia_secure_store'] == true) { //SECURE STORE
+                            //hier wird ueberprueft, ob das verschluesselte Speichern von Dateien ueberhaupt aktiviert ist
+                            //falls nicht, wird die Weiterverarbeitung abgebrochen und eine Meldung ausgegeben
+                            if(!$conf['upload']['securestore']) {
+                                echo "Encryption/Decryption is disabled!";
+                                exit(1);
+                            } 
+                            //sollte die Datei mit der Endung ".kastaliaenc" schon existieren, wird ein "_" an sie drangehaengt,
+                            //damit die existierende Datei nicht ueberschrieben wird
+                            while(file_exists($upload_target . ".kastaliaenc")) {
+                                $upload_target = $upload_target . "_";
+                            }
+                            //hier wird serverseitig ueberprueft ob das Passwort fuer die Verschluesselung leer ist
+                            //falls ja, wird mit einem Fehler abgebrochen, da dies verboten ist (und die temporaere Datei von
+                            //PHP automatisch geloescht) 
+                            if($_POST['kastalia_password'] == "") {
+                                echo "Error: Empty passwords not allowed!";
+                                exit(1);
+                            }
+                            //die hochgeladene Datei wird nun ersteinmal in das temporaere Verzeichnis von Kastalia verschoben
+                            //und mit der Endung "_kastalia" versehen
+                            if(move_uploaded_file($_FILES['userfile']['tmp_name'], $conf['upload']['tempdir'] . "/" . basename($_FILES['userfile']['tmp_name']) . "_kastalia")) {
+                                //die SESSION Variablen fuer die Verschluesselung werden gesetzt
+                                $_SESSION['kastalia_mode'] = "encrypt"; //diese Variable gibt den Modus an in welchem das Skript encrypt_decrypt_files.php ausgefuehrt werden soll
+                                $_SESSION['kastalia_input_name'] = $conf['upload']['tempdir'] . "/" . basename($_FILES['userfile']['tmp_name']) . "_kastalia"; //diese Variable gibt die zu verschluesselnde Datei an
+                                $_SESSION['kastalia_output_name'] = $upload_target; //diese Variable gibt das Ziel fuer die verschluesselte Datei an
+                                $_SESSION['kastalia_part_number'] = 0; //diese Variable gibt die aktuelle Verschluesselungsrunde an (die Beginnrunde ist immer 0)
+                                $_SESSION['kastalia_key'] = $_POST['kastalia_password']; //diese Variable beinhaltet das Passwort, welches fuer die Verschluesselung benutzt wird
+                                //mit der encrypt_decrypt_files.php wird die Verschluesselung fuer die Datei ausgefuehrt
+                                //(diese besteht aus mehreren Teilschritten wobei der Browser automatisch das Skript in Intervallen neu aufruft)
+                                include('encrypt_decrypt_files.php');
+                            } 
+                            else {
+                                echo "Error: File couldn't be moved to temporary directory!";
+                                //Debuging
+                                //print_r($_FILES);
+                                exit(1);
+                            }
+                        }
+                        else { //UNSECURE STORE
+                            //sollte die Datei schon existieren, wird ein "_" an sie drangehaengt,
+                            //damit die existierende Datei nicht ueberschrieben wird
+                            while(file_exists($upload_target)) {
+                                $upload_target = $upload_target . "_";
+                            }
+                            //die hochgeladene Datei wird nun an die dafuer vorgesehene stelle kopiert
+                            if(move_uploaded_file($_FILES['userfile']['tmp_name'], $upload_target)) {
+                                echo "File successfully stored under <b>" . substr($upload_target, strlen($conf['datastore']['location'] . "/")) . "</b> !\n";
+                            }
+                            else {
+                                echo "Error: File couldn't be moved!";
+                                //Debuging
+                                //print_r($_FILES);
+                                exit(1);
+                            }
+                        }
+                    }
+                    else {
+                        echo "Error: Used file is not uploaded via HTTP POST!";
+                        exit(1);
+                    }
+
+                }
+                else {
+                    echo "Error: The uploaded file exceeds the configured file size!";
+                    exit(1);
+                }
+                break;
+            case 1: //UPLOAD_ERR_INI_SIZE
+                echo "Error: The uploaded file exceeds the upload_max_filesize directive in php.ini!";
+                exit(1);
+                break;
+            case '2': //UPLOAD_ERR_FORM_SIZE
+                echo "Error: The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form!";
+                exit(1);
+                break;
+            case 3: //UPLOAD_ERR_PARTIAL
+                echo "Error: The file was only partially uploaded!";
+                exit(1);
+                break;
+            case 4: //UPLOAD_ERR_NO_FILE
+                echo "Error: No file was uploaded!";
+                exit(1);
+                break;
+            case 6: //UPLOAD_ERR_NO_TMP_DIR
+                echo "Error: Missing a temporary folder!";
+                exit(1);
+                break;
+            case 7: //UPLOAD_ERR_CANT_WRITE
+                echo "Error: Failed to write file to disk!";
+                exit(1);
+                break;
+            case 8: //UPLOAD_ERR_EXTENSION
+                echo "Error: File upload stopped by extension!";
+                exit(1);
+                break;
+            default:
+                echo "Error: Unexpected value of \$_FILES['file']['error'] in upload.php!";
+                exit(1);
+                break;
+        }
+    }
+    else {
+        echo "Error: \$_FILES is empty!<br /><br />";
+        echo "Possible reasons:<br />";
+        echo "-upload_max_filesize, post_max_size or memory_limit value is too low in php.ini.<br />";
+        echo "-file_uploads is set to Off in php.ini.";
+        exit(1);
+    }
+}
+?>
+
+<?php
+//der footer wird includiert
+require KASTALIA_TEMPLATES . '/common-footer.inc';
+?>
\ No newline at end of file
diff --git a/kastalia/upload_menu.php b/kastalia/upload_menu.php
new file mode 100644 (file)
index 0000000..3e07018
--- /dev/null
@@ -0,0 +1,258 @@
+<?php
+/**
+ *
+ * This product includes software developed by the Horde Project (http://www.horde.org/).
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author  Andre Pawlowski aka sqall <sqall@h4des.org>
+ */
+
+//das absolute Kastalia directory wird als Konstante definiert
+//um damit config Dateien zu includieren
+@define('KASTALIA_BASE', dirname(__FILE__));  
+
+//die Basis von Kastalia wird includiert
+//um die Anmeldung zu ueberpruefen
+require_once(KASTALIA_BASE . '/lib/base.php');
+//die Konfigurationsdatei von Kastalia wird includiert
+//um alle Kastalia Einstellungen in diesem Skript nutzen zu koennen
+require(KASTALIA_BASE . '/config/conf.php');
+//das Menu von Kastalia wird includiert
+//damit das Menu dem Benutzer angezeigt wird
+require_once(KASTALIA_BASE . '/list.php');
+
+echo "<div class=\"header\">Kastalia Datastore - Upload</div>\n";
+
+//nun wird ueberprueft, ob das hochladen von Dateien ueberhaupt erlaubt ist
+//falls nicht, wird eine Meldung ausgegeben und das Skript beendet
+if (!$conf['upload']['uploadenabled']) {
+    echo "<br />";
+    echo "File uploads are disabled!";
+    exit(0);
+}
+?>
+
+<!-- hier werden die JavaScripte zum erzeugen des sha-1 hashes includiert //-->
+<script src="js/sha1.js" type="text/javascript" language="JavaScript"></script>
+
+<script type="text/javascript" language="JavaScript">
+<!--
+//diese function ueberprueft die Werte des Formulars
+function FormularCheck() {
+   //hier wird ueberprueft ob eine Datei ausgewaehlt wurde
+   if(document.forms['upload'].elements['userfile'].value != "") {
+      //nun wird die Dateiendung ".kastaliaenc" extrahiert um zu pruefen, ob die Datei sie besitzt
+      var file_extension = document.forms['upload'].elements['userfile'].value;
+      file_extension = file_extension.substring(file_extension.length-12,file_extension.length);
+      file_extension = file_extension.toLowerCase();
+      //hier wird browserseitig ueberprueft, ob die Dateiendung ".kastaliaenc" nicht hochgeladen werden soll
+      if(file_extension == '.kastaliaenc') {
+         alert('Error: File extension \".kastaliaenc\" not allowed!');
+         return false;
+      }
+      //hier wird ueberprueft ob ein Zielordner fuer den upload ausgewaehlt wurde
+      if(document.forms['upload'].elements['kastalia_targetlocation'].selectedIndex != -1) {
+         <?php
+            //hier wird nun mit PHP ueberprueft, ob die Dateienverschluesselung aktiviert und das temporaere
+            //Verzeichnis schreibbar ist, da ansonsten das Element welches im JavaScript abgefragt wird nicht
+            //existiert und das JavaScript einen Fehler verursacht
+            if($conf['upload']['securestore'] && is_writable($conf['upload']['tempdir'])) {
+               //hier wird nun browserseitig ueberprueft, ob das verschluesselte speichern der Daten aktiviert wurde
+               echo "if(document.forms['upload'].elements['kastalia_secure_store'].checked == true) {\n";
+               //hier wird nun ueberprueft, ob das Passwort leer ist, falls ja, wird ein Error
+               //zurueck gegeben und abgebrochen
+               echo "if(document.forms['upload'].elements['kastalia_password'].value == '') {\n";
+                  echo "alert('Error: Empty passwords not allowed!');\n";
+                  echo "return false;\n";
+               echo "}\n";
+               echo "else {\n";
+                  //falls das Passwort gueltig ist und das verschluesselte speichern der Daten aktiviert wurde
+                  //wird das eingegebene Passwort vor dem abschicken durch einen sha-1 hash des Passwortes ersetzt
+                  //damit das Passwort nie im Klartext uebertragen wird, sondern nur der sha-1 hash zum ver/entschluesseln benutzt wird
+                  echo "document.forms['upload'].elements['kastalia_password'].value = hex_sha1(document.forms['upload'].elements['kastalia_password'].value);\n";
+                  echo "}\n";
+               echo "}\n";
+            }
+         ?>
+         //falls das verschluesselte speichern von Daten nicht aktiviert wurde
+         //oder die Ueberpruefungen des Passworts schon stattfanden
+         //wird true zurueck gegeben und der Loader sichtbar gemacht und das Menu unsichtbar
+         document.getElementById("loader").style.display='block';
+         document.getElementById("upload_menu").style.display='none';
+         return true;
+      }
+      else {
+         alert('Error: No upload directory chosen!');
+         return false;
+      }
+   }
+   else {
+      alert('Error: No file chosen!');
+      return false;
+   }
+}
+
+//diese Funktion zeigt im Browser die Passworteingabe an
+//sobald die checkbox zum verschluesselten speichern aktiviert wurde
+function ShowPasswordInput(input_id) {
+    //hier wird ueberprueft, ob die checkbox aktiviert ist...
+    if(document.forms['upload'].elements['kastalia_secure_store'].checked == true) {
+        //...falls ja, wird die Passworteingabe sichtbar
+        document.getElementById(input_id).style.display='block';
+    }
+    else {
+       //...falls nein, wird die Passworteingabe unsichtbar
+       document.getElementById(input_id).style.display='none';
+    }
+}
+
+//diese Funktion kopiert das von Kastalia generierte Passwort in das Passworteingabefeld
+function CopySuggestedPassword() {
+    document.forms['upload'].elements['kastalia_password'].value = document.forms['upload'].elements['kastalia_generated_password'].value;
+}
+//-->
+</script>
+
+<!--##################### <Informations Header> #####################//-->
+<p><b>notice:</b> cookies and javascripts must be enabled to upload files! | maximal upload size:
+
+<?php
+//Nutzerfreundlichere Ausgabe der maximalen upload file size auf zwei stellen hinter dem Komma gerundet
+$tempfilesize = $conf['upload']['maxfilesize'] / 1024 / 1024;
+if ($tempfilesize < 1) {
+    echo round($conf['upload']['maxfilesize'] / 1024, 2) . "kB";
+}
+else {
+    echo round($tempfilesize, 2) . "MB";
+}
+?>
+
+</p>
+<!--##################### </Informations Header> #####################//-->
+
+<!--##################### <Loader> #####################//-->
+<div id="loader" style="display:none;">
+<p>please wait...</p>
+<img border="0" src="themes/graphics/loader.gif" />
+</div>
+<!--##################### </Loader> #####################//-->
+
+<!--##################### <Form> #####################//-->
+<div id="upload_menu" style="display:block;">
+<form name="upload" enctype="multipart/form-data" method="post" action="upload.php" onsubmit="return FormularCheck()">
+<u>choose file:</u><input type="hidden" name="max_file_size" value="<?php echo $conf['upload']['maxfilesize']?>" />
+<input name="userfile" type="file" />
+<input type="submit" value="send" />
+<br />
+
+<?php
+//hier wird ueberprueft, ob die Option die Daten verschluesselt speichern zu lassen aktiviert ist
+//um die Eingabefelder fuer die Verschluesselung anzeigen zu lassen oder nicht
+if($conf['upload']['securestore']) {
+    //hier wird ueberprueft ob das temporaere Verzeichnis auch beschreibbar ist
+    //denn ansonsten wuerde ein verschluesseln der Daten nicht funktionieren
+    if(is_writable($conf['upload']['tempdir'])) {
+        //wenn das temporaere Verzeichnis beschreibbar ist, werden die EIngabefelder fuer die Verschluesselung ausgegeben
+        echo "<br /><u>encrypt file?:</u>\n";
+        echo "<input type=\"checkbox\" name=\"kastalia_secure_store\" onclick=\"ShowPasswordInput('password_input')\" />\n";
+        //dieser Teil wird nur angezeigt, wenn die checkbox zum 
+        //verschluesselten speichern der Daten aktiviert ist
+        echo "<div id=\"password_input\" style=\"display:none\">\n";
+        echo "<br /><u>password:</u>\n";
+        echo "<input name=\"kastalia_password\" type=\"password\" />\n";
+        echo "<input type=\"button\" value=\"insert suggested password\" onclick=\"CopySuggestedPassword()\" />\n";
+        echo "<br /><u>suggested password:</u>\n";
+        echo "<input name=\"kastalia_generated_password\" type=\"text\" value=\"" . CreateRandomPassword(10) . "\" disabled=\"disabled\" />\n";
+        echo "</div>\n";
+    }
+    //falls das temporaere Verzeichnis nicht beschreibbar ist, wird eine Warnmeldung ausgegeben
+    //und die Option Daten verschluesselt zu speichern wird ausgeblendet
+    else {
+        echo "<br />Warning: The option to store files encrypted is enabled by the administrator but still deactivated by Kastalia itself!<br />\n";
+        echo "Check if the temporary directory exists and is writable.\n";
+    }
+}
+?>
+
+<br />
+<br />
+<p><u>choose folder:</u></p>
+<select name="kastalia_targetlocation" size="20" class="kastalia_upload">
+
+<?php
+//diese if-Verzweigung ueberprueft das datastore selber
+//nach schreibrechten (Sonderfall der in der Scanfunction nicht geprueft werden kann) 
+if(is_dir($conf['datastore']['location']) && is_writable($conf['datastore']['location'])) {
+    echo "<option>/</option>";
+}
+//diese function scannt den Inhalt vom datastore
+//nach Ordnern mit schreibrechten und gibt diese dann aus
+ScanDirectory($conf['datastore']['location']);
+?>
+
+</select>
+</form>
+</div>
+<!--##################### </Form> #####################//-->
+
+<?php
+//diese function liest das datastore rekursiv aus
+//und gibt alle Ordner mit schreibzugriff in einer Auswahlliste aus
+function ScanDirectory($dir_name) {
+   //die Konfigurationsdatei von Kastalia wird includiert
+   //damit die Konfigurationen innerhalb dieser Funktion auch benutzt werden koennen
+   require(KASTALIA_BASE . '/config/conf.php');
+   if($dir_handle = opendir($dir_name)) {
+      //hier wird unser Array in dem die Ordnernamen zwischengespeichert werden deklariert
+      $directory_array = array();
+      //das Verzeichnis wird durchlaufen und der Inhalt untersucht
+      while(false !== ($file = readdir($dir_handle))) {
+         //Ueberpruefung ob es sich bei dem Element um einen Ordner handelt
+         //und dieser nicht in der Liste der nicht aufzulistenden Ordner steht...
+         if($file != "." && $file != ".." && is_dir($dir_name . '/' . $file) && !in_array($file, $conf['datastore']['directoryexcludes'])) {
+            //...falls ja, wird dieser zu unserem Array hinzugefuegt
+            $directory_array[] = $dir_name . '/' . $file;
+         }
+      }
+      //wenn das Verzeichnis ausgelesen wurde, wird unser Array sortiert
+      asort($directory_array);
+      //nun wird jedes einzelne Element unseres Arrays durchlaufen...
+      foreach($directory_array as $directory_element) {
+         //...und auf Schreibrechte ueberprueft, sind welche vorhanden
+         //wird der Ordner als Uploadordner ausgegeben
+         if(is_writable($directory_element)) {
+            echo "<option>";
+            echo substr($directory_element, strlen($conf['datastore']['location']));
+            echo "</option>";
+         }
+         //die Funktion wird noch einmal aufgerufen mit dem aktuellen Ordner um zu ueberpruefen
+         //ob Unterordner Schreibrechte enthalten
+         ScanDirectory($directory_element);
+      }
+      closedir($dir_handle);
+   }
+   else {
+      echo "Error: Can't open directory \"$dir_name\"!";
+      exit(1);
+   }
+}
+
+//diese Funktion generiert ein zufaelliges Passwort mit der uebergebenden laenge
+function CreateRandomPassword($passwordlength) {
+    //diese Zeichen koennen alle in dem Passwort vorkommen (beliebig veraenderbar)
+    $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-#*!$%=";
+    $password = '';
+    for($i=0;$i<$passwordlength;$i++) {
+        $randomnumber = mt_rand() % strlen($chars);
+        $password = $password . substr($chars, $randomnumber, 1);
+    }
+    return $password;
+}
+?>
+
+<?php
+//der footer wird includiert
+require KASTALIA_TEMPLATES . '/common-footer.inc';
+?>
\ No newline at end of file