Dateien nach "/" hochladen
This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Zwei Funktionen fuer den JViewer-Start mit IcedTea-Web:
|
||||
|
||||
1) JNLP-Strukturpatch (Standardaufruf):
|
||||
patch_jviewer.py <input.jnlp> <output.jnlp>
|
||||
|
||||
- <security>/<all-permissions> bleiben UNVERAENDERT: die Jars werden
|
||||
signiert (s.u.), signierter+vertrauter Code mit dieser Anforderung
|
||||
bekommt regulaer AllPermission - kein Grund mehr, das zu entfernen.
|
||||
- <nativelib> wird trotzdem zu <jar> umbenannt: das ist laut Fehlermeldung
|
||||
"nativelib kann nicht angegeben werden sofern vertrauenswuerdige
|
||||
Umgebung angefordert wird" mit <security><all-permissions/> inkompatibel,
|
||||
unabhaengig davon ob signiert oder nicht.
|
||||
- <codebase> bleibt UNVERAENDERT (zeigt weiter auf die echte BMC). Das ist
|
||||
wichtig: IcedTea-Web erlaubt unsignierten/nicht vertrauten Apps im
|
||||
Sandbox-Modus nur Netzwerkzugriff zurueck zu Host+Port der Codebase. Der
|
||||
KVM-Redirection-Socket (Port 7578) geht an dieselbe IP wie die BMC/
|
||||
Codebase, aber einen anderen Port - wuerde man die Codebase auf einen
|
||||
lokalen Proxy umbiegen, wuerde der Zugriff verboten (getestet, "access
|
||||
denied SocketPermission").
|
||||
|
||||
2) Manifest-Patch fuer ein bereits von IcedTea-Web heruntergeladenes,
|
||||
gecachtes Jar (wird NACH einem ersten, absichtlich fehlschlagenden
|
||||
javaws-Lauf aufgerufen, der nur zum Befuellen des Caches dient):
|
||||
patch_jviewer.py --strip-manifest <jarfile> [<jarfile> ...]
|
||||
|
||||
Frueherer Ansatz: entfernte "Permissions: all-permissions" aus dem
|
||||
Manifest, um IcedTea-Webs hartcodierte Forced-Sandbox fuer UNSIGNIERTEN
|
||||
Code mit dieser Deklaration zu umgehen. Wird seit Einfuehrung der
|
||||
Selbstsignierung NICHT MEHR aufgerufen (das Attribut wird fuer signierten,
|
||||
vertrauten Code wieder gebraucht) - Funktion bleibt nur als Fallback im
|
||||
Code, falls Signierung aus irgendeinem Grund nicht moeglich ist.
|
||||
"""
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import zipfile
|
||||
|
||||
|
||||
def localname(t):
|
||||
"""Tag-Namen ohne Namespace-Praefix, egal ob die JNLP ein xmlns deklariert
|
||||
oder nicht (manche AMI-Firmwarestaende tun es, manche nicht)."""
|
||||
return t.split("}", 1)[-1] if "}" in t else t
|
||||
|
||||
|
||||
def is_tag(el, name):
|
||||
return localname(el.tag) == name
|
||||
|
||||
|
||||
def strip_all_permissions_from_manifest(jar_path):
|
||||
with zipfile.ZipFile(jar_path, "r") as zin:
|
||||
manifest_name = "META-INF/MANIFEST.MF"
|
||||
try:
|
||||
manifest = zin.read(manifest_name).decode("utf-8", "replace")
|
||||
except KeyError:
|
||||
print(f"(kein Manifest in {jar_path}, nichts zu tun)")
|
||||
return
|
||||
|
||||
# Manifest-Continuation-Zeilen (beginnen mit einem Leerzeichen) an die
|
||||
# vorherige Zeile anhaengen, damit "Permissions: all-permissions"
|
||||
# sicher als eine logische Zeile erkannt wird.
|
||||
lines = manifest.splitlines()
|
||||
logical = []
|
||||
for line in lines:
|
||||
if line.startswith(" ") and logical:
|
||||
logical[-1] += line[1:]
|
||||
else:
|
||||
logical.append(line)
|
||||
|
||||
filtered = [l for l in logical if not re.match(r"(?i)^permissions\s*:", l)]
|
||||
|
||||
if filtered == logical:
|
||||
print(f"(Permissions-Attribut in {jar_path} nicht vorhanden, nichts zu tun)")
|
||||
return
|
||||
|
||||
new_manifest = "\n".join(filtered) + "\n"
|
||||
|
||||
entries = {}
|
||||
for item in zin.infolist():
|
||||
entries[item] = zin.read(item.filename)
|
||||
|
||||
tmp_path = jar_path + ".tmp"
|
||||
with zipfile.ZipFile(tmp_path, "w", zipfile.ZIP_DEFLATED) as zout:
|
||||
for item, data in entries.items():
|
||||
if item.filename == manifest_name:
|
||||
data = new_manifest.encode("utf-8")
|
||||
zout.writestr(item, data)
|
||||
|
||||
os.replace(tmp_path, jar_path)
|
||||
print(f"Manifest gepatcht (Permissions: all-permissions entfernt): {jar_path}")
|
||||
|
||||
|
||||
def patch_jnlp(src, dst):
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
tree = ET.parse(src)
|
||||
root = tree.getroot()
|
||||
|
||||
# Falls die JNLP ein xmlns deklariert (z.B. xmlns="http://www.w3.org/1999/xhtml"),
|
||||
# dieselbe Namespace-URI beim Schreiben wieder als Default-Namespace nutzen,
|
||||
# damit ET keine ns0:-Praefixe einfuegt.
|
||||
root_ns = localname(root.tag)
|
||||
if root.tag != root_ns:
|
||||
ns_uri = root.tag[1:root.tag.index("}")]
|
||||
ET.register_namespace("", ns_uri)
|
||||
|
||||
# <security>/<all-permissions> bleiben unangetastet (s. Docstring oben) -
|
||||
# nur <nativelib> zu <jar> umbenennen (Namespace-Praefix des Originaltags beibehalten)
|
||||
for el in root.iter():
|
||||
if is_tag(el, "nativelib"):
|
||||
prefix = el.tag[: el.tag.index("}") + 1] if "}" in el.tag else ""
|
||||
el.tag = f"{prefix}jar"
|
||||
|
||||
tree.write(dst, encoding="UTF-8", xml_declaration=True)
|
||||
print(f"Gepatchte JNLP geschrieben: {dst}")
|
||||
|
||||
|
||||
def main():
|
||||
args = sys.argv[1:]
|
||||
|
||||
if args and args[0] == "--strip-manifest":
|
||||
jar_paths = args[1:]
|
||||
if not jar_paths:
|
||||
print("Benutzung: patch_jviewer.py --strip-manifest <jarfile> [<jarfile> ...]")
|
||||
sys.exit(1)
|
||||
for jar_path in jar_paths:
|
||||
strip_all_permissions_from_manifest(jar_path)
|
||||
return
|
||||
|
||||
if len(args) != 2:
|
||||
print("Benutzung: patch_jviewer.py <input.jnlp> <output.jnlp>")
|
||||
print(" oder: patch_jviewer.py --strip-manifest <jarfile> [<jarfile> ...]")
|
||||
sys.exit(1)
|
||||
|
||||
patch_jnlp(args[0], args[1])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user