Frage:
Vertrauensprobleme in Bezug auf Open Source
zedman9991
2013-09-04 01:50:58 UTC
view on stackexchange narkive permalink

Zwei getrennte Diskussionen haben mir kürzlich die Augen für ein Problem geöffnet, das ich nicht in Betracht gezogen hatte. Wie man die verwendete Open Source-Binärdatei bestätigt, basiert auf dem veröffentlichten Quellcode.

Es gibt eine große Diskussion Thread über Kryptographie-Randombit, basierend auf Zooko Wilcox-O'Hearns, Gründer und CEO von LeastAuthority.com, offener Brief an Phil Zimmermann und Jon Callas, zwei der Auftraggeber hinter Silent Circle, der Firma, die Silent Mail betrieb und das Thema ansprach. Darüber hinaus wurde auch ein heute veröffentlichter Artikel von Dr. Dobbs mit dem Titel Absolut alles in die Versionskontrolle einbeziehen angesprochen.

Das Problem bei dieser Frage ist die Fähigkeit, Open Source-Code neu zu kompilieren und erhalten die gleichen Ergebnisse wie die veröffentlichte Binärdatei. Mit anderen Worten, wenn Sie dieselbe Binärdatei neu erstellen und aus dem Quellcode hashen, ist es unwahrscheinlich, dass sie aufgrund von Unterschieden in den Werkzeugketten und einigen Randomisierungen in den Compilern selbst identisch ist.

In dem Artikel von Dr. Dobbs wird vorgeschlagen, aus Gründen der Reproduzierbarkeit sogar die Werkzeugkette der Versionskontrolle zu unterziehen. Jon Callas weist darauf hin, dass es in vielen Fällen aus verschiedenen Gründen, einschließlich Lizenzbeschränkungen, unmöglich sein kann, die Toolkette neu zu verteilen. Wenn Sie den Code nicht selbst kompilieren, fügen Sie Ihrer Annahme einen Vertrauensschritt hinzu, da die Binärdatei nicht einmal von anderen neu erstellt werden kann mit den gleichen Ergebnissen.

Ich verstehe jetzt, dass dies ein verständlicherweise akzeptiertes Risiko ist. Meine Frage ist, ob es andere Diskussionen oder Hinweise gibt, wie Quellcode Byte für Byte beim Kompilieren reproduzierbar gemacht werden kann, sodass nicht mehr dem Anbieter von Open Source-Binärdateien vertraut werden muss. Wie in der Diskussion von Jon Callas erwähnt, zeigte Ken Thompson „Sie können Code nicht vertrauen, den Sie nicht vollständig selbst erstellt haben.“ Was sind die Sicherheitsaspekte zu diesem Thema?

Ich möchte darauf hinweisen, dass Sie, wenn Sie das Programm selbst kompilieren, um es mit der veröffentlichten ausführbaren Datei zu vergleichen, stattdessen auch Ihre eigene Version verwenden können. Auf diese Weise sparen Sie sich Zeit und können keinen Fehler machen. (Oh und außerdem ist der Vergleich von zwei Dateien Byte für Byte schneller als der Vergleich ihrer Hashes.)
@LS97: Streng genommen kann das Vergleichen von Hashes tatsächlich schneller sein, vorausgesetzt, der Direktzugriff ist teuer und jede Datei wird zusammenhängend auf der Festplatte gespeichert, da das parallele Lesen beider Dateien beim Vergleich einen zufälligen Zugriff ermöglicht, während das Hashing das Lesen nacheinander in Reihe ermöglicht.
@R .. das stimmt, die Geschwindigkeit des Vergleichs von Hashing und Byte hängt von vielen Faktoren ab. Wenn Sie beispielsweise über einen ausreichend großen Speicher verfügen, können Sie beide weiterhin seriell laden. Oder Sie tun es parallel und hoffen, in einer großen Datei frühzeitig einen Unterschied zu finden (und dann dort anzuhalten). Außerdem ist Byte für Byte die einzig mögliche Methode in einem Computer mit winzigem RAM (ich spreche von ein paar Kilobyte).
Acht antworten:
Lily Chung
2014-07-30 22:03:55 UTC
view on stackexchange narkive permalink

So einfach ist das nicht.

