2008-02-16 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

Added Message Stream Encryption(MSE) support.
	Currently, aria2 accepts incoming connections with Obfuscation Header
	and legacy BitTorrent Header and establishes connections with
	Obfuscation Header first and if failed then retry with legacy
	BitTorrent header. If plain text and ARC4 is provided, aria2 always
	choose ARC4. The new option to change the default behavior is planned.
	For tracker extension, "supportcrypto=1" is added statically.
	* src/PeerInitiateConnectionCommand.{h, cc}
	* src/PeerConnection.{h, cc}
	* src/HandleRegistry.h
	* src/SocketCore.h
	* src/PeerReceiveHandshakeCommand.{h, cc}
	* src/BtRegistry.{h, cc}
	* src/PeerListenCommand.cc
	* src/InitiatorMSEHandshakeCommand.{h, cc}
	* src/ReceiverMSEHandshakeCommand.{h, cc}
	* src/MSEHandshake.{h, cc}
	* src/ARC4Encryptor.h
	* src/ARC4Decryptor.h
	* src/LibgcryptARC4Encryptor.h
	* src/LibgcryptARC4Decryptor.h
	* src/LibgcryptARC4Context.h
	* src/LibsslARC4Encryptor.h
	* src/LibsslARC4Decryptor.h
	* src/LibsslARC4Context.h
	* src/DHKeyExchange.h
	* src/LibgcryptDHKeyExchange.h
	* src/LibsslDHKeyExchange.h
	* src/DefaultBtAnnounce.cc: Just added "supportcrypto=1" parameter.
	* test/DefaultBtAnnounceTest.cc
	* test/ARC4Test.cc
	* test/DHKeyExchangeTest.cc
	
	Removed prepareForRetry() because it is not used.
	* src/PeerAbstractCommand.{h, cc}
	* src/PeerInteractionCommand.{h, cc}
	* src/PeerInitiateConnectionCommand.{h, cc}
pull/1/head
Tatsuhiro Tsujikawa 2008-02-17 15:56:47 +00:00
parent 1302123368
commit c0d2223c77
41 changed files with 2569 additions and 96 deletions

View File

@ -1,3 +1,43 @@
2008-02-16 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Added Message Stream Encryption(MSE) support.
Currently, aria2 accepts incoming connections with Obfuscation Header
and legacy BitTorrent Header and establishes connections with
Obfuscation Header first and if failed then retry with legacy
BitTorrent header. If plain text and ARC4 is provided, aria2 always
choose ARC4. The new option to change the default behavior is planned.
For tracker extension, "supportcrypto=1" is added statically.
* src/PeerInitiateConnectionCommand.{h, cc}
* src/PeerConnection.{h, cc}
* src/HandleRegistry.h
* src/SocketCore.h
* src/PeerReceiveHandshakeCommand.{h, cc}
* src/BtRegistry.{h, cc}
* src/PeerListenCommand.cc
* src/InitiatorMSEHandshakeCommand.{h, cc}
* src/ReceiverMSEHandshakeCommand.{h, cc}
* src/MSEHandshake.{h, cc}
* src/ARC4Encryptor.h
* src/ARC4Decryptor.h
* src/LibgcryptARC4Encryptor.h
* src/LibgcryptARC4Decryptor.h
* src/LibgcryptARC4Context.h
* src/LibsslARC4Encryptor.h
* src/LibsslARC4Decryptor.h
* src/LibsslARC4Context.h
* src/DHKeyExchange.h
* src/LibgcryptDHKeyExchange.h
* src/LibsslDHKeyExchange.h
* src/DefaultBtAnnounce.cc: Just added "supportcrypto=1" parameter.
* test/DefaultBtAnnounceTest.cc
* test/ARC4Test.cc
* test/DHKeyExchangeTest.cc
Removed prepareForRetry() because it is not used.
* src/PeerAbstractCommand.{h, cc}
* src/PeerInteractionCommand.{h, cc}
* src/PeerInitiateConnectionCommand.{h, cc}
2008-02-13 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Added the ability to load nodes from torrent file. These nodes are

45
src/ARC4Decryptor.h Normal file
View File

@ -0,0 +1,45 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#ifndef _D_ARC4_DECRYPTOR_H_
#define _D_ARC4_DECRYPTOR_H_
#include "common.h"
#ifdef HAVE_LIBGCRYPT
# include "LibgcryptARC4Decryptor.h"
#elif HAVE_LIBSSL
# include "LibsslARC4Decryptor.h"
#endif // HAVE_LIBSSL
#endif // _D_ARC4_DECRYPTOR_H_

45
src/ARC4Encryptor.h Normal file
View File

@ -0,0 +1,45 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#ifndef _D_ARC4_ENCRYPTOR_H_
#define _D_ARC4_ENCRYPTOR_H_
#include "common.h"
#ifdef HAVE_LIBGCRYPT
# include "LibgcryptARC4Encryptor.h"
#elif HAVE_LIBSSL
# include "LibsslARC4Encryptor.h"
#endif // HAVE_LIBSSL
#endif // _D_ARC4_ENCRYPTOR_H_

View File

@ -131,6 +131,11 @@ BtRegistry::registerBtContext(const std::string& key,
btContextMap.registerHandle(key, btContext);
}
std::deque<SharedHandle<BtContext> > BtRegistry::getAllBtContext()
{
return btContextMap.getAll();
}
PeerObjectClusterHandle
BtRegistry::getPeerObjectCluster(const std::string& key)
{

View File

@ -99,6 +99,8 @@ public:
static void registerBtProgressInfoFile(const std::string& key,
const SharedHandle<BtProgressInfoFile>& btProgressInfoFile);
static std::deque<SharedHandle<BtContext> > getAllBtContext();
// for PeerObject
static PeerObjectClusterHandle
getPeerObjectCluster(const std::string& key);

45
src/DHKeyExchange.h Normal file
View File

@ -0,0 +1,45 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#ifndef _D_DH_KEY_EXCHANGE_H_
#define _D_DH_KEY_EXCHANGE_H_
#include "common.h"
#ifdef HAVE_LIBGCRYPT
# include "LibgcryptDHKeyExchange.h"
#elif HAVE_LIBSSL
# include "LibsslDHKeyExchange.h"
#endif // HAVE_LIBSSL
#endif // _D_DH_KEY_EXCHANGE_H_

View File

@ -160,6 +160,7 @@ std::string DefaultBtAnnounce::getAnnounceUrl() {
url += std::string("&")+"trackerid="+Util::torrentUrlencode((const unsigned char*)trackerId.c_str(),
trackerId.size());
}
url += "&supportcrypto=1";
return url;
}

View File

@ -38,6 +38,7 @@
#include "common.h"
#include "SharedHandle.h"
#include <map>
#include <deque>
namespace aria2 {
@ -66,6 +67,16 @@ public:
}
}
std::deque<SharedHandle<T> > getAll()
{
std::deque<SharedHandle<T> > l;
for(typename HandleMap::const_iterator itr = handleMap.begin(); itr != handleMap.end(); ++itr) {
const typename HandleMap::value_type& p = *itr;
l.push_back(p.second);
}
return l;
}
void clear() {
handleMap.clear();
}

View File

@ -0,0 +1,165 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#include "InitiatorMSEHandshakeCommand.h"
#include "PeerInitiateConnectionCommand.h"
#include "PeerInteractionCommand.h"
#include "DownloadEngine.h"
#include "DlAbortEx.h"
#include "message.h"
#include "prefs.h"
#include "CUIDCounter.h"
#include "Socket.h"
#include "Logger.h"
#include "Peer.h"
#include "PeerConnection.h"
#include "BtContext.h"
#include "BtRuntime.h"
#include "PieceStorage.h"
#include "PeerStorage.h"
#include "BtAnnounce.h"
#include "BtProgressInfoFile.h"
#include "Option.h"
#include "MSEHandshake.h"
#include "ARC4Encryptor.h"
#include "ARC4Decryptor.h"
namespace aria2 {
InitiatorMSEHandshakeCommand::InitiatorMSEHandshakeCommand
(int32_t cuid,
RequestGroup* requestGroup,
const SharedHandle<Peer>& p,
DownloadEngine* e,
const SharedHandle<BtContext>& btContext,
const SharedHandle<SocketCore>& s):
PeerAbstractCommand(cuid, p, e, s),
BtContextAwareCommand(btContext),
RequestGroupAware(requestGroup),
_sequence(INITIATOR_SEND_KEY),
_mseHandshake(new MSEHandshake(cuid, socket, e->option))
{
disableReadCheckSocket();
setWriteCheckSocket(socket);
setTimeout(e->option->getAsInt(PREF_PEER_CONNECTION_TIMEOUT));
btRuntime->increaseConnections();
}
InitiatorMSEHandshakeCommand::~InitiatorMSEHandshakeCommand()
{
btRuntime->decreaseConnections();
delete _mseHandshake;
}
bool InitiatorMSEHandshakeCommand::executeInternal() {
switch(_sequence) {
case INITIATOR_SEND_KEY: {
if(!socket->isWritable(0)) {
break;
}
disableWriteCheckSocket();
setReadCheckSocket(socket);
socket->setBlockingMode();
setTimeout(e->option->getAsInt(PREF_BT_TIMEOUT));
_mseHandshake->initEncryptionFacility(true);
_mseHandshake->sendPublicKey();
_sequence = INITIATOR_WAIT_KEY;
break;
}
case INITIATOR_WAIT_KEY: {
if(_mseHandshake->receivePublicKey()) {
_mseHandshake->initCipher(btContext->getInfoHash());
_mseHandshake->sendInitiatorStep2();
_sequence = INITIATOR_FIND_VC_MARKER;
}
break;
}
case INITIATOR_FIND_VC_MARKER: {
if(_mseHandshake->findInitiatorVCMarker()) {
_sequence = INITIATOR_RECEIVE_PAD_D_LENGTH;
}
break;
}
case INITIATOR_RECEIVE_PAD_D_LENGTH: {
if(_mseHandshake->receiveInitiatorCryptoSelectAndPadDLength()) {
_sequence = INITIATOR_RECEIVE_PAD_D;
}
break;
}
case INITIATOR_RECEIVE_PAD_D: {
if(_mseHandshake->receivePad()) {
SharedHandle<PeerConnection> peerConnection =
new PeerConnection(cuid, socket, e->option);
if(_mseHandshake->getNegotiatedCryptoType() == MSEHandshake::CRYPTO_ARC4) {
peerConnection->enableEncryption(_mseHandshake->getEncryptor(),
_mseHandshake->getDecryptor());
}
Command* c =
new PeerInteractionCommand(cuid, _requestGroup, peer, e, btContext,
socket,
PeerInteractionCommand::INITIATOR_SEND_HANDSHAKE,
peerConnection);
e->commands.push_back(c);
return true;
}
break;
}
}
e->commands.push_back(this);
return false;
}
bool InitiatorMSEHandshakeCommand::prepareForNextPeer(int32_t wait)
{
// try legacy BitTorrent handshake if preference allows it.
// TODO preference is not created yet.
logger->info("CUID#%d - Retry using legacy BitTorrent handshake.", cuid);
Command* command =
new PeerInitiateConnectionCommand(cuid, _requestGroup, peer, e, btContext,
false);
e->commands.push_back(command);
return true;
}
void InitiatorMSEHandshakeCommand::onAbort(Exception* ex) {}
bool InitiatorMSEHandshakeCommand::exitBeforeExecute()
{
return btRuntime->isHalt();
}
} // namespace aria2

