mirror of https://github.com/aria2/aria2
2010-02-27 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Added MessageDigest::isStronger(). Now aria2 selects stronger hash algorithm in Metalink properly * src/MetalinkParserController.cc * src/MetalinkParserController.h * src/messageDigest.cc * src/messageDigest.h * test/MetalinkProcessorTest.cc * test/metalink4.xmlpull/1/head
parent
e8d091af18
commit
18d7eb5b77
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
|||
2010-02-27 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||
|
||||
Added MessageDigest::isStronger(). Now aria2 selects stronger hash
|
||||
algorithm in Metalink properly
|
||||
* src/MetalinkParserController.cc
|
||||
* src/MetalinkParserController.h
|
||||
* src/messageDigest.cc
|
||||
* src/messageDigest.h
|
||||
* test/MetalinkProcessorTest.cc
|
||||
* test/metalink4.xml
|
||||
|
||||
2010-02-27 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||
|
||||
Replaced null or control characters in file path with '_'. For
|
||||
|
|
|
@ -54,8 +54,6 @@
|
|||
|
||||
namespace aria2 {
|
||||
|
||||
const std::string MetalinkParserController::SHA1("sha1");// Metalink3Spec
|
||||
|
||||
MetalinkParserController::MetalinkParserController():
|
||||
_metalinker(new Metalinker())
|
||||
{}
|
||||
|
@ -293,10 +291,8 @@ void MetalinkParserController::commitChecksumTransaction()
|
|||
return;
|
||||
}
|
||||
if(_tEntry->checksum.isNull() ||
|
||||
// Metalink3Spec
|
||||
(_tEntry->checksum->getAlgo() != MetalinkParserController::SHA1 &&
|
||||
// Metalink4Spec
|
||||
_tEntry->checksum->getAlgo() != MessageDigestContext::SHA1)) {
|
||||
MessageDigestContext::isStronger(_tChecksum->getAlgo(),
|
||||
_tEntry->checksum->getAlgo())) {
|
||||
_tEntry->checksum = _tChecksum;
|
||||
}
|
||||
_tChecksum.reset();
|
||||
|
@ -366,7 +362,8 @@ void MetalinkParserController::commitChunkChecksumTransactionV4()
|
|||
return;
|
||||
}
|
||||
if(_tEntry->chunkChecksum.isNull() ||
|
||||
_tEntry->chunkChecksum->getAlgo() != MessageDigestContext::SHA1) {
|
||||
MessageDigestContext::isStronger(_tChunkChecksumV4->getAlgo(),
|
||||
_tEntry->chunkChecksum->getAlgo())) {
|
||||
std::deque<std::string> checksums(_tempChunkChecksumsV4.begin(),
|
||||
_tempChunkChecksumsV4.end());
|
||||
_tChunkChecksumV4->setChecksums(checksums);
|
||||
|
@ -469,11 +466,14 @@ void MetalinkParserController::commitChunkChecksumTransaction()
|
|||
return;
|
||||
}
|
||||
if(_tEntry->chunkChecksum.isNull() ||
|
||||
_tEntry->chunkChecksum->getAlgo() != MetalinkParserController::SHA1) {
|
||||
std::sort(_tempChunkChecksums.begin(), _tempChunkChecksums.end(), Ascend1st<std::pair<size_t, std::string> >());
|
||||
MessageDigestContext::isStronger(_tChunkChecksum->getAlgo(),
|
||||
_tEntry->chunkChecksum->getAlgo())) {
|
||||
std::sort(_tempChunkChecksums.begin(), _tempChunkChecksums.end(),
|
||||
Ascend1st<std::pair<size_t, std::string> >());
|
||||
std::deque<std::string> checksums;
|
||||
std::transform(_tempChunkChecksums.begin(), _tempChunkChecksums.end(),
|
||||
std::back_inserter(checksums), select2nd<std::pair<size_t, std::string> >());
|
||||
std::back_inserter(checksums),
|
||||
select2nd<std::pair<size_t, std::string> >());
|
||||
_tChunkChecksum->setChecksums(checksums);
|
||||
_tEntry->chunkChecksum = _tChunkChecksum;
|
||||
}
|
||||
|
|
|
@ -81,8 +81,6 @@ private:
|
|||
#endif // ENABLE_MESSAGE_DIGEST
|
||||
|
||||
SharedHandle<Signature> _tSignature;
|
||||
|
||||
static const std::string SHA1;
|
||||
public:
|
||||
MetalinkParserController();
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
/* copyright --> */
|
||||
#include "messageDigest.h"
|
||||
#include "util.h"
|
||||
#include "array_fun.h"
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
|
@ -43,27 +44,55 @@ const std::string MessageDigestContext::SHA256("sha-256");
|
|||
|
||||
const std::string MessageDigestContext::MD5("md-5");
|
||||
|
||||
static MessageDigestContext::DigestAlgoMap::value_type digests[] = {
|
||||
namespace {
|
||||
struct DigestAlgoEntry {
|
||||
MessageDigestContext::DigestAlgo algo;
|
||||
int strength;
|
||||
DigestAlgoEntry(const MessageDigestContext::DigestAlgo& algo, int strength):
|
||||
algo(algo), strength(strength) {}
|
||||
};
|
||||
}
|
||||
|
||||
typedef std::map<std::string, DigestAlgoEntry>
|
||||
DigestAlgoMap;
|
||||
|
||||
static const DigestAlgoMap& getDigestAlgos()
|
||||
{
|
||||
enum AlgoStrength {
|
||||
STRENGTH_MD5 = 0,
|
||||
STRENGTH_SHA_1 = 1,
|
||||
STRENGTH_SHA_256 = 2
|
||||
};
|
||||
static const DigestAlgoMap::value_type digests[] = {
|
||||
#ifdef HAVE_LIBSSL
|
||||
MessageDigestContext::DigestAlgoMap::value_type("md5", EVP_md5()),
|
||||
MessageDigestContext::DigestAlgoMap::value_type("sha-1", EVP_sha1()),
|
||||
MessageDigestContext::DigestAlgoMap::value_type("sha1", EVP_sha1()),
|
||||
DigestAlgoMap::value_type("md5", DigestAlgoEntry(EVP_md5(), STRENGTH_MD5)),
|
||||
DigestAlgoMap::value_type
|
||||
("sha-1", DigestAlgoEntry(EVP_sha1(), STRENGTH_SHA_1)),
|
||||
DigestAlgoMap::value_type
|
||||
("sha1", DigestAlgoEntry(EVP_sha1(), STRENGTH_SHA_1)),
|
||||
# ifdef HAVE_EVP_SHA256
|
||||
MessageDigestContext::DigestAlgoMap::value_type("sha-256", EVP_sha256()),
|
||||
MessageDigestContext::DigestAlgoMap::value_type("sha256", EVP_sha256()),
|
||||
DigestAlgoMap::value_type
|
||||
("sha-256", DigestAlgoEntry(EVP_sha256(), STRENGTH_SHA_256)),
|
||||
DigestAlgoMap::value_type
|
||||
("sha256", DigestAlgoEntry(EVP_sha256(), STRENGTH_SHA_256)),
|
||||
# endif // HAVE_EVP_SHA256
|
||||
#elif HAVE_LIBGCRYPT
|
||||
MessageDigestContext::DigestAlgoMap::value_type("md5", GCRY_MD_MD5),
|
||||
MessageDigestContext::DigestAlgoMap::value_type("sha-1", GCRY_MD_SHA1),
|
||||
MessageDigestContext::DigestAlgoMap::value_type("sha1", GCRY_MD_SHA1),
|
||||
MessageDigestContext::DigestAlgoMap::value_type("sha-256", GCRY_MD_SHA256),
|
||||
MessageDigestContext::DigestAlgoMap::value_type("sha256", GCRY_MD_SHA256),
|
||||
DigestAlgoMap::value_type
|
||||
("md5", DigestAlgoEntry(GCRY_MD_MD5, STRENGTH_MD5)),
|
||||
DigestAlgoMap::value_type
|
||||
("sha-1", DigestAlgoEntry(GCRY_MD_SHA1, STRENGTH_SHA_1)),
|
||||
DigestAlgoMap::value_type
|
||||
("sha1", DigestAlgoEntry(GCRY_MD_SHA1, STRENGTH_SHA_1)),
|
||||
DigestAlgoMap::value_type
|
||||
("sha-256", DigestAlgoEntry(GCRY_MD_SHA256, STRENGTH_SHA_256)),
|
||||
DigestAlgoMap::value_type
|
||||
("sha256", DigestAlgoEntry(GCRY_MD_SHA256, STRENGTH_SHA_256)),
|
||||
#endif // HAVE_LIBGCRYPT
|
||||
};
|
||||
|
||||
MessageDigestContext::DigestAlgoMap
|
||||
MessageDigestContext::digestAlgos(&digests[0],
|
||||
&digests[sizeof(digests)/sizeof(DigestAlgoMap::value_type)]);
|
||||
};
|
||||
static const DigestAlgoMap algomap
|
||||
(&digests[0], &digests[arrayLength(digests)]);
|
||||
return algomap;
|
||||
}
|
||||
|
||||
std::string MessageDigestContext::digestFinal()
|
||||
{
|
||||
|
@ -75,15 +104,52 @@ std::string MessageDigestContext::digestFinal()
|
|||
return rawMDString;
|
||||
}
|
||||
|
||||
bool MessageDigestContext::supports(const std::string& algostring)
|
||||
{
|
||||
const DigestAlgoMap& allAlgos = getDigestAlgos();
|
||||
DigestAlgoMap::const_iterator itr = allAlgos.find(algostring);
|
||||
if(itr == allAlgos.end()) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
MessageDigestContext::DigestAlgo
|
||||
MessageDigestContext::getDigestAlgo(const std::string& algostring)
|
||||
{
|
||||
const DigestAlgoMap& allAlgos = getDigestAlgos();
|
||||
DigestAlgoMap::const_iterator itr = allAlgos.find(algostring);
|
||||
if(itr == allAlgos.end()) {
|
||||
throw DL_ABORT_EX
|
||||
(StringFormat("Digest algorithm %s is not supported.",
|
||||
algostring.c_str()).str());
|
||||
}
|
||||
return (*itr).second.algo;
|
||||
}
|
||||
|
||||
std::string MessageDigestContext::getSupportedAlgoString()
|
||||
{
|
||||
const DigestAlgoMap& allAlgos = getDigestAlgos();
|
||||
std::string algos;
|
||||
for(DigestAlgoMap::const_iterator itr = digestAlgos.begin();
|
||||
itr != digestAlgos.end(); ++itr) {
|
||||
for(DigestAlgoMap::const_iterator itr = allAlgos.begin();
|
||||
itr != allAlgos.end(); ++itr) {
|
||||
algos += (*itr).first;
|
||||
algos += ", ";
|
||||
}
|
||||
return util::trim(algos, ", ");
|
||||
}
|
||||
|
||||
bool MessageDigestContext::isStronger
|
||||
(const std::string& lhs, const std::string& rhs)
|
||||
{
|
||||
const DigestAlgoMap& allAlgos = getDigestAlgos();
|
||||
DigestAlgoMap::const_iterator lhsitr = allAlgos.find(lhs);
|
||||
DigestAlgoMap::const_iterator rhsitr = allAlgos.find(rhs);
|
||||
if(lhsitr == allAlgos.end() || rhsitr == allAlgos.end()) {
|
||||
return false;
|
||||
}
|
||||
return (*lhsitr).second.strength > (*rhsitr).second.strength;
|
||||
}
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -62,7 +62,6 @@ public:
|
|||
#ifdef HAVE_LIBGCRYPT
|
||||
typedef int DigestAlgo;
|
||||
#endif // HAVE_LIBGCRYPT
|
||||
typedef std::map<std::string, MessageDigestContext::DigestAlgo> DigestAlgoMap;
|
||||
|
||||
static const std::string SHA1;
|
||||
|
||||
|
@ -77,8 +76,6 @@ private:
|
|||
gcry_md_hd_t ctx;
|
||||
#endif // HAVE_LIBGCRYPT
|
||||
DigestAlgo algo;
|
||||
|
||||
static DigestAlgoMap digestAlgos;
|
||||
public:
|
||||
MessageDigestContext():algo(getDigestAlgo(MessageDigestContext::SHA1))
|
||||
{}
|
||||
|
@ -93,26 +90,9 @@ public:
|
|||
algo = getDigestAlgo(algostring);
|
||||
}
|
||||
|
||||
static bool supports(const std::string& algostring)
|
||||
{
|
||||
DigestAlgoMap::const_iterator itr = digestAlgos.find(algostring);
|
||||
if(itr == digestAlgos.end()) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
static bool supports(const std::string& algostring);
|
||||
|
||||
static DigestAlgo getDigestAlgo(const std::string& algostring)
|
||||
{
|
||||
DigestAlgoMap::const_iterator itr = digestAlgos.find(algostring);
|
||||
if(itr == digestAlgos.end()) {
|
||||
throw DL_ABORT_EX
|
||||
(StringFormat("Digest algorithm %s is not supported.",
|
||||
algostring.c_str()).str());
|
||||
}
|
||||
return (*itr).second;
|
||||
}
|
||||
static DigestAlgo getDigestAlgo(const std::string& algostring);
|
||||
|
||||
static std::string getSupportedAlgoString();
|
||||
|
||||
|
@ -121,6 +101,11 @@ public:
|
|||
return digestLength(getDigestAlgo(algostring));
|
||||
}
|
||||
|
||||
// Returns true if hash algorithm specified by lhs is stronger than
|
||||
// the one specified by rhs. If either lhs or rhs is not supported
|
||||
// or both are not supported, returns false.
|
||||
static bool isStronger(const std::string& lhs, const std::string& rhs);
|
||||
|
||||
std::string digestFinal();
|
||||
|
||||
#if defined(HAVE_OLD_LIBSSL)
|
||||
|
|
|
@ -96,7 +96,7 @@ void MetalinkProcessorTest::testParseFileV4()
|
|||
CPPUNIT_ASSERT(!e->checksum.isNull());
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("sha-1"), e->checksum->getAlgo());
|
||||
CPPUNIT_ASSERT(!e->chunkChecksum.isNull());
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("sha-1"), e->chunkChecksum->getAlgo());
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("sha-256"), e->chunkChecksum->getAlgo());
|
||||
CPPUNIT_ASSERT_EQUAL((size_t)262144, e->chunkChecksum->getChecksumLength());
|
||||
CPPUNIT_ASSERT_EQUAL((size_t)3, e->chunkChecksum->countChecksum());
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("metalinkhash1"),
|
||||
|
|
|
@ -7,12 +7,18 @@
|
|||
<version>1.0</version>
|
||||
<language>en</language>
|
||||
<description>A description of the example file for download.</description>
|
||||
<hash type="md5">80bc95fd391772fa61c91ed68567f0980bb45fd9</hash>
|
||||
<hash type="sha-1">80bc95fd391772fa61c91ed68567f0980bb45fd9</hash>
|
||||
<pieces length="262144" type="sha-1">
|
||||
<hash>metalinkhash1</hash>
|
||||
<hash>metalinkhash2</hash>
|
||||
<hash>metalinkhash3</hash>
|
||||
</pieces>
|
||||
<pieces length="262144" type="sha-256">
|
||||
<hash>metalinkhash1</hash>
|
||||
<hash>metalinkhash2</hash>
|
||||
<hash>metalinkhash3</hash>
|
||||
</pieces>
|
||||
<url location="de" priority="1">ftp://ftp.example.com/example.ext</url>
|
||||
<url location="fr" priority="1">http://example.com/example.ext</url>
|
||||
<metaurl mediatype="torrent" priority="2">http://example.com/example.ext.torrent</metaurl>
|
||||
|
|
Loading…
Reference in New Issue