Skip to content
Snippets Groups Projects
Commit 8d1f78ee authored by Dominik Hebeler's avatar Dominik Hebeler
Browse files

Erste gut funktionierende Version

Die neue Proxy Software ist soweit feritg, als dass diese Version nun mindestens so gut funktionieren dürfte, wie die bestehende
parent fd1315c5
No related branches found
No related tags found
No related merge requests found
<?php
namespace App;
class CssDocument extends Document
{
private $styleString;
public function __construct($password, $base, $styleString)
{
parent::__construct($password, $base);
$this->styleString = $styleString;
}
public function proxifyContent()
{
# All Resources that I know, that are included within an CSS Stylesheet must have the url() functional quoting
# We're gonna replace all URL's that we find within this document
# First with Quotation Marks:
$this->styleString = preg_replace_callback("/(url\()([\"\']{1})([^\\2]+?)\\2/si", "self::pregReplaceUrl", $this->styleString);
# And then the ones without Quotation Marks
$this->styleString = preg_replace_callback("/(url\()([^\"\'][^\)]+?)(\))/si", "self::pregReplaceUrlNoQuotes", $this->styleString);
}
private function pregReplaceUrl($matches)
{
$url = $matches[3];
# Relative to Absolute
$url = $this->convertRelativeToAbsoluteLink($url);
# Proxify Url
$url = $this->proxifyUrl($url, false);
$replacement = $matches[1] . $matches[2] . $url . $matches[2];
return $replacement;
}
private function pregReplaceUrlNoQuotes($matches)
{
$url = $matches[2];
# Relative to Absolute
$url = $this->convertRelativeToAbsoluteLink($url);
# Proxify Url
$url = $this->proxifyUrl($url, false);
$replacement = $matches[1] . $url . $matches[3];
return $replacement;
}
public function getResult()
{
return $this->styleString;
}
}
<?php
namespace App;
use Illuminate\Http\Request;
use URL;
abstract class Document
{
protected $password;
protected $baseUrl;
public function __construct($password, $base)
{
$this->password = $password;
$this->baseUrl = $base;
}
public function proxifyUrl($url, $topLevel)
{
// Only convert valid URLs
$url = trim($url);
if (strpos($url, "http") !== 0 || strpos($url, URL::to('/')) === 0) {
return $url;
}
$urlToProxy = base64_encode(str_rot13($url));
$urlToProxy = str_replace("/", "<<SLASH>>", $urlToProxy);
$urlToProxy = urlencode($urlToProxy);
if ($topLevel) {
$params = \Request::all();
# Password
$pw = md5(env('PROXY_PASSWORD') . $url);
$urlToProxy = base64_encode(str_rot13($url));
$urlToProxy = urlencode(str_replace("/", "<<SLASH>>", $urlToProxy));
# Params
$params['password'] = $pw;
$params['url'] = $urlToProxy;
$iframeUrl = action('ProxyController@proxyPage', $params);
} else {
$params = \Request::all();
$params['password'] = $this->password;
$params['url'] = $urlToProxy;
$iframeUrl = action('ProxyController@proxy', $params);
}
return $iframeUrl;
}
protected function convertRelativeToAbsoluteLink($rel)
{
if (strpos($rel, "//") === 0) {
$rel = parse_url($this->baseUrl, PHP_URL_SCHEME) . ":" . $rel;
}
/* return if already absolute URL or empty URL */
if (parse_url($rel, PHP_URL_SCHEME) != ''
|| strlen(trim($rel)) <= 0
|| preg_match("/^\s*mailto:/si", $rel)) {
return ($rel);
}
/* queries and anchors */
if ($rel[0] == '#' || $rel[0] == '?') {
return ($this->baseUrl . $rel);
}
/* parse base URL and convert to local variables:
$scheme, $host, $path */
extract(parse_url($this->baseUrl));
/* remove non-directory element from path */
if (isset($path)) {
$path = preg_replace('#/[^/]*$#', '', $path);
}
/* destroy path if relative url points to root */
if ($rel[0] == '/') {
$path = '';
}
/* dirty absolute URL */
$abs = '';
/* do we have a user in our URL? */
if (isset($user)) {
$abs .= $user;
/* password too? */
if (isset($pass)) {
$abs .= ':' . $pass;
}
$abs .= '@';
}
$abs .= $host;
/* did somebody sneak in a port? */
if (isset($port)) {
$abs .= ':' . $port;
}
if (isset($path)) {
$abs .= $path;
}
if (isset($rel)) {
$abs .= "/" . ltrim($rel, "/");
}
/* replace '//' or '/./' or '/foo/../' with '/' */
$re = array('#(/\.?/)#', '#/(?!\.\.)[^/]+/\.\./#');
for ($n = 1; $n > 0; $abs = preg_replace($re, '/', $abs, -1, $n)) {}
/* absolute URL is ready! */
return ($scheme . '://' . $abs);
}
abstract public function proxifyContent();
}
<?php
namespace App;
use DomDocument;
class HtmlDocument extends Document
{
private $htmlString;
public function __construct($password, $baseUrl, $htmlString, $encoding = "UTF-8")
{
parent::__construct($password, $baseUrl);
$this->htmlString = mb_convert_encoding($htmlString, 'HTML-ENTITIES', $encoding);
}
public function getResult()
{
return $this->htmlString;
}
/**
* Function proxifyContent
* This method parses the given String and Proxifies all Links/Urls in it so it's targetting this Proxy Server
**/
public function proxifyContent()
{
if (trim($this->htmlString) === "") {
return;
}
# Let's create a new DOM
libxml_use_internal_errors(true);
$dom = new DomDocument();
$dom->loadHtml($this->htmlString);
foreach ($dom->getElementsByTagName('base') as $base) {
$href = $base->getAttribute('href');
# Convert all relative Links to absolute Ones
$href = $this->convertRelativeToAbsoluteLink($href);
$this->baseUrl = $href;
# Delete Base Tag
$base->parentNode->removeChild($base);
}
# First things first. Let's change all a Tags that can define a target Attribute
foreach ($dom->getElementsByTagName('a') as $link) {
# All Links within a "a" Tag need to target the top level because they change the site on click
$this->convertTargetAttribute($link, "_top");
# Convert all relative Links to absolute Ones
$link->setAttribute("href", $this->convertRelativeToAbsoluteLink($link->getAttribute("href")));
# Convert all Links to the proxified Version
# All of this Links should target to the top Level
$link->setAttribute("href", $this->proxifyUrl($link->getAttribute("href"), true));
}
# All Buttons
foreach ($dom->getElementsByTagName('button') as $button) {
if ($button->hasAttribute("formtarget")) {
$button->setAttribute("formtarget", "_top");
}
if ($button->hasAttribute("formaction")) {
$formaction = $button->getAttribute("formaction");
# Rel to abs
$formaction = $this->convertRelativeToAbsoluteLink($formaction);
# Abs to proxified
$formaction = $this->proxifyUrl($formaction, true);
# And replace
$button->setAttribute("formaction", $formaction);
}
# Since when are buttons allowed to have a href?
# Youtube has such on it's site so we are converting it anyways
if ($button->hasAttribute("href")) {
$href = $button->getAttribute("href");
# Rel to abs
$href = $this->convertRelativeToAbsoluteLink($href);
# Abs to proxified
$href = $this->proxifyUrl($href, true);
# And replace
$button->setAttribute("href", $href);
}
}
foreach ($dom->getElementsByTagName('area') as $area) {
# All Links within a "a" Tag need to target the top level because they change the site on click
$this->convertTargetAttribute($area, "_top");
}
foreach ($dom->getElementsByTagName('form') as $form) {
# All Links within a "a" Tag need to target the top level because they change the site on click
$this->convertTargetAttribute($form, "_top");
# If a Form doesn't define a action It references itself but we need to set the link then
$action = $form->getAttribute("action");
if ($action === "") {
$action = $this->baseUrl;
} else {
# Otherwise the Link could be relative and we need to change it:
# Convert all relative Links to absolute Ones
$action = $this->convertRelativeToAbsoluteLink($action);
}
# And finally Proxify the Url
$action = $this->proxifyUrl($action, true);
$form->setAttribute("action", $action);
}
# Alle Link Tags
foreach ($dom->getElementsByTagName('link') as $link) {
# Convert all relative Links to absolute Ones
$link->setAttribute("href", $this->convertRelativeToAbsoluteLink($link->getAttribute("href")));
# Convert all Links to the proxified Version
# All of this Links should NOT target to the top Level
$link->setAttribute("href", $this->proxifyUrl($link->getAttribute("href"), false));
}
# All Iframes
foreach ($dom->getElementsByTagName('iframe') as $iframe) {
# There can be 2 Possible sources
# A - The src Attribute defines a Url that the Iframe loads
$src = $iframe->getAttribute("src");
if ($src !== "") {
# Make the Link absolute
$src = $this->convertRelativeToAbsoluteLink($src);
# Proxify the Link
$src = $this->proxifyUrl($src, false);
# Replace the old Link
$iframe->setAttribute("src", $src);
}
# B - The srcdoc Attribute defines Html-Code that should be displayed in the frame
$srcdoc = $iframe->getAttribute("srcdoc");
if ($srcdoc !== "") {
# The srcdoc should be a HTML String so we are gonna make a new HTML-Document Element
$htmlDoc = new HtmlDocument($this->password, $this->baseUrl, $srcdoc);
$htmlDoc->proxifyContent();
$srcdoc = $htmlDoc->getResult();
# Replace the Old HTML Code
$iframe->setAttribute("srcdoc", $srcdoc);
}
}
# All Image Tags
foreach ($dom->getElementsByTagName('img') as $img) {
# Convert all Image src's to Absolute Links
$img->setAttribute("src", $this->convertRelativeToAbsoluteLink($img->getAttribute("src")));
# Convert all Image Sources to proxified Versions
$img->setAttribute("src", $this->proxifyUrl($img->getAttribute("src"), false));
# Some Images might contain a srcset (Different Images for different resolutions)
# Syntax would be i.e. srcset="medium.jpg 1000w, large.jpg 2000w"
$srcset = $img->getAttribute("srcset");
if ($srcset !== "") {
$images = explode(",", $srcset);
foreach ($images as $index => $set) {
$set = trim($set);
$parts = preg_split("/\s+/si", $set);
# $parts[0] is the Image Path
# It could be relative so convert that one:
$parts[0] = $this->convertRelativeToAbsoluteLink($parts[0]);
# And now Proxify it:
$parts[0] = $this->proxifyUrl($parts[0], false);
$images[$index] = implode(" ", $parts);
}
$srcset = implode(",", $images);
$img->setAttribute("srcset", $srcset);
}
}
# Alle Meta Tags
foreach ($dom->getElementsByTagName('meta') as $meta) {
if ($meta->hasAttribute("href")) {
# Convert all relative Links to absolute Ones
$meta->setAttribute("href", $this->convertRelativeToAbsoluteLink($meta->getAttribute("href")));
# Convert all Links to the proxified Version
# All of this Links should NOT target to the top Level
$meta->setAttribute("href", $this->proxifyUrl($meta->getAttribute("href"), false));
}
if ($meta->hasAttribute("http-equiv") && $meta->getAttribute("http-equiv") === "refresh") {
# We should refresh the site with a meta tag
# But not before profifying the new URL
$content = $meta->getAttribute("content");
$url = substr($content, stripos($content, "url=") + 4);
# Convert all relative Links to absolute Ones
$url = $this->convertRelativeToAbsoluteLink($url);
# Convert all Links to the proxified Version
# All of this Links should NOT target to the top Level
$url = $this->proxifyUrl($url, false);
$content = substr($content, 0, stripos($content, "url=") + 4) . $url;
$meta->setAttribute("content", $content);
}
}
# Alle Script Tags
foreach ($dom->getElementsByTagName('script') as $script) {
$script->nodeValue = "";
$script->setAttribute("src", "");
$script->setAttribute("type", "");
}
# Alle Style Blöcke
# Werden extra geparsed
foreach ($dom->getElementsByTagName('style') as $style) {
$styleString = $style->nodeValue;
$cssElement = new CssDocument($this->password, $this->baseUrl, $styleString);
$cssElement->proxifyContent();
$style->nodeValue = $cssElement->getResult();
}
# Abschließend gehen wir noch einmal alle Tags durch
foreach ($dom->getElementsByTagName('*') as $el) {
if ($el->getAttribute("style") !== "") {
$styleString = $el->getAttribute("style");
$cssElement = new CssDocument($this->password, $this->baseUrl, $styleString);
$cssElement->proxifyContent();
$el->setAttribute("style", $cssElement->getResult());
}
# We Will Remove all Javascript Event attributes
# To keep things simple we're gonna remove all Attributes which names start with "on"
foreach ($el->attributes as $attr) {
if (stripos($attr->name, "on") === 0) {
$el->removeAttribute($attr->name);
}
}
}
$this->htmlString = $dom->saveHtml();
# Remove all now empty script Tags
$this->htmlString = preg_replace("/<\s*[\/]{0,1}\s*script[^>]*?>/si", "", $this->htmlString);
libxml_use_internal_errors(false);
}
/**
* This function changes the current Target Attribute on the link to given new target Attribute
*/
private function convertTargetAttribute($link, $newTarget)
{
$link->setAttribute("target", $newTarget);
}
}
This diff is collapsed.
<html>
<head>
<meta charset="utf-8" />
<link href="/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<link href="/css/style.css" rel="stylesheet" type="text/css" />
</head>
......@@ -18,16 +19,6 @@
</div>
<div id="proxy-options" class="col-xs-2">
<ul class="list-unstyled">
@if(!$scriptsEnabled)
<li><a href="{{$scriptUrl}}" class="btn btn-warning btn-xs">Skripte blockiert</a></li>
@else
<li><a href="{{$scriptUrl}}" class="btn btn-info btn-xs">Skripte zugelassen</a></li>
@endif
@if(!$cookiesEnabled)
<li><a href="{{$cookieUrl}}" class="btn btn-warning btn-xs">Cookies gesperrt</a></li>
@else
<li><a href="{{$cookieUrl}}" class="btn btn-info btn-xs">Cookies zugelassen</a></li>
@endif
<li><a href="{!!$targetUrl!!}" class="btn btn-danger btn-xs">Proxy ausschalten</a></li>
</ul>
</div>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment