/* */ #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 { const std::string AuthConfigFactory::ANONYMOUS("anonymous"); const std::string AuthConfigFactory::ARIA2USER_AT("ARIA2USER@"); AuthConfigFactory::AuthConfigFactory() {} AuthConfigFactory::~AuthConfigFactory() {} AuthConfigHandle AuthConfigFactory::createAuthConfig (const SharedHandle& request, const Option* op) { if(request->getProtocol() == Request::PROTO_HTTP || request->getProtocol() == Request::PROTO_HTTPS) { if(op->getAsBool(PREF_HTTP_AUTH_CHALLENGE)) { if(!request->getUsername().empty()) { SharedHandle bc(new BasicCred(request->getUsername(), request->getPassword(), request->getHost(), request->getPort(), request->getDir(), true)); updateBasicCred(bc); return createAuthConfig(request->getUsername(), request->getPassword()); } BasicCredSet::iterator i = findBasicCred(request->getHost(), request->getPort(), request->getDir()); if(i == basicCreds_.end()) { return SharedHandle(); } else { return createAuthConfig((*i)->user_, (*i)->password_); } } else { if(!request->getUsername().empty()) { return createAuthConfig(request->getUsername(), request->getPassword()); } else { return createHttpAuthResolver(op)->resolveAuthConfig(request->getHost()); } } } else if(request->getProtocol() == Request::PROTO_FTP) { if(!request->getUsername().empty()) { if(request->hasPassword()) { return createAuthConfig(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_); SharedHandle 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 createAuthConfig(request->getUsername(), op->get(PREF_FTP_PASSWD)); } } else { return createFtpAuthResolver(op)->resolveAuthConfig(request->getHost()); } } else { return SharedHandle(); } } AuthConfigHandle AuthConfigFactory::createAuthConfig(const std::string& user, const std::string& password) const { SharedHandle ac; if(!user.empty()) { ac.reset(new AuthConfig(user, password)); } return ac; } AuthResolverHandle AuthConfigFactory::createHttpAuthResolver (const Option* op) const { AbstractAuthResolverHandle resolver; if(op->getAsBool(PREF_NO_NETRC)) { resolver.reset(new DefaultAuthResolver()); } else { NetrcAuthResolverHandle authResolver(new NetrcAuthResolver()); authResolver->setNetrc(netrc_); authResolver->ignoreDefault(); resolver = authResolver; } resolver->setUserDefinedAuthConfig (createAuthConfig(op->get(PREF_HTTP_USER), op->get(PREF_HTTP_PASSWD))); return resolver; } AuthResolverHandle AuthConfigFactory::createFtpAuthResolver (const Option* op) const { AbstractAuthResolverHandle resolver; if(op->getAsBool(PREF_NO_NETRC)) { resolver.reset(new DefaultAuthResolver()); } else { NetrcAuthResolverHandle authResolver(new NetrcAuthResolver()); authResolver->setNetrc(netrc_); resolver = authResolver; } resolver->setUserDefinedAuthConfig (createAuthConfig(op->get(PREF_FTP_USER), op->get(PREF_FTP_PASSWD))); SharedHandle defaultAuthConfig (new AuthConfig(AuthConfigFactory::ANONYMOUS, AuthConfigFactory::ARIA2USER_AT)); resolver->setDefaultAuthConfig(defaultAuthConfig); return resolver; } void AuthConfigFactory::setNetrc(const SharedHandle& netrc) { netrc_ = netrc; } void AuthConfigFactory::updateBasicCred (const SharedHandle& basicCred) { BasicCredSet::iterator i = basicCreds_.lower_bound(basicCred); if(i != basicCreds_.end() && *(*i) == *basicCred) { *(*i) = *basicCred; } else { basicCreds_.insert(i, basicCred); } } bool AuthConfigFactory::activateBasicCred (const std::string& host, uint16_t port, const std::string& path, const Option* op) { BasicCredSet::iterator i = findBasicCred(host, port, path); if(i == basicCreds_.end()) { SharedHandle authConfig = createHttpAuthResolver(op)->resolveAuthConfig(host); if(!authConfig) { return false; } else { SharedHandle bc (new BasicCred(authConfig->getUser(), authConfig->getPassword(), host, port, path, true)); basicCreds_.insert(bc); return true; } } else { (*i)->activate(); return true; } } AuthConfigFactory::BasicCred::BasicCred (const std::string& user, const std::string& password, const std::string& host, uint16_t port, const std::string& path, bool activated): user_(user), password_(password), host_(host), port_(port), path_(path), activated_(activated) { if(path_.empty() || path_[path_.size()-1] != '/') { path_ += "/"; } } void AuthConfigFactory::BasicCred::activate() { activated_ = true; } bool AuthConfigFactory::BasicCred::isActivated() const { return activated_; } bool AuthConfigFactory::BasicCred::operator==(const BasicCred& cred) const { return host_ == cred.host_ && port_ == cred.port_ && path_ == cred.path_; } bool AuthConfigFactory::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) { SharedHandle bc(new BasicCred("", "", host, port, path)); BasicCredSet::iterator i = basicCreds_.lower_bound(bc); for(; i != basicCreds_.end() && (*i)->host_ == host && (*i)->port_ == port; ++i) { if(util::startsWith(bc->path_, (*i)->path_)) { return i; } } return basicCreds_.end(); } } // namespace aria2