Angesichts der großen Anzahl von Plattformen, auf denen das Programm hätte erstellt werden können, kann es äußerst schwierig sein, die ursprüngliche Build-Umgebung zu replizieren. Aus diesem Grund verwenden Sie möglicherweise einen anderen Compiler mit unterschiedlichen Einstellungen und unterschiedlichen Versionen von Bibliotheken. Diese geringfügigen Abweichungen in der Umgebung können sich definitiv auf die kompilierte Binärdatei auswirken. Wenn der Autor bereit ist, seine Build-Umgebung genau anzugeben, oder wenn Sie Glück haben (verschiedene Sprachen können dies beeinflussen), kann es natürlich möglich sein, genau dieselbe Binärdatei neu zu erstellen.

Für eine aktuelle Situation Informationen hierzu finden Sie unter TrueCrypt, einem Open-Source-Verschlüsselungsprogramm für 0 sup>. Als die TrueCrypt-Site abrupt durch eine Ankündigung ersetzt wurde, die das unerwartete Ende des TrueCrypt-Projekts erklärt, waren die Leute offensichtlich daran interessiert, den Code zu überprüfen. Verschiedene Benutzer, die TrueCrypt erstellen, haben jedoch häufig Binärdateien erhalten, die sich aufgrund von Abweichungen in der Build-Umgebung stark vom offiziellen Build unterscheiden. Eine Person hat es anscheinend geschafft (nach einigen mühsamen Arbeiten bei der Neuerstellung von Objekten, die der ursprünglichen Umgebung sehr nahe kommen), den TrueCrypt-Build von Grund auf mit nur geringfügigen Abweichungen in der kompilierten Ausgabe zu replizieren. 1 sup> Natürlich ist es nicht möglich, dies selbst zu überprüfen, wenn Sie nicht bereit sind, dasselbe zu versuchen.

Interessant auf dieser Seite ist die Tatsache, dass die Binärdatei einen Zeitstempel der Kompilierungszeit enthält. Dies allein bedeutet, dass das Kompilieren und Vergleichen der Hashes niemals funktionieren würde.

0: TrueCrypt hat eine seltsame Lizenz mit einigen Problemen. Es ist nicht sicher, ob es tatsächlich sicher wäre, das Projekt zu verzweigen. sup>

1: Eigentlich sieht es so aus, als hätten sie dies vor der Seltsamkeit der TrueCrypt-Site getan, aber seitdem ist die Replikation erfolgreich Die Version 7.2 wird ebenfalls erstellt. sup>

