Stand 29.06.2004
Dieses Dokument beschreibt die Änderungen und Erweiterungen, die bei der Implementierung der Bezahlfunktion am ursprünglichen von Andreas Müller in seiner Diplomarbeit entworfenen Protokoll vorgenommen wurden. Es soll dazu dienen, Entwicklern einen Überblick über die Implementierung zu geben und den Einstieg zu erleichtern. Zum Teil sind auch Aspekte enthalten, die vielleicht eher in eine Benutzerdokumentation gehören und später ausgegliedert werden können.
Für das gesamte Dokument gilt: Da die Implementierung noch nicht abgeschlossen ist, sind einige Bereiche noch nicht genau spezifiziert und können sich auch noch ändern.
Um das Konto eines Nutzerpseudonyms aufzuladen, werden so genannte Transaktionsnummern (transfer numbers) verwendet. Wenn der Nutzer eine Aufladung durchführen möchte und den entspr. Button im JAP anklickt, fordert der JAP per /charge Request eine Transaktionsnummer bei der Bezahlinstanz an. Diese generiert nach dem im c't-Magazin 4/97 ("Blütenrein") beschriebenen Diedergruppen-Prüfsummen-Verfahren eine 12-stellige Transaktionsnummer mit Prüfziffer am Ende und schickt diese in einem sogenannten transfer certificate an den JAP zurück.
Das Hinzufügen einer Prüfsumme erschien hier sinnvoll, da die Transaktionsnummern bei "manuellen" Bezahlmethoden wie der Banküberweisung von Hand aufgeschrieben werden müssen, und deshalb eine frühzeitige Erkennung von Abschreibefehlern die Verwaltung wesentlich vereinfachen kann.
Um die Einzahlung für den Benutzer zu vereinfachen, haben wir in PHP ein Web-Interface implementiert. Dieses sollte auf einem Apache-Server mit SSL-Verschlüsselung laufen. Die entsprechende URL mit der vorher generierten Transaktionsnummer als Parameter wird vom JAP automatisch aufgerufen. Die Interaktion mit dem Web-Interface kann auch über den Anonymisierungsdienst durchgeführt werden, damit die Bezahlinstanz nicht die IP-Adresse des Benutzers mit seiner Account-Nummer verketten kann.
Das Web-Interface ermöglicht eine Auswahl der angebotenen Tarife und der gewünschten Zahlungsmethode. Zur Zeit werden die Zahlungsmethoden Banküberweisung und PayPal unterstützt. Bei einer Überweisung per PayPal kann die Überweisung vollständig über das Webinterface durchgeführt werden und der eingezahlte Betrag landet (normalerweise!) innerhalb weniger Sekunden auf dem Pseudonymkonto und kann sofort versurft werden. Bei einer Banküberweisung zeigt das Webinterface lediglich eine Zusammenfassung an, auf der genau beschrieben wird was in die einzelnen Felder der Überweisung einzutragen ist. Dies erschien sinnvoll, da viele Benutzer sonst (nach Erfahrungen von CookieCooker-Maintainer Oliver Berthold) auf Überweisungsformularen zusätzliche unnötige Informationen eintragen und somit den Verwaltungsaufwand erhöhen.
Andreas Müller geht in seiner Diplomarbeit davon aus, dass es nur einen einzigen Tarif geben soll der so aussieht, dass Benutzer pro versurftem KByte eine bestimmte Gebühr zahlen müssen. Als Erweiterung unterstützt das System nun mehrere Tarifmodelle, so dass es beispielsweise möglich ist eine Art Flatrate, d.h. unbegrenzte Nutzung des Anonymisierungsdienstes gegen einen monatlichen Pauschalbetrag, sowie einige weitere Tarifmodelle anzubieten. Die Änderungen in der BI-Datenbank, die dies ermöglichen, sind in Kapitel 4.3 beschrieben.
Zur Erstellung von neuen Tarifen und deren Beschreibungstexten in verschiedenen Sprachen kann das Skript rate-manager.php verwendet werden, das bei der BI mitgeliefert wird. Es ist leider etwas kompliziert zu bedienen (da ein ganz schneller Hack), aber immerhin muss man nicht von Hand in der Datenbank herumpfuschen.
Bei der Abfrage des Kontostandes schickt die BI eine XML-Struktur an den JAP, in der der aktuelle Kontostand sowie auch der kumulierte bisher überwiesene Gesamtbetrag (G_max bzw. maxbalance) enthalten sind. Da das in der Diplomarbeit spezifizierte Format kein korrektes XML ist, haben wir das Format wie folgt verändert:
<?xml version="1.0"> <AccountInfo> <Balance> . . . </Balance> <Confirmations> <Confirmation> <CC> ... </CC> <Digest> ... </Digest> </Confirmation> . . . <Confirmation> <CC> ... </CC> <Digest> ... </Digest> </Confirmation> </Confirmations> </AccountInfo>
Die wichtigste Änderung besteht darin, das gesamte Dokument in ein AccountInfo-Element einzubetten, da es in XML genau ein Root-Element geben muss.
Für den in der Diplomarbeit noch nicht näher spezifizierten Übertragungskanal (dort Steuerkanal genannt) zwischen Jap und der Abrechnungsinstanz haben wir folgendes implementiert: Der Übertragungskanal ist in der bestehenden Socket-Verbindung zwischen JAP und erstem Mix integriert und hat die reservierte Channel-ID 0xffffffff. Der erste Mix filtert also alle Pakete, die mit dieser ID beginnen aus dem Datenstrom heraus und gibt sie an die AI weiter. Das gleiche passiert im JAP für von der AI kommende Nachrichten.
Da eine zwischen JAP und AI ausgetauschte XML-Nachricht auch mal länger sein kann als die 988 Bytes Payload/Paket, kann sich eine Nachricht auch über mehrere Pakete erstrecken. Die Gesamtlänge einer zu übertragenden Nachricht wird daher in den ersten 4 Bytes des ersten Paketes dieser Nachricht mitgesendet.
Der Übertragungskanal zwischen JAP und AI wird mit zwei dedizierten symmetrischen Stromchiffren verschlüsselt. Dabei ist die erste Chiffre für die Richtung JAP->AI, der zweite Schlüssel für die Richtung AI->JAP. Die Schlüssel dafür werden beim Verbindungsaufbau vom Jap generiert und zusammen mit den beiden anderen symmetrischen Schlüsseln, die zur Verschlüsselung der Kanalnummern eingesetzt werden, im ersten Mixpaket übertragen (siehe unten).
Achtung: Dieser Teil wird sich demnächst ändern, da die Anmeldung statt mit einem binären "keypacket" in Zukunft mit XML laufen wird
Den Verbindungsaufbau JAP-AI mussten wir wegen der anderen Beschaffenheit des Übertragungskanals (in der Diplomarbeit wurde von einer vollständigen Trennung der AI vom ersten Mix ausgegangen, wir haben jedoch die AI in den Mix integriert) leicht modifizieren:
Offset | Daten |
0 | String "KEYPACKET" |
9 | 32 Bytes Sitzungsschlüssel für die normalen Mixpakete (16 Byte upstream, 16 Byte downstream) |
41 | 16 Bytes Sitzungsschlüssel für den Steuerkanal in Richtung AI->JAP |
57 | 16 Bytes Sitzungsschlüssel für den Steuerkanal in Richtung JAP->AI |
73 | XYZ Bytes Response |
Einige erste Punkte:
Die Tabelle Transfers speichert Transaktionsnummern und übernimmt somit die Funktion der alten Tabelle CREDITCARDTRANSFERS. Gespeichert wird die Transaktionsnummer selbst als eindeutige ID, die Accountnummer für die die Transaktionsnummer erstellt wurde, die MAXBALANCE, die zum Erstellungszeitpunkt der TAN aktuell war (dies wird benötigt um zu verhindern, dass der Nutzer behaupten kann das überwiesene Guthaben sei nicht eingebucht worden), sowie ein Ablaufdatum und ein Flag, welches besagt ob die Nummer schon verwendet wurde.
In dieser Tabelle werden Tarifmodelle abgelegt. Jedes Tarifmodell hat eine eindeutige Nummer, die im Feld ID gespeichert wird. Im Feld Name kann dem Tarifmodell ein Name zugeordnet werden. Der Quotient aus den beiden Feldern AMOUNT/MBYTES bestimmt den Preis pro Megabyte. Das Flag FIXED_AMOUNT gibt an, ob der Benutzer gezwungen wird genau diesen Betrag zu überweisen (für Flatrate-ähnliche Modelle), oder ob er je nach gewünschtem Datenvolumen mehr oder weniger überweisen kann (Volumentarife).
In den Feldern VALID_DAYS und VALID_MONTHS wird gespeichert, wie lange der überwiesene Betrag auf dem Pseudonymkonto gültig bleibt. Dies ist nötig, um bei Pseudo-Flatrates den Restbetrag am Monatsende verfallen zu lassen.
Zusätzlich zur Tabelle RATES gibt es noch weitere Tabellen, in denen die Beschreibungen der Tarifmodelle in verschiedenen Sprachen gespeichert wird. Diese haben die Namen RATE_DESCR_XX, wobei XX für das 2stellige Landeskürzel steht (z.B. DE, EN, FR, ...).
Die Abrechnungsinstanz wurde, anders als in der Diplomarbeit beschrieben, direkt in den Mixcode (Projekt proxytest) integriert. Grundsätzlich ist alles, was zur Bezahlfunktion gehört, im Mixcode in "#ifdef PAYMENT" eingeschlossen, wird also nur dann mitcompiliert wenn man die Bezahlfunktion explizit einschaltet.
Implementiert wurde ein bidirektionaler in die normale Socketverbindung zum JAP integrierter Kommunikationskanal zum JAP sowie ein Thread, der die von verschiedenen JAPs hereinkommenden Nachrichten asynchron verarbeitet. Das Parsen der XML-Strukturen und daraufhin Anstoßen von Aktionen wie Verbindung schließen, Bestätigung von der BI holen usw. ist noch unvollständig.
Implementiert wurde eine Verbindung zu einer Postgresql-Datenbank, in der CostConfirmations gespeichert werden sollen. In der Klasse CACndLnOptions wurde zusätzlicher Code zum Auslesen der Verbindungsdaten zur Datenbank aus der XML-Configurationsdatei hinzugefügt
Implementierung eines SSL-verschlüsselten HTTP-Kommunikationskanals zur BI, aufbauend auf CASSLClientSocket. Status: Theoretisch vollständig, aber noch nicht getestet
Eine auf der OpenSSL-Bibliothek aufbauende einfache Socket-Klasse, die das Verbinden mit SSL-Servern ermöglicht. Die Klasse ist soweit vollständig dass man Verbindungen aufbauen und Daten transferieren kann. Die Authentifikation beim Verbindungsaufbau ist noch nicht getestet und evtl. fehlerhaft bzw. unvollständig
Diese Klasse kapselt das SSL_CTX Objekt. Diesem Objekt werden beim Aufbau der ersten SSLSocket-Verbindung das Mixzertifikat und der Signierschlüssel zugewiesen. Das Zertifikat und der Schlüssel werden dann für alle SSLSocket-Verbdinungen verwendet. Sollte vollständig sein, ist aber noch nicht getestet
Eine Klasse, die IP-Adressen von "bösen" JAP-Nutzern für eine bestimmte Zeitspanne (z.B. 10 Minuten) aufnimmt. In dieser Zeit nimmt der erste Mix dann Verbindungen von diesen IP-Adressen nicht an. Dies ist notwendig, da es möglich sein soll eine bestimmte Zeit ohne Anmeldung am Bezahlsystem auf Kulanz den Dienst zu nutzen. Man soll dies aber nicht unbegrenzt oft und immer wieder tun können, deshalb die 10-Minuten-Sperre
Die Bezahlfunktion im JAP wurde bis Ende 2003 von Grischan Glänzel <grischan@web.de> implementiert, ist allerdings noch nicht völlig vollständig. Den folgenden Text hat Grischan als "Pay_Todo" geschrieben, als sein Arbeitsvertrag auslief.
Was noch zu tun ist: JAP - BI -------- Die Kommunikation steht im Prinzip evententuell müsste das übertragen der Cost Confirmation nochmals getestet werden. JAP - AI -------- Der Kommunikationsaufbau zur AI und auch das versenden von CostConfirmations ist geschrieben aber beides noch nicht getestet. AICommunication.java es müsste überlegt werden wie oft die CostConfrimation gesendet wird und was bei abbruch des Programmes passiert (die letzten gesendeten Pakete werden dann -zurzeit- von Jap aus nicht berechnet - auch nicht gespeichert) [Zeile 61] beim test darauf achten ob das warten auf PayRequests das versenden der CC's blokiert. AnonProxy.java Nach dem Testen die alten einwege Methoden ausbauen [168] gucken ob die Verbindung zur AI an dieser Stelle gestartet werden sollte. MuxSocket.java Eventuell Methode nach AIComm. verschieben (siehe Quellcode AIComm) JAP ----- Inhalt Die PayFunktionalität müsste per CVS in den Code des orginal Jap integriert werden. Die Felder name der BI, port der BI sowie das flag sslOn könnten in das Jap XML File intigriert werden. (habe ich noch nicht gemacht weil diese daten zurzeit darüber immer aktuell angezeit werden das die speichernde Klasse eine Eventquelle ist - d.h es müssten evetuell umfangreicher änderungen im JAP Code vorgenommen werden - dies wollte ich nicht machen - solang es noch gar nie in die aktuelle Version intigriert war) Einige Strings die Ausgegeben werden müssten vermutlich noch internationalisiert werden. Code Eventuell könnte die Benutzerinteraktion aus den pay.view Klassen und PayAccountsControl komplett nach PayControl bzw. in klassen im pay.control Package verschoben werden.
Zuletzt geändert am 29.06.2004 von Bastian Voigt <bavoigt@inf.fu-berlin.de>