Login-System
Login-System
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 ?
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
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.
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
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 ?
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
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.
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 ...
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.
genau dass ist nicht trivial ^^ aber auch hier kann dir openssl und co helfen ..."zufälligen ID-Key speichere ihn und übertrage ihn an den Client"
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
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 ?
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
Die frage iss nur, ob server und client die verbindung halten ... bzw, du das so implementieren kannst (aka datenbankverbindungen, die machen es genau so ... )eine Verbindung zwischen Server und Client herzustellen und Daten auszutauschen
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
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 ?
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
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 ...
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
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.
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
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
myserver.cpp
sobald ich
und
entferne funktioniert wieder alles bestens., die Frage ist nur wieso ?
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;
};
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);
}
Code: Alles auswählen
QMap<QString, QSharedPointer<MyClient> > con;
Code: Alles auswählen
QSharedPointer<MyClient> clientpointer(client);
con.insert("NA", clientpointer);
Re: Login-System
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):
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
es öffnet sich dann typisches windows Fehlerfenster mit : AsSvr1.exe funktioniert nicht mehr und die Problemsignatur sieht so aus:
( Habe noch nicht wirklich viel mit dem Debugger gearbeitet )
und der Debugger sagt: Angehalten: Segmentation fault ( Signal SIGSEGV ).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
( Habe noch nicht wirklich viel mit dem Debugger gearbeitet )
Re: Login-System
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.zerobyte hat geschrieben: ( Habe noch nicht wirklich viel mit dem Debugger gearbeitet )
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ß