Skip to content

Commit c7c0dc8

Browse files
New exclude feature & Windows XP support
1 parent 1bcf1d2 commit c7c0dc8

39 files changed

Lines changed: 544 additions & 217 deletions

custom_files/wuproxy_release/jmagicproxy.cfg

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
#JMagicProxy Configuration File
2-
#Sun Feb 12 16:36:19 CET 2023
2+
#Sun Feb 19 19:20:41 CET 2023
33
proxy.ssl.keystoretype=pkcs12
44
proxy.plugins=io.github.explodingbottle.jmagicproxy.implementation.WUProxy;io.github.explodingbottle.jmagicproxy.implementation.BasicProxy
55
proxy.ssl.keystorepass=WindowsUpdate
66
proxy.ssl.warn.algorithms=true
77
proxy.ssl.keystorepath=certs/updks.p12
88
proxy.server.port=8087
99
proxy.logging.logfile=log&$LNUM$.txt
10+
proxy.ssl.sortmode=INCLUDE
11+
proxy.plugins.wuproxy.redirwuclient=true
12+
proxy.ssl.sortlist=windowsupdate.microsoft.com;*.windowsupdate.microsoft.com;*.update.microsoft.com;*.windowsupdate.com;download.windowsupdate.com;download.microsoft.com;*.download.windowsupdate.com;go.microsoft.com;*.one.microsoft.com
1013
proxy.plugin.wuproxy.redirectjs=content/redirect.js
1114
proxy.ssl.scan.startingport=9784
1215
proxy.logging.logsfolder=logs

custom_files/wuproxy_release/mu_optin.reg

Lines changed: 0 additions & 6 deletions
This file was deleted.

custom_files/wuproxy_release/mu_optin.vbs

Lines changed: 0 additions & 5 deletions
This file was deleted.

custom_files/wuproxy_release/note.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,3 @@ Files/Folders Index:
55
certs: Contains all the tools required to produce a certificate in use with WUProxy.
66
content: Contains content that is replaced by the proxy.
77
jmagicproxy.cfg: The configuration file which is ready to use with WUProxy.
8-
mu_optin.reg: A registry file to attempt to Opt-In for Microsoft Update ( it didn't work on Windows XP, and still untested on Windows 2000 )
9-
mu_optin.vbs: A VisualBasic script which will Opt-In for Microsoft Update ( tested on Windows XP, it works )

readme.md

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,20 @@ This proxy consists in a system which allows HTTP and HTTPS requests to be modif
1414
2) **Configuration file**
1515
| Options | Description |
1616
| ---------------------------- | --------------------------------------------------------------------------------- |
17-
| *-proxy.ssl.keystoretype* | Represents the type of the keystore ( pkcs12 by default ) |
18-
| *-proxy.plugins* | Represents the list of plugins to modify requests. Multiple plugins can be used with a semicolon. Example: io.github.explodingbottle.jmagicproxy.implementation.WUProxy;io.github.explodingbottle.jmagicproxy.implementation.BasicProxy. The plugin which is at the left will be the most priority, and the one at the right will be the less priority one. |
19-
| *-proxy.ssl.keystorepass* | Represents the password to access the keystore.
20-
| *-proxy.ssl.warn.algorithms* | Choose whether or not you must be warned if the java.security file disables some algorithms.
21-
| *-proxy.ssl.keystorepath* | Where to find the keystore file.
22-
| *-proxy.server.port* | Represents the proxy port for both HTTP and HTTPS.
23-
| *-proxy.logging.logfile* | Represents the naming of log files. **&\$LNUM\$** is a placeholder that can be used and denotes the current milliseconds. |
24-
| *-proxy.plugin.wuproxy.redirectjs* | A setting specific for WUProxy: Where can we find a replaced version of redirect.js
25-
| *-proxy.ssl.scan.startingport* | Represents what is the first port to scan to find where a SSL Server Socket can be created on the local machine.
26-
| *-proxy.logging.logsfolder* | Represents the folder in which you will find log files.
27-
| *-proxy.ssl.enabled* | Choose whether or not if SSL will be supported.
17+
| *proxy.ssl.keystoretype* | Represents the type of the keystore ( pkcs12 by default ) |
18+
| *proxy.plugins* | Represents the list of plugins to modify requests. Multiple plugins can be used with a semicolon. Example: io.github.explodingbottle.jmagicproxy.implementation.WUProxy;io.github.explodingbottle.jmagicproxy.implementation.BasicProxy. The plugin which is at the left will be the most priority, and the one at the right will be the less priority one. |
19+
| *proxy.ssl.keystorepass* | Represents the password to access the keystore. |
20+
| *proxy.ssl.warn.algorithms* | Choose whether or not you must be warned if the java.security file disables some algorithms. |
21+
| *proxy.ssl.keystorepath* | Where to find the keystore file. |
22+
| *proxy.server.port* | Represents the proxy port for both HTTP and HTTPS. |
23+
| *proxy.logging.logfile* | Represents the naming of log files. **&\$LNUM\$** is a placeholder that can be used and denotes the current milliseconds. |
24+
| *proxy.plugin.wuproxy.redirectjs* | A setting specific for WUProxy: Where can we find a replaced version of redirect.js |
25+
| *proxy.ssl.scan.startingport* | Represents what is the first port to scan to find where a SSL Server Socket can be created on the local machine. |
26+
| *proxy.logging.logsfolder* | Represents the folder in which you will find log files. |
27+
| *proxy.ssl.enabled* | Choose whether or not if SSL will be supported. |
28+
| *proxy.ssl.sortmode* | Represents the sorting mode used to determine if a direct SSL connection must be established or instead if the Proxy must handle it. **NONE** means that every SSL requests will be handled by the proxy. **INCLUDE** means that only listed requests will be handled by the proxy and **EXCLUDE** means that only listed requests will be sent through a tunel directly. |
29+
| *proxy.ssl.sortlist* | A list of requests splited with semi-colons that will be used with the sort mode. * can be used to mean everything. An example could be *.google.com;*.microsoft.com |
30+
| *proxy.plugin.wuproxy.redirwuclient* | A setting specific for WUProxy: Defines if we must simulate an older version of the Windows Update client in order to allow Windows XP to update |
2831
3) **Known issues**
2932