View File

@ -0,0 +1,80 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#ifndef _D_INITIATOR_MSE_HANDSHAKE_COMMAND_H_
#define _D_INITIATOR_MSE_HANDSHAKE_COMMAND_H_
#include "PeerAbstractCommand.h"
#include "RequestGroupAware.h"
#include "BtContextAwareCommand.h"
namespace aria2 {
class MSEHandshake;
class InitiatorMSEHandshakeCommand : public PeerAbstractCommand,
public BtContextAwareCommand,
public RequestGroupAware
{
public:
enum Seq {
INITIATOR_SEND_KEY,
INITIATOR_WAIT_KEY,
INITIATOR_FIND_VC_MARKER,
INITIATOR_RECEIVE_PAD_D_LENGTH,
INITIATOR_RECEIVE_PAD_D,
};
private:
Seq _sequence;
MSEHandshake* _mseHandshake;
protected:
virtual bool executeInternal();
virtual bool prepareForNextPeer(int32_t wait);
virtual void onAbort(Exception* ex);
virtual bool exitBeforeExecute();
public:
InitiatorMSEHandshakeCommand(int32_t cuid,
RequestGroup* requestGroup,
const SharedHandle<Peer>& peer,
DownloadEngine* e,
const SharedHandle<BtContext>& btContext,
const SharedHandle<SocketCore>& s);
virtual ~InitiatorMSEHandshakeCommand();
};
} // namespace aria2
#endif // _D_INITIATOR_MSE_HANDSHAKE_COMMAND_H_

View File

@ -0,0 +1,96 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#ifndef _D_LIBGCRYPT_ARC4_CONTEXT_H_
#define _D_LIBGCRYPT_ARC4_CONTEXT_H_
#include "common.h"
#include "DlAbortEx.h"
#include <gcrypt.h>
namespace aria2 {
class LibgcryptARC4Context {
private:
gcry_cipher_hd_t _cipherCtx;
void handleError(gcry_error_t errno) const
{
throw new DlAbortEx("Exception in libgcrypt routine(ARC4Context class): %s",
gcry_strerror(errno));
}
public:
LibgcryptARC4Context():_cipherCtx(0) {}
~LibgcryptARC4Context()
{
gcry_cipher_close(_cipherCtx);
}
gcry_cipher_hd_t getCipherContext() const
{
return _cipherCtx;
}
void init(const unsigned char* key, size_t keyLength)
{
gcry_cipher_close(_cipherCtx);
int algo = GCRY_CIPHER_ARCFOUR;
int mode = GCRY_CIPHER_MODE_STREAM;
unsigned int flags = 0;
{
gcry_error_t r = gcry_cipher_open(&_cipherCtx, algo, mode, flags);
if(r) {
handleError(r);
}
}
{
gcry_error_t r = gcry_cipher_setkey(_cipherCtx, key, keyLength);
if(r) {
handleError(r);
}
}
{
gcry_error_t r = gcry_cipher_setiv(_cipherCtx, 0, 0);
if(r) {
handleError(r);
}
}
}
};
} // namespace aria2
#endif // _D_LIBGCRYPT_ARC4_CONTEXT_H_

View File

@ -0,0 +1,77 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#ifndef _D_LIBGCRYPT_ARC4_DECRYPTOR_H_
#define _D_LIBGCRYPT_ARC4_DECRYPTOR_H_
#include "common.h"
#include "DlAbortEx.h"
#include "LibgcryptARC4Context.h"
#include <gcrypt.h>
namespace aria2 {
class ARC4Decryptor {
private:
LibgcryptARC4Context _ctx;
void handleError(gcry_error_t errno) const
{
throw new DlAbortEx("Exception in libgcrypt routine(ARC4Decryptor class): %s",
gcry_strerror(errno));
}
public:
ARC4Decryptor() {}
~ARC4Decryptor() {}
void init(const unsigned char* key, size_t keyLength)
{
_ctx.init(key, keyLength);
}
void decrypt(unsigned char* out, size_t outLength,
const unsigned char* in, size_t inLength)
{
gcry_error_t r = gcry_cipher_decrypt(_ctx.getCipherContext(),
out, outLength, in, inLength);
if(r) {
handleError(r);
}
}
};
} // namespace aria2
#endif // _D_LIBGCRYPT_ARC4_DECRYPTOR_H_

View File

@ -0,0 +1,77 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#ifndef _D_LIBGCRYPT_ARC4_ENCRYPTOR_H_
#define _D_LIBGCRYPT_ARC4_ENCRYPTOR_H_
#include "common.h"
#include "DlAbortEx.h"
#include "LibgcryptARC4Context.h"
#include <gcrypt.h>
namespace aria2 {
class ARC4Encryptor {
private:
LibgcryptARC4Context _ctx;
void handleError(gcry_error_t errno) const
{
throw new DlAbortEx("Exception in libgcrypt routine(ARC4Encryptor class): %s",
gcry_strerror(errno));
}
public:
ARC4Encryptor() {}
~ARC4Encryptor() {}
void init(const unsigned char* key, size_t keyLength)
{
_ctx.init(key, keyLength);
}
void encrypt(unsigned char* out, size_t outLength,
const unsigned char* in, size_t inLength)
{
gcry_error_t r = gcry_cipher_encrypt(_ctx.getCipherContext(),
out, outLength, in, inLength);
if(r) {
handleError(r);
}
}
};
} // namespace aria2
#endif // _D_LIBGCRYPT_ARC4_ENCRYPTOR_H_

View File

@ -0,0 +1,164 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#ifndef _D_LIBGCRYPT_DH_KEY_EXCHANGE_H_
#define _D_LIBGCRYPT_DH_KEY_EXCHANGE_H_
#include "common.h"
#include "DlAbortEx.h"
#include <gcrypt.h>
namespace aria2 {
class DHKeyExchange {
private:
gcry_mpi_t _prime;
gcry_mpi_t _generator;
gcry_mpi_t _privateKey;
gcry_mpi_t _publicKey;
void handleError(int errno) const
{
throw new DlAbortEx("Exception in libgcrypt routine(DHKeyExchange class): %s",
gcry_strerror(errno));
}
public:
DHKeyExchange():_prime(0),
_generator(0),
_privateKey(0),
_publicKey(0) {}
~DHKeyExchange()
{
gcry_mpi_release(_prime);
gcry_mpi_release(_generator);
gcry_mpi_release(_privateKey);
gcry_mpi_release(_publicKey);
}
void init(const unsigned char* prime, const unsigned char* generator,
size_t privateKeyBits)
{
gcry_mpi_release(_prime);
gcry_mpi_release(_generator);
gcry_mpi_release(_privateKey);
{
gcry_error_t r = gcry_mpi_scan(&_prime, GCRYMPI_FMT_HEX,
prime, 0, 0);
if(r) {
handleError(r);
}
}
{
gcry_error_t r = gcry_mpi_scan(&_generator, GCRYMPI_FMT_HEX,
generator, 0, 0);
if(r) {
handleError(r);
}
}
_privateKey = gcry_mpi_new(0);
gcry_mpi_randomize(_privateKey, privateKeyBits, GCRY_STRONG_RANDOM);
}
void generatePublicKey()
{
gcry_mpi_release(_publicKey);
_publicKey = gcry_mpi_new(0);
gcry_mpi_powm(_publicKey, _generator, _privateKey, _prime);
}
size_t publicKeyLength() const
{
return (gcry_mpi_get_nbits(_publicKey)+7)/8;
}
size_t getPublicKey(unsigned char* out, size_t outLength) const
{
if(outLength < publicKeyLength()) {
throw new DlAbortEx("Insufficient buffer for public key. expect:%u, actual:%u",
publicKeyLength(), outLength);
}
size_t nwritten;
gcry_error_t r = gcry_mpi_print(GCRYMPI_FMT_USG, out, outLength, &nwritten, _publicKey);
if(r) {
handleError(r);
}
return nwritten;
}
void generateNonce(unsigned char* out, size_t outLength) const
{
gcry_create_nonce(out, outLength);
}
size_t computeSecret(unsigned char* out, size_t outLength,
const unsigned char* peerPublicKeyData,
size_t peerPublicKeyLength) const
{
if(outLength < publicKeyLength()) {
throw new DlAbortEx("Insufficient buffer for secret. expect:%u, actual:%u",
publicKeyLength(), outLength);
}
gcry_mpi_t peerPublicKey;
{
gcry_error_t r = gcry_mpi_scan(&peerPublicKey, GCRYMPI_FMT_USG, peerPublicKeyData,
peerPublicKeyLength, 0);
if(r) {
handleError(r);
}
}
gcry_mpi_t secret = gcry_mpi_new(0);
gcry_mpi_powm(secret, peerPublicKey, _privateKey, _prime);
gcry_mpi_release(peerPublicKey);
size_t nwritten;
{
gcry_error_t r = gcry_mpi_print(GCRYMPI_FMT_USG, out, outLength, &nwritten, secret);
gcry_mpi_release(secret);
if(r) {
handleError(r);
}
}
return nwritten;
}
};
} // namespace aria2
#endif // _D_LIBGCRYPT_DH_KEY_EXCHANGE_H_

96
src/LibsslARC4Context.h Normal file
View File

@ -0,0 +1,96 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#ifndef _D_LIBSSL_ARC4_CONTEXT_H_
#define _D_LIBSSL_ARC4_CONTEXT_H_
#include "common.h"
#include "DlAbortEx.h"
#include <openssl/evp.h>
#include <openssl/err.h>
namespace aria2 {
class LibsslARC4Context {
private:
EVP_CIPHER_CTX* _cipherCtx;
void handleError() const
{
throw new DlAbortEx("Exception in libssl routine(ARC4Context class): %s",
ERR_error_string(ERR_get_error(), 0));
}
public:
LibsslARC4Context():_cipherCtx(0) {}
~LibsslARC4Context()
{
if(_cipherCtx) {
EVP_CIPHER_CTX_cleanup(_cipherCtx);
}
delete _cipherCtx;
}
EVP_CIPHER_CTX* getCipherContext() const
{
return _cipherCtx;
}
// enc == 1: encryption
// enc == 0: decryption
void init(const unsigned char* key, size_t keyLength, int enc)
{
if(_cipherCtx) {
EVP_CIPHER_CTX_cleanup(_cipherCtx);
}
delete _cipherCtx;
_cipherCtx = new EVP_CIPHER_CTX;
EVP_CIPHER_CTX_init(_cipherCtx);
if(!EVP_CipherInit_ex(_cipherCtx, EVP_rc4(), 0, 0, 0, enc)) {
handleError();
}
if(!EVP_CIPHER_CTX_set_key_length(_cipherCtx, keyLength)) {
handleError();
}
if(!EVP_CipherInit_ex(_cipherCtx, 0, 0, key, 0, -1)) {
handleError();
}
}
};
} // namespace aria2
#endif // _D_LIBSSL_ARC4_CONTEXT_H_

77
src/LibsslARC4Decryptor.h Normal file
View File