Sie haben mit TrueCrypt ein kluges Beispiel gewählt.
Das Tor-Projekt hat einen sehr interessanten Blog-Beitrag über [Deterministic Builds] (https://blog.torproject.org/blog/deterministic-builds-part-two-technical-details), der einige der damit verbundenen Probleme erklärt.
Thomas Pornin
2014-07-30 22:45:41 UTC
view on stackexchange narkive permalink

Wenn Sie den Code selbst kompilieren, erhalten Sie möglicherweise dieselbe Binärdatei. Oder nicht. Grundsätzlich stehen Ihre Chancen gut, wenn der Compiler deterministische Optimierungsalgorithmen verwendet (dies ist der übliche Fall). Und Sie verwenden genau dieselbe Compilerversion mit denselben Befehlszeilenoptionen (dies ist normalerweise viel schwieriger sicherzustellen).

Die deterministische Neukompilierung ist mit dem Programmierframework einfacher, bei dem das "kompilierte" Format formal spezifiziert und nicht wirklich optimiert ist. Ich spreche hier von Java-Bytecode oder .NET-Assemblys. Bei Verwendung solcher Tools ist es möglich , wenn auch schwierig, den Quellcode neu zu kompilieren und dieselbe Binärdatei zu erhalten. Vergessen Sie es mit C oder C ++.

Die üblichen Methoden sind:

  • Kompilieren Sie sich.
  • Haben Sie Vertrauen Dritte machen die Zusammenstellung. Dieser Drittanbieter erhält eine Kopie der Quelle, führt die Kompilierung von seinen Computern durch und signiert (mit Kryptografie oder Papier) sowohl das Quellarchiv als auch die erstellte Binärdatei.
  • Lassen Sie den Anbieter des Binärzeichens die Binärdatei und vertrauen Sie darauf, dass Reverse Engineering machbar genug ist, um bei Bedarf ein Foulspiel zu demonstrieren (auch dies ist viel weniger unplausibel, wenn es um Java-Bytecode geht als kompilierter C-Code).
  • Verwenden Sie keine externe Software. Implementieren Sie alles intern neu (und ja, dies ist eine übliche Methode, die nicht mit der empfohlenen >) identisch ist.
  • Gehen Sie einfach voran und vertrauen Sie in Ihrem Glück (sicherlich keine empfohlene Methode, aber kurzfristig sicherlich die billigste).

Beachten Sie, dass das (erneute) Kompilieren von Code auch erfordert, dass der Computer, auf dem die Kompilierung stattfindet, nicht unter feindlicher Kontrolle steht. Dieser sehr klassische Aufsatz ist ein Muss zu diesem Thema. Die Grundidee ist, dass Ihr Vertrauen immer noch irgendwo beginnen muss (wenn auch nur in der Hardware selbst, deren Firmware als Malware-frei angenommen wird). Das Beste, was Sie wirklich tun können, ist, einen klaren Prüfpfad beizubehalten . Eine solche Ablaufverfolgung garantiert nicht das Einfügen von Hintertüren, kann jedoch bei der Zuweisung von Schuld und Verantwortung bei auftretenden Problemen sehr hilfreich sein.

Wenn man einen Cross-Compiler für das Zielsystem hatte, der eine vollständig deterministische Ausgabe erzeugen sollte, überprüfte man den Code dieses Compilers, um sicherzustellen, dass nichts Böses darin war, und das Kompilieren eines Open-Source-Programms auf mehreren unabhängigen Systemen ergab identische Ergebnisse Es wäre nicht notwendig zu wissen, dass eine bestimmte Maschine vertrauenswürdig ist - lediglich, dass es keinen plausiblen Mechanismus gibt, mit dem sie alle auf die gleiche Weise infiziert werden könnten.
Tom Leek
2013-09-04 02:13:30 UTC
view on stackexchange narkive permalink

Wenn Sie den Quellcode neu kompilieren und eine eigene Binärdatei haben können, können Sie möglicherweise nicht genau dieselbe Binärdatei wie die verteilte Binärdatei erhalten. aber warum sollte es wichtig sein? Zu diesem Zeitpunkt haben Sie Ihre eigene Binärdatei, die notwendigerweise mit dem Quellcode übereinstimmt (vorausgesetzt, Ihr Compiler ist selbst nicht bösartig): Sie können das Binärpaket einfach fallen lassen und Ihre eigene Binärdatei verwenden. P. >

Mit anderen Worten, Situationen, in denen Sie die Kompilierungsausgabe überprüfen können, sind Situationen, in denen Sie sich selbst kompilieren können, wodurch die Überprüfung zu einem strittigen Punkt wird.

Es gibt Paketverteilungs-Frameworks, die Verlassen Sie sich auf die Verteilung des Quellcodes und die lokale Kompilierung anstelle von Binärpaketen. z.B. pkgsrc (das native System für NetBSD) oder MacPorts (für MacOS X-Computer). Sie tun dies jedoch nicht aus Gründen des Vertrauens oder der Sicherheit, sondern weil die Verteilung von Binärpaketen irgendwo Build-Systeme umfasst und diese nicht kostenlos sind. Ein Punkt von pkgsrc ist auch die einfache Verwaltung lokaler Kompilierungsoptionen.

Der berühmte Thompson-Aufsatz unterstreicht die Idee, dass es nicht ausreicht, selbst eine Kompilierung zu erstellen. Im Extremfall sollten Sie Ihren eigenen Code, aber auch Ihren eigenen Compiler schreiben und diesen auf Hardware ausführen, die Sie selbst entworfen und graviert haben: Sie können der Maschine nur vertrauen, wenn Sie mit einem Eimer Sand (für Silizium , die Hauptkomponente von Halbleitern). Dies ist natürlich ziemlich unpraktisch. Deshalb brauchen wir das zweitbeste, und dieses zweitbeste ist ein Paradigmenwechsel : Vertrauen durch Gewalt ersetzen .

Was wir tun, ist, dass Binärpakete signiert sind. Das Paketinstallationsprogramm überprüft die Signatur vor der Installation und lehnt Pakete ab, die nicht aus "vertrauenswürdigen Quellen" stammen. Das gleiche Konzept gilt für Java-Applets, denen zusätzliche Berechtigungen (und in der Tat die Berechtigung, mit Ihrem Computer zu tun, was sie wollen) erteilt werden können, sofern sie signiert sind. Beachten Sie, dass dies in der Tat eine Signatur ist, nicht nur eine Authentifizierung. Es ist nicht ausreichend (und auch nicht notwendig), dass das Paket über HTTPS aus einem "vertrauenswürdigen Repository" heruntergeladen wurde. Ein solcher Download würde Ihnen eine gewisse Garantie geben, dass das Paket von dem stammt, von dem Sie glauben, dass es während des Transports nicht geändert wurde. Aber Sie wollen mehr: Sie wollen einen Beweis . Sie möchten eine Signatur, denn wenn sich herausstellt, dass das Paket voller Malware ist, können Sie die Signatur verwenden, um zu demonstrieren, dass der Paketanbieter zumindest "fahrlässig" ein Komplize war. Aus Unterschriften geht Verantwortung hervor, und Verantwortung wirkt auf Angst . Angst vor Rechtsstreitigkeiten von missbrauchten Kunden. Angst vor Vergeltungsmaßnahmen durch Strafverfolgungsbehörden. Letztendlich Angst vor Gewalt.

Du hattest mich beim Schmelzen des Sandes.
Wie können Sie sicherstellen, dass der Sand nicht beeinträchtigt wurde?
Ist mir egal! Sie können aus kompromittiertem Sand einen korrekten Compiler machen! Ich muss nur überprüfen, ob der mit diesem Compiler kompilierte Compiler… sich selbst ergibt :).
@danielAzuelos, ignoriert den Sandwitz ... ein kompromittierter Compiler könnte sich selbst kompilieren (mit dem kompromittierten Teil hinzugefügt).
→ domen: leider hast du recht :(. Der erste C-Compiler wurde in PDP-7-Assembler handgeschrieben. Wenn zu dieser Zeit ein Maschinencode eingeführt würde, um wiederholt in jeden neuen kompilierten Compiler eingebettet zu werden, wäre er noch heute Fossilien dieser Maschine kodieren in * jedem * C-Compiler der Welt genau, da in jedem menschlichen Wesen eine Spur unseres Reptilienhirns eingebettet ist.
goodguys_activate
2014-07-30 22:40:43 UTC
view on stackexchange narkive permalink

Ja ist möglich. Es ist jedoch sehr schwierig, da der gesamte Kompilierungsprozess nicht für dieses Ziel konzipiert wurde. Es wird oft als "deterministische Builds", "reproduzierbare Builds", "idempotente Builds" bezeichnet und ist eine Herausforderung.

Bitcoin, Tor und Debian versuchen, deterministische Builds zu verwenden, und der technische Prozess wird hier beschrieben.

Zugegeben, der Prozess ist unvollkommen, fragil und sehr schwer richtig zu machen. Bei plattformübergreifenden Builds ist das Problem noch komplexer.

Beide Links führen zum selben Ort. Meinten Sie, dass der erste zu [Teil 1] gehen sollte (https://blog.torproject.org/blog/deterministic-builds-part-one-cyberwar-and-global-compromise)?
@IstvanChung - Danke, war auf einem mobilen Gerät. Ausschneiden und Einfügen schlagen fehl
Wenn eine Binärdatei auf Übereinstimmung mit dem Quellcode überprüft wurde, verwenden Sie die Binärdatei nur mit der überprüften Prüfsumme für das gesamte Archiv. Sogar zwei Tarballs, die nachweislich identische Dateien und Berechtigungen haben, können sich geringfügig unterscheiden. Wir haben dies bei der Reihenfolge der Dateierstellung gesehen, bei der eine Installation abstürzt und eine andere ordnungsgemäß ausgeführt wird. trotz jeder datei mit dem gleichen md5 cheksum. A vor B in einem Verzeichnis durchquert versus B vor A in einem anderen. Eine dieser Bestellungen kann mit einer Sicherheitsanfälligkeit usw. zusammenhängen.
this.josh
2013-09-04 12:07:15 UTC
view on stackexchange narkive permalink

Ich mag Determinismus.

Ein Compiler oder ein Software-Tool ist wirklich eine verschlagene mathematische Transformation. Es nimmt s (Quellcode), setzt es in eine Funktion C () und erzeugt eine binäre Ausgabe b.

b = C (s) jedes Mal! Andernfalls versagt der Determinismus und wir werden alle verrückt.

Die Theorie lautet also: Solange wir mit demselben s und demselben C () beginnen, werden wir immer dasselbe b produzieren.

Und das ist gut so, weil wir einen Hash von b oder H (b) ausführen und einen relativ kurzen Wert erhalten können, den wir mit dem H (b) eines anderen vergleichen können, um sicherzustellen, dass es sich um einen binären handelt wir erwarten.

Und dann geschieht eine Änderung: s ändert sich zu s ', C () ändert sich zu C' (). Oh nein!

Weil C (s) = b1 und C '(s) = b2 und C (s') = b3 und C '(s') = b4

