diff --git a/source/net/yacy/http/YaCyLegacyCredential.java b/source/net/yacy/http/YaCyLegacyCredential.java new file mode 100644 index 000000000..ad7111521 --- /dev/null +++ b/source/net/yacy/http/YaCyLegacyCredential.java @@ -0,0 +1,90 @@ +// +// YaCyLegacyCredentials +// Copyright 2011 by Florian Richter +// First released 16.04.2011 at http://yacy.net +// +// $LastChangedDate$ +// $LastChangedRevision$ +// $LastChangedBy$ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program in the file lgpl21.txt +// If not, see . +// + +package net.yacy.http; + +import net.yacy.kelondro.order.Base64Order; +import net.yacy.kelondro.order.Digest; +import net.yacy.kelondro.util.MapTools; + +import org.eclipse.jetty.http.security.Credential; + + +/** + * implementation of YaCy's old admin password as jetty Credential + */ +public class YaCyLegacyCredential extends Credential { + + private static final long serialVersionUID = -3527894085562480001L; + private String hash; + + /** + *

public static final String ADMIN_ACCOUNT_B64MD5 = "adminAccountBase64MD5"

+ *

Name of the setting holding the authentication hash for the static admin-account. It is calculated + * by first encoding username:password as Base64 and hashing it using {@link MapTools#encodeMD5Hex(String)}.

+ */ + public static final String ADMIN_ACCOUNT_B64MD5 = "adminAccountBase64MD5"; + + /** + * internal hash function + * @param clear password + * @return hash string + */ + private static String calcHash(String pw) { + return Digest.encodeMD5Hex(Base64Order.standardCoder.encodeString("admin:" + pw)); + } + + @Override + public boolean check(Object credentials) { + if(credentials instanceof String) { + final String pw = (String) credentials; + return calcHash(pw).equals(this.hash); + } else { + throw new UnsupportedOperationException(); + } + } + + /** + * create Credential object from config file hash + * @param configHash hash as in config file + * @return + */ + public static Credential getCredentialsFromConfig(String configHash) { + YaCyLegacyCredential c = new YaCyLegacyCredential(); + c.hash = configHash; + return c; + } + + /** + * create Credential object from password + * @param password + * @return + */ + public static Credential getCredentials(String password) { + YaCyLegacyCredential c = new YaCyLegacyCredential(); + c.hash = calcHash(password); + return c; + } + +} diff --git a/source/net/yacy/http/YaCyLoginService.java b/source/net/yacy/http/YaCyLoginService.java index fb939c571..a08e830d3 100644 --- a/source/net/yacy/http/YaCyLoginService.java +++ b/source/net/yacy/http/YaCyLoginService.java @@ -34,6 +34,8 @@ import org.eclipse.jetty.security.IdentityService; import org.eclipse.jetty.security.MappedLoginService; import org.eclipse.jetty.server.UserIdentity; +import de.anomic.search.Switchboard; + /** * jetty login service, provides one admin user @@ -44,7 +46,9 @@ public class YaCyLoginService extends MappedLoginService { protected UserIdentity loadUser(String username) { if(username.equals("admin")) { // TODO: implement legacy credentials - Credential credential = Credential.getCredential("admin"); + final Switchboard sb = Switchboard.getSwitchboard(); + final String adminAccountBase64MD5 = sb.getConfig(YaCyLegacyCredential.ADMIN_ACCOUNT_B64MD5, ""); + Credential credential = YaCyLegacyCredential.getCredentialsFromConfig(adminAccountBase64MD5); Principal userPrincipal = new MappedLoginService.KnownUser("admin", credential); Subject subject = new Subject(); subject.getPrincipals().add(userPrincipal); @@ -55,7 +59,7 @@ public class YaCyLoginService extends MappedLoginService { } return null; } - + @Override protected void loadUsers() throws IOException { // don't load any users into MappedLoginService on startup diff --git a/source/net/yacy/http/YaCySecurityHandler.java b/source/net/yacy/http/YaCySecurityHandler.java index 7c33e1683..b4ac01bb4 100644 --- a/source/net/yacy/http/YaCySecurityHandler.java +++ b/source/net/yacy/http/YaCySecurityHandler.java @@ -26,11 +26,15 @@ package net.yacy.http; import java.io.IOException; +import net.yacy.cora.protocol.Domains; + import org.eclipse.jetty.security.SecurityHandler; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Response; import org.eclipse.jetty.server.UserIdentity; +import de.anomic.search.Switchboard; + /** * jetty security handler * demands authentication for pages with _p. inside @@ -60,8 +64,18 @@ public class YaCySecurityHandler extends SecurityHandler { @Override protected Object prepareConstraintInfo(String pathInContext, Request request) { - // authentication mandatory as simple constraint info - return pathInContext.contains("_p."); + final Switchboard sb = Switchboard.getSwitchboard(); + final boolean adminAccountForLocalhost = sb.getConfigBool("adminAccountForLocalhost", false); + final String adminAccountBase64MD5 = sb.getConfig(YaCyLegacyCredential.ADMIN_ACCOUNT_B64MD5, ""); + + final String refererHost = request.getHeader("Referer"); + final boolean accessFromLocalhost = Domains.isLocalhost(request.getRemoteHost()) && (refererHost == null || refererHost.length() == 0 || Domains.isLocalhost(refererHost)); + final boolean grantedForLocalhost = adminAccountForLocalhost && accessFromLocalhost; + final boolean protectedPage = pathInContext.indexOf("_p.") > 0; + final boolean accountEmpty = adminAccountBase64MD5.length() == 0; + final boolean yacyBot = request.getHeader("User-Agent").startsWith("yacybot"); + + return protectedPage && ((!grantedForLocalhost && !accountEmpty) || yacyBot); } }