@ -0,0 +1,77 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#ifndef _D_LIBSSL_ARC4_DECRYPTOR_H_
#define _D_LIBSSL_ARC4_DECRYPTOR_H_
#include "common.h"
#include "DlAbortEx.h"
#include "LibsslARC4Context.h"
#include <openssl/evp.h>
#include <openssl/err.h>
namespace aria2 {
class ARC4Decryptor {
private:
LibsslARC4Context _ctx;
void handleError() const
{
throw new DlAbortEx("Exception in libssl routine(ARC4Decryptor class): %s",
ERR_error_string(ERR_get_error(), 0));
}
public:
ARC4Decryptor() {}
~ARC4Decryptor() {}
void init(const unsigned char* key, size_t keyLength)
{
_ctx.init(key, keyLength, 0);
}
void decrypt(unsigned char* out, size_t outLength,
const unsigned char* in, size_t inLength)
{
int soutLength = outLength;
if(!EVP_CipherUpdate(_ctx.getCipherContext(), out, &soutLength, in, inLength)) {
handleError();
}
}
};
} // namespace aria2
#endif // _D_LIBSSL_ARC4_DECRYPTOR_H_

77
src/LibsslARC4Encryptor.h Normal file
View File

@ -0,0 +1,77 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#ifndef _D_LIBSSL_ARC4_ENCRYPTOR_H_
#define _D_LIBSSL_ARC4_ENCRYPTOR_H_
#include "common.h"
#include "DlAbortEx.h"
#include "LibsslARC4Context.h"
#include <openssl/evp.h>
#include <openssl/err.h>
namespace aria2 {
class ARC4Encryptor {
private:
LibsslARC4Context _ctx;
void handleError() const
{
throw new DlAbortEx("Exception in libssl routine(ARC4Encryptor class): %s",
ERR_error_string(ERR_get_error(), 0));
}
public:
ARC4Encryptor() {}
~ARC4Encryptor() {}
void init(const unsigned char* key, size_t keyLength)
{
_ctx.init(key, keyLength, 1);
}
void encrypt(unsigned char* out, size_t outLength,
const unsigned char* in, size_t inLength)
{
int soutLength = outLength;
if(!EVP_CipherUpdate(_ctx.getCipherContext(), out, &soutLength, in, inLength)) {
handleError();
}
}
};
} // namespace aria2
#endif // _D_LIBSSL_ARC4_ENCRYPTOR_H_

171
src/LibsslDHKeyExchange.h Normal file
View File

@ -0,0 +1,171 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#ifndef _D_LIBSSL_DH_KEY_EXCHANGE_H_
#define _D_LIBSSL_DH_KEY_EXCHANGE_H_
#include "common.h"
#include "DlAbortEx.h"
#include <openssl/dh.h>
#include <openssl/rand.h>
#include <openssl/err.h>
namespace aria2 {
class DHKeyExchange {
private:
BN_CTX* _bnCtx;
BIGNUM* _prime;
BIGNUM* _generator;
BIGNUM* _privateKey;
BIGNUM* _publicKey;
void handleError() const
{
throw new DlAbortEx("Exception in libssl routine(DHKeyExchange class): %s",
ERR_error_string(ERR_get_error(), 0));
}
public:
DHKeyExchange():_bnCtx(0),
_prime(0),
_generator(0),
_privateKey(0),
_publicKey(0) {}
~DHKeyExchange()
{
BN_CTX_free(_bnCtx);
BN_free(_prime);
BN_free(_generator);
BN_free(_privateKey);
BN_free(_publicKey);
}
void init(const unsigned char* prime, const unsigned char* generator,
size_t privateKeyBits)
{
BN_CTX_free(_bnCtx);
_bnCtx = BN_CTX_new();
if(!_bnCtx) {
handleError();
}
BN_free(_prime);
_prime = 0;
BN_free(_generator);
_generator = 0;
BN_free(_privateKey);
_privateKey = 0;
if(BN_hex2bn(&_prime, reinterpret_cast<const char*>(prime)) == 0) {
handleError();
}
if(BN_hex2bn(&_generator, reinterpret_cast<const char*>(generator)) == 0) {
handleError();
}
_privateKey = BN_new();
if(!BN_rand(_privateKey, privateKeyBits, -1, false)) {
handleError();
}
}
void generatePublicKey()
{
BN_free(_publicKey);
_publicKey = BN_new();
BN_mod_exp(_publicKey, _generator, _privateKey, _prime, _bnCtx);
}
size_t publicKeyLength() const
{
return BN_num_bytes(_publicKey);
}
size_t getPublicKey(unsigned char* out, size_t outLength) const
{
if(outLength < publicKeyLength()) {
throw new DlAbortEx("Insufficient buffer for public key. expect:%u, actual:%u",
publicKeyLength(), outLength);
}
size_t nwritten = BN_bn2bin(_publicKey, out);
if(!nwritten) {
handleError();
}
return nwritten;
}
void generateNonce(unsigned char* out, size_t outLength) const
{
if(!RAND_bytes(out, outLength)) {
handleError();
}
}
size_t computeSecret(unsigned char* out, size_t outLength,
const unsigned char* peerPublicKeyData,
size_t peerPublicKeyLength) const
{
if(outLength < publicKeyLength()) {
throw new DlAbortEx("Insufficient buffer for secret. expect:%u, actual:%u",
publicKeyLength(), outLength);
}
BIGNUM* peerPublicKey = BN_bin2bn(peerPublicKeyData, peerPublicKeyLength, 0);
if(!peerPublicKey) {
handleError();
}
BIGNUM* secret = BN_new();
BN_mod_exp(secret, peerPublicKey, _privateKey, _prime, _bnCtx);
BN_free(peerPublicKey);
size_t nwritten = BN_bn2bin(secret, out);
BN_free(secret);
if(!nwritten) {
handleError();
}
return nwritten;
}
};
} // namespace aria2
#endif // _D_LIBSSL_DH_KEY_EXCHANGE_H_

591
src/MSEHandshake.cc Normal file
View File

