Login-System

Du bist neu in der Welt von C++? Dann schau hier herein!
Antworten
zerobyte
Beiträge: 18
Registriert: 7. August 2012 11:09

Login-System

Beitrag 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 ?
brax
Beiträge: 208
Registriert: 11. Mai 2010 11:22

Re: Login-System

Beitrag 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.
zerobyte
Beiträge: 18
Registriert: 7. August 2012 11:09

Re: Login-System

Beitrag 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 ?
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Re: Login-System

Beitrag 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 ...
zerobyte
Beiträge: 18
Registriert: 7. August 2012 11:09

Re: Login-System

Beitrag 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 ?
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Re: Login-System

Beitrag 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 ...
zerobyte
Beiträge: 18
Registriert: 7. August 2012 11:09

Re: Login-System

Beitrag 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 ?
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Re: Login-System

Beitrag 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 ...
zerobyte
Beiträge: 18
Registriert: 7. August 2012 11:09

Re: Login-System

Beitrag 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.
zerobyte
Beiträge: 18
Registriert: 7. August 2012 11:09

Re: Login-System

Beitrag 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

Code: Alles auswählen

QMap<QString, QSharedPointer<MyClient> > con;
und

Code: Alles auswählen

    QSharedPointer<MyClient> clientpointer(client);
    con.insert("NA", clientpointer);
entferne funktioniert wieder alles bestens., die Frage ist nur wieso ?
brax
Beiträge: 208
Registriert: 11. Mai 2010 11:22

Re: Login-System

Beitrag 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;
}
zerobyte
Beiträge: 18
Registriert: 7. August 2012 11:09

Re: Login-System

Beitrag 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 )
brax
Beiträge: 208
Registriert: 11. Mai 2010 11:22

Re: Login-System

Beitrag 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ß
Antworten