redesigned some parts of http authentication

added another access check for peer hops

git-svn-id: https://svn.berlios.de/svnroot/repos/yacy/trunk@3340 6c8d7289-2bf4-0310-a012-ef5d649a1542
pull/1/head
orbiter 18 years ago
parent 588e48ce0b
commit d25caa07bf

@ -53,6 +53,7 @@ import java.util.regex.Pattern;
import de.anomic.data.translator;
import de.anomic.http.httpHeader;
import de.anomic.http.httpd;
import de.anomic.http.httpdFileHandler;
import de.anomic.kelondro.kelondroBase64Order;
import de.anomic.plasma.plasmaSwitchboard;
@ -142,7 +143,7 @@ public class ConfigBasic {
// admin password
if ((user.length() > 0) && (pw1.length() > 3) && (pw1.equals(pw2))) {
// check passed. set account:
env.setConfig("adminAccountBase64MD5", serverCodings.encodeMD5Hex(kelondroBase64Order.standardCoder.encodeString(user + ":" + pw1)));
env.setConfig(httpd.ADMIN_ACCOUNT_B64MD5, serverCodings.encodeMD5Hex(kelondroBase64Order.standardCoder.encodeString(user + ":" + pw1)));
env.setConfig("adminAccount", "");
// authenticate immediately
//prop.put("AUTHENTICATE", "admin log-in");
@ -191,7 +192,7 @@ public class ConfigBasic {
}
// check if values are proper
boolean properPW = (env.getConfig("adminAccount", "").length() == 0) && (env.getConfig("adminAccountBase64MD5", "").length() > 0);
boolean properPW = (env.getConfig("adminAccount", "").length() == 0) && (env.getConfig(httpd.ADMIN_ACCOUNT_B64MD5, "").length() > 0);
boolean properName = (env.getConfig("peerName","").length() >= 3) && (!(yacySeed.isDefaultPeerName(env.getConfig("peerName",""))));
boolean properPort = (yacyCore.seedDB.mySeed.isSenior()) || (yacyCore.seedDB.mySeed.isPrincipal());

@ -124,7 +124,7 @@ public class SettingsAck_p {
return prop;
}
// check passed. set account:
env.setConfig("adminAccountBase64MD5", serverCodings.encodeMD5Hex(kelondroBase64Order.standardCoder.encodeString(user + ":" + pw1)));
env.setConfig(httpd.ADMIN_ACCOUNT_B64MD5, serverCodings.encodeMD5Hex(kelondroBase64Order.standardCoder.encodeString(user + ":" + pw1)));
env.setConfig("adminAccount", "");
prop.put("info", 5);//admin account changed
prop.put("info_user", user);

@ -50,6 +50,7 @@ import java.text.DecimalFormat;
import java.util.Date;
import de.anomic.http.httpHeader;
import de.anomic.http.httpd;
import de.anomic.http.httpdByteCountInputStream;
import de.anomic.http.httpdByteCountOutputStream;
import de.anomic.plasma.plasmaSwitchboard;
@ -137,7 +138,7 @@ public class Status {
}
// password protection
if (env.getConfig("adminAccountBase64MD5", "").length() == 0) {
if (env.getConfig(httpd.ADMIN_ACCOUNT_B64MD5, "").length() == 0) {
prop.put("protection", 0); // not protected
} else {
prop.put("protection", 1); // protected

@ -50,6 +50,7 @@ import java.io.IOException;
import de.anomic.data.userDB;
import de.anomic.http.httpHeader;
import de.anomic.http.httpd;
import de.anomic.kelondro.kelondroBase64Order;
import de.anomic.plasma.plasmaSwitchboard;
import de.anomic.server.serverCodings;
@ -112,7 +113,7 @@ public class User{
String password=(String)post.get("password");
entry=sb.userDB.passwordAuth(username, password);
boolean staticAdmin = sb.getConfig("adminAccountBase64MD5", "").equals(
boolean staticAdmin = sb.getConfig(httpd.ADMIN_ACCOUNT_B64MD5, "").equals(
serverCodings.encodeMD5Hex(
kelondroBase64Order.standardCoder.encodeString(username + ":" + password)
)

@ -58,6 +58,7 @@ import java.util.Iterator;
import de.anomic.data.userDB;
import de.anomic.http.httpHeader;
import de.anomic.http.httpd;
import de.anomic.plasma.plasmaURL;
import de.anomic.index.indexURLEntry;
import de.anomic.kelondro.kelondroBase64Order;
@ -113,7 +114,7 @@ public class dir {
prop.put("port", serverCore.getPortNr(env.getConfig("port","8080")));
// generate upload/download authorizations
final String adminAccountBase64MD5 = switchboard.getConfig("adminAccountBase64MD5", "");
final String adminAccountBase64MD5 = switchboard.getConfig(httpd.ADMIN_ACCOUNT_B64MD5, "");
final String uploadAccountBase64MD5 = switchboard.getConfig("uploadAccountBase64MD5", "");
final String downloadAccountBase64MD5 = switchboard.getConfig("downloadAccountBase64MD5", "");

@ -54,7 +54,6 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.TreeSet;
import de.anomic.data.wikiCode;
import de.anomic.htmlFilter.htmlFilterImageEntry;
import de.anomic.http.httpHeader;
import de.anomic.index.indexURLEntry;

@ -56,7 +56,6 @@ import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
@ -67,6 +66,7 @@ import java.util.StringTokenizer;
import de.anomic.data.userDB;
import de.anomic.data.wikiCode;
import de.anomic.kelondro.kelondroBase64Order;
import de.anomic.net.URL;
import de.anomic.plasma.plasmaSwitchboard;
import de.anomic.server.serverByteBuffer;
@ -90,6 +90,13 @@ import de.anomic.yacy.yacySeed;
*/
public final class httpd implements serverHandler {
/**
* <p><code>public static final String <strong>ADMIN_ACCOUNT_B64MD5</strong> = "adminAccountBase64MD5"</code></p>
* <p>Name of the setting holding the authentification hash for the static <code>admin</code>-account. It is calculated
* by first encoding <code>username:password</code> as Base64 and hashing it using {@link serverCodings#encodeMD5Hex(String)}.</p>
*/
public static final String ADMIN_ACCOUNT_B64MD5 = "adminAccountBase64MD5";
public static final int ERRORCASE_MESSAGE = 4;
public static final int ERRORCASE_FILE = 5;
@ -287,6 +294,16 @@ public final class httpd implements serverHandler {
return persistent;
}
public static int staticAdminAuthenticated(String authorization, serverSwitch sw){
if(authorization==null) return 1;
//if (authorization.length() < 6) return 1; // no authentication information given
//authorization = authorization.trim().substring(6);
String adminAccountBase64MD5 = sw.getConfig(ADMIN_ACCOUNT_B64MD5, "");
if (adminAccountBase64MD5.length() == 0) return 2; // no passwrd stored
if (adminAccountBase64MD5.equals(serverCodings.encodeMD5Hex(authorization))) return 4; // hard-authenticated, all ok
return 0;
}
private boolean handleServerAuthentication(httpHeader header) throws IOException {
// getting the http version that is used by the client
String httpVersion = this.prop.getProperty(httpHeader.CONNECTION_PROP_HTTP_VER, "HTTP/0.9");
@ -319,6 +336,24 @@ public final class httpd implements serverHandler {
return true;
}
private boolean handleYaCyHopAuthentication(httpHeader header) throws IOException {
// proxy hops must identify with 3 criteria:
// the access path must be into the yacy protocol path; it must start with 'yacy'
if (!(this.prop.getProperty(httpHeader.CONNECTION_PROP_PATH, "").startsWith("/yacy/"))) return false;
// the accessing client must identify with user:password, where
// user = addressed peer name
// pw = addressed peer hash (b64-hash)
String auth = (String) header.get(httpHeader.PROXY_AUTHORIZATION,"xxxxxx");
String test = kelondroBase64Order.standardCoder.encodeString(yacyCore.seedDB.mySeed.getName() + ":" + yacyCore.seedDB.mySeed.hash);
if (!test.equals(auth.trim().substring(6))) return false;
// the accessing client must use a yacy user-agent
return true;
}
private boolean handleProxyAuthentication(httpHeader header) throws IOException {
// getting the http version that is used by the client
String httpVersion = this.prop.getProperty("HTTP", "HTTP/0.9");
@ -456,8 +491,8 @@ public final class httpd implements serverHandler {
}
} else {
// pass to proxy
if (((this.allowYaCyHop) && (this.prop.getProperty(httpHeader.CONNECTION_PROP_PATH, "").startsWith("/yacy/"))) ||
((this.allowProxy) && (this.handleProxyAuthentication(header)))) {
if (((this.allowYaCyHop) && (handleYaCyHopAuthentication(header))) ||
((this.allowProxy) && (handleProxyAuthentication(header)))) {
proxyHandler.doGet(this.prop, header, this.session.out);
} else {
// not authorized through firewall blocking (ip does not match filter)
@ -529,8 +564,8 @@ public final class httpd implements serverHandler {
}
} else {
// pass to proxy
if (((this.allowYaCyHop) && (this.prop.getProperty(httpHeader.CONNECTION_PROP_PATH, "").startsWith("/yacy/"))) ||
((this.allowProxy) && (this.handleProxyAuthentication(header)))) {
if (((this.allowYaCyHop) && (handleYaCyHopAuthentication(header))) ||
((this.allowProxy) && (handleProxyAuthentication(header)))) {
proxyHandler.doHead(prop, header, this.session.out);
} else {
// not authorized through firewall blocking (ip does not match filter)
@ -611,8 +646,8 @@ public final class httpd implements serverHandler {
}
} else {
// pass to proxy
if (((this.allowYaCyHop) && (this.prop.getProperty(httpHeader.CONNECTION_PROP_PATH, "").startsWith("/yacy/"))) ||
((this.allowProxy) && (this.handleProxyAuthentication(header)))) {
if (((this.allowYaCyHop) && (handleYaCyHopAuthentication(header))) ||
((this.allowProxy) && (handleProxyAuthentication(header)))) {
proxyHandler.doPost(prop, header, this.session.out, this.session.in);
} else {
// not authorized through firewall blocking (ip does not match filter)
@ -678,7 +713,7 @@ public final class httpd implements serverHandler {
}
// pass to proxy
if (((this.allowYaCyHop) && (this.prop.getProperty(httpHeader.CONNECTION_PROP_PATH, "").startsWith("/yacy/"))) ||
if (((this.allowYaCyHop) && (handleYaCyHopAuthentication(header))) ||
((this.allowProxy) && (this.handleProxyAuthentication(header)))) {
proxyHandler.doConnect(prop, header, this.session.in, this.session.out);
} else {

@ -137,12 +137,8 @@ public final class httpdFileHandler extends httpdAbstractHandler implements http
private MessageDigest md5Digest = null;
/**
* Template Cache
* @param switchboard
*/
private static final HashMap templateCache;
private static final HashMap templateCache;
private static final HashMap templateMethodCache;
public static boolean useTemplateCache = false;
@ -319,7 +315,7 @@ public final class httpdFileHandler extends httpdAbstractHandler implements http
// check permission/granted access
String authorization = (String) requestHeader.get(httpHeader.AUTHORIZATION);
String adminAccountBase64MD5 = switchboard.getConfig("adminAccountBase64MD5", "");
String adminAccountBase64MD5 = switchboard.getConfig(httpd.ADMIN_ACCOUNT_B64MD5, "");
int pos = path.lastIndexOf(".");
@ -330,7 +326,7 @@ public final class httpdFileHandler extends httpdAbstractHandler implements http
//Authentication successful. remove brute-force flag
serverCore.bfHost.remove(conProp.getProperty("CLIENTIP"));
//static
}else if(authorization != null && sb.staticAdminAuthenticated(authorization.trim().substring(6))==4){
}else if(authorization != null && httpd.staticAdminAuthenticated(authorization.trim().substring(6), switchboard)==4){
//Authentication successful. remove brute-force flag
serverCore.bfHost.remove(conProp.getProperty("CLIENTIP"));
//no auth

@ -131,6 +131,7 @@ import de.anomic.htmlFilter.htmlFilterContentScraper;
import de.anomic.http.httpHeader;
import de.anomic.http.httpRemoteProxyConfig;
import de.anomic.http.httpc;
import de.anomic.http.httpd;
import de.anomic.index.indexContainer;
import de.anomic.index.indexRWIEntry;
import de.anomic.index.indexRWIEntryNew;
@ -148,7 +149,6 @@ import de.anomic.plasma.parser.ParserException;
import de.anomic.plasma.urlPattern.defaultURLPattern;
import de.anomic.plasma.urlPattern.plasmaURLPattern;
import de.anomic.server.serverAbstractSwitch;
import de.anomic.server.serverCodings;
import de.anomic.server.serverDate;
import de.anomic.server.serverFileUtils;
import de.anomic.server.serverInstantThread;
@ -632,12 +632,6 @@ public final class plasmaSwitchboard extends serverAbstractSwitch implements ser
*/
public static final String CRAWLER_THREADS_ACTIVE_MAX = "crawler.MaxActiveThreads";
/**
* <p><code>public static final String <strong>ADMIN_ACCOUNT_B64MD5</strong> = "adminAccountBase64MD5"</code></p>
* <p>Name of the setting holding the authentification hash for the static <code>admin</code>-account. It is calculated
* by first encoding <code>username:password</code> as Base64 and hashing it using {@link serverCodings#encodeMD5Hex(String)}.</p>
*/
public static final String ADMIN_ACCOUNT_B64MD5 = "adminAccountBase64MD5";
public static final String OWN_SEED_FILE = "yacyOwnSeedFile";
/**
* <p><code>public static final String <strong>STORAGE_PEER_HASH</strong> = "storagePeerHash"</code></p>
@ -2888,7 +2882,7 @@ public final class plasmaSwitchboard extends serverAbstractSwitch implements ser
public int adminAuthenticated(httpHeader header) {
String adminAccountBase64MD5 = getConfig("adminAccountBase64MD5", "");
String adminAccountBase64MD5 = getConfig(httpd.ADMIN_ACCOUNT_B64MD5, "");
String authorization = ((String) header.get(httpHeader.AUTHORIZATION, "xxxxxx")).trim().substring(6);
// security check against too long authorization strings
@ -2901,17 +2895,7 @@ public final class plasmaSwitchboard extends serverAbstractSwitch implements ser
if (userDB.hasAdminRight((String) header.get(httpHeader.AUTHORIZATION, "xxxxxx"), ((String) header.get("CLIENTIP", "")), header.getHeaderCookies())) return 4; //return, because 4=max
// authorization with admin keyword in configuration
return staticAdminAuthenticated(authorization);
}
public int staticAdminAuthenticated(String authorization){
if(authorization==null) return 1;
//if (authorization.length() < 6) return 1; // no authentication information given
//authorization = authorization.trim().substring(6);
String adminAccountBase64MD5 = getConfig(ADMIN_ACCOUNT_B64MD5, "");
if (adminAccountBase64MD5.length() == 0) return 2; // no passwrd stored
if (adminAccountBase64MD5.equals(serverCodings.encodeMD5Hex(authorization))) return 4; // hard-authenticated, all ok
return 0;
return httpd.staticAdminAuthenticated(authorization, this);
}
public boolean verifyAuthentication(httpHeader header, boolean strict) {

@ -67,6 +67,7 @@ import org.w3c.dom.Element;
import de.anomic.http.httpHeader;
import de.anomic.http.httpTemplate;
import de.anomic.http.httpd;
import de.anomic.server.serverClassLoader;
import de.anomic.server.serverObjects;
import de.anomic.server.serverSwitch;
@ -235,7 +236,7 @@ public abstract class AbstractService {
// the base64 encoded and md5 hashed authentication string
String authString = authElement.getValue();
String adminAccountBase64MD5 = this.switchboard.getConfig("adminAccountBase64MD5","");
String adminAccountBase64MD5 = this.switchboard.getConfig(httpd.ADMIN_ACCOUNT_B64MD5,"");
if (authString.length() == 0) {
throw new AxisFault("log-in required");
} else if (!(adminAccountBase64MD5.equals(authString))) {

@ -41,6 +41,7 @@ import java.io.File;
import java.io.IOException;
import de.anomic.data.listManager;
import de.anomic.http.httpd;
import de.anomic.kelondro.kelondroBase64Order;
import de.anomic.plasma.plasmaSwitchboard;
import de.anomic.server.serverFileUtils;
@ -187,7 +188,7 @@ public class migration {
sb.setConfig("serverAccount", "");
}
if ((acc = sb.getConfig("adminAccount", "")).length() > 0) {
sb.setConfig("adminAccountBase64MD5", de.anomic.server.serverCodings.encodeMD5Hex(kelondroBase64Order.standardCoder.encodeString(acc)));
sb.setConfig(httpd.ADMIN_ACCOUNT_B64MD5, de.anomic.server.serverCodings.encodeMD5Hex(kelondroBase64Order.standardCoder.encodeString(acc)));
sb.setConfig("adminAccount", "");
}
@ -201,7 +202,7 @@ public class migration {
sb.setConfig("serverAccountBase64", "");
}
if ((acc = sb.getConfig("adminAccountBase64", "")).length() > 0) {
sb.setConfig("adminAccountBase64MD5", de.anomic.server.serverCodings.encodeMD5Hex(acc));
sb.setConfig(httpd.ADMIN_ACCOUNT_B64MD5, de.anomic.server.serverCodings.encodeMD5Hex(acc));
sb.setConfig("adminAccountBase64", "");
}
if ((acc = sb.getConfig("uploadAccountBase64", "")).length() > 0) {

@ -379,7 +379,7 @@ public final class yacy {
final boolean browserPopUpTrigger = sb.getConfig("browserPopUpTrigger", "true").equals("true");
if (browserPopUpTrigger) {
String browserPopUpPage = sb.getConfig("browserPopUpPage", "ConfigBasic.html");
boolean properPW = (sb.getConfig("adminAccount", "").length() == 0) && (sb.getConfig("adminAccountBase64MD5", "").length() > 0);
boolean properPW = (sb.getConfig("adminAccount", "").length() == 0) && (sb.getConfig(httpd.ADMIN_ACCOUNT_B64MD5, "").length() > 0);
if (!properPW) browserPopUpPage = "ConfigBasic.html";
final String browserPopUpApplication = sb.getConfig("browserPopUpApplication", "netscape");
serverSystem.openBrowser((server.withSSL()?"https":"http") + "://localhost:" + serverCore.getPortNr(port) + "/" + browserPopUpPage, browserPopUpApplication);
@ -539,7 +539,7 @@ public final class yacy {
int port = serverCore.getPortNr(config.getProperty("port", "8080"));
// read password
String encodedPassword = (String) config.get("adminAccountBase64MD5");
String encodedPassword = (String) config.get(httpd.ADMIN_ACCOUNT_B64MD5);
if (encodedPassword == null) encodedPassword = ""; // not defined
// send 'wget' to web interface

@ -15,6 +15,8 @@ import org.apache.axis.MessageContext;
import org.apache.axis.client.Stub;
import org.apache.axis.transport.http.HTTPConstants;
import de.anomic.http.httpd;
public abstract class AbstractServiceTest extends TestCase {
protected static final String SOAP_HEADER_NAMESPACE = "http://http.anomic.de/header";
protected static final String SOAP_HEADER_AUTHORIZATION = "Authorization";
@ -47,7 +49,7 @@ public abstract class AbstractServiceTest extends TestCase {
fileInput.close();
// getting admin account auth string
authString = peerProperties.getProperty("adminAccountBase64MD5");
authString = peerProperties.getProperty(httpd.ADMIN_ACCOUNT_B64MD5);
if (authString == null) throw new Exception("Unable to find authentication information.");
peerPort = peerProperties.getProperty("port");

Loading…
Cancel
Save