und Natürlich stimmen keine zwei von H (b1), H (b2), H (b3) oder H (b4) jemals überein.

Und das Problem ist, dass als Komponenten (Werkzeugkette, Umgebung, Konfiguration, Betriebssystem usw.), die erforderlich sind, um binäres b zu erzeugen, werden zahlreicher und voneinander abhängig. Es wird immer schwieriger, dasselbe b zu reproduzieren.

Warten Sie, was ist, wenn wir nicht genau das gleiche b benötigen?

Wir haben es dann mit b und b 'und dem Unterschied zwischen ihnen zu tun.

Alles, was Sie brauchen, um den Unterschied zwischen einer Referenzbinärdatei b und Ihrer generierten Binärdatei b 'zu finden und zu sehen, was die Differenz bedeutet. Wenn die Quelle für b und b 's ist, bedeutet dies, dass es sich um C () und C' handelt. Und so können wir den Unterschied zwischen C () und C '() mit dem Unterschied zwischen b und b' korrelieren. Selbst wenn wir b nicht genau reproduzieren können, können wir ein gewisses Vertrauen in b 'gewinnen, indem wir uns darauf stützen, welcher Unterschied durch die Verwendung von C' () anstelle von C () verursacht wird.

Gute Argumente. Ich denke, die Technik zur Bestimmung, dass die Quelle für b und b 'tatsächlich dieselbe ist, ist der Knackpunkt, da die Compiler in den Händen anderer sind.
dan
2014-07-30 23:05:55 UTC
view on stackexchange narkive permalink

