void MainWindow::computeHash() { QString error = this->checkPasswords(); if (!error.isNull()) { this->ui->txtResult->setText(error); } else { Common::Hash hash = Common::Hasher::hashWithRandomSalt(this->ui->txtPass1->text(), this->salt); Protos::Core::Settings settings; const google::protobuf::FieldDescriptor* passField = settings.GetDescriptor()->FindFieldByName("remote_password"); const google::protobuf::FieldDescriptor* saltField = settings.GetDescriptor()->FindFieldByName("salt"); settings.mutable_remote_password()->set_hash(hash.getData(), Common::Hash::HASH_SIZE); settings.set_salt(this->salt); std::string encodedHash; std::string encodedSalt; google::protobuf::TextFormat::PrintFieldValueToString(settings, passField, -1, &encodedHash); google::protobuf::TextFormat::PrintFieldValueToString(settings, saltField, -1, &encodedSalt); this->ui->txtResult->setText("remote_password {\n " % QString::fromStdString(encodedHash) % "}\nsalt: " % QString::fromStdString(encodedSalt) % "\n"); } }
bool InternalCoreConnection::setCorePassword(const QString& newPassword, const QString& oldPassword) { Protos::GUI::ChangePassword passMess; const quint64 newSalt = static_cast<quint64>(mtrand.randInt()) << 32 | mtrand.randInt(); Common::Hash newPasswordHashed = Common::Hasher::hashWithSalt(newPassword, newSalt); passMess.mutable_new_password()->set_hash(newPasswordHashed.getData(), Common::Hash::HASH_SIZE); passMess.set_new_salt(newSalt); if (!oldPassword.isNull()) { Common::Hash oldPasswordHashed = Common::Hasher::hashWithSalt(oldPassword, this->salt); if (!this->connectionInfo.password.isNull() && this->connectionInfo.password != oldPasswordHashed) return false; passMess.mutable_old_password()->set_hash(oldPasswordHashed.getData(), Common::Hash::HASH_SIZE); } this->connectionInfo.password = newPasswordHashed; this->salt = newSalt; this->send(Common::MessageHeader::GUI_CHANGE_PASSWORD, passMess); return true; }
void InternalCoreConnection::download(const Common::Hash& peerID, const Protos::Common::Entry& entry, const Common::Hash& sharedFolderID, const QString& path) { // We cannot download our entries. if (peerID == this->getLocalID()) return; Protos::GUI::Download downloadMessage; downloadMessage.mutable_peer_id()->set_hash(peerID.getData(), Common::Hash::HASH_SIZE); downloadMessage.mutable_entry()->CopyFrom(entry); if (!sharedFolderID.isNull()) downloadMessage.mutable_destination_directory_id()->set_hash(sharedFolderID.getData(), Common::Hash::HASH_SIZE); Common::ProtoHelper::setStr(downloadMessage, &Protos::GUI::Download::set_destination_path, path); this->send(Common::MessageHeader::GUI_DOWNLOAD, downloadMessage); }
Common::Hash Hasher::hashWithSalt(const Common::Hash& hash, quint64 salt) { Hasher hasher; hasher.addData(hash.getData(), Hash::HASH_SIZE); hasher.addSalt(salt); return hasher.getResult(); }
NetworkListener::SendStatus NetworkListener::send(Common::MessageHeader::MessageType type, const google::protobuf::Message& message, const Common::Hash& peerID) { if (peerID.isNull()) return this->uDPListener.send(type, message); else return this->uDPListener.send(type, message, peerID); }
void Chunk::setHash(const Common::Hash& hash) { #ifdef DEBUG L_DEBU(QString("Chunk[%1] setHash(..) : %2").arg(this->num).arg(hash.toStr())); if (!this->hash.isNull() && this->hash != hash) L_WARN(QString("Chunk::setHash : Hash chunk changed from %1 to %2 for the file %3").arg(this->hash.toStr()).arg(hash.toStr()).arg(this->file->getFullPath())); #endif this->hash = hash; }
void File::populateEntry(Protos::Common::Entry* entry, bool setSharedDir, int maxHashes) const { QMutexLocker locker(&this->mutex); Entry::populateEntry(entry, setSharedDir); entry->set_type(Protos::Common::Entry_Type_FILE); entry->clear_chunk(); int nb = 0; for (QVectorIterator<QSharedPointer<Chunk>> i(this->chunks); i.hasNext();) { Protos::Common::Hash* protoHash = entry->add_chunk(); Common::Hash hash = i.next()->getHash(); if (!hash.isNull() && ++nb <= maxHashes) protoHash->set_hash(hash.getData(), Common::Hash::HASH_SIZE); } }
void InternalCoreConnection::download(const Common::Hash& peerID, const Protos::Common::Entry& entry) { // We cannot download our entries. if (peerID == this->getLocalID()) return; Protos::GUI::Download downloadMessage; downloadMessage.mutable_peer_id()->set_hash(peerID.getData(), Common::Hash::HASH_SIZE); downloadMessage.mutable_entry()->CopyFrom(entry); this->send(Common::MessageHeader::GUI_DOWNLOAD, downloadMessage); }
/** * When we ask to the fileManager some hashes for a given file this * slot will be called each time a new hash is available. */ void Socket::nextAskedHash(Common::Hash hash) { Protos::Common::Hash hashProto; hashProto.set_hash(hash.getData(), Common::Hash::HASH_SIZE); this->send(Common::MessageHeader::CORE_HASH, hashProto); if (--this->nbHash == 0) { this->currentHashesResult.clear(); this->finished(); } }
ChunkDownloader::ChunkDownloader(LinkedPeers& linkedPeers, OccupiedPeers& occupiedPeersDownloadingChunk, Common::TransferRateCalculator& transferRateCalculator, Common::ThreadPool& threadPool, Common::Hash chunkHash) : linkedPeers(linkedPeers), occupiedPeersDownloadingChunk(occupiedPeersDownloadingChunk), transferRateCalculator(transferRateCalculator), threadPool(threadPool), chunkHash(chunkHash), socket(0), downloading(false), closeTheSocket(false), lastTransferStatus(QUEUED), mainThread(QThread::currentThread()), mutex(QMutex::Recursive) { Q_ASSERT(!chunkHash.isNull()); L_DEBU(QString("New ChunkDownloader : %1").arg(this->chunkHash.toStr())); }
void UDPListener::send(Common::MessageHeader::MessageType type, const Common::Hash& peerID, const google::protobuf::Message& message) { PM::IPeer* peer = this->peerManager->getPeer(peerID); if (!peer) { L_WARN(QString("Unable to find the peer %1").arg(peerID.toStr())); return; } int messageSize; if (!(messageSize = this->writeMessageToBuffer(type, message))) return; L_DEBU(QString("Send unicast UDP to %1 : header.getType() = %2, message size = %3 \n%4"). arg(peer->toStringLog()). arg(Common::MessageHeader::messToStr(type)). arg(messageSize). arg(Common::ProtoHelper::getDebugStr(message)) ); if (this->unicastSocket.writeDatagram(this->buffer, messageSize, peer->getIP(), peer->getPort()) == -1) L_WARN("Unable to send datagram"); }
Common::Hash Hasher::hash(const Common::Hash& hash) { Hasher hasher; hasher.addData(hash.getData(), Hash::HASH_SIZE); return hasher.getResult(); }
void HashesReceiver::nextHash(Common::Hash hash) { qDebug() << this->num << " : " << hash.toStr(); this->receivedHashes << hash; this->num++; }
Chunk::Chunk(File* file, int num, quint32 knownBytes, const Common::Hash& hash) : file(file), num(num), knownBytes(knownBytes), hash(hash) { L_DEBU(QString("New chunk[%1] : %2. File : %3").arg(num).arg(hash.toStr()).arg(this->file ? this->file->getFullPath() : "<no file defined>")); }
void PeerMessageSocket::onNewMessage(const Common::Message& message) { switch (message.getHeader().getType()) { case Common::MessageHeader::CORE_GET_ENTRIES: { if (!this->entriesResultsToReceive.isEmpty()) return; const Protos::Core::GetEntries& getEntries = message.getMessage<Protos::Core::GetEntries>(); for (int i = 0; i < getEntries.dirs().entry_size(); i++) { QSharedPointer<FM::IGetEntriesResult> entriesResult = this->fileManager->getScannedEntries(getEntries.dirs().entry(i)); connect(entriesResult.data(), SIGNAL(result(const Protos::Core::GetEntriesResult::EntryResult&)), this, SLOT(entriesResult(const Protos::Core::GetEntriesResult::EntryResult&)), Qt::DirectConnection); connect(entriesResult.data(), SIGNAL(timeout()), this, SLOT(entriesResultTimeout()), Qt::DirectConnection); this->entriesResultsToReceive << entriesResult; this->entriesResultMessage.add_result(); } // Add the root directories if asked. if (getEntries.dirs().entry_size() == 0 || getEntries.get_roots()) this->entriesResultMessage.add_result()->mutable_entries()->CopyFrom(this->fileManager->getEntries()); if (this->entriesResultsToReceive.isEmpty()) this->sendEntriesResultMessage(); else foreach (QSharedPointer<FM::IGetEntriesResult> entriesResult, this->entriesResultsToReceive) entriesResult->start(); } break; case Common::MessageHeader::CORE_GET_ENTRIES_RESULT: this->finished(); break; case Common::MessageHeader::CORE_GET_HASHES: { const Protos::Core::GetHashes& getHashes = message.getMessage<Protos::Core::GetHashes>(); this->currentHashesResult = this->fileManager->getHashes(getHashes.file()); connect(this->currentHashesResult.data(), SIGNAL(nextHash(Protos::Core::HashResult)), this, SLOT(nextAskedHash(Protos::Core::HashResult)), Qt::QueuedConnection); Protos::Core::GetHashesResult res = this->currentHashesResult->start(); this->nbHash = res.nb_hash(); this->send(Common::MessageHeader::CORE_GET_HASHES_RESULT, res); if (res.status() != Protos::Core::GetHashesResult_Status_OK) { this->currentHashesResult.clear(); this->finished(); } } break; case Common::MessageHeader::CORE_GET_HASHES_RESULT: { const Protos::Core::GetHashesResult& getHashesResult = message.getMessage<Protos::Core::GetHashesResult>(); this->nbHash = getHashesResult.nb_hash(); } break; case Common::MessageHeader::CORE_HASH_RESULT: { if (--this->nbHash == 0) this->finished(); } break; case Common::MessageHeader::CORE_GET_CHUNK: { const Protos::Core::GetChunk& getChunkMessage = message.getMessage<Protos::Core::GetChunk>(); const Common::Hash hash(getChunkMessage.chunk().hash()); if (hash.isNull()) { L_WARN("GET_CHUNK: Chunk null"); this->finished(true); break; } // TODO: implements 'GetChunkResult.ALREADY_DOWNLOADING', 'GetChunkResult.TOO_MANY_CONNECTIONS' and 'GetChunkResult.DONT_HAVE_DATA_FROM_OFFSET' QSharedPointer<FM::IChunk> chunk = this->fileManager->getChunk(hash); if (chunk.isNull()) { Protos::Core::GetChunkResult result; result.set_status(Protos::Core::GetChunkResult::DONT_HAVE); this->send(Common::MessageHeader::CORE_GET_CHUNK_RESULT, result); this->finished(); L_WARN(QString("GET_CHUNK: Chunk unknown : %1").arg(hash.toStr())); } else { Protos::Core::GetChunkResult result; result.set_status(Protos::Core::GetChunkResult::OK); result.set_chunk_size(chunk->getKnownBytes()); this->send(Common::MessageHeader::CORE_GET_CHUNK_RESULT, result); this->stopListening(); emit getChunk(chunk, getChunkMessage.offset(), this); } } break; default:; // Do nothing. } }
void Socket::onNewMessage(Common::MessageHeader::MessageType type, const google::protobuf::Message& message) { switch (type) { case Common::MessageHeader::CORE_GET_ENTRIES: { const Protos::Core::GetEntries& getEntries = static_cast<const Protos::Core::GetEntries&>(message); Protos::Core::GetEntriesResult result; for (int i = 0; i < getEntries.dirs().entry_size(); i++) result.add_entries()->CopyFrom(this->fileManager->getEntries(getEntries.dirs().entry(i))); // Add the root directories if asked. if (getEntries.dirs().entry_size() == 0 || getEntries.get_roots()) result.add_entries()->CopyFrom(this->fileManager->getEntries()); this->send(Common::MessageHeader::CORE_GET_ENTRIES_RESULT, result); this->finished(); } break; case Common::MessageHeader::CORE_GET_ENTRIES_RESULT: this->finished(); break; case Common::MessageHeader::CORE_GET_HASHES: { const Protos::Core::GetHashes& getHashes = static_cast<const Protos::Core::GetHashes&>(message); this->currentHashesResult = this->fileManager->getHashes(getHashes.file()); connect(this->currentHashesResult.data(), SIGNAL(nextHash(Common::Hash)), this, SLOT(nextAskedHash(Common::Hash)), Qt::QueuedConnection); Protos::Core::GetHashesResult res = this->currentHashesResult->start(); this->nbHash = res.nb_hash(); this->send(Common::MessageHeader::CORE_GET_HASHES_RESULT, res); if (res.status() != Protos::Core::GetHashesResult_Status_OK) { this->currentHashesResult.clear(); this->finished(); } } break; case Common::MessageHeader::CORE_GET_HASHES_RESULT: { const Protos::Core::GetHashesResult& getHashesResult = static_cast<const Protos::Core::GetHashesResult&>(message); this->nbHash = getHashesResult.nb_hash(); } break; case Common::MessageHeader::CORE_HASH: { if (--this->nbHash == 0) this->finished(); } break; case Common::MessageHeader::CORE_GET_CHUNK: { const Protos::Core::GetChunk& getChunkMessage = static_cast<const Protos::Core::GetChunk&>(message); const Common::Hash hash(getChunkMessage.chunk().hash()); if (hash.isNull()) { L_WARN("GET_CHUNK: Chunk null"); this->finished(ISocket::SFS_ERROR); break; } QSharedPointer<FM::IChunk> chunk = this->fileManager->getChunk(hash); if (chunk.isNull()) { Protos::Core::GetChunkResult result; result.set_status(Protos::Core::GetChunkResult_Status_DONT_HAVE); this->send(Common::MessageHeader::CORE_GET_CHUNK_RESULT, result); this->finished(); L_WARN(QString("GET_CHUNK: Chunk unknown : %1").arg(hash.toStr())); } else { Protos::Core::GetChunkResult result; result.set_status(Protos::Core::GetChunkResult_Status_OK); result.set_chunk_size(chunk->getKnownBytes()); this->send(Common::MessageHeader::CORE_GET_CHUNK_RESULT, result); this->stopListening(); emit getChunk(chunk, getChunkMessage.offset(), this); } } break; default:; // Do nothing. } }