3033
- A lot of exceptions can be thrown in the console.
@@ -39,12 +42,7 @@ in order to allow the WUProxy plugin impact requests.
3942
Next, you must set proxy.plugin.wuproxy.redirectjs to where you can find a replaced redirect.js ( very important as it allows you to access the Windows Update website )
4043
Be sure to generate a certificate using the tools available in the certs folder and to install it as computer account.
4144

42-
Operating System Status:
45+
**Operating System Status**:
4346

44-
Windows 2000: If you install the proxy certificate as well as the Microsoft Root Certificate Authority
45-
(it can be extracted from https://fe2.update.microsoft.com/v8/windowsupdate/redir/muv3wuredir.cab), if you
46-
also configure Internet Explorer Proxy AND the System Proxy to point to this proxy, everything will work fine with no modifications.
47-
48-
Windows XP: You need to install this proxy certificate, configure Internet Explorer Proxy AND the System Proxy to point to this proxy
49-
and then configure the WSUS Server location as https://fe2.update.microsoft.com/v6 and the status server location as http://statsfe2.update.microsoft.com
50-
The website won't work.
47+
Windows 2000, Windows XP, Windows Server 2003, Windows POSReady 2009 and all the Windows NT 5 operating systems are supported. Please check out the wiki\
48+
for configuration instructions.

src/io/github/explodingbottle/jmagicproxy/ProxyMain.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
import io.github.explodingbottle.jmagicproxy.properties.PropertiesProvider;
2828
import io.github.explodingbottle.jmagicproxy.properties.PropertyKey;
2929
import io.github.explodingbottle.jmagicproxy.proxy.ssl.SSLObjectsProvider;
30+
import io.github.explodingbottle.jmagicproxy.proxy.ssl.SSLSortEngine;
31+
import io.github.explodingbottle.jmagicproxy.proxy.ssl.SSLSortMode;
3032
import io.github.explodingbottle.jmagicproxy.server.SocketAcceptorThread;
3133

3234
/**
@@ -39,6 +41,16 @@ public class ProxyMain {
3941
private static LoggerProvider lgp;
4042
private static PropertiesProvider propsProvider;
4143
private static PluginsManager pluginsManager;
44+
private static SSLSortEngine sslSortEngine;
45+
46+
/**
47+
* Returns the SSL sort engine.
48+
*
49+
* @return The SSL sort engine.
50+
*/
51+
public static SSLSortEngine getSSLSortEngine() {
52+
return sslSortEngine;
53+
}
4254

4355
/**
4456
* Returns the logger provider.
@@ -124,7 +136,8 @@ public static void main(String[] args) {
124136
if (ovc != null) {
125137
config = ovc;
126138
}
127-
System.out.println("Please report any bugs to https://github.com/ExplodingBottle/JMagicProxy/issues so a fix can be found.");
139+
System.out.println(
140+
"Please report any bugs to https://github.com/ExplodingBottle/JMagicProxy/issues so a fix can be found.");
128141
System.out.println();
129142
lgp = new LoggerProvider(true);
130143
shutdownThread = new ShutdownThread();
@@ -141,6 +154,13 @@ public static void main(String[] args) {
141154
"Failed to create the logs folder, this may cause issues afterwards.");
142155
}
143156
}
157+
SSLSortMode sortMode = SSLSortMode.NONE;
158+
try {
159+
sortMode = SSLSortMode.valueOf(propsProvider.getAsString(PropertyKey.PROXY_SSL_SORT_MODE));
160+
} catch (IllegalArgumentException e) {
161+
mainLogger.log(LoggingLevel.WARN, "Failed to parse sort mode. Default NONE will be used.", e);
162+
}
163+
sslSortEngine = new SSLSortEngine(sortMode, propsProvider.getAsString(PropertyKey.PROXY_SSL_SORT_LIST));
144164
lgp.openLogStream(new File(logsFolder, logPath));
145165
pluginsManager = new PluginsManager(propsProvider.getAsString(PropertyKey.PROXY_PLUGINS));
146166
pluginsManager.loadPlugins();

src/io/github/explodingbottle/jmagicproxy/api/ConnectionDirective.java

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ public class ConnectionDirective {
3333
private boolean isSSL;
3434
private HttpRequestHeader outcomingRequest;
3535

36+
private boolean isDirect;
37+
3638
private File fileInput;
3739

3840
private boolean isUsingFile;
@@ -46,13 +48,18 @@ public class ConnectionDirective {
4648
* Server Socket.
4749
* @param outcomingRequest Represents the out-coming first line sent to the
4850
* server. Ignored if isSSL is true.
51+
* @param isDirect Represents if the SSL connection must be through our
52+
* custom pipe or else direct ( with no modifications ).
53+
* Only works with HTTPS, isSSL must be true.
4954
*/
50-
public ConnectionDirective(String host, int port, boolean isSSL, HttpRequestHeader outcomingRequest) {
55+
public ConnectionDirective(String host, int port, boolean isSSL, HttpRequestHeader outcomingRequest,
56+
boolean isDirect) {
5157
this.host = host;
5258
this.port = port;
5359
this.isSSL = isSSL;
5460
this.outcomingRequest = outcomingRequest;
5561
isUsingFile = false;
62+
this.isDirect = isDirect;
5663
}
5764

5865
/**
@@ -68,7 +75,7 @@ public ConnectionDirective(File fileInput) {
6875
public String toString() {
6976
if (!isUsingFile)
7077
return "{Host=" + host + ";Port=" + port + ";IsSSL=" + isSSL + ";OutcomingRequest=" + outcomingRequest
71-
+ "}";
78+
+ ";IsDirect=" + isDirect + "}";
7279
else
7380
return "{UsingFile=true}";
7481
}
@@ -82,6 +89,17 @@ public File getFileInput() {
8289
return fileInput;
8390
}
8491

92+
/**
93+
* Used to set the file used to change content.
94+
*
95+
* @return The file to replace with.
96+
*/
97+
public void setFileInput(File input) {
98+
fileInput = input;
99+
if (fileInput != null)
100+
isUsingFile = true;
101+
}
102+
85103
/**
86104
* Used to see if the directive is using a file or an URL.
87105
*
@@ -154,6 +172,24 @@ public boolean isSSL() {
154172
return isSSL;
155173
}
156174

175+
/**
176+
* Gets if the connection will be direct.
177+
*
178+
* @return True if the connection be direct.
179+
*/
180+
public boolean isDirect() {
181+
return isDirect;
182+
}
183+
184+
/**
185+
* Sets if the connection will be direct.
186+
*
187+
* @param isDirect corresponds to if the connection will be direct.
188+
*/
189+
public void setDirect(boolean isDirect) {
190+
this.isDirect = isDirect;
191+
}
192+
157193
/**
158194
* Sets if the connection will be in SSL.
159195
*

src/io/github/explodingbottle/jmagicproxy/api/HttpRequestHeader.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,9 @@ public static HttpRequestHeader createFromHeaderBlock(StringBuilder builder) thr
155155
throw new MalformedParsableContent("First line is not a correct method.");
156156
host = splitedFL[1];
157157
httpVersion = splitedFL[2];
158+
if (!httpVersion.startsWith("HTTP/")) {
159+
throw new MalformedParsableContent("Request version doesn't starts with HTTP.");
160+
}
158161
} else {
159162
throw new MalformedParsableContent("First line doesn't have 3 chunks.");
160163
}

src/io/github/explodingbottle/jmagicproxy/api/HttpResponse.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ public static HttpResponse createFromHeaderBlock(StringBuilder builder) throws M
9090
String[] splitedFL = line.split(" ");
9191
if (splitedFL.length >= 3) {
9292
httpVersion = splitedFL[0];
93+
if (!httpVersion.startsWith("HTTP/")) {
94+
throw new MalformedParsableContent("Response version doesn't starts with HTTP.");
95+
}
9396
try {
9497
responseCode = new Integer(Integer.parseInt(splitedFL[1]));
9598
} catch (Exception e) {

src/io/github/explodingbottle/jmagicproxy/implementation/BasicProxy.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import io.github.explodingbottle.jmagicproxy.api.SSLControlInformations;
3232
import io.github.explodingbottle.jmagicproxy.logging.LoggingLevel;
3333
import io.github.explodingbottle.jmagicproxy.logging.ProxyLogger;
34+
import io.github.explodingbottle.jmagicproxy.proxy.ssl.SSLSortEngine;
3435

3536
/**
3637
* This is a required basic implementation of the proxy, else it won't work.
@@ -66,6 +67,8 @@ public ConnectionDirective onReceiveProxyRequest(HttpRequestHeader request) {
6667
String realHost = null;
6768
int realPort = 80;
6869

70+
boolean isDirect = false;
71+
6972
if (method == HttpMethod.CONNECT) {
7073
String[] splitedHostURL = host.split(":");
7174
if (splitedHostURL.length == 2) {
@@ -81,7 +84,12 @@ public ConnectionDirective onReceiveProxyRequest(HttpRequestHeader request) {
8184
realHost = host;
8285
realPort = 443;
8386
}
84-
isSSL = true;
87+
SSLSortEngine engine = ProxyMain.getSSLSortEngine();
88+
isDirect = !engine.shouldUseCustomPipe(realHost);
89+
if (isDirect) {
90+
logger.log(LoggingLevel.INFO, "SSLSortEngine decided that " + realHost + ":" + realPort
91+
+ " will be using direct connection.");
92+
}
8593
} else {
8694
String[] splitedHost = host.split("/");
8795
if (splitedHost.length >= 3) {
@@ -111,7 +119,7 @@ public ConnectionDirective onReceiveProxyRequest(HttpRequestHeader request) {
111119
return null;
112120
}
113121
}
114-
return new ConnectionDirective(realHost, realPort, isSSL, httpReq);
122+
return new ConnectionDirective(realHost, realPort, isSSL, httpReq, isDirect);
115123
}
116124

117125
@Override
@@ -132,8 +140,9 @@ public IncomingTransferDirective onReceiveServerAnswer(HttpResponse response) {
132140
logger.log(LoggingLevel.INFO, "Detected a Connection header with " + headers.get("Connection"));
133141
if ("Close".equalsIgnoreCase(headers.get("Connection")))
134142
defaultConType = ConnectionType.CLOSE;
135-
if ("Keep-Alive".equalsIgnoreCase(headers.get("Connection")))
143+
if ("Keep-Alive".equalsIgnoreCase(headers.get("Connection"))) {
136144
defaultConType = ConnectionType.KEEPALIVE;
145+
}
137146
}
138147
return new IncomingTransferDirective(response, defaultConType);
139148
}

0 commit comments

Comments
 (0)