@ -0,0 +1,591 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#include "MSEHandshake.h"
#include "message.h"
#include "DlAbortEx.h"
#include "LogFactory.h"
#include "Logger.h"
#include "BtHandshakeMessage.h"
#include "Socket.h"
#include "a2netcompat.h"
#include "DHKeyExchange.h"
#include "ARC4Encryptor.h"
#include "ARC4Decryptor.h"
#include "MessageDigestHelper.h"
#include "SimpleRandomizer.h"
#include "Util.h"
#include "BtRegistry.h"
#include "BtContext.h"
#include <cstring>
#include <cassert>
namespace aria2 {
const unsigned char* MSEHandshake::PRIME = reinterpret_cast<const unsigned char*>("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A63A36210000000000090563");
const unsigned char* MSEHandshake::GENERATOR = reinterpret_cast<const unsigned char*>("2");
const unsigned char MSEHandshake::VC[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
MSEHandshake::MSEHandshake(int32_t cuid,
const SocketHandle& socket,
const Option* op):
_cuid(cuid),
_socket(socket),
_option(op),
_logger(LogFactory::getInstance()),
_rbufLength(0),
_negotiatedCryptoType(CRYPTO_NONE),
_dh(0),
_encryptor(0),
_decryptor(0),
_initiator(true),
_markerIndex(0),
_padLength(0),
_iaLength(0),
_ia(0)
{}
MSEHandshake::~MSEHandshake()
{
delete _dh;
delete [] _ia;
}
MSEHandshake::HANDSHAKE_TYPE MSEHandshake::identifyHandshakeType()
{
if(!_socket->isReadable(0)) {
return HANDSHAKE_NOT_YET;
}
int32_t bufLength = 20;
_socket->peekData(_rbuf, bufLength);
if(bufLength != 20) {
return HANDSHAKE_NOT_YET;
}
if(_rbuf[0] == BtHandshakeMessage::PSTR_LENGTH &&
memcmp(BtHandshakeMessage::BT_PSTR, _rbuf+1, 19) == 0) {
_logger->debug("CUID#%d - This is legacy BitTorrent handshake.", _cuid);
return HANDSHAKE_LEGACY;
} else {
_logger->debug("CUID#%d - This may be encrypted BitTorrent handshake.", _cuid);
return HANDSHAKE_ENCRYPTED;
}
}
void MSEHandshake::initEncryptionFacility(bool initiator)
{
delete _dh;
_dh = new DHKeyExchange();
_dh->init(PRIME, GENERATOR, 160);
_dh->generatePublicKey();
_logger->debug("CUID#%d - DH initialized.", _cuid);
_initiator = initiator;
}
void MSEHandshake::sendPublicKey()
{
_logger->debug("CUID#%d - Sending public key.", _cuid);
unsigned char buffer[KEY_LENGTH+MAX_PAD_LENGTH];
_dh->getPublicKey(buffer, KEY_LENGTH);
size_t padLength = SimpleRandomizer::getInstance()->getRandomNumber(MAX_PAD_LENGTH+1);
_dh->generateNonce(buffer+KEY_LENGTH, padLength);
_socket->writeData(buffer, KEY_LENGTH+padLength);
}
bool MSEHandshake::receivePublicKey()
{
int32_t r = KEY_LENGTH-_rbufLength;
if(r > receiveNBytes(r)) {
return false;
}
_logger->debug("CUID#%d - public key received.", _cuid);
// TODO handle exception. in catch, resbufLength = 0;
_dh->computeSecret(_secret, sizeof(_secret), _rbuf, _rbufLength);
// reset _rbufLength
_rbufLength = 0;
return true;
}
void MSEHandshake::initCipher(const unsigned char* infoHash)
{
memcpy(_infoHash, infoHash, INFO_HASH_LENGTH);
//Initialize cipher
unsigned char s[4+KEY_LENGTH+INFO_HASH_LENGTH];
memcpy(s, _initiator?"keyA":"keyB", 4);
memcpy(s+4, _secret, KEY_LENGTH);
memcpy(s+4+KEY_LENGTH, infoHash, INFO_HASH_LENGTH);
unsigned char localCipherKey[20];
MessageDigestHelper::digest(localCipherKey, sizeof(localCipherKey), "sha1",
s, sizeof(s));
_encryptor = new ARC4Encryptor();
_encryptor->init(localCipherKey, sizeof(localCipherKey));
unsigned char peerCipherKey[20];
memcpy(s, _initiator?"keyB":"keyA", 4);
MessageDigestHelper::digest(peerCipherKey, sizeof(peerCipherKey), "sha1",
s, sizeof(s));
_decryptor = new ARC4Decryptor();
_decryptor->init(peerCipherKey, sizeof(peerCipherKey));
// discard first 1024 bytes ARC4 output.
unsigned char from[1024];
unsigned char to[1024];
_encryptor->encrypt(to, 1024, from, 1024);
_decryptor->decrypt(to, 1024, from, 1024);
if(_initiator) {
ARC4Encryptor enc;
enc.init(peerCipherKey, sizeof(peerCipherKey));
// discard first 1024 bytes ARC4 output.
enc.encrypt(to, 1024, from, 1024);
enc.encrypt(_initiatorVCMarker, sizeof(_initiatorVCMarker), VC, sizeof(VC));
}
}
ssize_t MSEHandshake::readDataAndDecrypt(unsigned char* data, size_t length)
{
unsigned char temp[MAX_BUFFER_LENGTH];
assert(MAX_BUFFER_LENGTH >= length);
int32_t rlength = length;
_socket->readData(temp, rlength);
_decryptor->decrypt(data, rlength, temp, rlength);
return rlength;
}
void MSEHandshake::encryptAndSendData(const unsigned char* data, size_t length)
{
unsigned char temp[4096];
const unsigned char* dptr = data;
size_t s;
size_t r = length;
while(r > 0) {
s = r > sizeof(temp)?sizeof(temp):r;
_encryptor->encrypt(temp, s, dptr, s);
_socket->writeData(temp, s);
dptr += s;
r -= s;
}
}
void MSEHandshake::createReq1Hash(unsigned char* md) const
{
unsigned char buffer[100];
memcpy(buffer, "req1", 4);
memcpy(buffer+4, _secret, KEY_LENGTH);
MessageDigestHelper::digest(md, 20, "sha1", buffer, 4+KEY_LENGTH);
}
void MSEHandshake::createReq23Hash(unsigned char* md, const unsigned char* infoHash) const
{
unsigned char x[24];
memcpy(x, "req2", 4);
memcpy(x+4, infoHash, INFO_HASH_LENGTH);
unsigned char xh[20];
MessageDigestHelper::digest(xh, sizeof(xh), "sha1", x, sizeof(x));
unsigned char y[4+96];
memcpy(y, "req3", 4);
memcpy(y+4, _secret, KEY_LENGTH);
unsigned char yh[20];
MessageDigestHelper::digest(yh, sizeof(yh), "sha1", y, sizeof(y));
for(size_t i = 0; i < 20; ++i) {
md[i] = xh[i]^yh[i];
}
}
uint16_t MSEHandshake::decodeLength16(const unsigned char* buffer)
{
uint16_t be;
_decryptor->decrypt(reinterpret_cast<unsigned char*>(&be),
sizeof(be),
buffer, sizeof(be));
return ntohs(be);
}
void MSEHandshake::sendInitiatorStep2()
{
_logger->debug("CUID#%d - Sending negotiation step2.", _cuid);
unsigned char md[20];
createReq1Hash(md);
_socket->writeData(md, sizeof(md));
createReq23Hash(md, _infoHash);
_socket->writeData(md, sizeof(md));
{
unsigned char buffer[8+4+2+MAX_PAD_LENGTH+2];
// VC
memcpy(buffer, VC, sizeof(VC));
// crypto_provide
unsigned char cryptoProvide[4];
memset(cryptoProvide, 0, sizeof(cryptoProvide));
cryptoProvide[3] = CRYPTO_PLAIN_TEXT | CRYPTO_ARC4;
memcpy(buffer+8, cryptoProvide, sizeof(cryptoProvide));
// len(padC)
uint16_t padCLength = SimpleRandomizer::getInstance()->getRandomNumber(MAX_PAD_LENGTH+1);
{
uint16_t padCLengthBE = htons(padCLength);
memcpy(buffer+8+4, &padCLengthBE, sizeof(padCLengthBE));
}
// padC
memset(buffer+8+4+2, 0, padCLength);
// len(IA)
// currently, IA is zero-length.
uint16_t iaLength = 0;
{
uint16_t iaLengthBE = htons(iaLength);
memcpy(buffer+8+4+2+padCLength, &iaLengthBE, sizeof(iaLengthBE));
}
encryptAndSendData(buffer, 8+4+2+padCLength+2);
}
}
// This function reads exactly until the end of VC marker is reached.
bool MSEHandshake::findInitiatorVCMarker()
{
// 616 is synchronization point of initiator
int32_t r = 616-KEY_LENGTH-_rbufLength;
if(!_socket->isReadable(0)) {
return false;
}
_socket->peekData(_rbuf+_rbufLength, r);
if(r == 0) {
throw new DlAbortEx(EX_EOF_FROM_PEER);
}
// find vc
{
std::string buf(&_rbuf[0], &_rbuf[_rbufLength+r]);
std::string vc(&_initiatorVCMarker[0], &_initiatorVCMarker[VC_LENGTH]);
if((_markerIndex = buf.find(vc)) == std::string::npos) {
if(616-KEY_LENGTH <= _rbufLength+r) {
throw new DlAbortEx("Failed to find VC marker.");
} else {
_socket->readData(_rbuf+_rbufLength, r);
_rbufLength += r;
return false;
}
}
}
assert(_markerIndex+VC_LENGTH-_rbufLength <= (size_t)r);
int32_t toRead = _markerIndex+VC_LENGTH-_rbufLength;
_socket->readData(_rbuf+_rbufLength, toRead);
_rbufLength += toRead;
_logger->debug("CUID#%d - VC marker found at %u", _cuid, _markerIndex);
verifyVC(_rbuf+_markerIndex);
// reset _rbufLength
_rbufLength = 0;
return true;
}
bool MSEHandshake::receiveInitiatorCryptoSelectAndPadDLength()
{
int32_t r = CRYPTO_BITFIELD_LENGTH+2/* PadD length*/-_rbufLength;
if(r > receiveNBytes(r)) {
return false;
}
//verifyCryptoSelect
unsigned char* rbufptr = _rbuf;
{
unsigned char cryptoSelect[CRYPTO_BITFIELD_LENGTH];
_decryptor->decrypt(cryptoSelect, sizeof(cryptoSelect),
rbufptr, sizeof(cryptoSelect));
if(cryptoSelect[3]&CRYPTO_PLAIN_TEXT) {
_logger->debug("CUID#%d - peer prefers plaintext.", _cuid);
_negotiatedCryptoType = CRYPTO_PLAIN_TEXT;
}
if(cryptoSelect[3]&CRYPTO_ARC4) {
_logger->debug("CUID#%d - peer prefers ARC4", _cuid);
_negotiatedCryptoType = CRYPTO_ARC4;
}
if(_negotiatedCryptoType == CRYPTO_NONE) {
throw new DlAbortEx("CUID#%d - No supported crypto type selected.", _cuid);
}
}
// padD length
rbufptr += CRYPTO_BITFIELD_LENGTH;
_padLength = verifyPadLength(rbufptr, "PadD");
// reset _rbufLength
_rbufLength = 0;
return true;
}
bool MSEHandshake::receivePad()
{
if(_padLength == 0) {
return true;
}
int32_t r = _padLength-_rbufLength;
if(r > receiveNBytes(r)) {
return false;
}
unsigned char temp[MAX_PAD_LENGTH];
_decryptor->decrypt(temp, _padLength, _rbuf, _padLength);
// reset _rbufLength
_rbufLength = 0;
return true;
}
bool MSEHandshake::findReceiverHashMarker()
{
// 628 is synchronization limit of receiver.
int32_t r = 628-KEY_LENGTH-_rbufLength;
if(!_socket->isReadable(0)) {
return false;
}
_socket->peekData(_rbuf+_rbufLength, r);
if(r == 0) {
throw new DlAbortEx(EX_EOF_FROM_PEER);
}
// find hash('req1', S), S is _secret.
{
std::string buf(&_rbuf[0], &_rbuf[_rbufLength+r]);
unsigned char md[20];
createReq1Hash(md);
std::string req1(&md[0], &md[sizeof(md)]);
if((_markerIndex = buf.find(req1)) == std::string::npos) {
if(628-KEY_LENGTH <= _rbufLength+r) {
throw new DlAbortEx("Failed to find hash marker.");
} else {
_socket->readData(_rbuf+_rbufLength, r);
_rbufLength += r;
return false;
}
}
}
assert(_markerIndex+20-_rbufLength <= (size_t)r);
int32_t toRead = _markerIndex+20-_rbufLength;
_socket->readData(_rbuf+_rbufLength, toRead);
_rbufLength += toRead;
_logger->debug("CUID#%d - Hash marker found at %u.", _cuid, _markerIndex);
verifyReq1Hash(_rbuf+_markerIndex);
// reset _rbufLength
_rbufLength = 0;
return true;
}
bool MSEHandshake::receiveReceiverHashAndPadCLength()
{
int32_t r = 20+VC_LENGTH+CRYPTO_BITFIELD_LENGTH+2/*PadC length*/-_rbufLength;
if(r > receiveNBytes(r)) {
return false;
}
// resolve info hash
std::deque<SharedHandle<BtContext> > btContexts = BtRegistry::getAllBtContext();
// pointing to the position of HASH('req2', SKEY) xor HASH('req3', S)
unsigned char* rbufptr = _rbuf;
SharedHandle<BtContext> btContext = 0;
for(std::deque<SharedHandle<BtContext> >::const_iterator i = btContexts.begin();
i != btContexts.end(); ++i) {
unsigned char md[20];
createReq23Hash(md, (*i)->getInfoHash());
if(memcmp(md, rbufptr, sizeof(md)) == 0) {
_logger->debug("CUID#%d - info hash found: %s", _cuid, (*i)->getInfoHashAsString().c_str());
btContext = *i;
break;
}
}
if(btContext.isNull()) {
throw new DlAbortEx("Unknown info hash.");
}
initCipher(btContext->getInfoHash());
// decrypt VC
rbufptr += 20;
verifyVC(rbufptr);
// decrypt crypto_provide
rbufptr += VC_LENGTH;
{
unsigned char cryptoProvide[4];
_decryptor->decrypt(cryptoProvide, sizeof(cryptoProvide),
rbufptr, sizeof(cryptoProvide));
// TODO choose the crypto type based on the preference.
// For now, choose ARC4.
if(cryptoProvide[3]&CRYPTO_PLAIN_TEXT) {
_logger->debug("CUID#%d - peer provides plaintext.", _cuid);
_negotiatedCryptoType = CRYPTO_PLAIN_TEXT;
}
if(cryptoProvide[3]&CRYPTO_ARC4) {
_logger->debug("CUID#%d - peer provides ARC4.", _cuid);
_negotiatedCryptoType = CRYPTO_ARC4;
}
if(_negotiatedCryptoType == CRYPTO_NONE) {
throw new DlAbortEx("CUID#%d - No supported crypto type provided.", _cuid);
}
}
// decrypt PadC length
rbufptr += CRYPTO_BITFIELD_LENGTH;
_padLength = verifyPadLength(rbufptr, "PadC");
// reset _rbufLength
_rbufLength = 0;
return true;
}
bool MSEHandshake::receiveReceiverIALength()
{
int32_t r = 2-_rbufLength;
assert(r > 0);
if(r > receiveNBytes(r)) {
return false;
}
_iaLength = decodeLength16(_rbuf);
_logger->debug("CUID#%d - len(IA)=%u.", _cuid, _iaLength);
// reset _rbufLength
_rbufLength = 0;
return true;
}
bool MSEHandshake::receiveReceiverIA()
{
int32_t r = _iaLength-_rbufLength;
if(r > receiveNBytes(r)) {
return false;
}
delete [] _ia;
_ia = new unsigned char[_iaLength];
_decryptor->decrypt(_ia, _iaLength, _rbuf, _iaLength);
_logger->debug("CUID#%d - IA received.", _cuid);
// reset _rbufLength
_rbufLength = 0;
return true;
}
void MSEHandshake::sendReceiverStep2()
{
unsigned char buffer[8+4+2+MAX_PAD_LENGTH];
// VC
memcpy(buffer, VC, sizeof(VC));
// crypto_select
unsigned char cryptoSelect[4];
memset(cryptoSelect, 0, sizeof(cryptoSelect));
cryptoSelect[3] = _negotiatedCryptoType;
memcpy(buffer+8, cryptoSelect, sizeof(cryptoSelect));
// len(padD)
uint16_t padDLength = SimpleRandomizer::getInstance()->getRandomNumber(MAX_PAD_LENGTH+1);
{
uint16_t padDLengthBE = htons(padDLength);
memcpy(buffer+8+4, &padDLengthBE, sizeof(padDLengthBE));
}
// padD, all zeroed
memset(buffer+8+4+2, 0, padDLength);
encryptAndSendData(buffer, 8+4+2+padDLength);
}
uint16_t MSEHandshake::verifyPadLength(const unsigned char* padlenbuf, const std::string& padName)
{
_logger->debug("CUID#%d - Veryfying Pad length for %s", _cuid, padName.c_str());
uint16_t padLength = decodeLength16(padlenbuf);
_logger->debug("CUID#%d - len(%s)=%u", _cuid, padName.c_str(), padLength);
if(padLength > 512) {
throw new DlAbortEx("Too large %s length: %u", padName.c_str(), padLength);
}
return padLength;
}
void MSEHandshake::verifyVC(const unsigned char* vcbuf)
{
_logger->debug("CUID#%d - Veryfying VC.", _cuid);
unsigned char vc[VC_LENGTH];
_decryptor->decrypt(vc, sizeof(vc), vcbuf, sizeof(vc));
if(memcmp(VC, vc, sizeof(VC)) != 0) {
throw new DlAbortEx("Invalid VC: %s", Util::toHex(vc, VC_LENGTH).c_str());
}
}
void MSEHandshake::verifyReq1Hash(const unsigned char* req1buf)
{
_logger->debug("CUID#%d - Verifying req hash.", _cuid);
unsigned char md[20];
createReq1Hash(md);
if(memcmp(md, req1buf, sizeof(md)) != 0) {
throw new DlAbortEx("Invalid req1 hash found.");
}
}
ssize_t MSEHandshake::receiveNBytes(size_t bytes)
{
int32_t r = bytes;
if(r > 0) {
if(!_socket->isReadable(0)) {
return 0;
}
_socket->readData(_rbuf+_rbufLength, r);
if(r == 0) {
throw new DlAbortEx(EX_EOF_FROM_PEER);
}
_rbufLength += r;
}
return r;
}
const unsigned char* MSEHandshake::getIA() const
{
return _ia;
}
size_t MSEHandshake::getIALength() const
{
return _iaLength;
}
const unsigned char* MSEHandshake::getInfoHash() const
{
return _infoHash;
}
MSEHandshake::CRYPTO_TYPE MSEHandshake::getNegotiatedCryptoType() const
{
return _negotiatedCryptoType;
}
SharedHandle<ARC4Encryptor> MSEHandshake::getEncryptor() const
{
return _encryptor;
}
SharedHandle<ARC4Decryptor> MSEHandshake::getDecryptor() const
{
return _decryptor;
}
} // namespace aria2

179
src/MSEHandshake.h Normal file
View File

@ -0,0 +1,179 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#ifndef _D_MSE_HANDSHAKE_H_
#define _D_MSE_HANDSHAKE_H_
#include "common.h"
#include "SharedHandle.h"
#include "BtConstants.h"
namespace aria2 {
class Option;
class Logger;
class SocketCore;
class DHKeyExchange;
class ARC4Encryptor;
class ARC4Decryptor;
class MSEHandshake {
public:
enum HANDSHAKE_TYPE {
HANDSHAKE_NOT_YET = 0,
HANDSHAKE_LEGACY,
HANDSHAKE_ENCRYPTED
};
enum CRYPTO_TYPE {
CRYPTO_NONE = 0,
CRYPTO_PLAIN_TEXT = 0x01,
CRYPTO_ARC4 = 0x02
};
private:
static const size_t PRIME_BITS = 768;
static const size_t KEY_LENGTH = (PRIME_BITS+7)/8;
static const size_t MAX_PAD_LENGTH = 512;
static const size_t VC_LENGTH = 8;
static const size_t CRYPTO_BITFIELD_LENGTH = 4;
static const size_t MAX_BUFFER_LENGTH = 6*1024;
int32_t _cuid;
SharedHandle<SocketCore> _socket;
const Option* _option;
const Logger* _logger;
unsigned char _rbuf[MAX_BUFFER_LENGTH];
size_t _rbufLength;
CRYPTO_TYPE _negotiatedCryptoType;
DHKeyExchange* _dh;
SharedHandle<ARC4Encryptor> _encryptor;
SharedHandle<ARC4Decryptor> _decryptor;
unsigned char _infoHash[INFO_HASH_LENGTH];
unsigned char _secret[KEY_LENGTH];
bool _initiator;
unsigned char _initiatorVCMarker[VC_LENGTH];
size_t _markerIndex;
uint16_t _padLength;
uint16_t _iaLength;
unsigned char* _ia;
static const unsigned char* PRIME;
static const unsigned char* GENERATOR;
static const unsigned char VC[VC_LENGTH];
ssize_t readDataAndDecrypt(unsigned char* data, size_t length);
void encryptAndSendData(const unsigned char* data, size_t length);
void createReq1Hash(unsigned char* md) const;
void createReq23Hash(unsigned char* md, const unsigned char* infoHash) const;
uint16_t decodeLength16(const unsigned char* buffer);
uint16_t decodeLength16(const char* buffer)
{
return decodeLength16(reinterpret_cast<const unsigned char*>(buffer));
}
uint16_t verifyPadLength(const unsigned char* padlenbuf,
const std::string& padName);
void verifyVC(const unsigned char* vcbuf);
void verifyReq1Hash(const unsigned char* req1buf);
ssize_t receiveNBytes(size_t bytes);
public:
MSEHandshake(int32_t cuid, const SharedHandle<SocketCore>& socket,
const Option* op);
~MSEHandshake();
HANDSHAKE_TYPE identifyHandshakeType();
void initEncryptionFacility(bool initiator);
void sendPublicKey();
bool receivePublicKey();
void initCipher(const unsigned char* infoHash);
void sendInitiatorStep2();
bool findInitiatorVCMarker();
bool receiveInitiatorCryptoSelectAndPadDLength();
bool receivePad();
bool findReceiverHashMarker();
bool receiveReceiverHashAndPadCLength();
bool receiveReceiverIALength();
bool receiveReceiverIA();
void sendReceiverStep2();
// returns plain text IA
const unsigned char* getIA() const;
size_t getIALength() const;
const unsigned char* getInfoHash() const;
CRYPTO_TYPE getNegotiatedCryptoType() const;
SharedHandle<ARC4Encryptor> getEncryptor() const;
SharedHandle<ARC4Decryptor> getDecryptor() const;
};
} // namespace aria2
#endif // _D_MSE_HANDSHAKE_H_

View File

@ -310,7 +310,10 @@ SRCS += MetaEntry.h\
DHTRoutingTableSerializer.cc\
DHTRoutingTableDeserializer.cc\
DHTAutoSaveCommand.cc\
DHTRegistry.cc
DHTRegistry.cc\
InitiatorMSEHandshakeCommand.cc\
ReceiverMSEHandshakeCommand.cc\
MSEHandshake.cc
endif # ENABLE_BITTORRENT
if ENABLE_METALINK

View File

@ -188,7 +188,10 @@ bin_PROGRAMS = aria2c$(EXEEXT)
@ENABLE_BITTORRENT_TRUE@ DHTRoutingTableSerializer.cc\
@ENABLE_BITTORRENT_TRUE@ DHTRoutingTableDeserializer.cc\
@ENABLE_BITTORRENT_TRUE@ DHTAutoSaveCommand.cc\
@ENABLE_BITTORRENT_TRUE@ DHTRegistry.cc
@ENABLE_BITTORRENT_TRUE@ DHTRegistry.cc\
@ENABLE_BITTORRENT_TRUE@ InitiatorMSEHandshakeCommand.cc\
@ENABLE_BITTORRENT_TRUE@ ReceiverMSEHandshakeCommand.cc\
@ENABLE_BITTORRENT_TRUE@ MSEHandshake.cc
@ENABLE_METALINK_TRUE@am__append_3 = Metalinker.cc Metalinker.h\
@ENABLE_METALINK_TRUE@ MetalinkEntry.cc MetalinkEntry.h\
@ -440,17 +443,18 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
DHTBucketRefreshCommand.cc DHTPeerAnnounceCommand.cc \
DHTReplaceNodeTask.cc DHTEntryPointNameResolveCommand.cc \
DHTRoutingTableSerializer.cc DHTRoutingTableDeserializer.cc \
DHTAutoSaveCommand.cc DHTRegistry.cc Metalinker.cc \
Metalinker.h MetalinkEntry.cc MetalinkEntry.h \
MetalinkResource.cc MetalinkResource.h MetalinkProcessor.h \
MetalinkProcessorFactory.cc MetalinkParserController.cc \
MetalinkParserStateMachine.cc InitialMetalinkParserState.cc \
MetalinkMetalinkParserState.cc FilesMetalinkParserState.cc \
FileMetalinkParserState.cc SizeMetalinkParserState.cc \
VersionMetalinkParserState.cc LanguageMetalinkParserState.cc \
OSMetalinkParserState.cc VerificationMetalinkParserState.cc \
HashMetalinkParserState.cc PiecesMetalinkParserState.cc \
PieceHashMetalinkParserState.cc \
DHTAutoSaveCommand.cc DHTRegistry.cc \
InitiatorMSEHandshakeCommand.cc ReceiverMSEHandshakeCommand.cc \
MSEHandshake.cc Metalinker.cc Metalinker.h MetalinkEntry.cc \
MetalinkEntry.h MetalinkResource.cc MetalinkResource.h \
MetalinkProcessor.h MetalinkProcessorFactory.cc \
MetalinkParserController.cc MetalinkParserStateMachine.cc \
InitialMetalinkParserState.cc MetalinkMetalinkParserState.cc \
FilesMetalinkParserState.cc FileMetalinkParserState.cc \
SizeMetalinkParserState.cc VersionMetalinkParserState.cc \
LanguageMetalinkParserState.cc OSMetalinkParserState.cc \
VerificationMetalinkParserState.cc HashMetalinkParserState.cc \
PiecesMetalinkParserState.cc PieceHashMetalinkParserState.cc \
ResourcesMetalinkParserState.cc URLMetalinkParserState.cc \
FinMetalinkParserState.cc SkipTagMetalinkParserState.cc \
Metalink2RequestGroup.cc Metalink2RequestGroup.h \
@ -571,7 +575,10 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
@ENABLE_BITTORRENT_TRUE@ DHTRoutingTableSerializer.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ DHTRoutingTableDeserializer.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ DHTAutoSaveCommand.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ DHTRegistry.$(OBJEXT)
@ENABLE_BITTORRENT_TRUE@ DHTRegistry.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ InitiatorMSEHandshakeCommand.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ ReceiverMSEHandshakeCommand.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ MSEHandshake.$(OBJEXT)
@ENABLE_METALINK_TRUE@am__objects_3 = Metalinker.$(OBJEXT) \
@ENABLE_METALINK_TRUE@ MetalinkEntry.$(OBJEXT) \
@ENABLE_METALINK_TRUE@ MetalinkResource.$(OBJEXT) \
@ -1267,11 +1274,13 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpResponseCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/InitialMetalinkParserState.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/InitiateConnectionCommandFactory.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/InitiatorMSEHandshakeCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IteratableChecksumValidator.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IteratableChunkChecksumValidator.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LanguageMetalinkParserState.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/List.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LogFactory.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MSEHandshake.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MemoryBufferPreDownloadHandler.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MessageDigestHelper.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MetaFileUtil.Po@am__quote@
@ -1315,6 +1324,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PiecesMetalinkParserState.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Platform.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RealtimeCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ReceiverMSEHandshakeCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Request.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RequestGroup.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RequestGroupAware.Po@am__quote@

View File

@ -106,10 +106,6 @@ bool PeerAbstractCommand::prepareForNextPeer(int32_t wait) {
return true;
}
bool PeerAbstractCommand::prepareForRetry(int32_t wait) {
return true;
}
void PeerAbstractCommand::disableReadCheckSocket() {
if(checkSocketIsReadable) {
e->deleteSocketForReadCheck(readCheckTarget, this);

View File

@ -57,7 +57,6 @@ protected:
void setTimeout(int32_t timeout) { this->timeout = timeout; }
virtual bool prepareForNextPeer(int32_t wait);
virtual bool prepareForRetry(int32_t wait);
virtual void onAbort(Exception* ex) {};
virtual bool exitBeforeExecute() = 0;
virtual bool executeInternal() = 0;

View File

@ -40,7 +40,11 @@
#include "BtHandshakeMessage.h"
#include "Socket.h"
#include "a2netcompat.h"
#include "ARC4Encryptor.h"
#include "ARC4Decryptor.h"
#include <cstring>
#include <cassert>
#include <algorithm>
namespace aria2 {
@ -53,7 +57,10 @@ PeerConnection::PeerConnection(int32_t cuid,
logger(LogFactory::getInstance()),
resbufLength(0),
currentPayloadLength(0),
lenbufLength(0)
lenbufLength(0),
_encryptionEnabled(false),
_encryptor(0),
_decryptor(0)
{}
PeerConnection::~PeerConnection() {}
@ -62,7 +69,7 @@ int32_t PeerConnection::sendMessage(const unsigned char* data, int32_t dataLengt
int32_t writtenLength = 0;
if(socket->isWritable(0)) {
// TODO fix this
socket->writeData((const char*)data, dataLength);
sendData(data, dataLength, _encryptionEnabled);
writtenLength += dataLength;
}
return writtenLength;
@ -76,7 +83,7 @@ bool PeerConnection::receiveMessage(unsigned char* data, int32_t& dataLength) {
// read payload size, 32bit unsigned integer
int32_t remaining = 4-lenbufLength;
int32_t temp = remaining;
socket->readData(lenbuf+lenbufLength, remaining);
readData(lenbuf+lenbufLength, remaining, _encryptionEnabled);
if(remaining == 0) {
// we got EOF
logger->debug("CUID#%d - In PeerConnection::receiveMessage(), remain=%d",
@ -101,7 +108,7 @@ bool PeerConnection::receiveMessage(unsigned char* data, int32_t& dataLength) {
int32_t remaining = currentPayloadLength-resbufLength;
int32_t temp = remaining;
if(remaining > 0) {
socket->readData(resbuf+resbufLength, remaining);
readData(resbuf+resbufLength, remaining, _encryptionEnabled);
if(remaining == 0) {
// we got EOF
logger->debug("CUID#%d - In PeerConnection::receiveMessage(), payloadlen=%d, remaining=%d",
@ -132,7 +139,7 @@ bool PeerConnection::receiveHandshake(unsigned char* data, int32_t& dataLength,
bool retval = true;
if(remaining > 0) {
int32_t temp = remaining;
socket->readData(resbuf+resbufLength, remaining);
readData(resbuf+resbufLength, remaining, _encryptionEnabled);
if(remaining == 0) {
// we got EOF
logger->debug("CUID#%d - In PeerConnection::receiveHandshake(), remain=%d",
@ -153,4 +160,51 @@ bool PeerConnection::receiveHandshake(unsigned char* data, int32_t& dataLength,
return retval;
}
void PeerConnection::readData(char* data, int32_t& length, bool encryption)
{
if(encryption) {
unsigned char* cdata = reinterpret_cast<unsigned char*>(data);
unsigned char temp[MAX_PAYLOAD_LEN];
assert(MAX_PAYLOAD_LEN >= length);
socket->readData(temp, length);
_decryptor->decrypt(cdata, length, temp, length);
} else {
socket->readData(data, length);
}
}
void PeerConnection::sendData(const unsigned char* data, size_t length, bool encryption)
{
if(encryption) {
unsigned char temp[4096];
const unsigned char* dptr = data;
size_t r = length;
while(r > 0) {
size_t s = std::min(r, sizeof(temp));
_encryptor->encrypt(temp, s, dptr, s);
socket->writeData(temp, s);
dptr += s;
r -= s;
}
} else {
socket->writeData(data, length);
}
}
void PeerConnection::enableEncryption(const SharedHandle<ARC4Encryptor>& encryptor,
const SharedHandle<ARC4Decryptor>& decryptor)
{
_encryptor = encryptor;
_decryptor = decryptor;
_encryptionEnabled = true;
}
void PeerConnection::presetBuffer(const unsigned char* data, size_t length)
{
size_t nwrite = std::min((size_t)MAX_PAYLOAD_LEN, length);
memcpy(resbuf, data, nwrite);
resbufLength = length;
}
} // namespace aria2

View File

@ -43,6 +43,8 @@ namespace aria2 {
class Option;
class Logger;
class SocketCore;
class ARC4Encryptor;
class ARC4Decryptor;
// we assume maximum length of incoming message is "piece" message with 16KB
// data. Messages beyond that size are dropped.
@ -61,6 +63,14 @@ private:
char lenbuf[4];
int32_t lenbufLength;
bool _encryptionEnabled;
SharedHandle<ARC4Encryptor> _encryptor;
SharedHandle<ARC4Decryptor> _decryptor;
void readData(char* data, int32_t& length, bool encryption);
void sendData(const unsigned char* data, size_t length, bool encryption);
public:
PeerConnection(int32_t cuid, const SharedHandle<SocketCore>& socket, const Option* op);
@ -78,6 +88,11 @@ public:
* is assigned to 'length'.
*/
bool receiveHandshake(unsigned char* data, int32_t& dataLength, bool peek = false);
void enableEncryption(const SharedHandle<ARC4Encryptor>& encryptor,
const SharedHandle<ARC4Decryptor>& decryptor);
void presetBuffer(const unsigned char* data, size_t length);
};
typedef SharedHandle<PeerConnection> PeerConnectionHandle;

View File

@ -33,8 +33,9 @@
*/
/* copyright --> */
#include "PeerInitiateConnectionCommand.h"
#include "DownloadEngine.h"
#include "InitiatorMSEHandshakeCommand.h"
#include "PeerInteractionCommand.h"
#include "DownloadEngine.h"
#include "DlAbortEx.h"
#include "message.h"
#include "prefs.h"
@ -56,10 +57,12 @@ PeerInitiateConnectionCommand::PeerInitiateConnectionCommand(int cuid,
RequestGroup* requestGroup,
const PeerHandle& peer,
DownloadEngine* e,
const BtContextHandle& btContext)
const BtContextHandle& btContext,
bool mseHandshakeEnabled)
:PeerAbstractCommand(cuid, peer, e),
BtContextAwareCommand(btContext),
RequestGroupAware(requestGroup)
RequestGroupAware(requestGroup),
_mseHandshakeEnabled(mseHandshakeEnabled)
{
btRuntime->increaseConnections();
}
@ -70,19 +73,19 @@ PeerInitiateConnectionCommand::~PeerInitiateConnectionCommand()
}
bool PeerInitiateConnectionCommand::executeInternal() {
Command* command;
logger->info(MSG_CONNECTING_TO_SERVER, cuid, peer->ipaddr.c_str(),
peer->port);
socket->establishConnection(peer->ipaddr, peer->port);
command =
new PeerInteractionCommand(cuid,
_requestGroup,
peer,
e,
btContext,
socket,
PeerInteractionCommand::INITIATOR_SEND_HANDSHAKE);
Command* command;
if(_mseHandshakeEnabled) {
command =
new InitiatorMSEHandshakeCommand(cuid, _requestGroup, peer, e, btContext,
socket);
} else {
command =
new PeerInteractionCommand(cuid, _requestGroup, peer, e, btContext, socket,
PeerInteractionCommand::INITIATOR_SEND_HANDSHAKE);
}
e->commands.push_back(command);
return true;
}
@ -92,28 +95,14 @@ bool PeerInitiateConnectionCommand::prepareForNextPeer(int wait) {
if(peerStorage->isPeerAvailable() && btRuntime->lessThanEqMinPeer()) {
PeerHandle peer = peerStorage->getUnusedPeer();
peer->usedBy(CUIDCounterSingletonHolder::instance()->newID());
PeerInitiateConnectionCommand* command =
new PeerInitiateConnectionCommand(peer->usedBy(),
_requestGroup,
peer,
e,
Command* command =
new PeerInitiateConnectionCommand(peer->usedBy(), _requestGroup, peer, e,
btContext);
e->commands.push_back(command);
}
return true;
}
bool PeerInitiateConnectionCommand::prepareForRetry(int wait) {
PeerInitiateConnectionCommand* command =
new PeerInitiateConnectionCommand(cuid,
_requestGroup,
peer,
e,
btContext);
e->commands.push_back(command);
return true;
}
void PeerInitiateConnectionCommand::onAbort(Exception* ex) {
peerStorage->returnPeer(peer);
}

View File

@ -45,9 +45,10 @@ class PeerInitiateConnectionCommand : public PeerAbstractCommand,
public BtContextAwareCommand,
public RequestGroupAware
{
private:
bool _mseHandshakeEnabled;
protected:
virtual bool executeInternal();
virtual bool prepareForRetry(int wait);
virtual bool prepareForNextPeer(int wait);
virtual void onAbort(Exception* ex);
virtual bool exitBeforeExecute();
@ -57,7 +58,8 @@ public:
RequestGroup* requestGroup,
const SharedHandle<Peer>& peer,
DownloadEngine* e,
const SharedHandle<BtContext>& btContext);
const SharedHandle<BtContext>& btContext,
bool mseHandshakeEnabled = true);
virtual ~PeerInitiateConnectionCommand();
};

View File

@ -259,11 +259,6 @@ bool PeerInteractionCommand::prepareForNextPeer(int32_t wait) {
return true;
}
bool PeerInteractionCommand::prepareForRetry(int32_t wait) {
e->commands.push_back(this);
return false;
}
void PeerInteractionCommand::onAbort(Exception* ex) {
btInteractive->cancelAllPiece();
peerStorage->returnPeer(peer);

View File

@ -60,7 +60,6 @@ private:
int32_t maxDownloadSpeedLimit;
protected:
virtual bool executeInternal();
virtual bool prepareForRetry(int32_t wait);
virtual bool prepareForNextPeer(int32_t wait);
virtual void onAbort(Exception* ex);
virtual bool exitBeforeExecute();

View File

@ -39,7 +39,7 @@
#include "RecoverableException.h"
#include "CUIDCounter.h"
#include "message.h"
#include "PeerReceiveHandshakeCommand.h"
#include "ReceiverMSEHandshakeCommand.h"
#include "Logger.h"
#include "Socket.h"
#include <utility>
@ -99,17 +99,19 @@ bool PeerListenCommand::execute() {
if(peerInfo.first == localInfo.first) {
continue;
}
// Since peerSocket may be in non-blocking mode, make it blocking mode
// here.
peerSocket->setBlockingMode();
PeerHandle peer = new Peer(peerInfo.first, 0);
PeerReceiveHandshakeCommand* command =
new PeerReceiveHandshakeCommand(CUIDCounterSingletonHolder::instance()->newID(),
peer, e, peerSocket);
int32_t cuid = CUIDCounterSingletonHolder::instance()->newID();
Command* command =
new ReceiverMSEHandshakeCommand(cuid, peer, e, peerSocket);
e->commands.push_back(command);
logger->debug("Accepted the connection from %s:%u.",
peer->ipaddr.c_str(),
peer->port);
logger->debug("Added CUID#%d to receive Bt handshake.",
command->getCuid());
logger->debug("Added CUID#%d to receive BitTorrent/MSE handshake.", cuid);
} catch(RecoverableException* ex) {
logger->debug(MSG_ACCEPT_FAILURE, ex, cuid);
delete ex;

View File

@ -55,11 +55,16 @@ namespace aria2 {
PeerReceiveHandshakeCommand::PeerReceiveHandshakeCommand(int32_t cuid,
const PeerHandle& peer,
DownloadEngine* e,
const SocketHandle& s):
const SocketHandle& s,
const SharedHandle<PeerConnection>& peerConnection):
PeerAbstractCommand(cuid, peer, e, s),
_peerConnection(new PeerConnection(cuid, s, e->option)),
_peerConnection(peerConnection),
_lowestSpeedLimit(20*1024)
{}
{
if(_peerConnection.isNull()) {
_peerConnection = new PeerConnection(cuid, socket, e->option);
}
}
PeerReceiveHandshakeCommand::~PeerReceiveHandshakeCommand() {}

View File

@ -61,7 +61,8 @@ public:
PeerReceiveHandshakeCommand(int32_t cuid,
const SharedHandle<Peer>& peer,
DownloadEngine* e,
const SharedHandle<SocketCore>& s);
const SharedHandle<SocketCore>& s,
const SharedHandle<PeerConnection>& peerConnection = 0);
virtual ~PeerReceiveHandshakeCommand();

View File

@ -0,0 +1,157 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#include "ReceiverMSEHandshakeCommand.h"
#include "PeerReceiveHandshakeCommand.h"
#include "PeerConnection.h"
#include "DownloadEngine.h"
#include "BtHandshakeMessage.h"
#include "DlAbortEx.h"
#include "Peer.h"
#include "message.h"
#include "Socket.h"
#include "Logger.h"
#include "prefs.h"
#include "Option.h"
#include "MSEHandshake.h"
#include "ARC4Encryptor.h"
#include "ARC4Decryptor.h"
namespace aria2 {
ReceiverMSEHandshakeCommand::ReceiverMSEHandshakeCommand
(int32_t cuid,
const SharedHandle<Peer>& peer,
DownloadEngine* e,
const SharedHandle<SocketCore>& s):
PeerAbstractCommand(cuid, peer, e, s),
_sequence(RECEIVER_IDENTIFY_HANDSHAKE),
_mseHandshake(new MSEHandshake(cuid, s, e->option))
{
setTimeout(e->option->getAsInt(PREF_PEER_CONNECTION_TIMEOUT));
}
ReceiverMSEHandshakeCommand::~ReceiverMSEHandshakeCommand()
{
delete _mseHandshake;
}
bool ReceiverMSEHandshakeCommand::exitBeforeExecute()
{
return e->isHaltRequested();
}
bool ReceiverMSEHandshakeCommand::executeInternal()
{
switch(_sequence) {
case RECEIVER_IDENTIFY_HANDSHAKE: {
MSEHandshake::HANDSHAKE_TYPE type = _mseHandshake->identifyHandshakeType();
switch(type) {
case MSEHandshake::HANDSHAKE_NOT_YET:
break;
case MSEHandshake::HANDSHAKE_ENCRYPTED:
_mseHandshake->initEncryptionFacility(false);
_sequence = RECEIVER_WAIT_KEY;
break;
case MSEHandshake::HANDSHAKE_LEGACY: {
Command* c = new PeerReceiveHandshakeCommand(cuid, peer, e, socket);
e->commands.push_back(c);
return true;
}
default:
throw new DlAbortEx("Not supported handshake type.");
}
break;
}
case RECEIVER_WAIT_KEY: {
if(_mseHandshake->receivePublicKey()) {
_mseHandshake->sendPublicKey();
_sequence = RECEIVER_FIND_HASH_MARKER;
}
break;
}
case RECEIVER_FIND_HASH_MARKER: {
if(_mseHandshake->findReceiverHashMarker()) {
_sequence = RECEIVER_RECEIVE_PAD_C_LENGTH;
}
break;
}
case RECEIVER_RECEIVE_PAD_C_LENGTH: {
if(_mseHandshake->receiveReceiverHashAndPadCLength()) {
_sequence = RECEIVER_RECEIVE_PAD_C;
}
break;
}
case RECEIVER_RECEIVE_PAD_C: {
if(_mseHandshake->receivePad()) {
_sequence = RECEIVER_RECEIVE_IA_LENGTH;
}
break;
}
case RECEIVER_RECEIVE_IA_LENGTH: {
if(_mseHandshake->receiveReceiverIALength()) {
_sequence = RECEIVER_RECEIVE_IA;
}
break;
}
case RECEIVER_RECEIVE_IA: {
if(_mseHandshake->receiveReceiverIA()) {
_mseHandshake->sendReceiverStep2();
SharedHandle<PeerConnection> peerConnection =
new PeerConnection(cuid, socket, e->option);
if(_mseHandshake->getNegotiatedCryptoType() == MSEHandshake::CRYPTO_ARC4) {
peerConnection->enableEncryption(_mseHandshake->getEncryptor(),
_mseHandshake->getDecryptor());
}
if(_mseHandshake->getIALength() > 0) {
peerConnection->presetBuffer(_mseHandshake->getIA(),
_mseHandshake->getIALength());
}
// TODO add _mseHandshake->getInfoHash() to PeerReceiveHandshakeCommand
// as a hint. If this info hash and one in BitTorrent Handshake does not
// match, then drop connection.
Command* c =
new PeerReceiveHandshakeCommand(cuid, peer, e, socket, peerConnection);
e->commands.push_back(c);
return true;
}
break;
}
}
e->commands.push_back(this);
return false;
}
} // namespace aria2

View File

@ -0,0 +1,76 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#ifndef _D_RECEIVER_MSE_HANDSHAKE_COMMAND_H_
#define _D_RECEIVER_MSE_HANDSHAKE_COMMAND_H_
#include "PeerAbstractCommand.h"
namespace aria2 {
class MSEHandshake;
class SocketCore;
class Peer;
class ReceiverMSEHandshakeCommand:public PeerAbstractCommand
{
public:
enum Seq {
RECEIVER_IDENTIFY_HANDSHAKE,
RECEIVER_WAIT_KEY,
RECEIVER_FIND_HASH_MARKER,
RECEIVER_RECEIVE_PAD_C_LENGTH,
RECEIVER_RECEIVE_PAD_C,
RECEIVER_RECEIVE_IA_LENGTH,
RECEIVER_RECEIVE_IA
};
private:
Seq _sequence;
MSEHandshake* _mseHandshake;
protected:
virtual bool executeInternal();
virtual bool exitBeforeExecute();
public:
ReceiverMSEHandshakeCommand(int32_t cuid,
const SharedHandle<Peer>& peer,
DownloadEngine* e,
const SharedHandle<SocketCore>& s);
virtual ~ReceiverMSEHandshakeCommand();
};
} // namespace aria2
#endif // _D_RECEIVER_MSE_HANDSHAKE_COMMAND_H_

View File

@ -180,6 +180,10 @@ public:
{
writeData(msg.c_str(), msg.size());
}
void writeData(const unsigned char* data, int32_t len)
{
writeData(reinterpret_cast<const char*>(data), len);
}
void writeData(const char* data, size_t len, const std::string& host, uint16_t port);
@ -197,6 +201,11 @@ public:
*/
void readData(char* data, int32_t& len);
void readData(unsigned char* data, int32_t& len)
{
readData(reinterpret_cast<char*>(data), len);
}
ssize_t readDataFrom(char* data, size_t len, struct sockaddr* sender,
socklen_t* senderLength);
@ -217,6 +226,11 @@ public:
*/
void peekData(char* data, int32_t& len);
void peekData(unsigned char* data, int32_t& len)
{
peekData(reinterpret_cast<char*>(data), len);
}
/**
* Makes this socket secure.
* If the system has not OpenSSL, then this method do nothing.

51
test/ARC4Test.cc Normal file
View File

@ -0,0 +1,51 @@
#include "ARC4Encryptor.h"
#include "ARC4Decryptor.h"
#include "Exception.h"
#include "Util.h"
#include "DHTUtil.h"
#include <cstring>
#include <cppunit/extensions/HelperMacros.h>
namespace aria2 {
class ARC4Test:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(ARC4Test);
CPPUNIT_TEST(testEncryptDecrypt);
CPPUNIT_TEST_SUITE_END();
public:
void setUp() {}
void tearDown() {}
void testEncryptDecrypt();
};
CPPUNIT_TEST_SUITE_REGISTRATION(ARC4Test);
void ARC4Test::testEncryptDecrypt()
{
ARC4Encryptor enc;
ARC4Decryptor dec;
const size_t LEN = 20;
unsigned char key[LEN];
memset(key, 0, LEN);
DHTUtil::generateRandomData(key, sizeof(key));
enc.init(key, sizeof(key));
dec.init(key, sizeof(key));
unsigned char encrypted[LEN];
unsigned char decrypted[LEN];
enc.encrypt(encrypted, LEN, key, LEN);
dec.decrypt(decrypted, LEN, encrypted, LEN);
CPPUNIT_ASSERT(memcmp(key, decrypted, LEN) == 0);
// once more
enc.encrypt(encrypted, LEN, key, LEN);
dec.decrypt(decrypted, LEN, encrypted, LEN);
CPPUNIT_ASSERT(memcmp(key, decrypted, LEN) == 0);
}
} // namespace aria2

52
test/DHKeyExchangeTest.cc Normal file
View File

@ -0,0 +1,52 @@
#include "DHKeyExchange.h"
#include "Exception.h"
#include "Util.h"
#include <cppunit/extensions/HelperMacros.h>
namespace aria2 {
class DHKeyExchangeTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(DHKeyExchangeTest);
CPPUNIT_TEST(testHandshake);
CPPUNIT_TEST_SUITE_END();
public:
void setUp() {}
void tearDown() {}
void testHandshake();
};
CPPUNIT_TEST_SUITE_REGISTRATION(DHKeyExchangeTest);
void DHKeyExchangeTest::testHandshake()
{
DHKeyExchange dhA;
DHKeyExchange dhB;
const unsigned char* PRIME = reinterpret_cast<const unsigned char*>("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A63A36210000000000090563");
const unsigned char* GENERATOR = reinterpret_cast<const unsigned char*>("2");
dhA.init(PRIME, GENERATOR, 160);
dhB.init(PRIME, GENERATOR, 160);
dhA.generatePublicKey();
dhB.generatePublicKey();
unsigned char publicKeyA[96];
unsigned char publicKeyB[96];
dhA.getPublicKey(publicKeyA, sizeof(publicKeyA));
dhB.getPublicKey(publicKeyB, sizeof(publicKeyB));
unsigned char secretA[96];
unsigned char secretB[96];
dhA.computeSecret(secretA, sizeof(secretA), publicKeyB, sizeof(publicKeyB));
dhB.computeSecret(secretB, sizeof(secretB), publicKeyA, sizeof(publicKeyA));
CPPUNIT_ASSERT(memcmp(secretA, secretB, sizeof(secretA)) == 0);
}
} // namespace aria2

View File

@ -113,35 +113,35 @@ void DefaultBtAnnounceTest::testNoMoreAnnounce()
btAnnounce.setRandomizer(new FixedNumberRandomizer());
btAnnounce.generateKey();
CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=50&no_peer_id=1&port=6989&event=started"), btAnnounce.getAnnounceUrl());
CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=50&no_peer_id=1&port=6989&event=started&supportcrypto=1"), btAnnounce.getAnnounceUrl());
btAnnounce.announceSuccess();
CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=50&no_peer_id=1&port=6989"), btAnnounce.getAnnounceUrl());
CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=50&no_peer_id=1&port=6989&supportcrypto=1"), btAnnounce.getAnnounceUrl());
btAnnounce.announceFailure();
CPPUNIT_ASSERT_EQUAL(std::string("http://backup/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=50&no_peer_id=1&port=6989&event=started"), btAnnounce.getAnnounceUrl());
CPPUNIT_ASSERT_EQUAL(std::string("http://backup/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=50&no_peer_id=1&port=6989&event=started&supportcrypto=1"), btAnnounce.getAnnounceUrl());
btAnnounce.announceSuccess();
_pieceStorage->setAllDownloadFinished(true);
CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=50&no_peer_id=1&port=6989&event=completed"), btAnnounce.getAnnounceUrl());
CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=50&no_peer_id=1&port=6989&event=completed&supportcrypto=1"), btAnnounce.getAnnounceUrl());
btAnnounce.announceSuccess();
CPPUNIT_ASSERT_EQUAL(std::string("http://backup/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=50&no_peer_id=1&port=6989&event=completed"), btAnnounce.getAnnounceUrl());
CPPUNIT_ASSERT_EQUAL(std::string("http://backup/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=50&no_peer_id=1&port=6989&event=completed&supportcrypto=1"), btAnnounce.getAnnounceUrl());
btAnnounce.announceSuccess();
_btRuntime->setHalt(true);
CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=0&no_peer_id=1&port=6989&event=stopped"), btAnnounce.getAnnounceUrl());
CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=0&no_peer_id=1&port=6989&event=stopped&supportcrypto=1"), btAnnounce.getAnnounceUrl());
btAnnounce.announceSuccess();
CPPUNIT_ASSERT_EQUAL(std::string("http://backup/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=0&no_peer_id=1&port=6989&event=stopped"), btAnnounce.getAnnounceUrl());
CPPUNIT_ASSERT_EQUAL(std::string("http://backup/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=0&no_peer_id=1&port=6989&event=stopped&supportcrypto=1"), btAnnounce.getAnnounceUrl());
btAnnounce.announceSuccess();
@ -164,23 +164,23 @@ void DefaultBtAnnounceTest::testGetAnnounceUrl()
btAnnounce.setRandomizer(new FixedNumberRandomizer());
btAnnounce.generateKey();
CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=50&no_peer_id=1&port=6989&event=started"), btAnnounce.getAnnounceUrl());
CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=50&no_peer_id=1&port=6989&event=started&supportcrypto=1"), btAnnounce.getAnnounceUrl());
btAnnounce.announceSuccess();
CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=50&no_peer_id=1&port=6989"), btAnnounce.getAnnounceUrl());
CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=50&no_peer_id=1&port=6989&supportcrypto=1"), btAnnounce.getAnnounceUrl());
btAnnounce.announceSuccess();
_pieceStorage->setAllDownloadFinished(true);
CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=50&no_peer_id=1&port=6989&event=completed"), btAnnounce.getAnnounceUrl());
CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=50&no_peer_id=1&port=6989&event=completed&supportcrypto=1"), btAnnounce.getAnnounceUrl());
btAnnounce.announceSuccess();
_btRuntime->setHalt(true);
CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=0&no_peer_id=1&port=6989&event=stopped"), btAnnounce.getAnnounceUrl());
CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=0&no_peer_id=1&port=6989&event=stopped&supportcrypto=1"), btAnnounce.getAnnounceUrl());
}
void DefaultBtAnnounceTest::testIsAllAnnounceFailed()
@ -206,11 +206,11 @@ void DefaultBtAnnounceTest::testIsAllAnnounceFailed()
btAnnounce.setRandomizer(new FixedNumberRandomizer());
btAnnounce.generateKey();
CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=50&no_peer_id=1&port=6989&event=started"), btAnnounce.getAnnounceUrl());
CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=50&no_peer_id=1&port=6989&event=started&supportcrypto=1"), btAnnounce.getAnnounceUrl());
btAnnounce.announceFailure();
CPPUNIT_ASSERT_EQUAL(std::string("http://backup/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=50&no_peer_id=1&port=6989&event=started"), btAnnounce.getAnnounceUrl());
CPPUNIT_ASSERT_EQUAL(std::string("http://backup/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=50&no_peer_id=1&port=6989&event=started&supportcrypto=1"), btAnnounce.getAnnounceUrl());
btAnnounce.announceFailure();
@ -238,17 +238,17 @@ void DefaultBtAnnounceTest::testURLOrderInStoppedEvent()
btAnnounce.setRandomizer(new FixedNumberRandomizer());
btAnnounce.generateKey();
CPPUNIT_ASSERT_EQUAL(std::string("http://localhost1/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=50&no_peer_id=1&port=6989&event=started"), btAnnounce.getAnnounceUrl());
CPPUNIT_ASSERT_EQUAL(std::string("http://localhost1/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=50&no_peer_id=1&port=6989&event=started&supportcrypto=1"), btAnnounce.getAnnounceUrl());
btAnnounce.announceSuccess();
_btRuntime->setHalt(true);
CPPUNIT_ASSERT_EQUAL(std::string("http://localhost1/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=0&no_peer_id=1&port=6989&event=stopped"), btAnnounce.getAnnounceUrl());
CPPUNIT_ASSERT_EQUAL(std::string("http://localhost1/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=0&no_peer_id=1&port=6989&event=stopped&supportcrypto=1"), btAnnounce.getAnnounceUrl());
btAnnounce.announceFailure();
CPPUNIT_ASSERT_EQUAL(std::string("http://localhost2/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=0&no_peer_id=1&port=6989&event=stopped"), btAnnounce.getAnnounceUrl());
CPPUNIT_ASSERT_EQUAL(std::string("http://localhost2/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=0&no_peer_id=1&port=6989&event=stopped&supportcrypto=1"), btAnnounce.getAnnounceUrl());
btAnnounce.announceSuccess();
}
@ -268,17 +268,17 @@ void DefaultBtAnnounceTest::testURLOrderInCompletedEvent()
btAnnounce.setRandomizer(new FixedNumberRandomizer());
btAnnounce.generateKey();
CPPUNIT_ASSERT_EQUAL(std::string("http://localhost1/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=50&no_peer_id=1&port=6989&event=started"), btAnnounce.getAnnounceUrl());
CPPUNIT_ASSERT_EQUAL(std::string("http://localhost1/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=50&no_peer_id=1&port=6989&event=started&supportcrypto=1"), btAnnounce.getAnnounceUrl());
btAnnounce.announceSuccess();
_pieceStorage->setAllDownloadFinished(true);
CPPUNIT_ASSERT_EQUAL(std::string("http://localhost1/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=50&no_peer_id=1&port=6989&event=completed"), btAnnounce.getAnnounceUrl());
CPPUNIT_ASSERT_EQUAL(std::string("http://localhost1/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=50&no_peer_id=1&port=6989&event=completed&supportcrypto=1"), btAnnounce.getAnnounceUrl());
btAnnounce.announceFailure();
CPPUNIT_ASSERT_EQUAL(std::string("http://localhost2/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=50&no_peer_id=1&port=6989&event=completed"), btAnnounce.getAnnounceUrl());
CPPUNIT_ASSERT_EQUAL(std::string("http://localhost2/announce?info_hash=%01%23Eg%89%ab%cd%ef%01%23Eg%89%ab%cd%ef%01%23Eg&peer_id=%2daria2%2dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=AAAAAAAA&numwant=50&no_peer_id=1&port=6989&event=completed&supportcrypto=1"), btAnnounce.getAnnounceUrl());
btAnnounce.announceSuccess();
}

View File

@ -128,7 +128,9 @@ aria2c_SOURCES += BtAllowedFastMessageTest.cc\
XORCloserTest.cc\
DHTIDCloserTest.cc\
DHTRoutingTableSerializerTest.cc\
DHTRoutingTableDeserializerTest.cc
DHTRoutingTableDeserializerTest.cc\
DHKeyExchangeTest.cc\
ARC4Test.cc
endif # ENABLE_BITTORRENT
if ENABLE_METALINK

View File

@ -113,7 +113,9 @@ check_PROGRAMS = $(am__EXEEXT_1)
@ENABLE_BITTORRENT_TRUE@ XORCloserTest.cc\
@ENABLE_BITTORRENT_TRUE@ DHTIDCloserTest.cc\
@ENABLE_BITTORRENT_TRUE@ DHTRoutingTableSerializerTest.cc\
@ENABLE_BITTORRENT_TRUE@ DHTRoutingTableDeserializerTest.cc
@ENABLE_BITTORRENT_TRUE@ DHTRoutingTableDeserializerTest.cc\
@ENABLE_BITTORRENT_TRUE@ DHKeyExchangeTest.cc\
@ENABLE_BITTORRENT_TRUE@ ARC4Test.cc
@ENABLE_METALINK_TRUE@am__append_3 = MetalinkerTest.cc\
@ENABLE_METALINK_TRUE@ MetalinkEntryTest.cc\
@ -207,8 +209,9 @@ am__aria2c_SOURCES_DIST = AllTest.cc SocketCoreTest.cc \
DHTPeerAnnounceEntryTest.cc DHTPeerAnnounceStorageTest.cc \
DHTTokenTrackerTest.cc XORCloserTest.cc DHTIDCloserTest.cc \
DHTRoutingTableSerializerTest.cc \
DHTRoutingTableDeserializerTest.cc MetalinkerTest.cc \
MetalinkEntryTest.cc Metalink2RequestGroupTest.cc \
DHTRoutingTableDeserializerTest.cc DHKeyExchangeTest.cc \
ARC4Test.cc MetalinkerTest.cc MetalinkEntryTest.cc \
Metalink2RequestGroupTest.cc \
MetalinkPostDownloadHandlerTest.cc MetalinkHelperTest.cc \
MetalinkParserControllerTest.cc MetalinkProcessorTest.cc
@ENABLE_MESSAGE_DIGEST_TRUE@am__objects_1 = \
@ -284,7 +287,9 @@ am__aria2c_SOURCES_DIST = AllTest.cc SocketCoreTest.cc \
@ENABLE_BITTORRENT_TRUE@ XORCloserTest.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ DHTIDCloserTest.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ DHTRoutingTableSerializerTest.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ DHTRoutingTableDeserializerTest.$(OBJEXT)
@ENABLE_BITTORRENT_TRUE@ DHTRoutingTableDeserializerTest.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ DHKeyExchangeTest.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ ARC4Test.$(OBJEXT)
@ENABLE_METALINK_TRUE@am__objects_3 = MetalinkerTest.$(OBJEXT) \
@ENABLE_METALINK_TRUE@ MetalinkEntryTest.$(OBJEXT) \
@ENABLE_METALINK_TRUE@ Metalink2RequestGroupTest.$(OBJEXT) \
@ -619,6 +624,7 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ARC4Test.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AllTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AlphaNumberDecoratorTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AnnounceListTest.Po@am__quote@
@ -653,6 +659,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CookieBoxFactoryTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CookieBoxTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CookieParserTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHKeyExchangeTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTAnnouncePeerMessageTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTAnnouncePeerReplyMessageTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DHTBucketTest.Po@am__quote@