/* */ #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()) { updateBasicCred(BasicCred(request->getUsername(), request->getPassword(), request->getHost(), request->getDir(), true)); return createAuthConfig(request->getUsername(), request->getPassword()); } std::deque::const_iterator i = findBasicCred(request->getHost(), 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.isNull() && 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 BasicCred& basicCred) { std::deque::iterator i = std::lower_bound(_basicCreds.begin(), _basicCreds.end(), basicCred); if(i != _basicCreds.end() && (*i) == basicCred) { (*i) = basicCred; } else { _basicCreds.insert(i, basicCred); } } bool AuthConfigFactory::activateBasicCred (const std::string& host, const std::string& path, const Option* op) { std::deque::iterator i = findBasicCred(host, path); if(i == _basicCreds.end()) { SharedHandle authConfig = createHttpAuthResolver(op)->resolveAuthConfig(host); if(authConfig.isNull()) { return false; } else { BasicCred bc(authConfig->getUser(), authConfig->getPassword(), host, path, true); i = std::lower_bound(_basicCreds.begin(), _basicCreds.end(), bc); _basicCreds.insert(i, bc); return true; } } else { (*i).activate(); return true; } } AuthConfigFactory::BasicCred::BasicCred (const std::string& user, const std::string& password, const std::string& host, const std::string& path, bool activated): _user(user), _password(password), _host(host), _path(path), _activated(activated) { if(!util::endsWith(_path, "/")) { _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 && _path == cred._path; } bool AuthConfigFactory::BasicCred::operator<(const BasicCred& cred) const { int c = _host.compare(cred._host); if(c == 0) { return _path > cred._path; } else { return c < 0; } } std::deque::iterator AuthConfigFactory::findBasicCred(const std::string& host, const std::string& path) { BasicCred bc("", "", host, path); std::deque::iterator i = std::lower_bound(_basicCreds.begin(), _basicCreds.end(), bc); for(; i != _basicCreds.end() && (*i)._host == host; ++i) { if(util::startsWith(bc._path, (*i)._path)) { return i; } } return _basicCreds.end(); } } // namespace aria2