Seite 1 von 1
Login-System
Verfasst: 7. August 2012 12:38
von zerobyte
Hallo,
Folgende Situation:
Ich habe ein Serverprogramm das zugriff auf eine Datenbank mit Benutzernamen und Passwort hat.
Wenn der Benutzer das Clientprogramm startet, erscheint ein loginfenster. Nun soll sich der Benutzer anmelden und nur wenn dies Erfolgreich geschieht soll er weiter in das Clientprogramm vordringen können. Jetzt bin ich am überlegen wie ich das am sichersten programmieren soll.
Eine Idee wäre dass wenn der Benutzer sich erfolgreich angemeldet hat der Server eine positive bestätigung an das Clientprogramm schickt und dort eine Variable zb. login auf true setzt und bei jeder Aktion im Clientprogramm wird diese Variable überprüft. Nur erscheint mir dies als nicht sicher, kann nicht sagen wieso aber habe da so ein komisches Gefühl.
Hat jemand eine Bessere Idee ?
Re: Login-System
Verfasst: 7. August 2012 13:22
von brax
So etwas clientseitig abzuhandeln ist immer gefährlich, da hast Du recht. Manipulationen durch "böse" Anwender sind hier sehr einfach. (Per Disassembler die Methode "isLoggedIn" oder ähnliches finden und dort manipulieren. Auch ein unverfänglicherer Name ist wenig hilfreich, da dies per tracing des Ablaufs auf jeden Fall leicht zu finden ist.)
Der Client sollte für jede Aktion zusätzlich zu der jeweiligen payload (also den für die Aktion relevanten Daten) auch Sicherheitsdaten mitschicken, damit die Berechtigung serverseitig gecheckt werden kann.
Am einfachsten wäre es wohl, wenn die Client Anwendung sich beim Login Benutzernamen und Passwort merkt und dies immer mitschickt. Dann checkt der Server jeweils vor der Ausführung der Aktion, ob das alles stimmt. Ich weiß nicht, was für ein Protokoll Du für die Kommunikation zwischen Client und Server benutzt, aber bei http zum Beispiel wird es (im einfachsten Fall) genau so gemacht. In dem Fall sind dann Benutzername und Passwort Base64-kodiert im Auth-Header.
Re: Login-System
Verfasst: 7. August 2012 14:26
von zerobyte
ok, ich würde das dann so machen:
Beim Login erstelle ich einen zufälligen ID-Key speichere ihn und übertrage ihn an den Client. Bei jeder Aktion des Clients wird der Key mitgesendet und vom Server überprüft.
Würde das eine gewisse Sicherheit geben ?
Re: Login-System
Verfasst: 7. August 2012 14:40
von RHBaum
Ich nehme an du kommunizierst per TCP textbasiert ?
Warum nicht verwenden, was tausend andere vor dir schon verwenden ? und was nachbweissbar so sicher wie möglich ist ? ^^
- Server Client -> "Halo" (erstes handshake) unverschluesselt
- "Update" auf TLS
- Login ueber die nun verschluesselte verbindung
- den Loginstatus des Clients kannst und solltest nun aufn server an der "Verbindung" festmachen .... das die jemand nun hijackt iss eher sehr unwahrscheinlich (Openssl iss your friend)
Problem bekommst nur wenn du ein verbindungsloses Protokoll hasst .... http/https oder UDP basierend.
Dann kannst die verbindung ned verschluesseln du muesstest mit SessionID's arbeiten ... aber auch da gibts standardisiertes Vorgehen.
"zufälligen ID-Key speichere ihn und übertrage ihn an den Client"
genau dass ist nicht trivial ^^ aber auch hier kann dir openssl und co helfen ...
Standardisiert nimmt man schon sowas wie nen "zufälligen ID-Key", nur sollte der noch mit den den privaten/öffentlichen Schluesseln vom Server und client codiert werden, so dass nur server / client bestimmen koennen, ob der ID nu gueltig war oder nicht ... nich das der Angreifer nur mitlauschen muss und die ID imitieren kann ..
Ciao ...
Re: Login-System
Verfasst: 7. August 2012 15:23
von zerobyte
Ich benutze sockets und QDataStream zur Kommunikation. ( Bin in der Netzwerkprogrammierung aber noch ein Anfänger, beschäftige mich damit ca seit 1 Monat und war froh als ich es endlich geschaft habe eine Verbindung zwischen Server und Client herzustellen und Daten auszutauschen ).
Mit derren Verschlüsselung habe ich mich noch garnicht beschäftigt aber ich müsste dann anstatt QTcpServer und QTcpSocket einfach QSslSocket nehmen ?
Gibt es zufällig ein kleines Tutorial das sich mit QSsl beschäftigt ?
Re: Login-System
Verfasst: 7. August 2012 17:04
von RHBaum
eine Verbindung zwischen Server und Client herzustellen und Daten auszutauschen
Die frage iss nur, ob server und client die verbindung halten ... bzw, du das so implementieren kannst (aka datenbankverbindungen, die machen es genau so ... )
Dann hasst du ein Verbindungs-orientiertes protokoll ^^
Mit dem Wirds recht einfach .
Bau erstmal alles so als waers unverschluesselt, laesst sich auch einfacher debuggen ...
QTCPSocket & co, sollten deine Implementationsdetails sein ....
Ausser bei der Erzeugung des sockets solltest ueberall nie den konkreten Typ, sondern die Basisklassen QAbstracktSocket, oder QIODevice verwenden.
Dann kannst spaeter easy alles durch nen QSSL's Socket ersetzen und musst nur noch das SSL-Authentifizierungs Gedoens hinzufuegen (Zertificate und co).
Das verschluesseln kannst optional machen ... wobei QDataStream ned wirklich gut lesbares Zeugs aus deinen Objecten macht ^^ Musst dann selber entscheiden obs dir beim debuggen hilft ....
Ciao ...
Re: Login-System
Verfasst: 14. August 2012 11:37
von zerobyte
so ich habe jetzt ein wenig experimentiert und weis nicht weiter, wie kann sich er Server die Verbindung merken ? Für jede Verbindung erstelle ich ein neues Socket.
Zb sind 5 Clients mit dem Server verbunden und Client 1 will eine Nachricht an Client 4 schicken, woher weis der Server welches Socket zu Client 4 gehört ?
ist es möglich wenn ich den Socketdescriptor habe irgendwie das passende Socket zu finden ?
Re: Login-System
Verfasst: 14. August 2012 17:28
von RHBaum
Ohje ...
Wie identifizierst du denn Clients ?
Nach ner IP ? die bekommst ueber den Socket wirklich raus ..
Nach dem Nutzer der Sich mit einem Namen einloggt ?
Dann wirst wohl etwas mehr tun muessen, als nur die sockets zu merken ...
Das sind aber wirklich basics ... und haben weniger mit c/c++ oder QT zu tun.
Ciao ...
Re: Login-System
Verfasst: 14. August 2012 20:13
von zerobyte
ich möchte nicht den Client direkt identifizieren sondern den dazugehörigen Socket den ich für den Client erstellt habe.
ich habe mir nun folgendes überlegt und werde es morgen mal testen:
Wenn der Client sich einloggt schreibe ich den usernamen und einen QSharedPointer auf das entsprechende Socket in eine QMap. Dann kann sich der Server den entsprechenden Client aussuchen und Daten an Ihn schicken.
Re: Login-System
Verfasst: 15. August 2012 14:44
von zerobyte
so hab jetzt einen kleinen Server programmiert, der funktioniert auch, doch als ich die QMap in meine Serverklasse integriert habe, stürzt das Programm beim Starten ab, und ich weis nicht warum:
myserver.h
Code: Alles auswählen
#include <QTcpServer>
#include <QTcpSocket>
#include <QAbstractSocket>
#include <QSharedPointer>
#include <QMap>
#include "myclient.h"
class MyServer : public QTcpServer
{
Q_OBJECT
public:
explicit MyServer(QObject *parent = 0);
void StartServer();
protected:
void incomingConnection(int handle);
signals:
public slots:
private:
QMap<QString, QSharedPointer<MyClient> > con;
};
myserver.cpp
Code: Alles auswählen
#include "myserver.h"
MyServer::MyServer(QObject *parent) :
QTcpServer(parent)
{
}
void MyServer::StartServer()
{
if(listen(QHostAddress::Any,1234))
{
qDebug() << "started";
}
else
{
qDebug() << "not started!";
}
}
void MyServer::incomingConnection(int handle)
{
MyClient *client = new MyClient(this);
client->SetSocket(handle);
QSharedPointer<MyClient> clientpointer(client);
con.insert("NA", clientpointer);
}
sobald ich
und
Code: Alles auswählen
QSharedPointer<MyClient> clientpointer(client);
con.insert("NA", clientpointer);
entferne funktioniert wieder alles bestens., die Frage ist nur wieso ?
Re: Login-System
Verfasst: 15. August 2012 17:19
von brax
Ganz interessant wäre die Art des Absturzes (SegFault, Exception ...) und in welcher Zeile genau. Was sagt der Debugger dazu?
Grundsätzlich sehe ich kein Problem mit dem Code, der folgende Code ist z.B. kein Problem bei mir (habe noch nie mit QSharedPointer gearbeitet, daher musste ich das erstmal testen):
Code: Alles auswählen
#include <QMap>
#include <QSharedPointer>
class Foo {
public:
~Foo() {
// nur hier damit ich einen breakpoint setzen konnte
// um sicher zu gehen, wann mein Foo-Objekt tatsächlich
// abgeräumt wird
int i = 0;
}
};
int main(int, char**) {
Foo* bar = new Foo();
QMap<QString, QSharedPointer<Foo> > map;
{
QSharedPointer<Foo> pointer(bar);
map.insert("a", pointer);
}
QSharedPointer<Foo> p = map["a"];
Foo* foobar = p.data();
return 0;
}
Re: Login-System
Verfasst: 15. August 2012 17:24
von zerobyte
es öffnet sich dann typisches windows Fehlerfenster mit : AsSvr1.exe funktioniert nicht mehr und die Problemsignatur sieht so aus:
Problemsignatur:
Problemereignisname: APPCRASH
Anwendungsname: AsSvr1.exe
Anwendungsversion: 0.0.0.0
Anwendungszeitstempel: 502bbcd4
Fehlermodulname: StackHash_0a9e
Fehlermodulversion: 0.0.0.0
Fehlermodulzeitstempel: 00000000
Ausnahmecode: c0000005
Ausnahmeoffset: 00000000
Betriebsystemversion: 6.1.7601.2.1.0.256.1
Gebietsschema-ID: 1031
Zusatzinformation 1: 0a9e
Zusatzinformation 2: 0a9e372d3b4ad19135b953a78882e789
Zusatzinformation 3: 0a9e
Zusatzinformation 4: 0a9e372d3b4ad19135b953a78882e789
und der Debugger sagt: Angehalten: Segmentation fault ( Signal SIGSEGV ).
( Habe noch nicht wirklich viel mit dem Debugger gearbeitet )
Re: Login-System
Verfasst: 16. August 2012 14:51
von brax
zerobyte hat geschrieben:
( Habe noch nicht wirklich viel mit dem Debugger gearbeitet )
Um ehrlich zu sein solltest Du ganz dringend damit anfangen, sonst wirst Du nicht viel Spaß am Programmieren haben. Aus den geposteten Informationen ist für uns nicht ersichtlich, an welcher Stelle etwas schief geht. Der Debugger sollte aber die Zeile zeigen, in der der SegFault auftritt zeigen.
Bist Du Dir sicher, dass Du das Programm überhaupt mit Debugger laufen lässt? Welche IDE benutzt Du denn? QtCreator? Dort gibt es unter dem "Run" button (grüner Pfeil) noch einen zweiten Run-Button mit kleinem Käfer dran. Das startet das Programm mit Debugger. Wenn er dann abschmiert wird die Source-Datei geöffnet in der der Crash passiert ist und links neben den Zeilennummern erscheint ein kleiner gelber Pfeil, der die aktuelle Zeile (also die wo es gecrasht ist) markiert. Zusätzlich bekommst Du den Callstack, in der Du nachvollziehen kannst von wo der angezeigte Code aufgerufen wurde.
Solltest Du das Visual Studio (meine bevorzugte C++IDE) benutzen sieht es sehr ähnlich aus (auch in der kostenlosen Express Edition).
Viel Spaß