forked from I2P_Developers/i2p.i2p
* i2ptunnel: Add inproxy block option to HTTP server
This commit is contained in:
@ -48,6 +48,7 @@ public class I2PTunnelHTTPServer extends I2PTunnelServer {
|
|||||||
public static final String OPT_POST_TOTAL_BAN_TIME = "postTotalBanTime";
|
public static final String OPT_POST_TOTAL_BAN_TIME = "postTotalBanTime";
|
||||||
public static final String OPT_POST_MAX = "maxPosts";
|
public static final String OPT_POST_MAX = "maxPosts";
|
||||||
public static final String OPT_POST_TOTAL_MAX = "maxTotalPosts";
|
public static final String OPT_POST_TOTAL_MAX = "maxTotalPosts";
|
||||||
|
public static final String OPT_REJECT_INPROXY = "rejectInproxy";
|
||||||
public static final int DEFAULT_POST_WINDOW = 5*60;
|
public static final int DEFAULT_POST_WINDOW = 5*60;
|
||||||
public static final int DEFAULT_POST_BAN_TIME = 30*60;
|
public static final int DEFAULT_POST_BAN_TIME = 30*60;
|
||||||
public static final int DEFAULT_POST_TOTAL_BAN_TIME = 10*60;
|
public static final int DEFAULT_POST_TOTAL_BAN_TIME = 10*60;
|
||||||
@ -95,6 +96,19 @@ public class I2PTunnelHTTPServer extends I2PTunnelServer {
|
|||||||
"</body></html>")
|
"</body></html>")
|
||||||
.getBytes();
|
.getBytes();
|
||||||
|
|
||||||
|
private final static byte[] ERR_INPROXY =
|
||||||
|
("HTTP/1.1 403 Denied\r\n"+
|
||||||
|
"Content-Type: text/html; charset=iso-8859-1\r\n"+
|
||||||
|
"Cache-control: no-cache\r\n"+
|
||||||
|
"Connection: close\r\n"+
|
||||||
|
"Proxy-Connection: close\r\n"+
|
||||||
|
"\r\n"+
|
||||||
|
"<html><head><title>403 Denied</title></head>\n"+
|
||||||
|
"<body><h2>403 Denied</h2>\n" +
|
||||||
|
"<p>Inproxy access denied. You must run <a href=\"https://geti2p.net/\">I2P</a> to access this site.</p>\n" +
|
||||||
|
"</body></html>")
|
||||||
|
.getBytes();
|
||||||
|
|
||||||
public I2PTunnelHTTPServer(InetAddress host, int port, String privData, String spoofHost, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel) {
|
public I2PTunnelHTTPServer(InetAddress host, int port, String privData, String spoofHost, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel) {
|
||||||
super(host, port, privData, l, notifyThis, tunnel);
|
super(host, port, privData, l, notifyThis, tunnel);
|
||||||
setupI2PTunnelHTTPServer(spoofHost);
|
setupI2PTunnelHTTPServer(spoofHost);
|
||||||
@ -198,6 +212,24 @@ public class I2PTunnelHTTPServer extends I2PTunnelServer {
|
|||||||
CLIENT_SKIPHEADERS, getTunnel().getContext());
|
CLIENT_SKIPHEADERS, getTunnel().getContext());
|
||||||
long afterHeaders = getTunnel().getContext().clock().now();
|
long afterHeaders = getTunnel().getContext().clock().now();
|
||||||
|
|
||||||
|
Properties opts = getTunnel().getClientOptions();
|
||||||
|
if (Boolean.parseBoolean(opts.getProperty(OPT_REJECT_INPROXY)) &&
|
||||||
|
(headers.containsKey("X-Forwarded-For") ||
|
||||||
|
headers.containsKey("X-Forwarded-Server") ||
|
||||||
|
headers.containsKey("X-Forwarded-Host"))) {
|
||||||
|
if (_log.shouldLog(Log.WARN))
|
||||||
|
_log.warn("Refusing inproxy access: " + peerHash.toBase64());
|
||||||
|
try {
|
||||||
|
// Send a 403, so the user doesn't get an HTTP Proxy error message
|
||||||
|
// and blame his router or the network.
|
||||||
|
socket.getOutputStream().write(ERR_INPROXY);
|
||||||
|
} catch (IOException ioe) {}
|
||||||
|
try {
|
||||||
|
socket.close();
|
||||||
|
} catch (IOException ioe) {}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (_postThrottler != null &&
|
if (_postThrottler != null &&
|
||||||
command.length() >= 5 &&
|
command.length() >= 5 &&
|
||||||
command.substring(0, 5).toUpperCase(Locale.US).equals("POST ")) {
|
command.substring(0, 5).toUpperCase(Locale.US).equals("POST ")) {
|
||||||
@ -221,7 +253,6 @@ public class I2PTunnelHTTPServer extends I2PTunnelServer {
|
|||||||
addEntry(headers, DEST64_HEADER, socket.getPeerDestination().toBase64());
|
addEntry(headers, DEST64_HEADER, socket.getPeerDestination().toBase64());
|
||||||
|
|
||||||
// Port-specific spoofhost
|
// Port-specific spoofhost
|
||||||
Properties opts = getTunnel().getClientOptions();
|
|
||||||
String spoofHost;
|
String spoofHost;
|
||||||
int ourPort = socket.getLocalPort();
|
int ourPort = socket.getLocalPort();
|
||||||
if (ourPort != 80 && ourPort > 0 && ourPort <= 65535 && opts != null) {
|
if (ourPort != 80 && ourPort > 0 && ourPort <= 65535 && opts != null) {
|
||||||
@ -668,15 +699,21 @@ public class I2PTunnelHTTPServer extends I2PTunnelServer {
|
|||||||
else
|
else
|
||||||
value = "";
|
value = "";
|
||||||
|
|
||||||
if ("accept-encoding".equals(name.toLowerCase(Locale.US)))
|
String lcName = name.toLowerCase(Locale.US);
|
||||||
|
if ("accept-encoding".equals(lcName))
|
||||||
name = "Accept-encoding";
|
name = "Accept-encoding";
|
||||||
else if ("x-accept-encoding".equals(name.toLowerCase(Locale.US)))
|
else if ("x-accept-encoding".equals(lcName))
|
||||||
name = "X-Accept-encoding";
|
name = "X-Accept-encoding";
|
||||||
|
else if ("x-forwarded-for".equals(lcName))
|
||||||
|
name = "X-Forwarded-For";
|
||||||
|
else if ("x-forwarded-server".equals(lcName))
|
||||||
|
name = "X-Forwarded-Server";
|
||||||
|
else if ("x-forwarded-host".equals(lcName))
|
||||||
|
name = "X-Forwarded-Host";
|
||||||
|
|
||||||
// For incoming, we remove certain headers to prevent spoofing.
|
// For incoming, we remove certain headers to prevent spoofing.
|
||||||
// For outgoing, we remove certain headers to improve anonymity.
|
// For outgoing, we remove certain headers to improve anonymity.
|
||||||
boolean skip = false;
|
boolean skip = false;
|
||||||
String lcName = name.toLowerCase(Locale.US);
|
|
||||||
for (String skipHeader: skipHeaders) {
|
for (String skipHeader: skipHeaders) {
|
||||||
if (skipHeader.toLowerCase(Locale.US).equals(lcName)) {
|
if (skipHeader.toLowerCase(Locale.US).equals(lcName)) {
|
||||||
skip = true;
|
skip = true;
|
||||||
|
@ -808,6 +808,21 @@ public class IndexBean {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 0.9.12 */
|
||||||
|
public void setRejectInproxy(String moo) {
|
||||||
|
_booleanOptions.add(I2PTunnelHTTPServer.OPT_REJECT_INPROXY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 0.9.12 */
|
||||||
|
public boolean isRejectInproxy(int tunnel) {
|
||||||
|
TunnelController tun = getController(tunnel);
|
||||||
|
if (tun != null) {
|
||||||
|
Properties opts = tun.getClientOptionProps();
|
||||||
|
return Boolean.parseBoolean(opts.getProperty(I2PTunnelHTTPServer.OPT_REJECT_INPROXY));
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
protected static final String PROP_ENABLE_ACCESS_LIST = "i2cp.enableAccessList";
|
protected static final String PROP_ENABLE_ACCESS_LIST = "i2cp.enableAccessList";
|
||||||
protected static final String PROP_ENABLE_BLACKLIST = "i2cp.enableBlackList";
|
protected static final String PROP_ENABLE_BLACKLIST = "i2cp.enableBlackList";
|
||||||
|
|
||||||
@ -1243,7 +1258,8 @@ public class IndexBean {
|
|||||||
};
|
};
|
||||||
private static final String _booleanServerOpts[] = {
|
private static final String _booleanServerOpts[] = {
|
||||||
"i2cp.reduceOnIdle", "i2cp.encryptLeaseSet", PROP_ENABLE_ACCESS_LIST, PROP_ENABLE_BLACKLIST,
|
"i2cp.reduceOnIdle", "i2cp.encryptLeaseSet", PROP_ENABLE_ACCESS_LIST, PROP_ENABLE_BLACKLIST,
|
||||||
I2PTunnelServer.PROP_USE_SSL
|
I2PTunnelServer.PROP_USE_SSL,
|
||||||
|
I2PTunnelHTTPServer.OPT_REJECT_INPROXY
|
||||||
};
|
};
|
||||||
private static final String _otherClientOpts[] = {
|
private static final String _otherClientOpts[] = {
|
||||||
"i2cp.reduceIdleTime", "i2cp.reduceQuantity", "i2cp.closeIdleTime",
|
"i2cp.reduceIdleTime", "i2cp.reduceQuantity", "i2cp.closeIdleTime",
|
||||||
|
@ -381,7 +381,22 @@ input.default { width: 1px; height: 1px; visibility: hidden; }
|
|||||||
<textarea rows="2" style="height: 8em;" cols="60" id="hostField" name="accessList" title="Access List" wrap="off" spellcheck="false"><%=editBean.getAccessList(curTunnel)%></textarea>
|
<textarea rows="2" style="height: 8em;" cols="60" id="hostField" name="accessList" title="Access List" wrap="off" spellcheck="false"><%=editBean.getAccessList(curTunnel)%></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="subdivider">
|
<% if (("httpserver".equals(tunnelType)) || ("httpbidirserver".equals(tunnelType))) {
|
||||||
|
%><div class="rowItem">
|
||||||
|
<div id="optionsField" class="rowItem">
|
||||||
|
<label>
|
||||||
|
<%=intl._("Block Access via Inproxies")%>:
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div id="portField" class="rowItem">
|
||||||
|
<label for="access" accesskey="d">
|
||||||
|
<%=intl._("Enable")%>:
|
||||||
|
</label>
|
||||||
|
<input value="1" type="checkbox" id="startOnLoad" name="rejectInproxy" title="Deny inproxy access when enabled"<%=(editBean.isRejectInproxy(curTunnel) ? " checked=\"checked\"" : "")%> class="tickbox" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% } // httpserver
|
||||||
|
%><div class="subdivider">
|
||||||
<hr />
|
<hr />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user