();
+ for (final AccessRight right : AccessRight.values()) {
+ if (user.hasRight(right)) {
+ roletmp.add(right.toString());
+ }
}
+ if (roletmp.size() > 0) roles = roletmp.toArray(new String[roletmp.size()]);
+ credential = YaCyLegacyCredential.getCredentialForUserDB(username, user.getMD5EncodedUserPwd());
+ }
+ }
+
+ if (credential != null) {
+ if (roles != null) {
+ return putUser(username, credential, roles);
+ } else {
+ return putUser(username, credential); // w/o role makes not much sense, but succeeds login....
}
- Credential credential = YaCyLegacyCredential.getCredentials(username, user.getMD5EncodedUserPwd());
- Principal userPrincipal = new MappedLoginService.KnownUser(username, credential);
- Subject subject = new Subject();
- subject.getPrincipals().add(userPrincipal);
- subject.getPrivateCredentials().add(credential);
- subject.setReadOnly();
- IdentityService is = getIdentityService();
- return is.newUserIdentity(subject, userPrincipal, role);
}
return null;
}
-
- @Override
- protected void loadUsers() throws IOException {
- // don't load any users into MappedLoginService on startup
- // we use loadUser for dynamic checking
- }
+
+ @Override
+ protected void loadUsers() throws IOException {
+ // don't load any users into MappedLoginService on startup
+ // we use loadUser for dynamic checking
+ }
}
diff --git a/source/net/yacy/http/servlets/YaCyDefaultServlet.java b/source/net/yacy/http/servlets/YaCyDefaultServlet.java
index c5de34758..bf2da4e5e 100644
--- a/source/net/yacy/http/servlets/YaCyDefaultServlet.java
+++ b/source/net/yacy/http/servlets/YaCyDefaultServlet.java
@@ -48,9 +48,14 @@ import javax.servlet.http.HttpServletResponse;
import net.yacy.cora.date.GenericFormatter;
import net.yacy.cora.document.analysis.Classification;
+import net.yacy.cora.order.Base64Order;
+import net.yacy.cora.protocol.Domains;
import net.yacy.cora.protocol.HeaderFramework;
import net.yacy.cora.protocol.RequestHeader;
import net.yacy.cora.util.ConcurrentLog;
+import net.yacy.data.UserDB;
+import net.yacy.data.UserDB.AccessRight;
+import net.yacy.data.UserDB.Entry;
import net.yacy.http.ProxyHandler;
import net.yacy.kelondro.util.FileUtils;
import net.yacy.kelondro.util.MemoryControl;
@@ -644,11 +649,28 @@ public class YaCyDefaultServlet extends HttpServlet {
legacyRequestHeader.put(HeaderFramework.CONNECTION_PROP_PATH, target);
legacyRequestHeader.put(HeaderFramework.CONNECTION_PROP_EXT, targetExt);
- // for userDB user legacyRequest expect login in Cookie (add one)
- if (request.getUserPrincipal() != null) {
- String userpassEncoded = request.getHeader("Authorization"); // e.g. "Basic xxXXxxXXxxXX"
- if (userpassEncoded != null) {
- legacyRequestHeader.setCookie("login", userpassEncoded);
+ if (legacyRequestHeader.containsKey(RequestHeader.AUTHORIZATION)) {
+ if (HttpServletRequest.BASIC_AUTH.equalsIgnoreCase(request.getAuthType())) {
+ } else {
+ // handle DIGEST auth for legacyHeader (create username:md5pwdhash
+ if (request.getUserPrincipal() != null) {
+ String userpassEncoded = request.getHeader(RequestHeader.AUTHORIZATION); // e.g. "Basic AdminMD5hash"
+ if (userpassEncoded != null) {
+ if (request.isUserInRole(AccessRight.ADMIN_RIGHT.toString()) && !Switchboard.getSwitchboard().getConfig(SwitchboardConstants.ADMIN_ACCOUNT_B64MD5,"").isEmpty()) {
+ // fake admin authentication for legacyRequestHeader (as e.g. DIGEST is not supported by legacyRequestHeader)
+ legacyRequestHeader.put(RequestHeader.AUTHORIZATION, HttpServletRequest.BASIC_AUTH + " "
+ + Switchboard.getSwitchboard().getConfig(SwitchboardConstants.ADMIN_ACCOUNT_B64MD5, ""));
+ } else {
+ // fake Basic auth header for Digest auth (Basic username:md5pwdhash)
+ String username = request.getRemoteUser();
+ Entry user = Switchboard.getSwitchboard().userDB.getEntry(username);
+ if (user != null) {
+ legacyRequestHeader.put(RequestHeader.AUTHORIZATION, HttpServletRequest.BASIC_AUTH + " "
+ + username + ":" + user.getMD5EncodedUserPwd());
+ }
+ }
+ }
+ }
}
}
return legacyRequestHeader;
@@ -842,7 +864,7 @@ public class YaCyDefaultServlet extends HttpServlet {
// handle action auth: check if the servlets requests authentication
if (templatePatterns.containsKey(serverObjects.ACTION_AUTHENTICATE)) {
if (!request.authenticate(response)) {
- return;
+ return;
}
//handle action forward
} else if (templatePatterns.containsKey(serverObjects.ACTION_LOCATION)) {
diff --git a/source/net/yacy/search/Switchboard.java b/source/net/yacy/search/Switchboard.java
index b45b3190b..53947d450 100644
--- a/source/net/yacy/search/Switchboard.java
+++ b/source/net/yacy/search/Switchboard.java
@@ -3233,6 +3233,8 @@ public final class Switchboard extends serverSwitch {
* http-authentify: auth-level 4
*
* @param requestHeader
+ * - requestHeader..AUTHORIZATION = B64encode("adminname:password") or = B64encode("adminname:valueOf_Base64MD5cft")
+ * - adminAccountBase64MD5 = MD5(B64encode("adminname:password") or = "MD5:"+MD5("adminname:peername:password")
* @return the auth-level as described above or 1 which means 'not authorized'. a 0 is returned in case of
* fraud attempts
*/
@@ -3254,8 +3256,13 @@ public final class Switchboard extends serverSwitch {
}
// get the authorization string from the header
- final String realmProp = (requestHeader.get(RequestHeader.AUTHORIZATION, "xxxxxx")).trim();
- final String realmValue = realmProp.substring(6);
+ final String realmProp = (requestHeader.get(RequestHeader.AUTHORIZATION, "")).trim();
+ String realmValue = realmProp.isEmpty() ? null : realmProp.substring(6); // take out "BASIC "
+
+ // authorization with admin keyword in configuration
+ if ( realmValue == null || realmValue.isEmpty() ) {
+ return 1;
+ }
// security check against too long authorization strings
if ( realmValue.length() > 256 ) {
@@ -3264,24 +3271,42 @@ public final class Switchboard extends serverSwitch {
// authorization by encoded password, only for localhost access
String pass = Base64Order.standardCoder.encodeString(adminAccountUserName + ":" + adminAccountBase64MD5);
- if ( accessFromLocalhost && (pass.equals(realmValue)) ) {
+ if ( accessFromLocalhost && (pass.equals(realmValue)) ) { // assume realmValue as is in cfg
adminAuthenticationLastAccess = System.currentTimeMillis();
return 3; // soft-authenticated for localhost
}
- // authorization by hit in userDB
- if ( this.userDB.hasAdminRight(realmProp, requestHeader.getHeaderCookies()) ) {
+ // authorization by hit in userDB (realm username:encodedpassword - handed over by DefaultServlet)
+ if ( this.userDB.hasAdminRight(realmValue, requestHeader.getHeaderCookies()) ) {
adminAuthenticationLastAccess = System.currentTimeMillis();
return 4; //return, because 4=max
}
- // authorization with admin keyword in configuration
- if ( realmValue == null || realmValue.isEmpty() ) {
- return 1;
+ // athorization by BASIC auth (realmValue = "adminname:password")
+ if (adminAccountBase64MD5.startsWith("MD5:")) {
+ // handle new option adminAccountBase64MD5="MD5:xxxxxxx" = encodeMD5Hex ("adminname:peername:password")
+ String realmtmp = Base64Order.standardCoder.decodeString(realmValue); //decode to clear text
+ int i = realmtmp.indexOf(':');
+ if (i > 4) { // put peer name in realmValue (>4 is correct to scipt "MD5:" and usernames are min 4 characters)
+ realmtmp = realmtmp.substring(0, i + 1) + sb.getConfig(SwitchboardConstants.ADMIN_REALM,"YaCy") + ":" + realmtmp.substring(i + 1);
+
+ if (adminAccountBase64MD5.substring(4).equals(Digest.encodeMD5Hex(realmtmp))) {
+ adminAuthenticationLastAccess = System.currentTimeMillis();
+ return 4; // hard-authenticated, all ok
}
- if ( adminAccountBase64MD5.equals(Digest.encodeMD5Hex(realmValue)) ) {
+ } else {
+ // handle DIGEST auth (realmValue = adminAccountBase (set for lecacyHeader in DefaultServlet for authenticated requests)
+ if (adminAccountBase64MD5.equals(realmValue)) {
adminAuthenticationLastAccess = System.currentTimeMillis();
return 4; // hard-authenticated, all ok
+ }
+ }
+ } else {
+ // handle old option adminAccountBase64MD5="xxxxxxx" = encodeMD55Hex(encodeB64("adminname:password")
+ if (adminAccountBase64MD5.equals(Digest.encodeMD5Hex(realmValue))) {
+ adminAuthenticationLastAccess = System.currentTimeMillis();
+ return 4; // hard-authenticated, all ok
+ }
}
return 1;
}
diff --git a/source/net/yacy/search/SwitchboardConstants.java b/source/net/yacy/search/SwitchboardConstants.java
index a0853842d..2a23254b0 100644
--- a/source/net/yacy/search/SwitchboardConstants.java
+++ b/source/net/yacy/search/SwitchboardConstants.java
@@ -40,11 +40,14 @@ public final class SwitchboardConstants {
* 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)}.
+ * With introduction of DIGEST authentication all passwords are MD5 encoded and calculatd as username:adminrealm:password
+ * To differentiate old and new admin passwords, use the new calculated passwords a "MD5:" prefix.
*/
public static final String ADMIN_ACCOUNT = "adminAccount";
public static final String ADMIN_ACCOUNT_B64MD5 = "adminAccountBase64MD5";
public static final String ADMIN_ACCOUNT_USER_NAME = "adminAccountUserName"; // by default 'admin'
public static final String ADMIN_ACCOUNT_FOR_LOCALHOST = "adminAccountForLocalhost";
+ public static final String ADMIN_REALM = "adminRealm";
public static final int CRAWLJOB_SYNC = 0;
public static final int CRAWLJOB_STATUS = 1;