void OutgoingContactRequest::startConnection() { if (m_client) return; qDebug() << "Starting outgoing contact request for" << user->uniqueID; m_client = new ContactRequestClient(user); connect(m_client, SIGNAL(accepted()), SLOT(accept())); connect(m_client, SIGNAL(rejected(int)), SLOT(requestRejected(int))); connect(m_client, SIGNAL(acknowledged()), SLOT(requestAcknowledged())); connect(m_client, SIGNAL(responseChanged()), SIGNAL(connectedChanged())); m_client->setMyNickname(myNickname()); m_client->setMessage(message()); m_client->sendRequest(); }
bool ContactRequestClient::buildRequestData(QByteArray cookie) { /* [2*length][16*hostname][16*serverCookie][16*connSecret][data:pubkey][str:nick][str:message][data:signature] */ QByteArray requestData; CommandDataParser request(&requestData); /* Hostname */ QString hostname = user->hostname(); hostname.truncate(hostname.lastIndexOf(QLatin1Char('.'))); if (hostname.size() != 16) { qWarning() << "Cannot send contact request: unable to determine the remote service hostname"; return false; } /* Connection secret */ QByteArray connSecret = user->settings()->read<Base64Encode>("localSecret"); if (connSecret.size() != 16) { qWarning() << "Cannot send contact request: invalid local secret"; return false; } /* Public service key */ Tor::HiddenService *service = user->identity->hiddenService(); CryptoKey serviceKey; if (!service || !(serviceKey = service->cryptoKey()).isLoaded()) { qWarning() << "Cannot send contact request: failed to load service key"; return false; } QByteArray publicKeyData = serviceKey.encodedPublicKey(); if (publicKeyData.isNull()) { qWarning() << "Cannot send contact request: failed to encode service key"; return false; } /* Build request */ request << (quint16)0; /* placeholder for length */ request.writeFixedData(hostname.toLatin1()); request.writeFixedData(cookie); request.writeFixedData(connSecret); request.writeVariableData(publicKeyData); request << myNickname() << message(); if (request.hasError()) { qWarning() << "Cannot send contact request: command building failed"; return false; } /* Sign request, excluding the length field */ QByteArray signature = serviceKey.signData(requestData.mid(2)); if (signature.isNull()) { qWarning() << "Cannot send contact request: failed to sign request"; return false; } request.writeVariableData(signature); if (request.hasError()) { qWarning() << "Cannot send contact request: command building failed"; return false; } /* Set length */ qToBigEndian((quint16)requestData.size(), reinterpret_cast<uchar*>(requestData.data())); /* Send */ qint64 re = socket->write(requestData); Q_ASSERT(re == requestData.size()); Q_UNUSED(re); qDebug() << "Contact request for" << user->uniqueID << "sent request data"; return true; }