Client-server application



  • I am going to develop client-server application. First of all i am interested how to realize sessions. Is identifying user by IP after authorization the best way? Or sending login with password in packets each time is better. Does QT have already done decisions?



  • The best way to identify the user is to use the RSA encryption.
    What exactly do you mean by 'sessions'?



  • Using the IP address for authentication is nonsense! First of all, users with dial-up internet connection (like DSL) get a new IP address every time they connect (or after 24h). Thus IP address 123 might be assigned to "Alice" now, but two hours later that very same address might be assigned to "Bob". Also there may be a large number of computers (e.g. a complete company or a complete university!) connected to the Internet trough a NAT router. So it's easily possible that you have hundreds of users with the very same (public) IP address...

    You will need to authenticate the session with login + password, but don't even dare to send the password un-encrypted. Send them via encrypted connection - or use a challenge-response method. Also never (never ever!) store passwords on the server as plain text. Store (salted!) hashes of passwords.



  • Thanks. I have seen there is QSessionManager class. Is it suitable class for this task?



  • The documentation says
    The session manager is used to save the session, e.g., when the machine is shut down, and to restore a session, e.g., when the machine is started up. We recommend that you use QSettings to save an application's settings, for example, window positions, recently used files, etc. When the application is restarted by the session manager, you can restore the settings.

    For network app i'd recommended use array of password+login and session parameters. In case accessing is done without passwords you can generate some unique data for identify user and send back to him. All subsequent requests will be done with this identifier, in case a long idle identifier on server side will be destroyed and user start new session.



  • What is your idea of what this session is supposed to represent?
    Normally, a session would just be the time a TCP connection stays open. Why do you think you need to send some kind of token back and forth the whole time?

    Anyway, if you want your sessions to survive disconnects, for instance if you're going to be using very unrelyable networks, you might want to consider having the server send a token to the client after the log in that can be used as the session key. Obviously, such tokens should not be exchanged in the plain. Use an SSL connection instead, otherwise you're going to be vunerable to man-in-the-middle attacks.



  • Do I have to use QSslSocket?
    I'd like to look at simple client and server example.





  • Using an SSL socket is not that much more complicated than using a plain TCP socket. If you are going to allow authentication based on a token, you should IMHO not exchange this token in plain text over an open connection. Not unless you really want your application to get hacked...



  • Are there any complete simple examples for server?



  • In links above you can find what you need. Read docs and do little bit effort.



  • I did enough efforts but I have never worked with SSL. Example would help me.
    http://qt-project.org/forums/viewthread/21401 this is server example. But I don't know how can I make it working.

    This attempt does not work.
    [CODE]
    #include <QApplication>
    #include <QtNetwork/QSslSocket>
    #include <QDebug>

    class Server : public QObject
    {
    public:
    void f()
    {
    m_socket = new QSslSocket(this);
    m_socket->setSocketDescriptor(handle);
    m_socket->setProtocol(QSsl::SslV3);

        QByteArray key;
        QByteArray cert;
    
        QFile file_key("../ssl/server.key");
        if(file_key.open(QIODevice::ReadOnly))
        {
            key = file_key.readAll();
            file_key.close();
        }
        else
        {
            qDebug() << file_key.errorString();
        }
    
        QFile file_cert("../ssl/server.crt");
        if(file_cert.open(QIODevice::ReadOnly))
        {
            cert = file_cert.readAll();
            file_cert.close();
        }
        else
        {
            qDebug() << file_cert.errorString();
        }
    
        //qDebug() << key + "\n" + cert;
    
    
        QSslKey ssl_key(key, QSsl::Rsa);
    
        QSslCertificate ssl_cert(cert);
    
        m_socket->setPrivateKey(ssl_key);
        m_socket->setLocalCertificate(ssl_cert);
        m_socket->startServerEncryption();
    }
    

    private:
    QSslSocket m_socket;
    };

    int main( int argc, char **argv )
    {
    Server server;
    server.f();
    }
    [/CODE]



  • Of course not! You are not even creating an application object, you are not starting an event loop, etc. Did you actually look at the examples that were referenced?



  • I worked with QT long ago. But I thought this code must be though compiling. Isn't it?


  • Lifetime Qt Champion

    In addition to what Andre said: Are sure that "../ssl/server.crt" is the right path ?



  • I created an application object but code is still not compiling as I expected.
    main.cpp:10: error: no match for 'operator=' in '((Server*)this)->Server::m_socket = (operator new(8u), (<statement>, ((QSslSocket*)<anonymous>)))'
    [code]
    #include <QApplication>
    #include <QtNetwork/QSslSocket>
    #include <QDebug>

    class Server : public QObject
    {
    public:
    void f()
    {
    m_socket = new QSslSocket(this);
    m_socket->setSocketDescriptor(handle);
    m_socket->setProtocol(QSsl::SslV3);

        QByteArray key;
        QByteArray cert;
    
        QFile file_key("../ssl/server.key");
        if(file_key.open(QIODevice::ReadOnly))
        {
            key = file_key.readAll();
            file_key.close();
        }
        else
        {
            qDebug() << file_key.errorString();
        }
    
        QFile file_cert("../ssl/server.crt");
        if(file_cert.open(QIODevice::ReadOnly))
        {
            cert = file_cert.readAll();
            file_cert.close();
        }
        else
        {
            qDebug() << file_cert.errorString();
        }
    
        //qDebug() << key + "\n" + cert;
    
    
        QSslKey ssl_key(key, QSsl::Rsa);
    
        QSslCertificate ssl_cert(cert);
    
        m_socket->setPrivateKey(ssl_key);
        m_socket->setLocalCertificate(ssl_cert);
        m_socket->startServerEncryption();
    }
    

    private:
    QSslSocket m_socket;
    };

    int main( int argc, char **argv )
    {
    QApplication app(argc, argv);

    if (!QSslSocket::supportsSsl()) {
    QMessageBox::information(0, "Secure Socket Server",
                 "This system does not support OpenSSL.");
        return -1;
    }
    
    Server server;
    server.f();
    
    return app.exec(&#41;;
    

    }
    [/code]


  • Lifetime Qt Champion

    Have a look at the declaration of m_socket



  • Thanks.
    error: variable 'QSslKey ssl_key' has initializer but incomplete type (Solved #include <QtNetwork/QSslKey>)



  • How to include libs?
    I wrote
    [code]
    LIBS += -L/C:/OpenSSL-Win32/lib ssleay32.lib libeay32.lib
    [/code]
    error: ssleay32.lib: No such file or directory


  • Lifetime Qt Champion

    That's not all for m_socket.

    Please, search the documentation a bit "Other libraries":http://qt-project.org/doc/qt-4.8/qmake-project-files.html#declaring-other-libraries



  • Thanks but unfortunately it does not help me.

    main.cpp:13: error: undefined reference to _imp___ZN10QSslSocketC1EP7QObject' main.cpp:15: error: undefined reference to_imp___ZN10QSslSocket11setProtocolEN4QSsl11SslProtocolE'
    main.cpp:45: error: undefined reference to _imp___ZN7QSslKeyC1ERK10QByteArrayN4QSsl12KeyAlgorithmENS3_14EncodingFormatENS3_7KeyTypeES2_' main.cpp:47: error: undefined reference to_imp___ZN15QSslCertificateC1ERK10QByteArrayN4QSsl14EncodingFormatE'
    main.cpp:49: error: undefined reference to _imp___ZN10QSslSocket13setPrivateKeyERK7QSslKey' main.cpp:50: error: undefined reference to_imp___ZN10QSslSocket19setLocalCertificateERK15QSslCertificate'
    main.cpp:51: error: undefined reference to _imp___ZN10QSslSocket21startServerEncryptionEv' main.cpp:51: error: undefined reference to_imp___ZN15QSslCertificateD1Ev'
    main.cpp:51: error: undefined reference to _imp___ZN7QSslKeyD1Ev' main.cpp:45: error: undefined reference to_imp___ZN7QSslKeyD1Ev'
    main.cpp:51: error: undefined reference to _imp___ZN15QSslCertificateD1Ev' main.cpp:51: error: undefined reference to_imp___ZN7QSslKeyD1Ev'


  • Lifetime Qt Champion

    Sure it helps, that's a new error. Did you build Qt with ssl support ?



  • I did not build Qt. I just installed it on Windows.
    How can I do it? Can I use that build for commercial applications under LGPL?


  • Moderators

    You are ship your commercial applications under LGPL license? Those are of course compatible with LGPL Qt.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.