/* */ #include "AuthConfigFactory.h" #include #include "Option.h" #include "AuthConfig.h" #include "Netrc.h" #include "DefaultAuthResolver.h" #include "NetrcAuthResolver.h" #include "prefs.h" #include "Request.h" #include "util.h" namespace aria2 { namespace { const std::string AUTH_DEFAULT_USER("anonymous"); const std::string AUTH_DEFAULT_PASSWD("ARIA2USER@"); } // namespace AuthConfigFactory::AuthConfigFactory() {} AuthConfigFactory::~AuthConfigFactory() {} std::unique_ptr AuthConfigFactory::createAuthConfig (const std::shared_ptr& request, const Option* op) { if(request->getProtocol() == "http" || request->getProtocol() == "https") { if(op->getAsBool(PREF_HTTP_AUTH_CHALLENGE)) { if(!request->getUsername().empty()) { updateBasicCred(make_unique(request->getUsername(), request->getPassword(), request->getHost(), request->getPort(), request->getDir(), true)); return AuthConfig::create(request->getUsername(), request->getPassword()); } auto i = findBasicCred(request->getHost(), request->getPort(), request->getDir()); if(i == std::end(basicCreds_)) { return nullptr; } else { return AuthConfig::create((*i)->user_, (*i)->password_); } } else { if(!request->getUsername().empty()) { return AuthConfig::create(request->getUsername(), request->getPassword()); } else { return createHttpAuthResolver(op)->resolveAuthConfig(request->getHost()); } } } else if(request->getProtocol() == "ftp") { if(!request->getUsername().empty()) { if(request->hasPassword()) { return AuthConfig::create(request->getUsername(), request->getPassword()); } else { if(!op->getAsBool(PREF_NO_NETRC)) { // First, check we have password corresponding to host and // username NetrcAuthResolver authResolver; authResolver.setNetrc(netrc_.get()); auto ac = authResolver.resolveAuthConfig(request->getHost()); if(ac && ac->getUser() == request->getUsername()) { return ac; } } // We don't have password for host and username. Return // password specified by --ftp-passwd return AuthConfig::create(request->getUsername(), op->get(PREF_FTP_PASSWD)); } } else { return createFtpAuthResolver(op)->resolveAuthConfig(request->getHost()); } } else { return nullptr; } } std::unique_ptr AuthConfigFactory::createHttpAuthResolver (const Option* op) const { std::unique_ptr resolver; if(op->getAsBool(PREF_NO_NETRC)) { resolver.reset(new DefaultAuthResolver()); } else { auto authResolver = make_unique(); authResolver->setNetrc(netrc_.get()); authResolver->ignoreDefault(); resolver = std::move(authResolver); } resolver->setUserDefinedCred(op->get(PREF_HTTP_USER), op->get(PREF_HTTP_PASSWD)); return std::move(resolver); } std::unique_ptr AuthConfigFactory::createFtpAuthResolver (const Option* op) const { std::unique_ptr resolver; if(op->getAsBool(PREF_NO_NETRC)) { resolver.reset(new DefaultAuthResolver()); } else { auto authResolver = make_unique(); authResolver->setNetrc(netrc_.get()); resolver = std::move(authResolver); } resolver->setUserDefinedCred(op->get(PREF_FTP_USER), op->get(PREF_FTP_PASSWD)); resolver->setDefaultCred(AUTH_DEFAULT_USER, AUTH_DEFAULT_PASSWD); return std::move(resolver); } void AuthConfigFactory::setNetrc(std::unique_ptr netrc) { netrc_ = std::move(netrc); } void AuthConfigFactory::updateBasicCred(std::unique_ptr basicCred) { auto i = basicCreds_.lower_bound(basicCred); if(i != std::end(basicCreds_) && *i == basicCred) { *(*i) = std::move(*basicCred); } else { basicCreds_.insert(i, std::move(basicCred)); } } bool AuthConfigFactory::activateBasicCred (const std::string& host, uint16_t port, const std::string& path, const Option* op) { auto i = findBasicCred(host, port, path); if(i == std::end(basicCreds_)) { auto authConfig = createHttpAuthResolver(op)->resolveAuthConfig(host); if(!authConfig) { return false; } else { basicCreds_.insert(make_unique(authConfig->getUser(), authConfig->getPassword(), host, port, path, true)); return true; } } else { (*i)->activate(); return true; } } BasicCred::BasicCred (std::string user, std::string password, std::string host, uint16_t port, std::string path, bool activated) : user_(std::move(user)), password_(std::move(password)), host_(std::move(host)), port_(port), path_(std::move(path)), activated_(activated) { if(path_.empty() || path_[path_.size()-1] != '/') { path_ += "/"; } } void BasicCred::activate() { activated_ = true; } bool BasicCred::isActivated() const { return activated_; } bool BasicCred::operator==(const BasicCred& cred) const { return host_ == cred.host_ && port_ == cred.port_ && path_ == cred.path_; } bool BasicCred::operator<(const BasicCred& cred) const { return host_ < cred.host_ || (!(cred.host_ < host_) && (port_ < cred.port_ || (!(cred.port_ < port_) && path_ > cred.path_))); } AuthConfigFactory::BasicCredSet::iterator AuthConfigFactory::findBasicCred (const std::string& host, uint16_t port, const std::string& path) { auto bc = make_unique("", "", host, port, path); auto i = basicCreds_.lower_bound(bc); for(; i != std::end(basicCreds_) && (*i)->host_ == host && (*i)->port_ == port; ++i) { if(util::startsWith(bc->path_, (*i)->path_)) { return i; } } return std::end(basicCreds_); } } // namespace aria2