Selbst mit denselben Quellen, demselben Betriebssystem, denselben Bibliotheken, demselben Compiler und demselben Loader stimmen zwei Binärdateien nicht überein, da sie Informationen zum Datum der Kompilierung und zum Laden enthalten.

Wenn Sie in genau derselben System- und Entwicklungsumgebung zweimal dieselbe Binärdatei erstellen, ist diese unterschiedlich, und daher unterscheidet sich jeder Hash:

 $ md5 nmapMD5 (nmap) = 8ef4b7c1cb2c96ce68d9e08224419b4f $ # make clean, make install $ md5 nmapMD5 (nmap) = 94467bc53973550f919293f891f245f9 

Wenn die Symboltabellen nicht entfernt wurden, stimmen diese Symboltabellen überein und sind eine gute Annäherung, um zu diagnostizieren, dass eine Binärdatei wirklich aus a aufgebaut ist angegebene Quelle:

 $ nm -a nmap> /tmp/nmap.nm.1$ # sauber machen, installieren $ nm -a nmap> /tmp/nmap.nm.2$ diff / tmp / nmap.nm. [12] $ 

Dies gilt nur für mich, um zu überprüfen, ob eine Binärdatei tatsächlich von einer bestimmten Version meiner Baumquelle stammt. Wenn ich eine externe Temperierungsquelle für alles vermute, dann sogar die Diese Symboltabellen könnten "angeordnet" sein.

keshlam
2014-07-31 09:11:14 UTC
view on stackexchange narkive permalink

Wenn Sie nicht sicher sind, ob Sie der Zusammenstellung eines anderen vertrauen, würden Sie sich im Allgemeinen die Mühe machen, Ihre eigenen zu erstellen, oder jemanden finden, der sie erhält, von dem Sie vertrauen.

Aber sind Sie sicher Sie können darauf vertrauen, dass Ihr Compiler nicht infiziert wurde?

