0
0
Fork 0
easterhegg-2005-website/announce.php

416 lines
11 KiB
PHP

<?php
// diese Seite stellt Orga-Funktionen für die eh2005-Seite zur Verfügung
// + diese Seite liegt im öffentlichen Serverbereich, dieser darf *.php nicht als plain/text ausliefern ;)
// + diese Seite verlangt zwingend https
// + diese Seite fragt bei jedem Submit ein Authentifikationspasswort ab, es gibt jedoch keine Session
/*
Struktur dieser Seite:
+ write HTTP header
+ check, defuse and shorten input variables
+ Prüfung auf https
= OK => continue
= FAIL => Abbruchmeldung und Schlußverarbeitung
+ Prüfung auf gültige Authentifizierung
= OK => continue
= FAIL => Abbruchmeldung und Schlußverarbeitung
+ Prüfung auf Wartungsstatus
= OK => continue
= FAIL => Abbruchmeldung und Schlußverarbeitung
+ Verarbeitung der Submit-Aktionen (POST), Anzeige der einzelnen Orga-Formulare
*/
// this script needs following additional server modules for PHP
// - (none)
// write HTTP header (anti-cache)
header('Expires: Sun, 31 Dec 1989 23:59:59 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0');
header('Pragma: no-cache');
// define general server constants
define( "SERVER_SITE_MAINTENANCE", false ); // maintenance state, set to TRUE to lock this page temporarily
define( "SERVER_LOCALHOST_IP", "127.0.0.1" ); // localhost IP, which does not need authentication
define( "SERVER_PROTOCOL_HTTPS", "HTTPS" ); // HTTPS protocol name
// define server file constants
define( "SERVER_FILE_MYSELF", "announce.php" ); // submit target of forms = this file itself
define( "SERVER_FILE_ANNOUNCE", "index.shtml" ); // announcement file; e.g. index file
define( "SERVER_FILE_HEADER", "ssi_site_header.html" ); // SSI file for site header
define( "SERVER_FILE_INTRO", "ssi_site_intro.html" ); // SSI file for site intro
define( "SERVER_FILE_EXTRO", "ssi_site_extro.html" ); // SSI file for site extro
// define auth constants
define( "AUTH_SERVER_PASS", "Osterüberraschung" ); // auth password, [todo:] should be outsourced to an external, secured data file
// init references to $_POST variables ($pxxx)
$pstrauth = & $_POST['txtauth'];
$pstrtitle = & $_POST['txttitle'];
$pstrannouncement = & $_POST['txtannouncement'];
$pbolannouncement = & $_POST['cmdannouncement'];
// init post variables (only for mandatory variables, ignore variables submitted by special forms!)
if ( !isset($pstrauth) ) $pstrauth = '';
if ( !isset($pstrtitle) ) $pstrtitle = '';
if ( !isset($pstrannouncement) ) $pstrannouncement = '';
// init instance variables
$intnow = time();
$strmsg = ''; // (status/error/etc.) message to user
$strauth = '';
$strinput = '';
$stroutput = '';
$intfileid = 0;
$strtitle = '';
$strannouncement = '';
$strauth = '';
$bolannouncement = false;
$bolauthabort= false;
$bolok = false; // action feedback, triggers confirmation if true or warning if false
// function library
function addmsg ($straddmsg)
{
// adds $straddmsg to $strmsg
global $strmsg;
if ( $straddmsg != '' )
{
$strmsg = $strmsg . '<li>' . $straddmsg . '</li>';
}
}
function showmsg ()
{
// shows messages in $strmsg if available
global $strmsg, $bolok;
if ( $strmsg != '' )
{
echo
'
<div class="announcement">
<h3 class="';
if ( $bolok )
{
echo 'confirmation';
}
else
{
echo 'warning';
}
echo '">Feedback</h3>
<ul>' . $strmsg . '</ul>
</div>
';
$strmsg = '';
}
}
// check input variables
//$bolannouncement = isset( $pbolannouncement ); // does not work in IE when submitted from within a text field by pressing Return key, reason unknown
$bolannouncement = ( isset( $pbolannouncement ) || $pstrannouncement != '' ); //workaround for IE problem, see line above
$intwsid = $pintwsid;
$strtitle = $pstrtitle;
$strannouncement = $pstrannouncement;
$strauth = $pstrauth;
// defuse input variables
$strtitle = trim( htmlentities( $pstrtitle, ENT_QUOTES ));
// leave announcement html'ed
//$strannouncement = trim( htmlentities( $pstrannouncement, ENT_QUOTES ));
$strauth = trim( htmlentities( $pstrauth, ENT_QUOTES ));
// shorten input variables
if ( strlen( $strauth ) > 255 ) $strauth = substr( $strauth, 0, 4095 ); //cut it, do not modify
if ( strlen( $strtitle ) > 255 ) $strtitle = substr( $strtitle, 0, 252 ) . "...";
if ( strlen( $strannouncement ) > 4095 ) $strannouncement = substr( $strannouncement, 0, 4092 ) . "...";
if
(
// localhost access
(
// direkter Aufruf von localhost
htmlspecialchars( $_SERVER['HTTP_X_FORWARDED_FOR'], ENT_QUOTES ) == ''
&&
htmlspecialchars( $_SERVER['REMOTE_ADDR'], ENT_QUOTES ) == constant("SERVER_LOCALHOST_IP")
)
||
(
// indirekter Aufruf (z.B. transparenter SSL-Proxy) mit übergebenem localhost
htmlspecialchars( $_SERVER['HTTP_X_FORWARDED_FOR'], ENT_QUOTES ) == constant("SERVER_LOCALHOST_IP")
)
)
{
// localhost ist immer eingeloggt
// -> continue
}
else
{
// check protocol and timeout
// check secure connection
// possible results:
// - secure => continue
// - insecure => force logout ($bolauthlogoutnow), show error page and prepare message ($strmsg)
if
(
(
// direct connection without HTTPS
$_SERVER['HTTPS'] == ''
&&
$_SERVER['HTTP_X_FORWARDED_PROTO'] == ''
)
||
(
// indirect connection without local HTTPS proxy, e.g. orenosp
strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) != strtolower(constant("SERVER_PROTOCOL_HTTPS"))
&& $_SERVER['HTTP_X_FORWARDED_PROTO'] != ''
)
)
{
// insecure connection -> abort
addmsg ( 'Dein Verbindungsprotokoll ist HTTP. Bitte verwende für die Announce-Seite Verschlüsselung mittels HTTPS.' );
$bolauthabort = true;
}
}
// check maintenance state
if ( constant("SERVER_SITE_MAINTENANCE") )
{
// cancel because of maintenance
addmsg ( 'Die Announce-Seite ist zurzeit wegen Wartungsarbeiten deaktiviert. Bitte sp&auml;ter wiederkommen. Danke.' );
$bolauthabort = true;
}
// prepare announce page
// assume that all ssi files are there. No, I won't check _that_ explicitely.
// If they ain't there, the user gets a partial page. ...so what? ;o)
readfile( constant("SERVER_FILE_HEADER") );
echo
'
<!-- begin of specific page header -->
<title>Easterhegg 2005 - Announce</title>
<!-- end of specific page header -->
';
readfile( constant("SERVER_FILE_INTRO") );
echo
'
<!-- begin of specific page content -->
';
// show msg, if available
if ( $strmsg != '' )
{
echo
'
<div class="announcement">
<h3 class="warning">Authentifizierungshinweis:</h3>
<ul>' . $strmsg . '</ul>
</div>
';
$strmsg = '';
$bolauthabort = true;
}
showmsg();
if ( $bolauthabort )
{
// close page and stoprun.
echo
'
<!-- end of specific page content -->
';
readfile( constant("SERVER_FILE_EXTRO") );
die();
}
// Well, Checkpoint.
// Now a defined and normal state of checking has been reached.
// Possible states are now:
// - $bolauthabort = false: user is authenticated to see this page
// - $bolauthabort = true: user is not authenticated to see this page
// If there were any messages on the way up to here, they are stored as list items (<li>) in variable $strmsg.
// check auth phrase if user tries to login
if ( $bolannouncement )
{
if ( $strauth == htmlentities( constant("AUTH_SERVER_PASS") , ENT_QUOTES ))
{
// auth accepted
if ( $strannouncement != '' )
{
// announcement accepted
if ( $strtitle != '' )
{
// title accepted
// -> continue
$bolok = true;
// this feature has been deactivated on the production machine due to security reasons
// to use it on your own machine just delete or uncomment the following lines
//addmsg ( 'Diese Funktion wurde aus Sicherheitsgründen deaktiviert.<br>Um sie auf Deiner Umgebung zu reaktivieren, entferne die Sperre in der Datei &quot;announce.php&quot;.' );
//$bolok = false;
}
else
{
// title empty
addmsg ( 'Bitte gib noch einen griffigen Titel an! Danke :-)' );
}
}
else
{
// announcement empty
addmsg ( 'Das Announcement funktioniert besser, wenn Du etwas zum Announcen einträgst... ;-)' );
}
}
else
{
// auth failed
addmsg ( 'Das klappt so nicht. Vermutlich hast Du Dich beim Passwort vertippt.' );
}
}
echo
'
<div class="announcement">
<h3 class="announcement">Announce</h3>
</div>
';
if ( $bolok && $bolannouncement )
{
$bolok = false;
//announce it now
$strinput = file_get_contents( constant("SERVER_FILE_ANNOUNCE") );
$stroutput =
'
<div class="chapter">
<h4>' . $strtitle . '</h4>
<p>
<span class="timestamp">' . date( "d.m.Y", $intnow ) . '</span>
' . $strannouncement . '
</p>
</div>
';
$stroutput = str_replace( "<!--> [%announcement%] </!-->", '<!--> [%announcement%] </!-->' . $stroutput, $strinput );
if ( is_writable( constant("SERVER_FILE_ANNOUNCE") ))
{
// file_put_contents does not work with PHP 4.x, so use instead: fopen, fwrite, fclose
// file_put_contents( constant("SERVER_FILE_ANNOUNCE"), $stroutput );
$intfileid = fopen( constant("SERVER_FILE_ANNOUNCE"), "w" );
fwrite( $intfileid, $stroutput );
fclose( $intfileid );
$bolok = true;
}
else
{
addmsg ( 'Die Workshopdatei &quot;' . constant("SERVER_FILE_ANNOUNCE") . '&quot; konnte nicht geschrieben werden. (Rechteproblem?)');
$bolok = false;
}
}
if ( $bolannouncement )
{
if ( $bolok )
{
addmsg ( 'Das Announcement wurde gesetzt.' );
}
else
{
addmsg ( 'Das Announcement wurde nicht gesetzt.' );
}
}
showmsg();
// show announce page
echo
'
<div class="chapter">
<h4>Startseiten-Announcement</h4>
</div>
<div>
<form id="announceform" name="announceform" action="' . constant("SERVER_FILE_MYSELF") . '" method="post">
<p>
Hier können Announcements abgegeben werden, die anschließend auf der Startseite erscheinen.<br />
HTML ist nicht nur erlaubt, sondern auch präferiert. Es wird darum gebeten, XHTML-konform zu bleiben.<br />
<span class="line important"><span class="topic">Achtung:</span>Abgegebene Announcements können hier nicht mehr zurückgenommen oder korrigiert werden!</span>
</p>
<p>
<span class="topic">Authentifizierung:</span><input name="txtauth" type="password" />
<span class="topic">Titel:</span><input name="txttitle" type="text" ';
if ( !$bolok ) echo 'value="' . $strtitle . '" ';
echo '/>
<span class="topic">Announcement: <span class="small">(HTML accepted)</span></span>
<textarea class="db big" name="txtannouncement">';
if ( !$bolok ) echo $strannouncement;
echo
'</textarea>
<input name="cmdannouncement" type="submit" value="Spread it now!" />
</p>
</form>
</div>
';
// close page and stoprun.
echo
'
<!-- end of specific page content -->
';
readfile( constant("SERVER_FILE_EXTRO") );
die();
?>