qmlfrontend/net_session.cpp
changeset 15099 fb7a9b0119d3
parent 15068 773beead236f
child 15919 d52f5d8e75e6
equal deleted inserted replaced
15098:a2d09a597fbb 15099:fb7a9b0119d3
     1 #include "net_session.h"
     1 #include "net_session.h"
       
     2 
       
     3 #include <QUuid>
     2 
     4 
     3 #include "players_model.h"
     5 #include "players_model.h"
     4 #include "rooms_model.h"
     6 #include "rooms_model.h"
     5 
     7 
     6 NetSession::NetSession(QObject *parent)
     8 NetSession::NetSession(QObject *parent)
     7     : QObject(parent),
     9     : QObject(parent),
     8       m_playersModel(new PlayersListModel()),
    10       m_playersModel(new PlayersListModel()),
     9       m_roomsModel(new RoomsListModel()) {}
    11       m_roomsModel(new RoomsListModel()),
       
    12       m_sessionState(NotConnected) {}
    10 
    13 
    11 NetSession::~NetSession() { close(); }
    14 NetSession::~NetSession() { close(); }
    12 
    15 
    13 QUrl NetSession::url() const { return m_url; }
    16 QUrl NetSession::url() const { return m_url; }
    14 
    17 
    31                           static_cast<quint16>(m_url.port(46631)));
    34                           static_cast<quint16>(m_url.port(46631)));
    32 }
    35 }
    33 
    36 
    34 QString NetSession::nickname() const { return m_nickname; }
    37 QString NetSession::nickname() const { return m_nickname; }
    35 
    38 
    36 QString NetSession::password() const { return m_password; }
       
    37 
       
    38 NetSession::SessionState NetSession::sessionState() const {
    39 NetSession::SessionState NetSession::sessionState() const {
    39   return m_sessionState;
    40   return m_sessionState;
    40 }
    41 }
    41 
    42 
    42 QString NetSession::room() const { return m_room; }
    43 QString NetSession::room() const { return m_room; }
    43 
    44 
       
    45 QString NetSession::passwordHash() const { return m_passwordHash; }
       
    46 
    44 void NetSession::setUrl(const QUrl &url) {
    47 void NetSession::setUrl(const QUrl &url) {
    45   if (m_url == url) return;
    48   if (m_url == url) return;
    46 
    49 
    47   m_url = url;
    50   m_url = url;
    48   emit urlChanged(m_url);
    51   emit urlChanged(m_url);
    53 
    56 
    54   m_nickname = nickname;
    57   m_nickname = nickname;
    55   emit nicknameChanged(m_nickname);
    58   emit nicknameChanged(m_nickname);
    56 }
    59 }
    57 
    60 
    58 void NetSession::setPassword(const QString &password) {
    61 void NetSession::setPasswordHash(const QString &passwordHash) {
    59   if (m_password == password) return;
    62   if (m_passwordHash == passwordHash) return;
    60 
    63 
    61   m_password = password;
    64   m_passwordHash = passwordHash;
    62   emit passwordChanged(m_password);
    65   emit passwordHashChanged(m_passwordHash);
       
    66 
       
    67   if (m_sessionState == Authentication) sendPassword();
    63 }
    68 }
    64 
    69 
    65 void NetSession::setRoom(const QString &room) {
    70 void NetSession::setRoom(const QString &room) {
    66   if (m_room == room) return;
    71   if (m_room == room) return;
    67 
    72 
   172   qWarning() << "Command is not recognized";
   177   qWarning() << "Command is not recognized";
   173 }
   178 }
   174 
   179 
   175 void NetSession::handleAddTeam(const QStringList &parameters) {}
   180 void NetSession::handleAddTeam(const QStringList &parameters) {}
   176 
   181 
   177 void NetSession::handleAskPassword(const QStringList &parameters) {}
   182 void NetSession::handleAskPassword(const QStringList &parameters) {
       
   183   if (parameters.length() != 1 || parameters[0].length() < 16) {
       
   184     qWarning("Bad ASKPASSWORD message");
       
   185     return;
       
   186   }
       
   187 
       
   188   setSessionState(Authentication);
       
   189 
       
   190   m_serverSalt = parameters[0];
       
   191   m_clientSalt = QUuid::createUuid().toString();
       
   192 
       
   193   if (m_passwordHash.isEmpty()) {
       
   194     emit passwordAsked();
       
   195   } else {
       
   196     sendPassword();
       
   197   }
       
   198 }
   178 
   199 
   179 void NetSession::handleBanList(const QStringList &parameters) {}
   200 void NetSession::handleBanList(const QStringList &parameters) {}
   180 
   201 
   181 void NetSession::handleCfg(const QStringList &parameters) {}
   202 void NetSession::handleCfg(const QStringList &parameters) {}
   182 
   203 
   304   qDebug() << "[CLIENT]" << message;
   325   qDebug() << "[CLIENT]" << message;
   305 
   326 
   306   m_socket->write(message.join('\n').toUtf8() + "\n\n");
   327   m_socket->write(message.join('\n').toUtf8() + "\n\n");
   307 }
   328 }
   308 
   329 
       
   330 void NetSession::sendPassword() {
       
   331   /* When we got password hash, and server asked us for a password, perform
       
   332    * mutual authentication: at this point we have salt chosen by server. Client
       
   333    * sends client salt and hash of secret (password hash) salted with client
       
   334    * salt, server salt, and static salt (predefined string + protocol number).
       
   335    * Server should respond with hash of the same set in different order.
       
   336    */
       
   337 
       
   338   if (m_passwordHash.isEmpty() || m_serverSalt.isEmpty()) return;
       
   339 
       
   340   QString hash =
       
   341       QCryptographicHash::hash(m_clientSalt.toLatin1()
       
   342                                    .append(m_serverSalt.toLatin1())
       
   343                                    .append(m_passwordHash)
       
   344                                    .append(QByteArray::number(cProtocolVersion))
       
   345                                    .append("!hedgewars"),
       
   346                                QCryptographicHash::Sha1)
       
   347           .toHex();
       
   348 
       
   349   m_serverHash =
       
   350       QCryptographicHash::hash(m_serverSalt.toLatin1()
       
   351                                    .append(m_clientSalt.toLatin1())
       
   352                                    .append(m_passwordHash)
       
   353                                    .append(QByteArray::number(cProtocolVersion))
       
   354                                    .append("!hedgewars"),
       
   355                                QCryptographicHash::Sha1)
       
   356           .toHex();
       
   357 
       
   358   send("PASSWORD", QStringList{hash, m_clientSalt});
       
   359 }
       
   360 
   309 void NetSession::setSessionState(NetSession::SessionState sessionState) {
   361 void NetSession::setSessionState(NetSession::SessionState sessionState) {
   310   if (m_sessionState == sessionState) return;
   362   if (m_sessionState == sessionState) return;
   311 
   363 
   312   m_sessionState = sessionState;
   364   m_sessionState = sessionState;
   313 
   365