<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ulrich-Block.de</title>
	<atom:link href="http://www.ulrich-block.de/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.ulrich-block.de</link>
	<description></description>
	<lastBuildDate>Mon, 13 Feb 2012 13:29:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Die Steam Web API und Updates</title>
		<link>http://www.ulrich-block.de/die-steam-web-api-und-updates/</link>
		<comments>http://www.ulrich-block.de/die-steam-web-api-und-updates/#comments</comments>
		<pubDate>Mon, 13 Feb 2012 12:57:46 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[Server]]></category>
		<category><![CDATA[steam]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Autoupdate]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1733</guid>
		<description><![CDATA[Von vielen unbemerkt hat Valve schon seit einiger Zeit eine umfangreiche Steam Web API bereitgestellt. Die Dokumentation ist leider nicht sehr vollständig und in der Valve Developer WIKI zu finden. Die Anfrage an die API wird mittels GET Parametern gemacht. Die Antwort kann in den Formaten XML, JSON und VDF ausgegeben werden. Ein für Serveroperatoren sehr interessanter Teil ist leider nicht dokumentiert. Mittels der Valve Developer WIKI kann man zu SteamApps Versionsnummern mit der aktuellen abgleichen lassen. Im Fall von Counter-Strike: Source würde eine Abfrage mit XML folgendermaßen aussehen: https://api.steampowered.com/ISteamApps/UpToDateCheck/v0001/?appid=240&#38;version=1.0.0.69&#38;format=xml Die aktuelle Version ist 1.0.0.70. Deswegen ist die XML Antwort:]]></description>
			<content:encoded><![CDATA[<p>Von vielen unbemerkt hat Valve schon seit einiger Zeit eine umfangreiche Steam Web API bereitgestellt. Die Dokumentation ist leider nicht sehr vollständig und in der <a href="referrer.php?r=https://developer.valvesoftware.com/wiki/Steam_Web_API" target="_blank">Valve Developer WIKI</a> zu finden.</p>
<p>Die Anfrage an die API wird mittels GET Parametern gemacht. Die Antwort kann in den Formaten XML, JSON und VDF ausgegeben werden.</p>
<p>Ein für Serveroperatoren sehr interessanter Teil ist leider nicht dokumentiert. Mittels der Valve Developer WIKI kann man zu SteamApps Versionsnummern mit der aktuellen abgleichen lassen. Im Fall von Counter-Strike: Source würde eine Abfrage mit XML folgendermaßen aussehen:</p>
<blockquote><p>https://api.steampowered.com/ISteamApps/UpToDateCheck/v0001/?appid=240&amp;version=1.0.0.69&amp;format=xml</p></blockquote>
<p>Die aktuelle Version ist 1.0.0.70. Deswegen ist die XML Antwort:</p>
<pre class="brush:xml">
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE response&gt;
&lt;response&gt;
	&lt;success&gt;true&lt;/success&gt;
	&lt;up_to_date&gt;false&lt;/up_to_date&gt;
	&lt;version_is_listable&gt;false&lt;/version_is_listable&gt;
	&lt;required_version&gt;10070&lt;/required_version&gt;
	&lt;message&gt;Your server is out of date, please upgrade&lt;/message&gt;
&lt;/response&gt;
</pre>
<p>Fragt man mit einer aktuellen Version nach:</p>
<pre class="brush:xml">
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE response&gt;
&lt;response&gt;
	&lt;success&gt;true&lt;/success&gt;
	&lt;up_to_date&gt;true&lt;/up_to_date&gt;
	&lt;version_is_listable&gt;true&lt;/version_is_listable&gt;
&lt;/response&gt;
</pre>
<p>Mittels der API kann man  sich also relativ einfach ein Script schreiben, dass die lokale Serverversion mit der aktuellen abgleicht. Im Folgenden wird dann je nach Output reagiert. Wenn &#8220;up_to_date&#8221; &#8220;False&#8221; ist, kann z.B. ein Update gestartet werden.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/die-steam-web-api-und-updates/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Vserver, Rootserver und dedizierte Server Nr.2</title>
		<link>http://www.ulrich-block.de/vserver-rootserver-und-dedizierte-server-nr-2/</link>
		<comments>http://www.ulrich-block.de/vserver-rootserver-und-dedizierte-server-nr-2/#comments</comments>
		<pubDate>Thu, 09 Feb 2012 12:51:45 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[dedizierte Server]]></category>
		<category><![CDATA[Rootserver]]></category>
		<category><![CDATA[Vserver]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1728</guid>
		<description><![CDATA[In einem früheren Beitrag hatte ich den Unterschiede zwischen Vserver, Rootserver und dediziertem Server beschrieben. Dort bin ich auch auf Möglichkeiten eingegangen, wie man ein System auf der Konsole als Vserver identifizieren kann. Eine sehr einfach Möglichkeit hatte ich vergessen. Mit dem Programm dmidecode kann man die Hardwareinformationen seines Servers auslesen. Manchen Images enthalten es bereits. Bei anderen muss es noch installiert werden. Die interessanteste Ausgabe ist die des Systemherstellers. Der Befehl dazu lautet: dmidecode -s system-manufacturer Auf einem mit VMWare virtualisiertem System ist die Ausgabe: dmidecode -s system-manufacturer VMware, Inc. Bei Virtuozzo hingegen ist ein Zugriff auf diese Informationen]]></description>
			<content:encoded><![CDATA[<p>In einem <a href="http://www.ulrich-block.de/vserver-rootserver-dedizierte-server-und-schwarze-schafe/" target="_blank">früheren Beitrag</a> hatte ich den Unterschiede zwischen Vserver, Rootserver und dediziertem Server beschrieben. Dort bin ich auch auf Möglichkeiten eingegangen, wie man ein System auf der Konsole als Vserver identifizieren kann.</p>
<p>Eine sehr einfach Möglichkeit hatte ich vergessen. Mit dem Programm <strong>dmidecode</strong> kann man die Hardwareinformationen seines Servers auslesen. Manchen Images enthalten es bereits. Bei anderen muss es noch installiert werden.</p>
<p>Die interessanteste Ausgabe ist die des Systemherstellers. Der Befehl dazu lautet:</p>
<blockquote><p>dmidecode -s system-manufacturer</p></blockquote>
<p>Auf einem mit VMWare virtualisiertem System ist die Ausgabe:</p>
<blockquote><p>
dmidecode -s system-manufacturer<br />
VMware, Inc.
</p></blockquote>
<p>Bei Virtuozzo hingegen ist ein Zugriff auf diese Informationen gar nicht erst möglich:</p>
<blockquote><p>
dmidecode -s system-manufacturer<br />
/dev/mem: Permission denied
</p></blockquote>
<p>Auf einem dedizierten Server von Fujitsu ist die Ausgabe:</p>
<blockquote><p>
dmidecode -s system-manufacturer<br />
FUJITSU
</p></blockquote>
<p>Auch MSI Mainboads melden sich entsprechend:</p>
<blockquote><p>
dmidecode -s system-manufacturer<br />
MSI
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/vserver-rootserver-und-dedizierte-server-nr-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Steam-Service wird installiert</title>
		<link>http://www.ulrich-block.de/steam-service-wird-installiert/</link>
		<comments>http://www.ulrich-block.de/steam-service-wird-installiert/#comments</comments>
		<pubDate>Mon, 06 Feb 2012 11:12:54 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[Steam]]></category>
		<category><![CDATA[Installieren]]></category>
		<category><![CDATA[Service]]></category>
		<category><![CDATA[steam]]></category>
		<category><![CDATA[Steam-Service]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1720</guid>
		<description><![CDATA[Beim Straten von Steam begrüßte mich heute folgende Meldung: Steam-Service wird installiert Zum korrekten Ausführen von Steam mit dieser Version von Windows muss die Steam-Service-Komponente innstaliert sein. Für die Installation der Service-Komponente sind Administratoren-Zugriffsrechte erforderlich. SERVICE INSTALLIEREN ABBRECHEN Ich war erstmal reichlich verwundert, zumal Steam dies bisher nicht getan hatte. Bevor ich auf den Button &#8220;SERVICE INSTALLIEREN&#8221; klicke, wollte ich erst einmal wissen, ob dieses Fenster überhaupt zu Steam gehört, oder mir etwas untergeschoben worden ist. Mein Nutzerverhalten kann man zwar als vorsichtig bezeichnen, dennoch kann man nie wissen, was man sich trotzdem eingefangen haben könnte. Eine Google Suche brachte]]></description>
			<content:encoded><![CDATA[<p>Beim Straten von Steam begrüßte mich heute folgende Meldung:</p>
<blockquote><p>Steam-Service wird installiert</p>
<p>Zum korrekten Ausführen von Steam mit dieser Version von Windows muss die Steam-Service-Komponente innstaliert sein.<br />
Für die Installation der Service-Komponente sind Administratoren-Zugriffsrechte erforderlich.</p>
<p>SERVICE INSTALLIEREN		ABBRECHEN</p></blockquote>
<p>Ich war erstmal reichlich verwundert, zumal Steam dies bisher nicht getan hatte. Bevor ich auf den Button <em>&#8220;SERVICE INSTALLIEREN&#8221;</em> klicke, wollte ich erst einmal wissen, ob dieses Fenster überhaupt zu Steam gehört, oder mir etwas untergeschoben worden ist. Mein Nutzerverhalten kann man zwar als vorsichtig bezeichnen, dennoch kann man nie wissen, was man sich trotzdem eingefangen haben könnte.</p>
<p>Eine Google Suche brachte nichts 100% konkretes zu Tage. Man konnte aber sehen, dass die Nachricht von Valve bzw. Steam kommt. Damit war meine erste Befürchtung, dass mein System kompromittiert ist, zum Glück falsch.</p>
<p>Tendentiell ist es wohl ein Problem mit der Rechteverwaltung des Windowsusers. Steam benötigt für die Installation eines Updates wohl Adminsitratorrechte. Bei der Autoerkennung dieser Rechte muss ein Problem bestehen, so dass der Updater nicht direkt gestartet werden kann.</p>
<p>Ich entschied mich dafür, den <em>&#8220;SERVICE INSTALLIEREN&#8221;</em> Button zu betätigen. Die Windows Administrator Warnung erschien. Sie bestätigte mir, dass die Anwendung von Valve kommt und als solche verifiziert ist.<br />
Nachdem ich Windows erlaubt hatte, das Programm auszuführen, wurde der Updater gestartet. Im Anschluss startete Steam ohne weitere Probleme.</p>
<p>Mein Fazit:<br />
Lieber einmal zu vorsichtig sein, als irgendwann das Nachsehen zu haben.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/steam-service-wird-installiert/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Neues aus dem Maschinenraum</title>
		<link>http://www.ulrich-block.de/neues-aus-dem-maschinenraum/</link>
		<comments>http://www.ulrich-block.de/neues-aus-dem-maschinenraum/#comments</comments>
		<pubDate>Tue, 31 Jan 2012 10:05:07 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[easy-wi.com]]></category>
		<category><![CDATA[Webinterface]]></category>
		<category><![CDATA[cms]]></category>
		<category><![CDATA[Gameserver]]></category>
		<category><![CDATA[MYSQL]]></category>
		<category><![CDATA[Neuerungen]]></category>
		<category><![CDATA[panel]]></category>
		<category><![CDATA[Update]]></category>
		<category><![CDATA[voiceserver]]></category>
		<category><![CDATA[webinterface]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1712</guid>
		<description><![CDATA[Ich möchte einen kleinen Einblick auf die kommende Version meines Webinterfaces Easy-Wi geben. Es wird zwei wesentliche Neuerungen geben. Zum einen arbeite ich gerade mit Hochdruck an einem CMS. Heutzutage selbstverständliche Funktionen, wie Rewrite Urls und Mehrsprachigkeit, werden selbstverständlich unterstützt. Setzt man Rewrite Urls ein, kann man Links wie domain.tld/de/Leihserver/, oder domain.tld/uk/Lendserver/Gameserver/ benutzen. Keywords können je Artikel oder Seite gesetzt werden. Seiten, wie die Verleih- und Protectionmodeseite, die bereits losgelöst vom CMS bestanden haben, sind ebenfalls mit von der Partie. Die zweite Neuerung ist das Layout der Adminoberfläche. Die Menüführung wurde komplett überarbeitet und sollte die Arbeitsabläufe beschleunigen. Beim Hover]]></description>
			<content:encoded><![CDATA[<p>Ich möchte einen kleinen Einblick auf die kommende Version meines Webinterfaces <a href="http://easy-wi.com" target="_blank">Easy-Wi</a> geben. Es wird zwei wesentliche Neuerungen geben.</p>
<p>Zum einen arbeite ich gerade mit Hochdruck an einem CMS. Heutzutage selbstverständliche Funktionen, wie Rewrite Urls und Mehrsprachigkeit, werden selbstverständlich unterstützt. Setzt man Rewrite Urls ein, kann man Links wie <em>domain.tld/de/Leihserver</em>/, oder <em>domain.tld/uk/Lendserver/Gameserver/</em> benutzen.<br />
Keywords können je Artikel oder Seite gesetzt werden.<br />
Seiten, wie die Verleih- und Protectionmodeseite, die bereits losgelöst vom CMS bestanden haben, sind ebenfalls mit von der Partie.</p>
<p>Die zweite Neuerung ist das Layout der Adminoberfläche. Die Menüführung wurde komplett überarbeitet und sollte die Arbeitsabläufe beschleunigen.</p>
<p>Beim Hover über das Menü wird das jeweilige Untermenü eingeblendet. Sobald man in einem Unterbereich arbeitet, wird die Subnavi zu diesem Bereich, die vorher nur über Hover erreichbar war, unterhalb der Überschrift des Bereiches aufgeklappt und permanent angezeigt. Sobald man den Bereich wieder verlässt, wird das zugehörige Untermenü wieder ausgeblendet.<br />
Durch die neue Struktur kann ich wesentlich mehr Menüelemente einbauen, ohne dass es unübersichtlich wird.</p>
<p>Des Weiteren gibt es nun Rechts eine Übersicht, die bei Events, also Anzahl der Einträge größer als 0, farblich hervorgehoben wird. Es wird demnach beim Arbeiten sofort farblich ins Auge stechen, wenn man sich um etwas kümmern sollte.</p>
<p>Insgesamt habe ich versucht, durch Schattenwürfe, Trennlinien und Farbverläufe das Layout etwas aufzulockern.</p>
<p>Der derzeitige WIP Status sieht folgendermaßen aus:<br />
<a href="http://www.ulrich-block.de/wp-content/uploads/2012/01/easy-wi-preview.jpg" target="_blank"><img src="http://www.ulrich-block.de/wp-content/uploads/2012/01/easy-wi-preview-300x262.jpg" alt="" title="easy-wi-preview" width="300" height="262" class="alignleft size-medium wp-image-1715" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/neues-aus-dem-maschinenraum/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Spammer, Webspell und Stopforumspam.com</title>
		<link>http://www.ulrich-block.de/spammer-webspell-und-stopforumspam-com/</link>
		<comments>http://www.ulrich-block.de/spammer-webspell-und-stopforumspam-com/#comments</comments>
		<pubDate>Fri, 27 Jan 2012 14:01:35 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Spam]]></category>
		<category><![CDATA[stopforumspam.com]]></category>
		<category><![CDATA[Webspell]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1698</guid>
		<description><![CDATA[Das CMS Webspell hat, wie so ziemlich jedes andere CMS auch, mit Spammern zu kämpfen. Der Clan myRevenge e.V. setzt Webspell ein und hat mich um Hilfe mit ihrem Spam Problem gebeten. Trotz Captcha und Bestätigungslink schaffen es Spammer immer wieder sich anzumelden oder als Gast zu spammen. Nach einer erfolgreichen Anmeldung wird im zweiten Schritt auch in Bereichen gespmamt, in denen Gäste keine Schreibrechte haben. Um den Spam einzudämmen, bietet sich eine Überprüfung an, wer so schreibt. Dabei macht man sich zu Nutze, dass Spammer wiederkehrende E-Mail Adressen und Usernamen verwenden. Im ersten Schritt werden unerwünschte Top Level Domains]]></description>
			<content:encoded><![CDATA[<p>Das CMS <a href="referrer.php?r=http://www.webspell.org" target="_blank">Webspell</a> hat, wie so ziemlich jedes andere CMS auch, mit Spammern zu kämpfen. Der Clan <a href="referrer.php?r=http://www.myrevenge.net" target="_blank">myRevenge e.V.</a> setzt Webspell ein und hat mich um Hilfe mit ihrem Spam Problem gebeten. Trotz Captcha und Bestätigungslink schaffen es Spammer immer wieder sich anzumelden oder als Gast zu spammen. Nach einer erfolgreichen Anmeldung wird im zweiten Schritt auch in Bereichen gespmamt, in denen Gäste keine Schreibrechte haben.</p>
<p>Um den Spam einzudämmen, bietet sich eine Überprüfung an, wer so schreibt. Dabei macht man sich zu Nutze, dass Spammer wiederkehrende E-Mail Adressen und Usernamen verwenden.</p>
<p>Im ersten Schritt werden unerwünschte Top Level Domains und Domainendungen in 2 Arrays übergeben und überprüft, ob die verwendete E-Mail einen dieser Kriterien entspricht. Weil Spammer sehr flexibel sind, stellt diese Maßnahme lediglich einen Tropfen auf den heißen Stein dar.</p>
<p>Wesentlich effizienter ist der zweite Schritt. Hier wird die API von <a href="referrer.php?r=http://stopforumspam.com" target="_blank">stopforumspam.com</a> kontaktiert und gefragt, ob Name, oder E-Mail bereits als Spammer bekannt sind. Stopforumspam.com ist eine Seite, die bekannte Spammer sammelt und nicht kommerziellen Nutzern eine API zu der Datenbank anbietet.<br />
Nur wenn die API antwortet, dass der Datensatz unbekannt ist, darf der User sich anmelden, bzw. einen Kommentar schreiben.</p>
<p>Die beschriebenen Ergänzungen werden in den Dateien register.php und comments.php vorgenommen.<br />
<span id="more-1698"></span><br />
Die Erweiterung der register.php:</p>
<pre class="brush:php">
// check e-mail
if(!validate_email($mail)) {
	$error[]=$_language-&gt;module['invalid_mail'];
} else {
	// Liste mit unzulaessigen Maildomains
	$badmaildomains=array('willich.nicht','auchnicht.de');
	// Liste mit unzulaessigen TLs array('cn','xxx')
	$badtld=array();
	// Useraccount von Domain trennen
	list($user,$domain)=explode('@',$mail);
	// Top Level herausfinden
	$domain_explode=explode('.',$domain);
	$last_array_entry=count($domain_explode)-1;
	// Überpruefen, ob die Domain geblacklisted ist
	if (in_array($domain,$badmaildomains) or in_array($domain_explode[$last_array_entry],$badtld)) {
		$error[]=$_language-&gt;module['invalid_mail'];
	} else {
		// Stopforumspam kontaktieren:
		$opts=stream_context_create(array('http'=&gt;array('method'=&gt;'GET','header'=&gt;"Accept-language: en\r\nUser-Agent: ".$_SERVER['HTTP_HOST']."\r\n")));
		$contact_stopforumspam=@file_get_contents('http://www.stopforumspam.com/api?email[]='.urlencode($mail).'&amp;username[]='.urlencode($username).'&amp;username[]='.urlencode($nickname),false,$opts);
		if($contact_stopforumspam!=false) {
			$xmlreply = simplexml_load_string($contact_stopforumspam);
			foreach ($xmlreply as $xml_key =&gt; $xmlcheck) {
				// Wenn der Spammer in der Datenbank erfasst ist, feststellen, ob die Mail und oder der Username bekannt war und einen entsprechenden Fehler ausgeben
				if ($xmlcheck-&gt;appears==1) {
					if ($xml_key=='email') {
						$error[]=$_language-&gt;module['invalid_mail'];
					} else if ($xml_key=='username') {
						$error[]=$_language-&gt;module['nickname_inuse'];
					}
				}
			}
		}
	}
}
</pre>
<p>Und die Änderung in der comments.php:</p>
<pre class="brush:php">
function IsNoSpammer ($mail,$username,$useragent) {
	$nospammer=true;
	// Liste mit unzulaessigen Maildomains
	$badmaildomains=array('willich.nicht','auchnicht.de');
	// Liste mit unzulaessigen TLs array('cn','xxx')
	$badtld=array();
	// Useraccount von Domain trennen
	list($user,$domain)=explode('@',$mail);
	// Top Level herausfinden
	$domain_explode=explode('.',$domain);
	$last_array_entry=count($domain_explode)-1;
	// Überpruefen, ob die Domain geblacklisted ist
	if (in_array($domain,$badmaildomains) or in_array($domain_explode[$last_array_entry],$badtld)) {
		$nospammer=false;
	}
	$opts=stream_context_create(array('http'=&gt;array('method'=&gt;'GET','header'=&gt;"Accept-language: en\r\nUser-Agent: ".$useragent."\r\n")));
	$contact_stopforumspam=@file_get_contents('http://www.stopforumspam.com/api?email[]='.urlencode($mail).'&amp;username[]='.urlencode($username),false,$opts);
	if($contact_stopforumspam!=false) {
		$xmlreply = simplexml_load_string($contact_stopforumspam);
		foreach ($xmlreply as $xml_key =&gt; $xmlcheck) {
			// Wenn der Spammer in der Datenbank erfasst ist, $nospammer auf false setzen
			if ($xmlcheck-&gt;appears==1) {
				$nospammer=false;
			}
		}
	}
	return $nospammer;
}
if (IsNoSpammer($mail,$name,$_SERVER['HTTP_HOST'])==true) {
	// hier den DB Eintrag vornehmen.
} else {
	die();
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/spammer-webspell-und-stopforumspam-com/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>2-Klick-Empfehlungsbutton</title>
		<link>http://www.ulrich-block.de/2-klick-empfehlungsbutton/</link>
		<comments>http://www.ulrich-block.de/2-klick-empfehlungsbutton/#comments</comments>
		<pubDate>Fri, 27 Jan 2012 01:57:00 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[2 klick]]></category>
		<category><![CDATA[Empfehlungsbutton]]></category>
		<category><![CDATA[social media]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1687</guid>
		<description><![CDATA[In den Nachrichten und Kommentaren wird das Thema Datenschutz im Zusammenhang mit Social Media schon länger diskutiert. Trotz mancher Bedenken möchte man aus verschiedenen Gründen Social Media Buttons einfügen. Als die Diskussion aufflammte hat heise.de eine 2-Klick Lösung entwickelt, um Social Media Buttons mit dem Datenschutz unter einen Hut zu bringen. Bei dieser Methode wird erst nach ausdrücklicher Aufforderung durch den Benutzer der externe Code von Facebook und Co. angefordert und eingebunden. Wegen der großen Nachfrage wurde der Code zu der 2-Klick Lösung unter der MIT Lizenz veröffentlicht. Diese 2-Klick Lösung habe ich in meinem Blog eingebaut. Sie kann von]]></description>
			<content:encoded><![CDATA[<p>In den Nachrichten und Kommentaren wird das Thema Datenschutz im Zusammenhang mit Social Media schon länger diskutiert.<br />
Trotz mancher Bedenken möchte man aus verschiedenen Gründen Social Media Buttons einfügen.</p>
<p>Als die Diskussion aufflammte hat <a href="referrer.php?r=http://www.heise.de/newsticker/meldung/Code-fuer-2-Klick-Empfehlungsbutton-von-Heise-ist-erhaeltlich-1337833.html" target="_blank">heise.de eine 2-Klick Lösung</a> entwickelt, um Social Media Buttons mit dem Datenschutz unter einen Hut zu bringen. Bei dieser Methode wird erst nach ausdrücklicher Aufforderung durch den Benutzer der externe Code von Facebook und Co. angefordert und eingebunden.</p>
<p>Wegen der großen Nachfrage wurde der Code zu der 2-Klick Lösung unter der <a href="refferrer.php?r=http://www.opensource.org/licenses/mit-license.php" target="_blank">MIT Lizenz</a> veröffentlicht.</p>
<p>Diese 2-Klick Lösung habe ich in meinem Blog eingebaut. Sie kann von nun an beim Aufruf der einzelnen Beiträge am Ende genutzt werden.</p>
<p>Nachtrag:<br />
Ich habe die Einbindung erweitert. Nun kann man die Buttons auch in der Übersicht benutzen.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/2-klick-empfehlungsbutton/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Umstellung der Textausrichtung</title>
		<link>http://www.ulrich-block.de/umstellung-der-textausrichtung/</link>
		<comments>http://www.ulrich-block.de/umstellung-der-textausrichtung/#comments</comments>
		<pubDate>Mon, 23 Jan 2012 11:06:22 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[Allgemein]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1684</guid>
		<description><![CDATA[Ich habe gerade die Textausrichtung des Blogs von Linksbündig auf Blocksatz umgeändert. Dazu musste ich im Stylesheet lediglich die Einstellungen zu den einzelnen Posts um die Angabe &#8220;text-align:justify;&#8221; erweitern. Ich hoffe, dass diese Änderung die Texte etwas lesbarer machen wird.]]></description>
			<content:encoded><![CDATA[<p>Ich habe gerade die Textausrichtung des Blogs von Linksbündig auf Blocksatz umgeändert. Dazu musste ich im Stylesheet lediglich die Einstellungen zu den einzelnen Posts um die Angabe <em>&#8220;text-align:justify;&#8221;</em> erweitern.</p>
<p>Ich hoffe, dass diese Änderung die Texte etwas lesbarer machen wird.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/umstellung-der-textausrichtung/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CSS Layout: Header, 3 Reihen (Fixed-Fluid-Fixed), Footer</title>
		<link>http://www.ulrich-block.de/css-layout-header-3-reihen-fixed-fluid-fixed-footer/</link>
		<comments>http://www.ulrich-block.de/css-layout-header-3-reihen-fixed-fluid-fixed-footer/#comments</comments>
		<pubDate>Mon, 23 Jan 2012 11:00:52 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[3 columns]]></category>
		<category><![CDATA[dynamisch]]></category>
		<category><![CDATA[fest]]></category>
		<category><![CDATA[fixed]]></category>
		<category><![CDATA[fluid]]></category>
		<category><![CDATA[footer]]></category>
		<category><![CDATA[header]]></category>
		<category><![CDATA[reihen]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1673</guid>
		<description><![CDATA[Ein 3 Spalten Layout, dass einen Header und Footer hat, kann man mit HTML und CSS auf unterschiedliche Weise gestalten. Die beiden meist genutzten Varianten sollten Divs und Tabellen sein. Mit Tabellen ist die gleichmäßige Höhen- und Breitengestaltung sehr einfach. Die Höhe und Breite aller Spalten richtet sich an den Maximalwerten der anderen Elemente aus. Eine einfache Tabelle sieht so aus: &#60;table&#62;     &#60;tr&#62;         &#60;td colspan="3"&#62;Header&#60;/td&#62;     &#60;/tr&#62;     &#60;tr&#62;         &#60;td&#62;Linkes Menu&#60;/td&#62;         &#60;td&#62;Inhalt&#60;/td&#62;         &#60;td&#62;Rechtes Menu&#60;/td&#62;     &#60;/tr&#62;     &#60;tr&#62;        &#60;td colspan="3"&#62;Footer&#60;/td&#62;     &#60;/tr&#62; &#60;/table&#62; Der Einsatz von Tabellen zu diesem]]></description>
			<content:encoded><![CDATA[<p>Ein 3 Spalten Layout, dass einen Header und Footer hat, kann man mit HTML und CSS auf unterschiedliche Weise gestalten. Die beiden meist genutzten Varianten sollten Divs und Tabellen sein.</p>
<p>Mit Tabellen ist die gleichmäßige Höhen- und Breitengestaltung sehr einfach. Die Höhe und Breite aller Spalten richtet sich an den Maximalwerten der anderen Elemente aus. Eine einfache Tabelle sieht so aus:</p>
<pre class="brush:html">
&lt;table&gt;
    &lt;tr&gt;
        &lt;td colspan="3"&gt;Header&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Linkes Menu&lt;/td&gt;
        &lt;td&gt;Inhalt&lt;/td&gt;
        &lt;td&gt;Rechtes Menu&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
       &lt;td colspan="3"&gt;Footer&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;
</pre>
<p>Der Einsatz von Tabellen zu diesem Zweck gilt aber als veraltet und damit nicht mehr zeitgemäß.</p>
<p>Zur Zeit verwendet man für die Layout Gestaltung überwiegend Divs. Dabei schreibt man die Positionsangaben zum DIV nicht in selbiges hinein, sondern weist diesem eine ID und oder Klasse zu. Die Eigenschaften der IDs und Klassen definiert man dann in einer extra <em>*.css</em> Datei.</p>
<p>Wenn man feste mit flexiblen Breiten- und Höhenangaben vermischt, wird man bei Divs auf Hürden und Hindernisse treffen.</p>
<p>Wenn man z.B. möchte, dass die Höhe des Layouts immer minimal 100% der Höhe des Browserfensters beträgt, umfasst man das eigentliche Layout mit einem Div. Dieses Div macht man dann zu einem Wrapper. In den Eigenschaften wird dann bestimmt, dass der Wrapper immer mindestens 100% der Seitenhöhe belegen soll. Die Divs, die das eigentliche Aussehen bestimmen sollen, werden in diesem Wrapper positioniert.</p>
<p>Bei einem Layout mit drei Spalten kann man diese mittels Float ausrichten. Bei dem Linken und Mittleren setzt man <em><strong>&#8220;float:left;&#8221;</strong></em>. Beim Rechten <em><strong>&#8220;float:right;&#8221;</strong></em>.<br />
Ist die Höhe der Divs ein fester Wert, bekommt man keine Probleme. Soll aber zumindest eine Höhe flexibel sein, werden alle drei eine, an ihrem Inhalt bestimmte, unterschiedliche Höhe erhalten. Möchte man unterschiedliche Hintergründe verwenden, kann das Endergebnis sehr unsymmetrisch aussehen.</p>
<p>Eine Alternative ist es, die Position der 3 Spalten absolut (<em>&#8220;position:absolute;&#8221;</em>) zu bestimmen. Im Folgenden definiert man dann den Abstand der rechten und linken Spalte zum Rand mit 0. Die mittleren Spalte wird mit Margin nach Links und Rechts ausgerichtet. Als Werte für die Margin Angabe nimmt man die Spaltenbreite der äußeren beiden Spalten.<br />
Im Ergebnis hat man 3 Spalten, bei denen für die beiden äußeren feste Pixelwerte verwendet werden können. Die Mittlere Spalte wird immer die restliche Breite für sich in Anspruch nehmen, egal wie Breit das Browserfenster des Users gerade ist.</p>
<p>Definiert man nun die minimale Höhe aller drei Spalten mit 100%, werden durch diese Höhenangabe alle Spalten gleichmäßig bis zum Ende des Wrappers getreckt.</p>
<p>Die farbliche Gestaltung der einzelnen Divs erfolgt ebenfalls mittels CSS. Im Beispiel habe ich die Farben Grün <strong>#0F0</strong>, Rot <strong>#0F0</strong> und Blau <strong>#00F</strong> verwendet. Die Farben passen so sicher nicht zusammen und beißen sicher etwas in den Augen. Ich habe sie dennoch gewählt, um mittels des Kontrastes die gleichmäßige Höhe der Spalten besser darstellen zu können.</p>
<p>Eine Beispielseite, die den nachfolgenden Code verwendet, kann man hier ansehen: <a href="http://www.ulrich-block.de/download/3cols.html" target="_blank">3cols.html</a></p>
<p>Die CSS Angaben:<br />
<span id="more-1673"></span></p>
<pre class="brush:css">
html,body {
	margin:0;
	height:100%;
	font-size:12px;
	font-family:"HelveticaNeue-Light","Helvetica Neue Light","Helvetica Neue",Helvetica,Arial,"Lucida Grande",sans-serif;
}
#header{
	position:relative;
	z-index:100;
	width:100%;
	height:30px;
	line-height:30px;
	text-align:center;
	font-size:14px;
	background-color:#3D3D3D;
	color:#CCCCCC;
}
#wrapper {
	position:relative;
	min-height:97%;
	height:auto !important;
	height:97%;
	overflow:hidden;
}
#menuleft {
	position:absolute;
	z-index:50;
	top:0px;
	left:0px;
	width:140px;
	height:100%;
	background-color:#0F0;
}
#datapage {
	position:absolute;
	z-index:1;
	height:100%;
	margin:0 140px 0 140px;
	background-color:#F00;
}
#menuright {
	position:absolute;
	z-index:50;
	top:0px;
	right:0px;
	width:140px;
	height:100%;
	background-color:#00F;
}
#footer{
	position:absolute;
	z-index:100;
	bottom:0px;
	width:100%;
	height:30px;
	line-height:30px;
	background-color:#3D3D3D;
	text-align:center;
	font-size:14px;
	color:#CCCCCC;
}
</pre>
<p>Der HTML Code, der diese CSS Angaben verwendet:</p>
<pre class="brush:html">
&lt;body&gt;
	&lt;div id="header"&gt;
		Header
	&lt;/div&gt;
	&lt;div id="wrapper"&gt;
		&lt;div id="menuleft"&gt;
			Linkes Menu
		&lt;/div&gt;
		&lt;div id="datapage"&gt;
			Inhalt
		&lt;/div&gt;
		&lt;div id="menuright"&gt;
			Rechtes Menu
		&lt;/div&gt;
		&lt;div id="footer"&gt;
			Footer
		&lt;/div&gt;
	&lt;/div&gt;
&lt;/body&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/css-layout-header-3-reihen-fixed-fluid-fixed-footer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mit PHP nach Inhalten in bestimmten Dateitypen suchen</title>
		<link>http://www.ulrich-block.de/mit-php-nach-inhalten-in-bestimmten-dateitypen-suchen/</link>
		<comments>http://www.ulrich-block.de/mit-php-nach-inhalten-in-bestimmten-dateitypen-suchen/#comments</comments>
		<pubDate>Mon, 16 Jan 2012 15:39:38 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Dateien]]></category>
		<category><![CDATA[Inhalt durchsuchen]]></category>
		<category><![CDATA[rekursiv]]></category>
		<category><![CDATA[Webspace]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1654</guid>
		<description><![CDATA[Ich wurde heute von jemanden angeschrieben, bei dem über einen Exploit eine umfangreiche PHP Shell eingeschleust wurde. Das Einfallstor war ein Uploadskript, welches eigentlich für Zip Archive gedacht war. Dieses Skript hat leider nicht geschaut, was wirklich hochgeladen wird. Dank strenger Chmods war der PHP User sehr eingeschränkt. Durch den Einsatz von disable_functions in der php.ini war es dem PHP User weder möglich, Systembefehle auszuführen, noch Sockets zu öffnen. Aus diesem Grund konnte nur Schaden bei der betroffenen Webseite selber angerichtet werden. Es war zum Beispiel möglich sämtliche Dateien auszulesen und zu manipuliert. Des Weiteren ist es sehr wahrscheinlich, dass]]></description>
			<content:encoded><![CDATA[<p>Ich wurde heute von jemanden angeschrieben, bei dem über einen Exploit eine umfangreiche PHP Shell eingeschleust wurde. Das Einfallstor war ein Uploadskript, welches eigentlich für Zip Archive gedacht war. Dieses Skript hat leider nicht geschaut, was wirklich hochgeladen wird.</p>
<p>Dank strenger Chmods war der PHP User sehr eingeschränkt. Durch den Einsatz von disable_functions in der php.ini war es dem PHP User weder möglich, Systembefehle auszuführen, noch Sockets zu öffnen. Aus diesem Grund konnte nur Schaden bei der betroffenen Webseite selber angerichtet werden. Es war zum Beispiel möglich sämtliche Dateien auszulesen und zu manipuliert. Des Weiteren ist es sehr wahrscheinlich, dass der Inhalt der Datenbank sich in den Händen des Angreifers befindet.</p>
<p>Da es sich um einen angemieteten Webspace handelt, wäre es nun extrem aufwendig gewesen, alle Dateien per Hand nach Manipulationen zu durchsuchen. Ich wurde deswegen gebeten, ein PHP Skript zu schreiben, das diese Aufgabe für den Betroffenen erledigt.</p>
<p>Das Ergebnis sind diese beiden Functions:</p>
<pre class="brush:php">&lt;?php
// Function, die die einzelnen Dateien überprüft.
function checkfile($file) {
	// Der Inhalt dieser Dateitypen wird überprüft.
	$types=array('php', 'php4', 'php5', 'txt', 'html', 'htm');
	// Nach diesem Inhalt wird in den Dateien gesucht.
	$contents=array('Suchbegriff', 'Suchausdruck');
	$found=array();
	// Namen der ausführenden Datei und der zu durchsuchenden bestimmen.
	$thisfile=preg_split('/\//', $_SERVER['SCRIPT_FILENAME'], -1, PREG_SPLIT_NO_EMPTY);
	$filename=preg_split('/\//', $file, -1, PREG_SPLIT_NO_EMPTY);
	// Den Dateityp bestimmen.
	$filetype=preg_split('/\./', $file, -1, PREG_SPLIT_NO_EMPTY);
	// Wenn es sich nicht um die ausführende Datei handelt und der Typ in der Dateiliste ist, einen Filehandler für die Datei öffnen.
	if ($thisfile[count($thisfile)-1]!=$filename[count($filename)-1] and in_array($filetype[count($filetype)-1], $types)) {
		// Die Datei so lange auslesen, bis das Ende erreicht wurde.
		$fp= @fopen($file, 'r');
		// Wenn der Filehandler erfolgreich geöffnet werden konnte, die Datei durchsuchen.
		if ($fp) {
			while (!feof($fp)){
				// Alle Suchbegriffe durchgehen und wenn einer gefunden wurde, diesen Treffer dem Trefferarray hinzufügen.
				foreach ($contents as $content) {
					if(strpos(strtolower(fgets($fp)), strtolower($content)) !== false) $found[]=$content;
				}
			}
			// Dateihandler schließen
			fclose($fp);
		}
	}
	unset($fp);
	// Wenn Suchbegrife gefunden wurden, diese als String ausgeben. Anderenfalls mit false antworten.
	if (count($found) == 0) return false;
	else return implode(', ',$found);
}
// Das angegeben Verzeichnis und alle Unterverzeichnisse durchsuchen.
// Wenn kein Verzeichnis angegeben wird, dann im aktuellen beginnen.
function listcontent($dir='.') {
	// Wenn es sich um ein Verzeichnis handelt, den Inhalt listen.
	if (is_dir($dir)) {
		$dircontent=scandir($dir);
		// Den gesamten Inhalt des Verzeichnisses durchgehen.
		foreach ($dircontent as $c) {
			// Wenn es sich um ein Verzeichnis handelt, die Function listcontent() aufrufen;
			if ($c!='.' and $c!='..' and is_dir($dir.'/'.$c)) {
				listcontent($dir.'/'.$c);
			// Wenn es sich um eine Datei handelt und die checkfile() Function einen String zurückgibt, einen Suchtreffer ausgeben.
			} else if ($c!='.' and $c!='..' and checkfile($dir.'/'.$c)) {
				echo 'Found file: '.$dir.'/'.$c.' with content: '.checkfile($dir.'/'.$c).'&lt;br /&gt;';
			}
		}
	// Wenn es sich um eine Datei handelt und die checkfile() Function einen String zurückgibt, einen Suchtreffer ausgeben.
	} else if (checkfile($dir.'/'.$c)) {
		echo 'Found potential bad file: '.$dir.'/'.$c.' with content: '.checkfile($dir.'/'.$c).'&lt;br /&gt;';
	}
}
// Die Suche starten.
echo "Starting search&lt;br /&gt;";
listcontent();
echo "Search finished&lt;br /&gt;";
?&gt;</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/mit-php-nach-inhalten-in-bestimmten-dateitypen-suchen/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Userinput validieren mittels PHP Klasse</title>
		<link>http://www.ulrich-block.de/userinput-validieren-mittels-php-klasse/</link>
		<comments>http://www.ulrich-block.de/userinput-validieren-mittels-php-klasse/#comments</comments>
		<pubDate>Tue, 10 Jan 2012 19:56:08 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Klasse]]></category>
		<category><![CDATA[Userinput]]></category>
		<category><![CDATA[Validieren]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1642</guid>
		<description><![CDATA[Die Grundregel, dass man keinem Userinput vertrauen soll, wird jedem ein Begriff sein. Zum Validieren habe ich mir nun folgendes Konzept überlegt: Im ersten Schritt werden die Superglobals in ein Object übergeben und dabei escaped. Nach der Übergabe werden die Superglobals gelöscht, da ihr Inhalt nicht mehr benötigt wird. Im folgenden kann der vorherige Inhalt der Superglobals zusammen mit einer Funktion aufgerufen werden, die den Inhalt überprüft. Nur wenn die Überprüfung erfolgreich war, wird der Wert zurückgegeben. Bei dem Aufruf der Funktion gibt man an, welchen Key aus welcher Superglobal erwünscht ist. Wenn die Funktion auch auf Länge überprüfen kann,]]></description>
			<content:encoded><![CDATA[<p>Die Grundregel, dass man keinem Userinput vertrauen soll, wird jedem ein Begriff sein.</p>
<p>Zum Validieren habe ich mir nun folgendes Konzept überlegt:<br />
Im ersten Schritt werden die Superglobals in ein Object übergeben und dabei escaped. Nach der Übergabe werden die Superglobals gelöscht, da ihr Inhalt nicht mehr benötigt wird.</p>
<p>Im folgenden kann der vorherige Inhalt der Superglobals zusammen mit einer Funktion aufgerufen werden, die den Inhalt überprüft. Nur wenn die Überprüfung erfolgreich war, wird der Wert zurückgegeben.</p>
<p>Bei dem Aufruf der Funktion gibt man an, welchen Key aus welcher Superglobal erwünscht ist. Wenn die Funktion auch auf Länge überprüfen kann, dann muss man auch noch die Länge angegeben werden.<br />
Mit dem ersten Wert sagt man, welcher Key gewünscht ist, mit dem zweiten Wert sagt man, von welcher der vorherigen Superglobals der Wert genommen werden soll.</p>
<p>Für den produktiven Einsatz braucht man sicher noch mehr Funktionen. Als Ausgangscode ist die Klasse sicher gut zu gebrauchen:</p>
<pre class="brush:php">
< ?php
class ValidateUserinput {
	private $get=array();
	private $post=array();
	private $server=array();
	private $cookie=array();
	private $request=array();
	private $env=array();
	// Wenn die Magic Quotes nicht zum escapen eingesetzt werden, dann mit addcslashes escapen
	private function magic_quotes ($value) {
		if (!function_exists('get_magic_quotes_gpc') or get_magic_quotes_gpc()==0) {
			$value=addcslashes($value);
		}
		return $value;
	}
	private function inputsecurity ($value,$what) {
		foreach ($value as $key => $val) {
			if (is_string($val)) {
				$this->$what[$key] = $this->magic_quotes($val);
			} else if (is_array($val)) {
				$this->$what[$key] = $this->inputsecurity($val,$what);
			}
		}
	}
	// Constructor
	function __construct($get,$post,$server,$cookie,$request,$env) {
		foreach ($get as $key => $val) {
			if (is_string($val)) {
				$this->get[$key] = $this->magic_quotes($val);
			} else if (is_array($val)) {
				$this->get[$key] = $this->inputsecurity($val,'get');
			}
		}
		foreach ($post as $key => $val) {
			if (is_string($val)) {
				$this->post[$key] = $this->magic_quotes($val);
			} else if (is_array($val)) {
				$this->post[$key] = $this->inputsecurity($val,'post');
			}
		}
		foreach ($server as $key => $val) {
			if (is_string($val)) {
				$this->server[$key] = $this->magic_quotes($val);
			} else if (is_array($val)) {
				$this->server[$key] = $this->inputsecurity($val,'server');
			}
		}
		foreach ($cookie as $key => $val) {
			if (is_string($val)) {
				$this->cookie[$key] = $this->magic_quotes($val);
			} else if (is_array($val)) {
				$this->cookie[$key] = $this->inputsecurity($val,'cookie');
			}
		}
		foreach ($request as $key => $val) {
			if (is_string($val)) {
				$this->request[$key] = $this->magic_quotes($val);
			} else if (is_array($val)) {
				$this->request[$key] = $this->inputsecurity($val,'request');
			}
		}
		foreach ($env as $key => $val) {
			if (is_string($val)) {
				$this->env[$key] = $this->magic_quotes($val);
			} else if (is_array($val)) {
				$this->env[$key] = $this->inputsecurity($val,'env');
			}
		}
	}
	// Destructor
	function __destruct() {
		unset($this->get);
		unset($this->post);
		unset($this->server);
		unset($this->cookie);
		unset($this->reques);
		unset($this->env);
	}
	// Url Filter
	function url ($value,$type) {
		$check=$this->$type;
		if(filter_var($check[$value],FILTER_VALIDATE_URL)) {
			return $check[$value];
		}
	}
	// Mail Filter
	function ismail($value,$type) {
		$check=$this->$type;
		if(filter_var($check[$value],FILTER_VALIDATE_EMAIL)) {
			return $check[$value];
		}
	}
	// IP4 Adressen
	function ip4 ($value,$type) {
		$check=$this->$type;
		if(filter_var($check[$value], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)){
			return $check[$value];
		}
	}
	// IP 6 Adressen
	function ip6 ($value,$type) {
		$check=$this->$type;
		if(filter_var($check[$value], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)){
		return $check[$value];
		}
	}
	// IP4 und IP6 Adressen
	function ip ($value,$type) {
		$check=$this->$type;
		if(filter_var($check[$value], FILTER_VALIDATE_IP)){
			return $value;
		}
	}
	// Serverport
	function port($value,$type) {
		$check=$this->$type;
		if (preg_match("/^(0|([1-9]\d{0,3}|[1-5]\d{4}|[6][0-5][0-5]([0-2]\d|[3][0-5])))$/",$check[$value])) {
			return $check[$value];
		}
	}
	// A-Z, a-z und 0-9 sind in beliebiger Anordnung mit einer maximalen Stringlänge erlaubt.
	function pregw($value,$length,$type) {
		$check=$this->$type;
		if (preg_match("/^[\w]{1,$length}$/",$check[$value])) {
			return $check[$value];
		}
	}
	// Gibt den Wert ohne Inputüberprüfung zurück.
	function escaped ($value,$type) {
		$check=$this->$type;
		return $check[$value];
	}
}
// Die Superglobals leeren, nachdem sie in das Object übergeben worden sind.
$ui=new ValidateUserinput($_GET,$_POST,$_SERVER,$_COOKIE,$_REQUEST,$_ENV);
unset($_GET);
unset($_POST);
unset($_SERVER);
unset($_COOKIE);
unset($_REQUEST);
unset($_ENV);
// Ab hier würde dann der restliche PHP Code beginnen.
// Die einzelnen Werte werden dadurch aufgerufen, dass man mit der Funktion bestimmt, auf was der Wert überprüft werden soll.
// Mit dem ersten Wert sagt man, welcher Key gewünscht ist, mit dem zweiten Wert sagt man, von welcher der vorherigen Superglobals der Wert genommen werden soll.
// Bei dem Beispielaufruf datei.php?w=test würde test ausgegeben werden
if ($ui->escaped('w','get')) echo $ui->escaped('w','get');
else echo 'Nicht validiert';
?>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/userinput-validieren-mittels-php-klasse/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Vorschlag einer genaueren Protection Mode Richtlinie der ESL</title>
		<link>http://www.ulrich-block.de/vorschlag-einer-genaueren-protection-mode-richtlinie-der-esl/</link>
		<comments>http://www.ulrich-block.de/vorschlag-einer-genaueren-protection-mode-richtlinie-der-esl/#comments</comments>
		<pubDate>Sat, 07 Jan 2012 14:42:28 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Counter-Strike Source]]></category>
		<category><![CDATA[ESL]]></category>
		<category><![CDATA[Counter-Strike]]></category>
		<category><![CDATA[Counter-Strike: Source]]></category>
		<category><![CDATA[esl]]></category>
		<category><![CDATA[esl.eu]]></category>
		<category><![CDATA[Gameserver]]></category>
		<category><![CDATA[protection mode]]></category>
		<category><![CDATA[Sicherheit]]></category>
		<category><![CDATA[webinterface]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1630</guid>
		<description><![CDATA[Möchte man als Hoster bei der ESL als zertifizierter Hoster geführt werden, muss er seinen Kunden ein Webinterface bereitstellen, dass den genannten Protection Mode unterstützt. beim Zulassungsverfahren wurde bisher eine PDF versandt, die nur recht Wage aufgelistet hat, welche Maßnahmen man ergreifen kann, damit der Server als sicher eingestuft wird. Das man hier keine genauen Vorschriften machen kann, was genau, auf welche Art umzusetzen ist, liegt in der Natur der Sache. Jedes Interface arbeitet anders. Das die Vorgabe sehr wage sind, kann man der ESL deswegen nicht vorwerfen. Es ist somit die Verantwortung der Webinterface Entwickler eine Lösung für ihren]]></description>
			<content:encoded><![CDATA[<p>Möchte man als Hoster bei der <a href="referrer.php?r=http://esl.eu" target="_blank">ESL</a> als zertifizierter Hoster geführt werden, muss er seinen Kunden ein Webinterface bereitstellen, dass den genannten <em>Protection Mode</em> unterstützt. beim Zulassungsverfahren wurde bisher eine PDF versandt, die nur recht Wage aufgelistet hat, welche Maßnahmen man ergreifen kann, damit der Server als sicher eingestuft wird. Das man hier keine genauen Vorschriften machen kann, was genau, auf welche Art umzusetzen ist, liegt in der Natur der Sache. Jedes Interface arbeitet anders. Das die Vorgabe sehr wage sind, kann man der ESL deswegen nicht vorwerfen. Es ist somit die Verantwortung der Webinterface Entwickler eine Lösung für ihren Spezialfall zu schaffen.</p>
<p>Was hingegen teilweise auf die Kappe der ESL geht, ist der Umstand, dass sich über mögliche Angriffswege ausgeschwiegen wurde. Nicht jeder Coder kennt sich in den Eigenarten einzelner Gameserver aus, oder verfolgt die Diskussionen zu diesen. Wenn er sich nur auf die ESL verlässt und auf den Rat von Dritten verzichtet, wird er wichtige Dinge übersehen. Wenn er jedoch Hinweise Dritter bewusst übergeht, ist eine fehlerhafte Umsetzung alleinig ihm anzulasten.</p>
<p>Da es bis heute keine zusammenfassende Auflistung über mögliche Angriffswege und Abwehrmaßnahmen gibt, habe ich nun im Rahmen meiner ehrenamtlichen Tätigkeit bei der ESL einen Vorschlag für eine Richtlinie erarbeitet und diese an die ESL weitergeleitet. Ob und in welcher Form mein Vorschlag übernommen wird, ist Sache der ESL.</p>
<p>Auch unabhängig vom Protection Mode ist es sicherlich interessant, über welche Wege Kunden ihre Server anderes betreiben können, als vom Anbieter vorgesehen.</p>
<p>Viele der Punkte gibt es schon seitdem es Gameserver gibt und sind versierten Anwendern ebenso lange bekannt. Dennoch werden sie leider immer wieder übersehen.</p>
<p>Im folgenden nun mein Vorschlag einer Richtlinie für den Protection Mode</p>
<p><em><span style="text-decoration: underline;">Ziel:</span></em><br />
Der Server, der unter der angegeben Adresse (IP:Port) erreicht wird, darf außer den Servertools eslplugin und zblock keine weiteren Servertools geladen haben.</p>
<p><em><span style="text-decoration: underline;">Angriffswege , die nicht funktionieren dürfen:</span></em><br />
<em>1. Upload in das geschütze Verzeichnis:</em><br />
Der User darf nicht in der Lage sein, Servertools in die Verzeichnisse des geschützen Server zu laden und von dort auszuführen.</p>
<p><em>2. plugin_load:</em><br />
Das Ausführen des Servercommands &#8220;plugin_load&#8221; muss verhindert werden. Dabei ist auch zu beachten, das die *.so Dateien des Servers manipuliert werden können, so dass der Befehl unter dem Beispielnamen &#8220;plg1n_load&#8221; läuft. Über das deaktivieren des Befehls hinaus, muss deswegen sicher gestellt sein, dass der Benutzer die *.so des Servers nicht verändern kann.</p>
<p><em>3. Änderung der ausführbaren Dateien:</em><br />
Mittels eines FTP Client und Editor können Änderungen an den Startskripten , ausgeführten Binaries und den *.so in den bin/ Ordern der Server gemacht werden. Des Weiteren kann man diese Änderungen auch mit Servertools wie Sourcemod und Eventscript herbeiführen.<br />
Diese Veränderungen müssen sowohl beim geschützten, als auch ungeschützen Server entweder rückgängig, oder von vornherein verhindert werden.</p>
<p><em>4. (Reverse) Shells:</em><br />
Manche Servertools können Shells bereitstellen, mit denen man Prozesse vom Gameserverprozess losgelöst starten kann. Diese Prozesse müssen beim Start des Protected Modes beim normalen User beendet werden.</p>
<p><em>5. Folgen von Punkt 3 und 4:</em><br />
Ein nach den Punkt 3 oder 4 kompromitierter ungeschützter Server kann auch durch eine Firewall hindurch eine Reverse Shell aufbauen. Wenn diese beim Start des Protected Modes nicht erkannt wird, kann man die Adresse des geschützten Servers mit einem ungeschützten belegen.<br />
Eine Belegung der Adresse kann ebenso mit Endlosschleifen und Cronjobs erreicht werden.<br />
Es müssen deswegen alle ungewollten Cronjobs und Prozesse beim Benutzer des ungeschützten Servers beendet werden, bevor der protected Server gestartet wird. Es darf nicht möglich sein, dass die Adresse voin einem anderen Prozess, als dem geschützten benutzt wird.</p>
<p><em><span style="text-decoration: underline;">Mögliche Maßnahmen:</span></em><br />
Folgende Maßnahmen müssen nicht alle umgesetzt werden. Sie sind lediglich eine Liste von Dingen, mit denen man das Ziel erreichen kann.</p>
<ol>
<li>Strenge Chmods</li>
<li>Zugriffseinschränkungen und Dateifilter am FTP Server</li>
<li>Prozess und Port Kontrolle</li>
<li>Verbieten des Befehls plugin_load</li>
<li>Überprüfung kritischer Serverdateien vor jedem Serverstart sowohl im Protected Mode als auch im Unprotected Mode</li>
<li>Ohne Differenzierung alle Prozesse des ungeschützten Users beim Start des Protection Modes killen</li>
<li>Die Server mit unterschiedlichen Usern starten. Dabei sollte unter keinen Umständen ein User mit Root, oder Sudo Rechten den Prozesse ausführen.</li>
<li>Für jeden Gameserverprozess ein eigenes Chroot</li>
</ol>
<p>&nbsp;</p>
<p><span style="text-decoration: underline;"><em>Zusätzlicher Hinweis:</em></span><br />
Es gibt keine wirksamen Maßnahmen gegen Shellplugins. Im Extremfall könnte dies ausgenutzt werden, um über veralterte Pakete oder Kernel Rootrechte erlangt werden. Es ist deswegen darauf zu achten, dass der Server nicht über bekannte Exploits von innen angreifbar ist.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/vorschlag-einer-genaueren-protection-mode-richtlinie-der-esl/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Bestimmen der includieren Datei anhand von $_SERVER</title>
		<link>http://www.ulrich-block.de/bestimmen-der-includieren-datei-anhand-von-_server/</link>
		<comments>http://www.ulrich-block.de/bestimmen-der-includieren-datei-anhand-von-_server/#comments</comments>
		<pubDate>Sat, 07 Jan 2012 12:02:28 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[$_SERVER]]></category>
		<category><![CDATA[Dateiname]]></category>
		<category><![CDATA[Superglobal]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1621</guid>
		<description><![CDATA[$_SERVER ist eine so genannte Superglobal und enthält Informationen, wie die Sprache des Users und Daten zu der aufgerufenen Datei. Mit folgendem Code kann man sich den gesamten Inhalt samt Keys auflisten lassen: < ?php foreach ($_SERVER as $key => $info) { echo $key.': '.$info.''; } ?> Die Ausgabe kann dann wie folgt aussehen: TMPDIR: /var/www/html/project.tld/temp/ PATH: /usr/local/bin:/usr/bin:/bin PHPRC: /var/www/html/project.tld/conf/ PWD: /var/www/html/project.tld/php-fcgi FCGI_ROLE: RESPONDER UNIQUE_ID: Twgt2T5asdUAAHbGuiIAAACS HTTP_HOST: project.tld HTTP_USER_AGENT: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:9.0.1) Gecko/20100101 Firefox/9.0.1 HTTP_ACCEPT: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 HTTP_ACCEPT_LANGUAGE: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3 HTTP_ACCEPT_ENCODING: gzip, deflate HTTP_ACCEPT_CHARSET: ISO-8859-1,utf-8;q=0.7,*;q=0.7 HTTP_COOKIE: PHPSESSID=2a03a4eec3as2b9a4afd692474c64c1e HTTP_DNT: 1 HTTP_CONNECTION: close SERVER_SIGNATURE: SERVER_SOFTWARE: Apache/2.2.17 SERVER_NAME: project.tld SERVER_ADDR: 1.1.1.1 SERVER_PORT:]]></description>
			<content:encoded><![CDATA[<p>$_SERVER ist eine so genannte <a href="referrer.php?r=http://www.php.net/manual/de/language.variables.superglobals.php" target="_blank">Superglobal</a> und enthält Informationen, wie die Sprache des Users und Daten zu der aufgerufenen Datei.</p>
<p>Mit folgendem Code kann man sich den gesamten Inhalt samt Keys auflisten lassen:</p>
<pre class="brush:php">
< ?php
foreach ($_SERVER as $key => $info) {
	echo $key.': '.$info.'';
}
?>
</pre>
<p>Die Ausgabe kann dann wie folgt aussehen:</p>
<blockquote><p>
TMPDIR: /var/www/html/project.tld/temp/<br />
PATH: /usr/local/bin:/usr/bin:/bin<br />
PHPRC: /var/www/html/project.tld/conf/<br />
PWD: /var/www/html/project.tld/php-fcgi<br />
FCGI_ROLE: RESPONDER<br />
UNIQUE_ID: Twgt2T5asdUAAHbGuiIAAACS<br />
HTTP_HOST: project.tld<br />
HTTP_USER_AGENT: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:9.0.1) Gecko/20100101 Firefox/9.0.1<br />
HTTP_ACCEPT: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8<br />
HTTP_ACCEPT_LANGUAGE: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3<br />
HTTP_ACCEPT_ENCODING: gzip, deflate<br />
HTTP_ACCEPT_CHARSET: ISO-8859-1,utf-8;q=0.7,*;q=0.7<br />
HTTP_COOKIE: PHPSESSID=2a03a4eec3as2b9a4afd692474c64c1e<br />
HTTP_DNT: 1<br />
HTTP_CONNECTION: close<br />
SERVER_SIGNATURE:<br />
SERVER_SOFTWARE: Apache/2.2.17<br />
SERVER_NAME: project.tld<br />
SERVER_ADDR: 1.1.1.1<br />
SERVER_PORT: 80<br />
REMOTE_ADDR: 2.2.2.2<br />
DOCUMENT_ROOT: /var/www/html/project.tld/httpd<br />
SERVER_ADMIN: admin@project.tld<br />
SCRIPT_FILENAME: /var/www/html/project.tld/httpd/test.php<br />
REMOTE_PORT: 50156<br />
GATEWAY_INTERFACE: CGI/1.1<br />
SERVER_PROTOCOL: HTTP/1.1<br />
REQUEST_METHOD: GET<br />
QUERY_STRING: test=test<br />
REQUEST_URI: /test.php?test=test<br />
SCRIPT_NAME: /test.php<br />
PHP_SELF: /test.php<br />
REQUEST_TIME: 1325936089
</p></blockquote>
<p>$_SERVER enthält keinen Key für den Namen der aufgerufenen Datei selber. Wenn man darauf reagieren möchte, welche Datei einen bestimmten Code includiert hat, wird man mit dem Aufruf eines Keys von $_SERVER alleine erfolglos sein. Man kann die notwendige Information aber aus dem Key &#8216;SCRIPT_NAME&#8217; gewinnen:</p>
<pre class="brush:php">
< ?php
// den Key 'SCRIPT_NAME' an den "/" trennen.
$split=preg_split("/\//",$_SERVER['SCRIPT_NAME'],-1,PREG_SPLIT_NO_EMPTY);
// Die Einträge des Arrays bestimmen und 1 abziehen, da bei den Array Keys bei 0 zu zählen begonnen wird
$count=count($split)-1;
// Der Letzte Eintrag ist unsere Datei
$file=$split[$count];
// Wenn es die Datei x ist, 'Hello World' ausgeben, ansonsten den Dateinamen
if ($file=='x.php') {
	echo 'Hello World';
} else {
	echo $file;
}
?>
</pre>
<p>Ohne Kommentare und zusammegefasst sieht der Code dann so aus:</p>
<pre class="brush:php">
< ?php
$split=preg_split("/\//",$_SERVER['SCRIPT_NAME'],-1,PREG_SPLIT_NO_EMPTY);
$file=$split[count($split)-1];
if ($file=='x.php') {
	echo 'Hello World';
} else {
	echo $file;
}
?>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/bestimmen-der-includieren-datei-anhand-von-_server/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rekursives löschen, oder rm -r mit PHP</title>
		<link>http://www.ulrich-block.de/rekursives-loschen-oder-rm-r-mit-php/</link>
		<comments>http://www.ulrich-block.de/rekursives-loschen-oder-rm-r-mit-php/#comments</comments>
		<pubDate>Mon, 02 Jan 2012 09:54:29 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[löschen]]></category>
		<category><![CDATA[rekursiv]]></category>
		<category><![CDATA[rm -r]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1611</guid>
		<description><![CDATA[Die Dateifunktionen zum Löschen von Ordnern und Dateien sind bei PHP sehr limitiert. unlink(); kann eine Datei und rmdir(); einen Ordner löschen. Die Möglichkeit des rekursiven Löschens ist nicht gegeben. Des Weiteren kann man Ordner nur dann löschen, wenn diese bereits leer sind. Ein rm -r, wie auf der Linux Shell ist somit nicht möglich. Man könnte nun mit exec(); arbeiten. Diese Funktion wird aber von vielen Hostern als Sicherheitsrisiko eingestuft. Deswegen ist sie zu Recht deaktiviert. Wenn die Funktion zugelassen ist, kann man mit PHP rm -r aufrufen: exec("rm -r /Absoluter/Pfad/Zum/löschenden/Ordner/"); Wenn die exec(); Funktion nicht zur Verfügung steht,]]></description>
			<content:encoded><![CDATA[<p>Die Dateifunktionen zum Löschen von Ordnern und Dateien sind bei PHP sehr limitiert. <strong>unlink();</strong> kann eine Datei  und <strong>rmdir();</strong> einen Ordner löschen. Die Möglichkeit des rekursiven Löschens ist nicht gegeben. Des Weiteren kann man Ordner nur dann löschen, wenn diese bereits leer sind.<br />
Ein <strong>rm -r</strong>, wie auf der Linux Shell ist somit nicht möglich.</p>
<p>Man könnte nun mit <strong>exec();</strong> arbeiten. Diese Funktion wird aber von vielen Hostern als Sicherheitsrisiko eingestuft. Deswegen ist sie zu Recht deaktiviert. Wenn die Funktion zugelassen ist, kann man mit PHP <strong>rm -r</strong> aufrufen:</p>
<pre class="brush:php">
exec("rm -r /Absoluter/Pfad/Zum/löschenden/Ordner/");
</pre>
<p>Wenn die <strong>exec();</strong> Funktion nicht zur Verfügung steht, kommt man nicht darum herum eine Funktion zu schreiben, die die Funktionsweise von<strong> rm -r</strong> nachbildet.<br />
Die eigene Funktion muss den Ordnerinhalt auflisten und für jedes Element der Liste überprüfen können, ob es sich um eine Datei, oder einen Ordner handelt. Wenn es sich um eine Datei handelt, soll die Datei mit der PHP Funktion <strong>unlink();</strong> gelöscht werden. Wenn es sich um einen Ordner handelt, sollte die Funktion sich selber so lange selber aufrufen, bis sie in keinen weiteren Unterordner herabsteigen und dabei die Dateien aus den Unterordnern löschen kann.</p>
<pre class="brush:php">
function rmr($dir) {
	// Wenn der Input ein Ordner ist, dann Überprüfung des Inhaltes beginnen
	if (is_dir($dir)) {
		// Ordnerinhalt auflisten und jedes Element nacheinander überprüfen
		$dircontent=scandir($dir);
		foreach ($dircontent as $c) {
			// Wenn es sich um einen Ordner handelt, die Funktion rmr(); aufrufen
			if ($c!='.' and $c!='..' and is_dir($dir.'/'.$c)) {
				rmr($dir.'/'.$c);
			// Wenn es eine Datei ist, diese löschen
			} else if ($c!='.' and $c!='..') {
				unlink($dir.'/'.$c);
			}
		}
		// Den nun leeren Ordner löschen
		rmdir($dir);
	// Wenn es sich um eine Datei handelt, diese löschen
	} else {
		unlink($dir);
	}
}
// Aufrufen der Funktion
rmdir('Zu/Löschender/Ordner');
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/rekursives-loschen-oder-rm-r-mit-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zip Archiv mit PHP rekursiv entacken</title>
		<link>http://www.ulrich-block.de/zip-archiv-mit-php-rekursiv-entacken/</link>
		<comments>http://www.ulrich-block.de/zip-archiv-mit-php-rekursiv-entacken/#comments</comments>
		<pubDate>Sun, 01 Jan 2012 21:09:50 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[entpacken]]></category>
		<category><![CDATA[rekursiv]]></category>
		<category><![CDATA[zip]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1599</guid>
		<description><![CDATA[Ich wünsche allen Lesern ein frohes neues Jahr. Zum neuen Jahr möchte ich euch ein kleines PHP Skript zur Verfügung stellen, mit dem man ein Zip Archiv rekursiv auf dem Webspace entpacken kann. $zielordner='entpacken/'; $archivname='archiv.zip'; $zo=@zip_open($archivname); // Wenn das Archiv geöffnet werden konnte, weitermachen if (is_resource($zo)) { // Den Inhalt in einer While Schleife durchgehen while ($ze=zip_read($zo)) { // Den Namen von der Datei, oder Ordner bestimmen. $name=zip_entry_name($ze); // Den Eintrag öffnen und mittels Regex überprüfen, ob es sich um eine Datei handelt. $zeo=zip_entry_open($zo,$ze,'r'); if (preg_match('/^(.*)\.[\w]{1,}$/',$name)) { // Den Ordner, bzw. die Unterordner bestimmen, in dem sich die Datei befindet]]></description>
			<content:encoded><![CDATA[<p>Ich wünsche allen Lesern ein frohes neues Jahr.</p>
<p>Zum neuen Jahr möchte ich euch ein kleines PHP Skript zur Verfügung stellen, mit dem man ein Zip Archiv rekursiv auf dem Webspace entpacken kann.</p>
<pre class="brush:php">
$zielordner='entpacken/';
$archivname='archiv.zip';
$zo=@zip_open($archivname);
// Wenn das Archiv geöffnet werden konnte, weitermachen
if (is_resource($zo)) {
	// Den Inhalt in einer While Schleife durchgehen
	while ($ze=zip_read($zo)) {
		// Den Namen von der Datei, oder Ordner bestimmen.
		$name=zip_entry_name($ze);
		// Den Eintrag öffnen und mittels Regex überprüfen, ob es sich um eine Datei handelt.
		$zeo=zip_entry_open($zo,$ze,'r');
		if (preg_match('/^(.*)\.[\w]{1,}$/',$name)) {
			// Den Ordner, bzw. die Unterordner bestimmen, in dem sich die Datei befindet
			$folders=preg_split('/\//',$name,-1,PREG_SPLIT_NO_EMPTY);
			$count=count($folders)-1;
			$i=0;
			unset($checkfolder);
			while ($i< $count) {
				if (isset($checkfolder)) {
					$checkfolder .='/'.$folders[$i];
				} else {
					$checkfolder=$folders[$i];
				}
				$i++;
			}
			// Wenn es sich um einen Unterordner handelt und er nicht existiert, diesen erstellen.
			if (isset($checkfolder) and $checkfolder!='' and !is_dir($zielordner.$checkfolder) and !is_file($zielordner.$checkfolder)) {
				@mkdir($zielordner.$name);
			}
		// Falls der Regex ergibt, dass es sich um einen Ordner handeln muss, überprüfen, ob er existiert und gegebenen Falls erstellen
		} else if (!is_dir($zielordner.$name)) {
			@mkdir($zielordner.$name);
		}
		// Wenn es sich um eine Datei handelt, einen File Handler für die zu entpackende Datei öffnen und den Inhalt der gepackten Datei in diesen Handler Schreiben
		if (preg_match('/^(.*)\.[\w]{1,}$/',$name) and $zeo) {
			// File Handler öffnen
			$nf=fopen($zielordner.$name,'w');
			// Dateigröße bestimmen
			$fz=zip_entry_filesize($ze);
			// Den Inhalt der gepackten Datei in den Handler schreiben
			fwrite($nf,zip_entry_read($ze,$fz),$fz);
			// Handler schließen
			zip_entry_close($ze);
			fclose($nf);
		}
	}
	// Archiv schließen
	zip_close($zo);
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/zip-archiv-mit-php-rekursiv-entacken/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SourceTV Demouploader</title>
		<link>http://www.ulrich-block.de/sourcetv-demouploader/</link>
		<comments>http://www.ulrich-block.de/sourcetv-demouploader/#comments</comments>
		<pubDate>Sat, 31 Dec 2011 10:54:32 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[Bashscript]]></category>
		<category><![CDATA[Counter-Strike Source]]></category>
		<category><![CDATA[Counter-Strike: Source]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Day of Defeat: Source]]></category>
		<category><![CDATA[Demo Upload]]></category>
		<category><![CDATA[Half-Life 2]]></category>
		<category><![CDATA[HL2]]></category>
		<category><![CDATA[orangebox]]></category>
		<category><![CDATA[SourceTV]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1592</guid>
		<description><![CDATA[Manch einer möchte seine SourceTV Demos automatisiert komprimieren und auf einen externen Webspace hochladen. Wenn man Zugriff auf die Shell hat, kann man dies mit einem kleinen Bashscript machen. Der folgende Code ist sicherlich nicht der performanteste, erfüllt jedoch seinen Zweck. Für einzelne Gameserver mag es hilfreich sein. Ein komplettes System würde ich darauf aber nicht aufzubauen wollen. Wenn man die Demos auch auf dem Gameserver archivieren möchte, muss man den zusätzlichen Parameter -k bei bzip2 verwenden. Er steht für keep und weist bzip2 an, die Ausgangsdatei nicht zu entfernen. Hier nun das kleine Bashscript: #!/bin/bash DIR='/home/username/servername/css' DEMODIR='cstrike' cd $DIR/$DEMODIR]]></description>
			<content:encoded><![CDATA[<p>Manch einer möchte seine SourceTV Demos automatisiert komprimieren und auf einen externen Webspace hochladen. Wenn man Zugriff auf die Shell hat, kann man dies mit einem kleinen Bashscript machen.</p>
<p>Der folgende Code ist sicherlich nicht der performanteste, erfüllt jedoch seinen Zweck. Für einzelne Gameserver mag es hilfreich sein. Ein komplettes System würde ich darauf aber nicht aufzubauen wollen.</p>
<p>Wenn man die Demos auch auf dem Gameserver archivieren möchte, muss man den zusätzlichen Parameter <strong>-k</strong> bei bzip2 verwenden. Er steht für <strong>keep</strong> und weist bzip2 an, die Ausgangsdatei nicht zu entfernen.</p>
<p>Hier nun das kleine Bashscript:</p>
<pre class="brush:bash">
#!/bin/bash

DIR='/home/username/servername/css'
DEMODIR='cstrike'

cd $DIR/$DEMODIR
tail -f $DIR/screenlog.0 | while read line; do
 if [[ `echo $line | grep 'Completed SourceTV demo'` ]]; then
  DEMONAME=`echo -n "$line" | awk '{print $4}' | tr -d '"' | tr -d ','`
  if [[ ! `lsof $DEMONAME` ]]; then
   nice -n +19 bzip2 -s -q -9 $DEMONAME
   wput --remove-source-files $DEMONAME.bz2 ftp://user:password@1.1.1.1/demos/
  fi
 fi
done
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/sourcetv-demouploader/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GTA San Andreas Server Query</title>
		<link>http://www.ulrich-block.de/gta-san-andreas-server-query/</link>
		<comments>http://www.ulrich-block.de/gta-san-andreas-server-query/#comments</comments>
		<pubDate>Thu, 29 Dec 2011 17:26:51 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[GTA]]></category>
		<category><![CDATA[Query]]></category>
		<category><![CDATA[San Andreas]]></category>
		<category><![CDATA[Statusscript]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1587</guid>
		<description><![CDATA[Hier mal eine, in PHP geschriebene, Statusabfrage für den GTA San Andreas Server: $ip='1.1.1.1'; $port=7777; $socket= @fsockopen("udp://".$ip,$port,$errnum,$errstr,5); if ($socket==true) { $ex=explode('.',$ip); $packet='SAMP'.chr($ex[0]).chr($ex[1]).chr($ex[2]).chr($ex[3]).chr($port &#38; 0xFF).chr($port &#62;&#62; 8 &#38; 0xFF).'i'; fwrite($socket,$packet); fread($socket,11); $return['password']=ord(fread($socket,1)); $return['player']=ord(fread($socket,2)); $return['slots']=ord(fread($socket,2)); $return['hostname']=htmlentities(fread($socket,ord(fread($socket,4)))); $return['mode']=htmlentities(fread($socket,ord(fread($socket,4)))); $return['map']=htmlentities(fread($socket,ord(fread($socket,4)))); } else { $return=$errnum.': '.$errstr; } if (is_resource($socket)) { fclose($socket); }]]></description>
			<content:encoded><![CDATA[<p>Hier mal eine, in PHP geschriebene, Statusabfrage für den GTA San Andreas Server:</p>
<pre class="brush:php">
$ip='1.1.1.1';
$port=7777;
$socket= @fsockopen("udp://".$ip,$port,$errnum,$errstr,5);
if ($socket==true) {
 $ex=explode('.',$ip);
 $packet='SAMP'.chr($ex[0]).chr($ex[1]).chr($ex[2]).chr($ex[3]).chr($port &amp; 0xFF).chr($port &gt;&gt; 8 &amp; 0xFF).'i';
 fwrite($socket,$packet);
 fread($socket,11);
 $return['password']=ord(fread($socket,1));
 $return['player']=ord(fread($socket,2));
 $return['slots']=ord(fread($socket,2));
 $return['hostname']=htmlentities(fread($socket,ord(fread($socket,4))));
 $return['mode']=htmlentities(fread($socket,ord(fread($socket,4))));
 $return['map']=htmlentities(fread($socket,ord(fread($socket,4))));
} else {
 $return=$errnum.': '.$errstr;
}
if (is_resource($socket)) {
 fclose($socket);
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/gta-san-andreas-server-query/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sonderbares Verhalten des TSDNS Servers</title>
		<link>http://www.ulrich-block.de/sonderbares-verhalten-des-tsdns-servers/</link>
		<comments>http://www.ulrich-block.de/sonderbares-verhalten-des-tsdns-servers/#comments</comments>
		<pubDate>Wed, 21 Dec 2011 22:34:37 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[Server]]></category>
		<category><![CDATA[Teamspeak]]></category>
		<category><![CDATA[Teamspeak 3]]></category>
		<category><![CDATA[TS3]]></category>
		<category><![CDATA[tsdns]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1582</guid>
		<description><![CDATA[Ich nutze seit kurzem den TSDNS Server, der mit der Teamspeak 3 Serversoftware mitgeliefert wird. Dabei gehe ich so vor, dass ich als TSDNS Adressen Subdmains zu der Subdomain ts.domain.tld verwende. Ein entsprechender A Record *.ts.domain.tld A 1.1.1.1 mit einer Wilcard wurde angelegt. Außer TSDNS soll nichts domainbezogenes auf diesem Server laufen. Der Hostname und ein Reserve DNS Eintrag wurde deswegen nicht auf ts.domain.tld eingestellt. Weil diese Subdomain nicht in Gebrauch ist, wurde kein A Record zu ts.domain.tld erstellt. Nach dem Konfigurieren der tsdns_settings.ini wurde dann noch der TSDNS Server geupdatet. In der Theorie sollte nun alles gehen. Nicht so]]></description>
			<content:encoded><![CDATA[<p>Ich nutze seit kurzem den TSDNS Server, der mit der Teamspeak 3 Serversoftware mitgeliefert wird. Dabei gehe ich so vor, dass ich als TSDNS Adressen Subdmains zu der Subdomain <em>ts.domain.tld</em> verwende.<br />
Ein entsprechender A Record <em>*.ts.domain.tld A 1.1.1.1</em> mit einer Wilcard wurde angelegt.</p>
<p>Außer TSDNS soll nichts domainbezogenes auf diesem Server laufen. Der Hostname und ein Reserve DNS Eintrag wurde deswegen nicht auf <em>ts.domain.tld</em> eingestellt. Weil diese Subdomain nicht in Gebrauch ist, wurde kein A Record zu <em>ts.domain.tld</em> erstellt.</p>
<p>Nach dem Konfigurieren der <em>tsdns_settings.ini</em> wurde dann noch der TSDNS Server geupdatet.</p>
<p>In der Theorie sollte nun alles gehen. Nicht so in der Praxis. Ein Ping bzw. Tracert auf eine Subdomain zur Subdomain landet bei der richtigen IP. Beim Verbinden mit dem Teamspeak 3 Client gibt es aber Probleme. Egal welche Subdomain man benutzt, man landet immer auf dem virtuellen Teamspeak 3 Server dieser IP, der auf dem Standardport betrieben wird.</p>
<p>Sobald man einen A Record für die nicht verwendete Subdomain <em>ts.domain.tld</em> erstellt und die Änderung übernommen wurde, stoppt dieses Verhalten. Ab diesem Zeitpunkt ist es dann möglich, auf den virtuellen Teamspeak 3 Server zu verbinden, der in der <em>tsdns_settings.ini</em> angegeben wurde.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/sonderbares-verhalten-des-tsdns-servers/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Die Zukunft von Fake Clients und ähnlichen</title>
		<link>http://www.ulrich-block.de/die-zukunft-von-fake-clients-und-ahnlichen/</link>
		<comments>http://www.ulrich-block.de/die-zukunft-von-fake-clients-und-ahnlichen/#comments</comments>
		<pubDate>Tue, 20 Dec 2011 14:39:32 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[Counter-Strike Source]]></category>
		<category><![CDATA[Server]]></category>
		<category><![CDATA[Counter-Strike: Source]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Day of Defeat: Source]]></category>
		<category><![CDATA[DODS]]></category>
		<category><![CDATA[Fake Clients]]></category>
		<category><![CDATA[Half-Life 2]]></category>
		<category><![CDATA[HL2]]></category>
		<category><![CDATA[orangebox]]></category>
		<category><![CDATA[team fortress 2]]></category>
		<category><![CDATA[TF2]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1577</guid>
		<description><![CDATA[Der Valve Mitarbeiter Fletcher Dunn hat vor kurzem ein Statement zu der Verwendung von verschiedenen Methoden, die die Serverstatusanzeige verändern, über die [hlds_linux] Mailingliste gemacht. Die betroffenen Maßnahmen haben alle das Ziel, Spieler auf den Server zu locken, die ansonsten nicht connected hätten. Hauptsächlich geht es Valve um Folgendes: Fake Clients werden dem Gameserver Bots hinzugefügt und täuschen vor, dass diese Menschliche Spieler seien. Eine andere Methode um die Beliebtheit seines Servers zu steigern ist es, den Server mehrfach unter unterschiedlichen Adressen in den Serverbrowser zu bringen. Egal auf welche der Adressen man verbindet, man landet immer auf dem gleichen]]></description>
			<content:encoded><![CDATA[<p>Der Valve Mitarbeiter Fletcher Dunn hat vor kurzem ein Statement zu der Verwendung von verschiedenen Methoden, die die Serverstatusanzeige verändern, über die <a href="referrer.php?r=http://www.mail-archive.com/hlds_linux@list.valvesoftware.com/msg65348.html" target="_blank">[hlds_linux] Mailingliste</a> gemacht.<br />
Die betroffenen Maßnahmen haben alle das Ziel, Spieler auf den Server zu locken, die ansonsten nicht connected hätten. Hauptsächlich geht es Valve um Folgendes:</p>
<p><strong>Fake Clients</strong> werden dem Gameserver Bots hinzugefügt und täuschen vor, dass diese Menschliche Spieler seien.</p>
<p>Eine andere Methode um die Beliebtheit seines Servers zu steigern ist es, den Server <strong>mehrfach unter unterschiedlichen Adressen in den Serverbrowser</strong> zu bringen. Egal auf welche der Adressen man verbindet, man landet immer auf dem gleichen Gameserver.</p>
<p>Des Weiteren unterdrücken manche Serverbetreiber <strong>Informationen, die zeigen, das der Server modifiziert wurde</strong>. Sie werden unterdrückt, weil sie ein niedrigeres Serverranking zur Folge haben. Die Folge davon sind weniger Spieler.</p>
<p>Diese Art von Modifikationen werden von Valve als sehr schädlich für die Community angesehen. Deswegen wird Valve im ersten Schritt Kontakt mit Serverbetreibern suchen, um ihnen eine Chance zu geben, das Verhalten einzustellen.<br />
Zu einem späteren, bisher nicht bekannten Zeitpunkt, wird dieses Vorgehen dann verschärft werden. Die genauen Konsequenzen werden zwar nicht genannt. Ich gehe davon aus, dass Valve irgendwann damit beginnen wird, die Server von Unbelehrbaren aus dem Serverbrowser zu nehmen.</p>
<p>Die Nutzer dieser Methoden sollten sich also vorsehen und ihre Strategie ändern. Wer möchte schon, dass sein Server über Kurz, oder Lang aus der Serverliste entfernt wird.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/die-zukunft-von-fake-clients-und-ahnlichen/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Wozu noch Staatstrojaner?</title>
		<link>http://www.ulrich-block.de/wozu-noch-staatstrojaner/</link>
		<comments>http://www.ulrich-block.de/wozu-noch-staatstrojaner/#comments</comments>
		<pubDate>Fri, 16 Dec 2011 13:27:53 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[Geheimdienst]]></category>
		<category><![CDATA[Windows 8]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1574</guid>
		<description><![CDATA[Es wurde in letzter Zeit viel berichtet, dass Geheimdienste auf Daten, die in der Cloud gespeichert sind, zugreifen können. Dies kann man z.B. in einem aktuellen Beitrag von Golem lesen. Heise berichtet so eben, dass Windows 8 die Zugangsdaten in der Cloud speichern wird. Wer braucht denn noch Staatstrojaner, wenn er direkt auf Daten zugreifen kann&#8230;]]></description>
			<content:encoded><![CDATA[<p>Es wurde in letzter Zeit viel berichtet, dass Geheimdienste auf Daten, die in der Cloud gespeichert sind, zugreifen können. Dies kann man z.B. in einem <a href="referrer.php?r=http://www.golem.de/1112/88467.html" target="_blank">aktuellen Beitrag von Golem</a> lesen.</p>
<p><a href="referrer.php?r=http://www.heise.de/newsticker/meldung/Windows-8-speichert-Passwoerter-in-der-Cloud-1396911.html" target="_blank">Heise</a> berichtet so eben, dass Windows 8 die Zugangsdaten in der Cloud speichern wird.</p>
<p>Wer braucht denn noch Staatstrojaner, wenn er direkt auf Daten zugreifen kann&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/wozu-noch-staatstrojaner/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Teamspeak 3, TSDNS, Leihserver und Easy-WI</title>
		<link>http://www.ulrich-block.de/teamspeak-3-tsdns-leihserver-und-easy-wi/</link>
		<comments>http://www.ulrich-block.de/teamspeak-3-tsdns-leihserver-und-easy-wi/#comments</comments>
		<pubDate>Fri, 09 Dec 2011 14:10:04 +0000</pubDate>
		<dc:creator>Ulrich Block</dc:creator>
				<category><![CDATA[easy-wi.com]]></category>
		<category><![CDATA[Server]]></category>
		<category><![CDATA[Teamspeak 3]]></category>
		<category><![CDATA[TSNDS]]></category>
		<category><![CDATA[Webinterface]]></category>
		<category><![CDATA[tsdns]]></category>
		<category><![CDATA[verleih modul]]></category>
		<category><![CDATA[verleihserver]]></category>
		<category><![CDATA[webinterface]]></category>

		<guid isPermaLink="false">http://www.ulrich-block.de/?p=1569</guid>
		<description><![CDATA[Im letzten Beitrag Teamspeak 3 und Domains (TSDNS) habe ich beschrieben, was TSDNS ist und wie man es manuell einrichtet. In diesem Beitrag möchte ich etwas Eigenwerbung für das Teamspeak 3 Modul von meinem Interface Easy-Wi machen. Der Sinn von TSDNS ist es, dem Benutzer das Verbinden auf Teamspeak 3 Server so einfach, wie möglich zu machen. Das Verbinden auf eine Domain ist einfacher, weil sie einfacher zu merken ist und weil sie weniger verwirren kann, als eine Kombination von IP und Port. Des Weiteren verlangen zahlreiche Benutzer den Standardport zu einem Serverdienst. Technisch gesehen ist dies sinnlos. Darüber hinaus]]></description>
			<content:encoded><![CDATA[<p>Im letzten Beitrag <a href="http://www.ulrich-block.de/teamspeak-3-und-domains-tsdns/" target="_blank">Teamspeak 3 und Domains (TSDNS)</a> habe ich beschrieben, was TSDNS ist und wie man es manuell einrichtet.</p>
<p>In diesem Beitrag möchte ich etwas Eigenwerbung für das Teamspeak 3 Modul von meinem Interface <a href="http://easy-wi.com" target="_blank">Easy-Wi</a> machen.</p>
<p>Der Sinn von TSDNS ist es, dem Benutzer das Verbinden auf Teamspeak 3 Server so einfach, wie möglich zu machen. Das Verbinden auf eine Domain ist einfacher, weil sie einfacher zu merken ist und weil sie weniger verwirren kann, als eine Kombination von IP und Port.<br />
Des Weiteren verlangen zahlreiche Benutzer den Standardport zu einem Serverdienst. Technisch gesehen ist dies sinnlos. Darüber hinaus werden unnötigerweise kostbare IP4 Adressen verschwendet, wenn man diesem Wunsch nachkommt. Verbindet man nun auf eine Domain, benötigt man keinen Port mehr, so dass der Wunsch nach einem Standardport entfällt und damit kostbare IP4 Adressen gespart werden können.</p>
<p>Egal, ob man Teamspeak 3 Server nun gewerblich vermietet, oder mittels einer NPO Lizenz kostenlos an Freunde und Bekannte verteilt. Es bleibt ein kleiner Schwachpunkt. Man muss jedes mal arbeiten, wenn jemand eine Änderung wünscht.</p>
<p>Aus diesem Grund ist die Nutzung von TSDNS bei <a href="http://easy-wi.com" target="_blank">Easy-Wi</a> vollständig automatisiert. Die Verwaltung der <strong><em>tsdns_settings.ini</em></strong>, so wie das Starten und Updaten des TSDNS Servers, werden von Easy-Wi übernommen.</p>
<p>Beim Anlegen einer Teamspeak 3 Grundinstallation wird einmalig eine Standarddns, wie <strong><em>ts3.myclan.tld</em></strong> angegeben. Wird nun ein Voiceserver angelegt, wird eine Subdomain nach dem Schema <strong><em>Username-VirtualserverID.ts3.myclan.tld</em></strong> vorgegeben. Möchte man diese Kombination nicht nutzen, steht es einem natürlich frei, diese Vorgabe durch die gewünschte (Sub) Domain zu überschreiben. Selbstverständlich kann die (Sub)Domain jederzeit sowohl vom Benutzer, als auch vom Admin nachträglich bearbeitet werden. Dafür reicht es, die Domain im zuständigen Formularfeld zu ändern und die Änderung zu speichern. Der Admin muss somit nur eingreifen, wenn der Benutzer mit dem Eingeben einer Domain überfordert ist.</p>
<p>Sollte man bereits manuell, oder mit einem anderen Interface, Teamspeak 3 Server angelegt haben, so bietet Easy-Wi die Möglichkeit, die bestehenden Server zu übernehmen. In diesem Fall wird überprüft, ob bereits ein TSDNS Server konfiguriert wurde. Ist dies der Fall, werden die Einstellungen ebenfalls übernommen. Falls für einen Server keine TSDNS Einstellungen gemacht worden sind, so wird eine Subdomain nach dem oben beschriebenen Schema generiert.</p>
<p>Damit der Arbeitsaufwand auch in allen anderen Fällen reduziert wird, gibt es eine Überwachung vom Status der Teamspeak 3 Server.<br />
Es wird z.B. überwacht, ob der Benutzer bestimmte Parameter, wie Passwort, Hostbanner, Hostbutton, usw. einhält. Sollte ein Wert nicht eingehalten worden sein, werden die Admins und der Benutzer mit einer E-Mail informiert.</p>
<p>Neben Benutzern, die sich nicht an Vorgaben halten, kann es auch zu kleineren technischen Problemen kommen. So kommt es manchmal vor, dass beim Starten der Teamspeak 3 Hauptinstanz, nicht alle virtuellen Server gestartet werden. Dies kann passieren, obwohl der Parameter autostart gesetzt wurde. Manuelles Starten kann hier sehr viel Zeit kosten. Aus diesem Grund wird ein Server, der offline ist, obwohl er online sein sollte, automatisch gestartet und der Benutzer darüber informiert.</p>
<p>Sollte die Hauptinstanz also solche nicht erreichbar sein, werden die Admins natürlich auch informiert.</p>
<p>Die angelegten Teamspeak 3 Server können auch automatisiert mit dem Verleihmodul verliehen werden. Bei diesem gibt man vor, wie lange die Server minimal und maximal ausleihbar sein sollen und wie viele Slots minimal und maximal je Server vergeben werden dürfen. Zusätzlich definiert man die Schritte zwischen dem Minimal- und Maximalwert. Bei jedem Verleihvorgang wird der Server dann resettet und ein neuer initialer Admintoken ausgegeben. Das Verleihen kann dabei entweder über das mitgelieferte Formular geschehen, oder die XML Schnittstelle geregelt werden.</p>
<p>Wenn man Teamspeak 3 mit einer NPO Lizenz verleiht sollte man dringenst beachten, dass man keinerlei Gewinn daraus ziehen darf. Bereits Google Werbung auf der Webseite kann als gewinnbringend im Sinne der NPO Lizenz gesehen werden. Im schlimmsten Fall wird dann die NPO Lizenz entzogen und die IP des eingesetzten Servers geblacklistet.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ulrich-block.de/teamspeak-3-tsdns-leihserver-und-easy-wi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