Es sind Schildkröten ganz unten. Irgendwann müssen Sie immer ein Urteil fällen und / oder sich auf Virenprüfer, Firewalls und andere Sicherheitssysteme verlassen.

AFTERTHOUGHT - Dies ist eines der Gründe, warum Unternehmen existieren, die produzierte Versionen von Open-Source-Code vertreiben. Sie überwachen ihre Codebasis, versprechen, dass ihre Builds sauber sind, und bieten (wenn Sie sie kaufen) fortlaufende Unterstützung. Denken Sie daran, dass sogar Stallmans GNU-Manager sagte: "Software sollte kostenlos sein, Support sollte kosten."

Die Vertrauenswürdigkeit der Downloads ist eine Form der Unterstützung. Sie erhalten möglicherweise gute Unterstützung von einer kostenlosen Community ... aber Sie erhalten möglicherweise bessere Unterstützung, wenn Sie ein paar Dollar darauf werfen. Wählen Sie Ihren bevorzugten Kompromisspunkt.

Ich bin bereit, einen zufälligen Linux-Build zum Herumhacken auf einem sekundären Computer zu verwenden. Ich würde so etwas wie Fedora für die persönliche Maschine bevorzugen, auf die ich mich tatsächlich verlasse. Und wenn ich ein Unternehmen darauf wetten würde, würde ich mich für die vollständige Version des gekauften Produkts, Red Hat Enterprise oder ähnliches, entscheiden. (Bestätigung nicht impliziert; Fedora und RHEL sind nur gute Beispiele dafür, wie ein Unternehmen zwei verschiedene Punkte in diesem Spektrum anspricht.)

Vielen Dank für diese Antwort, aber sie fügt den vorhandenen Antworten nichts hinzu. In der akzeptierten Antwort wird bereits darauf hingewiesen, dass Sie Ihrem Compiler vertrauen müssen.
OK; vermisst, dass es bereits abgedeckt war. Angesichts der Tatsache, dass mich jemand positiv bewertet hat, bin ich anscheinend nicht der einzige.
Inhalt hinzugefügt. Glücklicher, Giles?
PsychoData
2013-09-04 04:24:38 UTC
view on stackexchange narkive permalink

Eines der grundlegenden Dinge, denen Sie in eine Binärdatei vertrauen, ist der Ort, von dem Sie sie erhalten haben. Wenn sourceforge oder download.com oder wer auch immer sagt, dass es frei von Viren ist und das gut genug für Sie ist, dann machen Sie es. Du nimmst ihr Wort drauf.

Wenn Sie einer Binärdatei nicht vertrauen möchten, besteht die einzige echte Antwort darin, aus dem Quellcode zu kompilieren. Entweder zu etwas wie Java-Bytecode, den Sie ausführen können, oder zu einem JAR oder zu einer Binärdatei.

Wenn Sie Ihre eigene Binärdatei kompilieren, erhalten Sie möglicherweise etwas, das mit der Standard-Binärdatei identisch ist (was bedeutet, dass ALLES GLEICH ist, ein bisschen für Bit-Übereinstimmung). Großartig! Sie haben zufällig dieselbe Hardware ausgeführt und für dieselben Prozessoren kompiliert. Niemand hat versehentlich einen zusätzlichen Zeilenumbruch in Ihrer Kopie des Codes hinterlassen. Unabhängig davon, ob er übereinstimmt oder nicht, vertrauen Sie zu diesem Zeitpunkt dem Code, den Sie haben hatte gerade (zumindest die Fähigkeit) zu lesen. Wenn Sie C ++ nicht kennen und anderen Personen, die den Code überprüft haben, nicht vertrauen, ist dies schwierig. Lernen Sie C ++ und überprüfen Sie es selbst.

Das alles läuft darauf hinaus, dass Sie eine Binärdatei nur überprüfen können, wenn alles genau übereinstimmt. Sie können den Open Source Code jedoch jederzeit auf etwas überprüfen. Ob Sie sich die Zeit nehmen oder der Analyse vertrauen, die vermutlich jemand da draußen durchgeführt hat, ist Ihre Wahl.



Diese Fragen und Antworten wurden automatisch aus der englischen Sprache übersetzt.Der ursprüngliche Inhalt ist auf stackexchange verfügbar. Wir danken ihm für die cc by-sa 3.0-Lizenz, unter der er vertrieben wird.
Loading...