├── .github
├── dependabot.yml
└── images
│ ├── logo.png
│ └── ui.png
├── .gitignore
├── CHANGELOG
├── LICENSE
├── README.md
├── VERSION
├── build.gradle
├── core
├── .gitignore
├── build.gradle
└── src
│ └── main
│ └── java
│ └── io
│ └── github
│ └── krlvm
│ └── powertunnel
│ ├── BuildConstants.java
│ ├── LittleProxyServer.java
│ ├── PowerTunnel.java
│ ├── adapters
│ ├── ProxyFiltersSourceAdapter.java
│ └── UpstreamChainedProxyAdapter.java
│ ├── callbacks
│ └── InputStreamConsumer.java
│ ├── configuration
│ └── ConfigurationStore.java
│ ├── exceptions
│ ├── ConfigurationParseException.java
│ └── PreferenceParseException.java
│ ├── filters
│ └── ProxyFilter.java
│ ├── http
│ ├── LHttpHeaders.java
│ ├── LProxyMessage.java
│ ├── LProxyRequest.java
│ └── LProxyResponse.java
│ ├── i18n
│ ├── I18NBundle.java
│ └── UTF8Control.java
│ ├── listener
│ ├── CoreProxyListener.java
│ ├── ProxyListenerCallback.java
│ ├── ProxyListenerInfo.java
│ └── ServerListenerCallback.java
│ ├── managers
│ ├── ProxyAuthenticationManager.java
│ └── UpstreamProxyChainedProxyManager.java
│ ├── mitm
│ └── MITMAuthority.java
│ ├── plugin
│ ├── PluginInjector.java
│ └── PluginLoader.java
│ ├── preferences
│ ├── Preference.java
│ ├── PreferenceGroup.java
│ ├── PreferenceParser.java
│ └── PreferenceType.java
│ ├── resolver
│ ├── DNSResolverWrapper.java
│ └── LDNSResolver.java
│ └── utilities
│ └── JarLoader.java
├── desktop
├── .gitignore
├── build.gradle
├── libs
│ └── swingdpi-1.2.jar
└── src
│ └── main
│ ├── java
│ └── io
│ │ └── github
│ │ └── krlvm
│ │ └── powertunnel
│ │ └── desktop
│ │ ├── BuildConstants.java
│ │ ├── Main.java
│ │ ├── application
│ │ ├── ConsoleApp.java
│ │ ├── DesktopApp.java
│ │ └── GraphicalApp.java
│ │ ├── configuration
│ │ ├── AdvancedConfiguration.java
│ │ └── ServerConfiguration.java
│ │ ├── frames
│ │ ├── AppFrame.java
│ │ ├── MainFrame.java
│ │ ├── OptionsFrame.java
│ │ ├── PluginsFrame.java
│ │ └── PreferencesFrame.java
│ │ ├── managers
│ │ ├── ApplicationManager.java
│ │ ├── ConsoleHandler.java
│ │ └── TrayManager.java
│ │ ├── parser
│ │ └── ArgumentParser.java
│ │ ├── system
│ │ ├── ConsoleReader.java
│ │ ├── SystemProxy.java
│ │ └── windows
│ │ │ ├── WindowsProxyHandler.java
│ │ │ └── Wininet.java
│ │ ├── types
│ │ ├── ConsoleCommand.java
│ │ └── TrayMode.java
│ │ ├── ui
│ │ ├── ComboBoxScroll.java
│ │ ├── FieldFilter.java
│ │ ├── I18N.java
│ │ ├── PluginInfoRenderer.java
│ │ ├── ScrollablePanel.java
│ │ ├── SelectPreferenceRenderer.java
│ │ └── TextRightClickPopup.java
│ │ ├── updater
│ │ ├── UpdateInfo.java
│ │ └── UpdateNotifier.java
│ │ └── utilities
│ │ ├── SystemUtility.java
│ │ ├── UIUtility.java
│ │ └── Utility.java
│ └── resources
│ ├── icon.png
│ ├── icon_dev.png
│ ├── locale
│ ├── messages_en.properties
│ └── messages_ru.properties
│ ├── log4j2.xml
│ └── plugins
│ ├── DNSResolver.jar
│ └── LibertyTunnel.jar
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── littleproxy
├── .gitignore
├── build.gradle
└── src
│ └── main
│ └── java
│ ├── io
│ └── netty
│ │ └── handler
│ │ └── codec
│ │ └── http
│ │ └── HttpMethod.java
│ ├── java
│ └── nio
│ │ └── charset
│ │ └── StandardCharsets.java
│ └── org
│ └── littleshoot
│ └── proxy
│ ├── HttpFilters.java
│ ├── HttpFiltersAdapter.java
│ ├── impl
│ ├── CategorizedThreadFactory.java
│ ├── ClientToProxyConnection.java
│ └── ProxyToServerConnection.java
│ └── mitm
│ ├── Authority.java
│ ├── BouncyCastleSslEngineSource.java
│ ├── CertificateHelper.java
│ ├── CertificateSniffingMitmManager.java
│ ├── FakeCertificateException.java
│ ├── MergeTrustManager.java
│ ├── MitmHelper.java
│ ├── RootCertificateException.java
│ └── SubjectAlternativeNameHolder.java
├── sample-plugin
├── .gitignore
├── build.gradle
└── src
│ └── main
│ ├── java
│ └── io
│ │ └── github
│ │ └── krlvm
│ │ └── powertunnel
│ │ └── plugins
│ │ └── sample
│ │ └── SamplePlugin.java
│ └── resources
│ ├── locale
│ ├── messages_en.properties
│ └── messages_ru.properties
│ ├── plugin.ini
│ └── preferences.json
├── sdk
├── .gitignore
├── build.gradle
├── libs
│ └── android-base64.jar
└── src
│ └── main
│ └── java
│ └── io
│ └── github
│ └── krlvm
│ └── powertunnel
│ └── sdk
│ ├── PowerTunnelServer.java
│ ├── ServerAdapter.java
│ ├── ServerListener.java
│ ├── configuration
│ └── Configuration.java
│ ├── exceptions
│ ├── ConfigurationLoadException.java
│ ├── PluginLoadException.java
│ └── ProxyStartException.java
│ ├── http
│ ├── HttpHeaders.java
│ ├── HttpMethod.java
│ ├── ProxyMessage.java
│ ├── ProxyRequest.java
│ └── ProxyResponse.java
│ ├── plugin
│ ├── IPowerTunnelPlugin.java
│ ├── PluginInfo.java
│ └── PowerTunnelPlugin.java
│ ├── proxy
│ ├── DNSRequest.java
│ ├── DNSResolver.java
│ ├── ProxyAdapter.java
│ ├── ProxyAddress.java
│ ├── ProxyCredentials.java
│ ├── ProxyListener.java
│ ├── ProxyServer.java
│ ├── ProxyStatus.java
│ └── UpstreamProxyServer.java
│ ├── types
│ ├── FullAddress.java
│ ├── PowerTunnelPlatform.java
│ ├── UpstreamProxyType.java
│ └── VersionInfo.java
│ └── utiities
│ ├── Base64Compat.java
│ └── TextReader.java
├── settings.gradle
└── version.txt
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # To get started with Dependabot version updates, you'll need to specify which
2 | # package ecosystems to update and where the package manifests are located.
3 | # Please see the documentation for all configuration options:
4 | # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
5 |
6 | version: 2
7 | updates:
8 | - package-ecosystem: gradle
9 | directory: "/"
10 | schedule:
11 | interval: "daily"
12 |
--------------------------------------------------------------------------------
/.github/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krlvm/PowerTunnel/3e5df1e6ce4e12628fee4e2b940e4db9067cde3c/.github/images/logo.png
--------------------------------------------------------------------------------
/.github/images/ui.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krlvm/PowerTunnel/3e5df1e6ce4e12628fee4e2b940e4db9067cde3c/.github/images/ui.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Idea Files
2 | /.idea/
3 | /PowerTunnel.iml
4 |
5 | # Build Files
6 | /build/
7 | /.gradle/
8 |
9 | key.properties
10 | keystore.jks
--------------------------------------------------------------------------------
/CHANGELOG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krlvm/PowerTunnel/3e5df1e6ce4e12628fee4e2b940e4db9067cde3c/CHANGELOG
--------------------------------------------------------------------------------
/VERSION:
--------------------------------------------------------------------------------
1 | 100;2.0
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | plugins {
19 | id 'idea'
20 | }
21 |
22 | subprojects {
23 | apply plugin: 'java'
24 |
25 | group 'io.github.krlvm.powertunnel'
26 |
27 | ext {
28 | isReleaseVersion = !version.endsWith('SNAPSHOT')
29 | }
30 |
31 | java {
32 | sourceCompatibility = JavaVersion.VERSION_1_8
33 | targetCompatibility = JavaVersion.VERSION_1_8
34 | }
35 | tasks.withType(JavaCompile) {
36 | options.encoding = 'UTF-8'
37 | options.compilerArgs += ['-Xlint:deprecation']
38 | }
39 |
40 | repositories {
41 | mavenCentral()
42 | }
43 |
44 | test {
45 | useJUnitPlatform()
46 | }
47 | }
--------------------------------------------------------------------------------
/core/.gitignore:
--------------------------------------------------------------------------------
1 | /build/
2 |
--------------------------------------------------------------------------------
/core/build.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | plugins {
19 | id 'java-library'
20 | id 'application'
21 | }
22 |
23 | version '2.5.2'
24 |
25 | configurations {
26 | runtimeClasspath {
27 | exclude group: 'com.google.guava', module: 'guava'
28 | }
29 | }
30 | task fatJar(type: Jar, group: 'build', description: 'Assembles a jar archive containing the main classes and all dependencies.') {
31 | archiveClassifier = 'all'
32 | duplicatesStrategy DuplicatesStrategy.EXCLUDE
33 |
34 | from {
35 | configurations.runtimeClasspath.findAll {it.name.endsWith('jar') }.collect { zipTree(it) }
36 | } {
37 | exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA'
38 | }
39 |
40 | with jar
41 | }
42 |
43 | dependencies {
44 | api project(':sdk')
45 | api project(':littleproxy')
46 | api 'org.jetbrains:annotations:23.0.0'
47 | implementation 'com.google.code.gson:gson:2.8.9'
48 |
49 | testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.2'
50 | testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.2'
51 | }
--------------------------------------------------------------------------------
/core/src/main/java/io/github/krlvm/powertunnel/BuildConstants.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel;
19 |
20 | public class BuildConstants {
21 | public static final String NAME = "PowerTunnel";
22 | public static final String REPO = "https://github.com/krlvm/PowerTunnel";
23 | public static final String VERSION = "2.5.2";
24 | public static final int VERSION_CODE = 110;
25 | public static final int SDK = 110;
26 |
27 | public static boolean IS_RELEASE = isReleaseVersion(VERSION);
28 | public static final boolean DEBUG = !IS_RELEASE;
29 |
30 | public static boolean isReleaseVersion(final String version) {
31 | return !(
32 | version.contains("-dev") ||
33 | version.contains("-alpha") ||
34 | version.contains("-beta") ||
35 | version.contains("-preview") ||
36 | version.contains("-rc")
37 | );
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/core/src/main/java/io/github/krlvm/powertunnel/adapters/ProxyFiltersSourceAdapter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.adapters;
19 |
20 | import io.github.krlvm.powertunnel.filters.ProxyFilter;
21 | import io.github.krlvm.powertunnel.sdk.proxy.ProxyListener;
22 | import io.netty.channel.ChannelHandlerContext;
23 | import io.netty.handler.codec.http.HttpRequest;
24 | import org.littleshoot.proxy.HttpFilters;
25 | import org.littleshoot.proxy.HttpFiltersSourceAdapter;
26 |
27 | public class ProxyFiltersSourceAdapter extends HttpFiltersSourceAdapter {
28 |
29 | private final ProxyListener listener;
30 | private final boolean isFullRequest, isFullResponse;
31 |
32 | public ProxyFiltersSourceAdapter(ProxyListener listener, boolean isFullRequest, boolean isFullResponse) {
33 | this.listener = listener;
34 | this.isFullRequest = isFullRequest;
35 | this.isFullResponse = isFullResponse;
36 | }
37 |
38 | @Override
39 | public HttpFilters filterRequest(HttpRequest originalRequest) {
40 | return new ProxyFilter(this.listener, originalRequest);
41 | }
42 |
43 | @Override
44 | public HttpFilters filterRequest(HttpRequest originalRequest, ChannelHandlerContext ctx) {
45 | return new ProxyFilter(this.listener, originalRequest/*, ctx*/);
46 | }
47 |
48 | @Override
49 | public int getMaximumRequestBufferSizeInBytes() {
50 | return this.isFullRequest ? 10 * 1024 * 1024 : super.getMaximumResponseBufferSizeInBytes();
51 | }
52 |
53 | @Override
54 | public int getMaximumResponseBufferSizeInBytes() {
55 | return this.isFullResponse ? 10 * 1024 * 1024 : super.getMaximumResponseBufferSizeInBytes();
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/core/src/main/java/io/github/krlvm/powertunnel/callbacks/InputStreamConsumer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.callbacks;
19 |
20 | import java.io.IOException;
21 | import java.io.InputStream;
22 |
23 | public interface InputStreamConsumer {
24 | void accept(InputStream inputStream) throws IOException;
25 | }
26 |
--------------------------------------------------------------------------------
/core/src/main/java/io/github/krlvm/powertunnel/configuration/ConfigurationStore.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.configuration;
19 |
20 | import io.github.krlvm.powertunnel.sdk.configuration.Configuration;
21 |
22 | import java.io.*;
23 | import java.nio.charset.StandardCharsets;
24 | import java.util.Collection;
25 | import java.util.HashMap;
26 | import java.util.Map;
27 | import java.util.Set;
28 |
29 | public class ConfigurationStore implements Configuration {
30 |
31 | private static final String DELIMITER = ": ";
32 | private static final int DELIMITER_LENGTH = DELIMITER.length();
33 |
34 | protected final Map data = new HashMap<>();
35 |
36 | public void read(File file) throws IOException {
37 | file.createNewFile();
38 | this.read(new FileReader(file));
39 | }
40 |
41 | public void read(InputStream in) throws IOException {
42 | this.read(new InputStreamReader(in, StandardCharsets.UTF_8));
43 | }
44 |
45 | public void read(Reader source) throws IOException {
46 | data.clear();
47 |
48 | try(BufferedReader reader = new BufferedReader(source)) {
49 | String line;
50 | while((line = reader.readLine()) != null) {
51 | final int pos = line.indexOf(DELIMITER);
52 | if (pos == -1) continue;
53 | data.put(
54 | line.substring(0, pos),
55 | line.substring(pos + DELIMITER_LENGTH)
56 | );
57 | }
58 | }
59 | }
60 |
61 | public void save(File file) throws IOException {
62 | int current = 0;
63 | try(BufferedWriter writer = new BufferedWriter(new FileWriter(file))) {
64 | for (Map.Entry entry : entries()) {
65 | writer.write(entry.getKey() + DELIMITER + entry.getValue());
66 | if (++current != data.size()) {
67 | writer.write("\r\n");
68 | }
69 | }
70 | writer.flush();
71 | }
72 | }
73 |
74 | protected Set> entries() {
75 | return data.entrySet();
76 | }
77 |
78 | @Override
79 | public String get(String key, String defaultValue) {
80 | if (!data.containsKey(key)) set(key, defaultValue);
81 | return data.get(key);
82 | }
83 |
84 | @Override
85 | public void set(String key, String value) {
86 | data.put(key, value);
87 | }
88 |
89 | @Override
90 | public int getInt(String key, int defaultValue) {
91 | if (!data.containsKey(key)) setInt(key, defaultValue);
92 | return Integer.parseInt(data.get(key));
93 | }
94 |
95 | @Override
96 | public void setInt(String key, int value) {
97 | data.put(key, String.valueOf(value));
98 | }
99 |
100 | @Override
101 | public long getLong(String key, long defaultValue) {
102 | if (!data.containsKey(key)) setLong(key, defaultValue);
103 | return Long.parseLong(data.get(key));
104 | }
105 |
106 | @Override
107 | public void setLong(String key, long value) {
108 | data.put(key, String.valueOf(value));
109 | }
110 |
111 | @Override
112 | public boolean getBoolean(String key, boolean defaultValue) {
113 | if (!data.containsKey(key)) setBoolean(key, defaultValue);
114 | return Boolean.parseBoolean(data.get(key));
115 | }
116 |
117 | @Override
118 | public void setBoolean(String key, boolean value) {
119 | data.put(key, String.valueOf(value));
120 | }
121 |
122 | @Override
123 | public boolean contains(String key) {
124 | return data.containsKey(key);
125 | }
126 |
127 | @Override
128 | public void remove(String key) {
129 | data.remove(key);
130 | }
131 |
132 | @Override
133 | public Map toMap() {
134 | return data;
135 | }
136 |
137 | @Override
138 | public Collection keys() {
139 | return data.keySet();
140 | }
141 |
142 | @Override
143 | public void clear() {
144 | data.clear();
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/core/src/main/java/io/github/krlvm/powertunnel/exceptions/ConfigurationParseException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.exceptions;
19 |
20 | public class ConfigurationParseException extends Exception {
21 |
22 | public ConfigurationParseException(String message) {
23 | super(message);
24 | }
25 |
26 | public ConfigurationParseException(Throwable cause) {
27 | super(cause);
28 | }
29 |
30 | public ConfigurationParseException(String message, Throwable cause) {
31 | super(message, cause);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/core/src/main/java/io/github/krlvm/powertunnel/exceptions/PreferenceParseException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.exceptions;
19 |
20 | public class PreferenceParseException extends Exception {
21 |
22 | private final String source;
23 |
24 | public PreferenceParseException(String source, String message) {
25 | this(source, message, null);
26 | }
27 |
28 | public PreferenceParseException(String source, String message, Throwable cause) {
29 | super(message, cause);
30 | this.source = source;
31 | }
32 |
33 | public String getSource() {
34 | return source;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/core/src/main/java/io/github/krlvm/powertunnel/filters/ProxyFilter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.filters;
19 |
20 | import io.github.krlvm.powertunnel.http.LProxyRequest;
21 | import io.github.krlvm.powertunnel.http.LProxyResponse;
22 | import io.github.krlvm.powertunnel.sdk.proxy.ProxyListener;
23 | import io.github.krlvm.powertunnel.sdk.types.FullAddress;
24 | import io.netty.channel.ChannelHandlerContext;
25 | import io.netty.handler.codec.http.HttpObject;
26 | import io.netty.handler.codec.http.HttpRequest;
27 | import io.netty.handler.codec.http.HttpResponse;
28 | import org.littleshoot.proxy.HttpFiltersAdapter;
29 |
30 | public class ProxyFilter extends HttpFiltersAdapter {
31 |
32 | private final ProxyListener listener;
33 | private FullAddress address;
34 |
35 | public ProxyFilter(ProxyListener listener, HttpRequest originalRequest) {
36 | this(listener, originalRequest, null);
37 | }
38 |
39 | public ProxyFilter(ProxyListener listener, HttpRequest originalRequest, ChannelHandlerContext ctx) {
40 | super(originalRequest, ctx);
41 | this.listener = listener;
42 | }
43 |
44 | @Override
45 | public void saveAddress(String hostAndPort, boolean isCONNECT) {
46 | this.address = FullAddress.fromString(hostAndPort, isCONNECT ? 443 : 80);
47 | }
48 |
49 | @Override
50 | public HttpResponse clientToProxyRequest(HttpObject httpObject) {
51 | if(!(httpObject instanceof HttpRequest)) return null;
52 | LProxyRequest req = new LProxyRequest(((HttpRequest) httpObject), address);
53 | listener.onClientToProxyRequest(req);
54 | return req.getLittleProxyResponse();
55 | }
56 |
57 | @Override
58 | public HttpResponse proxyToServerRequest(HttpObject httpObject) {
59 | if(!(httpObject instanceof HttpRequest)) return null;
60 | LProxyRequest req = new LProxyRequest(((HttpRequest) httpObject), address);
61 | listener.onProxyToServerRequest(req);
62 | return req.getLittleProxyResponse();
63 | }
64 |
65 | @Override
66 | public HttpObject serverToProxyResponse(HttpObject httpObject) {
67 | if(!(httpObject instanceof HttpResponse)) return httpObject;
68 | LProxyResponse res = new LProxyResponse(((HttpResponse) httpObject), address);
69 | listener.onServerToProxyResponse(res);
70 | return res.getLittleProxyObject();
71 | }
72 |
73 | @Override
74 | public HttpObject proxyToClientResponse(HttpObject httpObject) {
75 | if(!(httpObject instanceof HttpResponse)) return httpObject;
76 | LProxyResponse res = new LProxyResponse(((HttpResponse) httpObject), address);
77 | listener.onProxyToClientResponse(res);
78 | return res.getLittleProxyObject();
79 | }
80 |
81 | @Override
82 | public int chunkSize() {
83 | return listener.onGetChunkSize(address);
84 | }
85 |
86 | @Override
87 | public boolean fullChunking() {
88 | return listener.isFullChunking(address);
89 | }
90 |
91 | @Override
92 | public String mitmGetSNI(String hostname) {
93 | return (String)listener.onGetSNI(hostname);
94 | }
95 |
96 | @Override
97 | public boolean proxyToServerAllowMitm() {
98 | return listener.isMITMAllowed(address);
99 | }
100 |
101 | static {
102 | System.setProperty("sun.net.http.allowRestrictedHeaders", "true");
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/core/src/main/java/io/github/krlvm/powertunnel/http/LHttpHeaders.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.http;
19 |
20 | import io.github.krlvm.powertunnel.sdk.http.HttpHeaders;
21 | import org.jetbrains.annotations.NotNull;
22 | import org.jetbrains.annotations.Nullable;
23 |
24 | import java.util.Set;
25 |
26 | public class LHttpHeaders implements HttpHeaders {
27 |
28 | private final io.netty.handler.codec.http.HttpHeaders headers;
29 |
30 | public LHttpHeaders(io.netty.handler.codec.http.HttpHeaders headers) {
31 | this.headers = headers;
32 | }
33 |
34 | @Override
35 | public @Nullable String get(String name) {
36 | return headers.get(name);
37 | }
38 |
39 | @Override
40 | public void set(@NotNull String name, @NotNull String value) {
41 | headers.set(name, value);
42 | }
43 |
44 | @Override
45 | public @Nullable Integer getInt(String name) {
46 | return headers.getInt(name);
47 | }
48 |
49 | @Override
50 | public void setInt(@NotNull String name, int value) {
51 | headers.setInt(name, value);
52 | }
53 |
54 | @Override
55 | public @Nullable Short getShort(String name) {
56 | return headers.getShort(name);
57 | }
58 |
59 | @Override
60 | public void setShort(@NotNull String name, short value) {
61 | headers.setShort(name, value);
62 | }
63 |
64 | @Override
65 | public @NotNull Set names() {
66 | return headers.names();
67 | }
68 |
69 | @Override
70 | public boolean contains(@NotNull String name) {
71 | return headers.contains(name);
72 | }
73 |
74 | @Override
75 | public void remove(@NotNull String name) {
76 | headers.remove(name);
77 | }
78 |
79 | @Override
80 | public boolean isEmpty() {
81 | return headers.isEmpty();
82 | }
83 |
84 | @Override
85 | public int size() {
86 | return headers.size();
87 | }
88 |
89 | @Override
90 | public String toString() {
91 | return headers.toString();
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/core/src/main/java/io/github/krlvm/powertunnel/http/LProxyMessage.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.http;
19 |
20 | import io.github.krlvm.powertunnel.sdk.http.HttpHeaders;
21 | import io.github.krlvm.powertunnel.sdk.http.ProxyMessage;
22 | import io.github.krlvm.powertunnel.sdk.types.FullAddress;
23 | import org.jetbrains.annotations.NotNull;
24 | import org.jetbrains.annotations.Nullable;
25 |
26 | public abstract class LProxyMessage implements ProxyMessage {
27 |
28 | protected T httpObject;
29 | protected HttpHeaders headers;
30 |
31 | protected final FullAddress address;
32 |
33 | protected LProxyMessage(T httpObject, FullAddress address) {
34 | this.httpObject = httpObject;
35 | this.address = address;
36 | }
37 |
38 | @Override
39 | public @Nullable FullAddress address() {
40 | return address;
41 | }
42 |
43 | @Override
44 | public @NotNull HttpHeaders headers() {
45 | if(headers == null) headers = new LHttpHeaders(this.getHeaders());
46 | return headers;
47 | }
48 |
49 | protected abstract io.netty.handler.codec.http.HttpHeaders getHeaders();
50 |
51 | public T getLittleProxyObject() {
52 | return httpObject;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/core/src/main/java/io/github/krlvm/powertunnel/http/LProxyRequest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.http;
19 |
20 | import io.github.krlvm.powertunnel.sdk.http.HttpMethod;
21 | import io.github.krlvm.powertunnel.sdk.http.ProxyRequest;
22 | import io.github.krlvm.powertunnel.sdk.http.ProxyResponse;
23 | import io.github.krlvm.powertunnel.sdk.types.FullAddress;
24 | import io.netty.buffer.ByteBuf;
25 | import io.netty.buffer.ByteBufUtil;
26 | import io.netty.buffer.Unpooled;
27 | import io.netty.handler.codec.http.*;
28 | import org.jetbrains.annotations.NotNull;
29 | import org.jetbrains.annotations.Nullable;
30 |
31 | public class LProxyRequest extends LProxyMessage implements ProxyRequest {
32 |
33 | private ProxyResponse response;
34 |
35 | public LProxyRequest(HttpRequest request, FullAddress address) {
36 | super(request, address);
37 | }
38 |
39 | @Override
40 | public @NotNull HttpMethod getMethod() {
41 | return HttpMethod.valueOf(httpObject.method().name());
42 | }
43 |
44 | @Override
45 | public void setMethod(@NotNull HttpMethod method) {
46 | httpObject.setMethod(io.netty.handler.codec.http.HttpMethod.valueOf(method.name()));
47 | }
48 |
49 | @Override
50 | public void setMethod(@NotNull String method) {
51 | httpObject.setMethod(new io.netty.handler.codec.http.HttpMethod(method));
52 | }
53 |
54 | @Override
55 | public boolean isEncrypted() {
56 | return httpObject.method() == io.netty.handler.codec.http.HttpMethod.CONNECT;
57 | }
58 |
59 | @Override
60 | public void setBlocked(boolean blocked) {
61 | if (blocked) {
62 | setResponse(new LProxyResponse.Builder("Access denied by proxy server", 403)
63 | .contentType("text/plain")
64 | .build()
65 | );
66 | } else {
67 | this.response = null;
68 | }
69 | }
70 |
71 | @Override
72 | public boolean isBlocked() {
73 | return this.response != null;
74 | }
75 |
76 | @Override
77 | public @NotNull String getUri() {
78 | return httpObject.uri();
79 | }
80 |
81 | @Override
82 | public void setUri(@NotNull String uri) {
83 | httpObject.setUri(uri);
84 | }
85 |
86 | @Override
87 | public @Nullable ProxyResponse getResponse() {
88 | return this.response;
89 | }
90 |
91 | @Override
92 | public void setResponse(@NotNull ProxyResponse response) {
93 | this.response = response;
94 | }
95 |
96 | @Override
97 | public boolean isDataPacket() {
98 | return httpObject instanceof FullHttpRequest;
99 | }
100 |
101 | @Override
102 | public byte[] content() {
103 | if(!isDataPacket()) throw new IllegalStateException("Can't get raw content of HttpRequest chunk");
104 |
105 | final ByteBuf buf = ((FullHttpRequest) httpObject).content();
106 | return ByteBufUtil.getBytes(buf, 0, buf.readableBytes(), false);
107 | }
108 |
109 | @Override
110 | public void setContent(byte[] content) {
111 | if(!isDataPacket()) throw new IllegalStateException("Can't set raw content of HttpRequest chunk");
112 |
113 | final HttpRequest response = new DefaultFullHttpRequest(
114 | httpObject.protocolVersion(),
115 | httpObject.method(),
116 | httpObject.uri(),
117 | Unpooled.wrappedBuffer(content));
118 | response.headers().set(httpObject.headers());
119 |
120 | response.headers().set(HttpHeaderNames.CONTENT_LENGTH, content.length);
121 |
122 | httpObject = response;
123 | }
124 |
125 | @Override
126 | protected HttpHeaders getHeaders() {
127 | return httpObject.headers();
128 | }
129 |
130 | public HttpResponse getLittleProxyResponse() {
131 | if(this.response == null) return null;
132 | return ((LProxyResponse) this.response).getLittleProxyObject();
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/core/src/main/java/io/github/krlvm/powertunnel/http/LProxyResponse.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.http;
19 |
20 | import io.github.krlvm.powertunnel.sdk.http.ProxyResponse;
21 | import io.github.krlvm.powertunnel.sdk.types.FullAddress;
22 | import io.netty.buffer.ByteBuf;
23 | import io.netty.buffer.ByteBufUtil;
24 | import io.netty.buffer.Unpooled;
25 | import io.netty.handler.codec.http.*;
26 |
27 | import java.nio.charset.StandardCharsets;
28 |
29 | public class LProxyResponse extends LProxyMessage implements ProxyResponse {
30 |
31 | public LProxyResponse(HttpResponse response, FullAddress address) {
32 | super(response, address);
33 | }
34 |
35 | @Override
36 | public int code() {
37 | return httpObject.status().code();
38 | }
39 |
40 | @Override
41 | public void setCode(int code) {
42 | httpObject.setStatus(HttpResponseStatus.valueOf(code));
43 | }
44 |
45 | @Override
46 | public boolean isDataPacket() {
47 | return httpObject instanceof FullHttpResponse;
48 | }
49 |
50 | @Override
51 | public byte[] content() {
52 | if(!isDataPacket()) throw new IllegalStateException("Can't get raw content of HttpResponse chunk");
53 |
54 | final ByteBuf buf = ((FullHttpResponse) httpObject).content();
55 | return ByteBufUtil.getBytes(buf, 0, buf.readableBytes(), false);
56 | }
57 |
58 | @Override
59 | public void setContent(byte[] content) {
60 | if(!isDataPacket()) throw new IllegalStateException("Can't set raw content of HttpResponse chunk");
61 |
62 | final HttpResponse response = new DefaultFullHttpResponse(
63 | httpObject.protocolVersion(),
64 | httpObject.status(),
65 | Unpooled.wrappedBuffer(content));
66 | response.headers().set(httpObject.headers());
67 |
68 | response.headers().set(HttpHeaderNames.CONTENT_LENGTH, content.length);
69 |
70 | httpObject = response;
71 | }
72 |
73 | @Override
74 | protected HttpHeaders getHeaders() {
75 | return httpObject.headers();
76 | }
77 |
78 | public static class Builder implements ProxyResponse.Builder {
79 |
80 | private final DefaultFullHttpResponse response;
81 |
82 | public Builder(String content) {
83 | this(HttpResponseStatus.OK, content);
84 | }
85 |
86 | public Builder(String content, int code) {
87 | this(HttpResponseStatus.valueOf(code), content);
88 | }
89 |
90 | public Builder(HttpResponseStatus status, String content) {
91 | final byte[] bytes = content.getBytes(StandardCharsets.UTF_8);
92 | response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status, Unpooled.wrappedBuffer(bytes));
93 | response.headers().set(HttpHeaderNames.CONTENT_LENGTH, bytes.length);
94 | response.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE);
95 | }
96 |
97 | @Override
98 | public ProxyResponse.Builder code(int code) {
99 | response.setStatus(HttpResponseStatus.valueOf(code));
100 | return this;
101 | }
102 |
103 | @Override
104 | public ProxyResponse.Builder contentType(String contentType) {
105 | response.headers().set(HttpHeaderNames.CONTENT_TYPE, contentType + "; charset=UTF-8");
106 | return this;
107 | }
108 |
109 | @Override
110 | public ProxyResponse.Builder header(String name, String value) {
111 | response.headers().set(name, value);
112 | return this;
113 | }
114 |
115 | @Override
116 | public ProxyResponse.Builder header(String name, int value) {
117 | response.headers().setInt(name, value);
118 | return this;
119 | }
120 |
121 | @Override
122 | public ProxyResponse.Builder header(String name, short value) {
123 | response.headers().setShort(name, value);
124 | return this;
125 | }
126 |
127 | @Override
128 | public ProxyResponse build() {
129 | return new LProxyResponse(response, null);
130 | }
131 | }
132 | }
133 |
--------------------------------------------------------------------------------
/core/src/main/java/io/github/krlvm/powertunnel/i18n/I18NBundle.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.i18n;
19 |
20 | import java.util.ResourceBundle;
21 |
22 | public class I18NBundle {
23 |
24 | private final ResourceBundle bundle;
25 |
26 | public I18NBundle(ResourceBundle bundle) {
27 | this.bundle = bundle;
28 | }
29 |
30 | public String get(String key) {
31 | return get(key, "Missing locale");
32 | }
33 |
34 | public String get(String key, String defaultValue) {
35 | if(bundle == null || !bundle.containsKey(key)) return defaultValue;
36 | return bundle.getString(key);
37 | }
38 |
39 | public static String getLocalePath(String lang) {
40 | return "locale/messages_" + (lang != null ? lang : "en");
41 | }
42 | public static String getLocaleFilePath(String lang) {
43 | return getLocalePath(lang) + ".properties";
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/core/src/main/java/io/github/krlvm/powertunnel/i18n/UTF8Control.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.i18n;
19 |
20 | import java.io.IOException;
21 | import java.io.InputStream;
22 | import java.io.InputStreamReader;
23 | import java.net.URL;
24 | import java.net.URLConnection;
25 | import java.nio.charset.StandardCharsets;
26 | import java.util.Locale;
27 | import java.util.PropertyResourceBundle;
28 | import java.util.ResourceBundle;
29 |
30 | // https://stackoverflow.com/a/4660195
31 | public class UTF8Control extends ResourceBundle.Control {
32 |
33 | @Override
34 | public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload)
35 | throws IOException {
36 |
37 | final String bundleName = toBundleName(baseName, locale);
38 | final String resourceName = toResourceName(bundleName, "properties");
39 |
40 | ResourceBundle bundle = null;
41 | InputStream stream = null;
42 | if (reload) {
43 | final URL url = loader.getResource(resourceName);
44 | if (url != null) {
45 | URLConnection connection = url.openConnection();
46 | if (connection != null) {
47 | connection.setUseCaches(false);
48 | stream = connection.getInputStream();
49 | }
50 | }
51 | } else {
52 | stream = loader.getResourceAsStream(resourceName);
53 | }
54 | if (stream != null) {
55 | try {
56 | // Only this line is changed to make it to read properties files as UTF-8.
57 | bundle = new PropertyResourceBundle(new InputStreamReader(stream, StandardCharsets.UTF_8));
58 | } finally {
59 | stream.close();
60 | }
61 | }
62 | return bundle;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/core/src/main/java/io/github/krlvm/powertunnel/listener/CoreProxyListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.listener;
19 |
20 | import io.github.krlvm.powertunnel.sdk.http.ProxyRequest;
21 | import io.github.krlvm.powertunnel.sdk.http.ProxyResponse;
22 | import io.github.krlvm.powertunnel.sdk.proxy.DNSRequest;
23 | import io.github.krlvm.powertunnel.sdk.proxy.ProxyListener;
24 | import io.github.krlvm.powertunnel.sdk.types.FullAddress;
25 | import org.jetbrains.annotations.NotNull;
26 | import org.slf4j.Logger;
27 | import org.slf4j.LoggerFactory;
28 |
29 | import java.util.Map;
30 |
31 | public class CoreProxyListener implements ProxyListener {
32 |
33 | private static final Logger LOGGER = LoggerFactory.getLogger(CoreProxyListener.class);
34 |
35 | private final Map proxyListeners;
36 |
37 | public CoreProxyListener(Map proxyListeners) {
38 | this.proxyListeners = proxyListeners;
39 | }
40 |
41 | @Override
42 | public void onClientToProxyRequest(@NotNull ProxyRequest request) {
43 | callProxyListeners((ProxyListenerCallback.Void) listener -> listener.onClientToProxyRequest(request));
44 | }
45 |
46 | @Override
47 | public void onProxyToServerRequest(@NotNull ProxyRequest request) {
48 | callProxyListeners((ProxyListenerCallback.Void) listener -> listener.onProxyToServerRequest(request));
49 | }
50 |
51 | @Override
52 | public void onServerToProxyResponse(@NotNull ProxyResponse response) {
53 | callProxyListeners((ProxyListenerCallback.Void) listener -> listener.onServerToProxyResponse(response));
54 | }
55 |
56 | @Override
57 | public void onProxyToClientResponse(@NotNull ProxyResponse response) {
58 | callProxyListeners((ProxyListenerCallback.Void) listener -> listener.onProxyToClientResponse(response));
59 | }
60 |
61 | @Override
62 | public Boolean onResolutionRequest(@NotNull DNSRequest request) {
63 | final Object result = callProxyListeners(listener -> listener.onResolutionRequest(request), false);
64 | return ((Boolean) result);
65 | }
66 |
67 | @Override
68 | public Integer onGetChunkSize(final @NotNull FullAddress address) {
69 | final Object result = callProxyListeners(listener -> listener.onGetChunkSize(address));
70 | return result != null ? ((int) result) : 0;
71 | }
72 |
73 | @Override
74 | public Boolean isFullChunking(@NotNull FullAddress address) {
75 | final Object result = callProxyListeners(listener -> listener.isFullChunking(address));
76 | return result != null && ((boolean) result);
77 | }
78 |
79 | @Override
80 | public Boolean isMITMAllowed(@NotNull FullAddress address) {
81 | final Object result = callProxyListeners(listener -> listener.isMITMAllowed(address));
82 | return result == null || ((boolean) result);
83 | }
84 |
85 | @Override
86 | public Object onGetSNI(@NotNull String hostname) {
87 | final Object result = callProxyListeners(listener -> listener.onGetSNI(hostname), null, Void.TYPE);
88 | return result != Void.TYPE ? result : hostname;
89 | }
90 |
91 | private Object callProxyListeners(ProxyListenerCallback callback) {
92 | return callProxyListeners(callback, null);
93 | }
94 |
95 | private Object callProxyListeners(ProxyListenerCallback callback, Object errVal) {
96 | return callProxyListeners(callback, errVal, null);
97 | }
98 |
99 | private Object callProxyListeners(ProxyListenerCallback callback, Object errVal, Object defObj) {
100 | Object result = defObj;
101 | for (Map.Entry entry : proxyListeners.entrySet()) {
102 | Object res;
103 | try {
104 | res = callback.call(entry.getValue());
105 | } catch (Exception ex) {
106 | LOGGER.error(
107 | "An error occurred in ProxyListener of '{}' [{}, priority={}]: {}",
108 | entry.getKey().getPluginInfo().getId(),
109 | entry.getValue().getClass().getSimpleName(), entry.getKey().getPriority(),
110 | ex.getMessage(),
111 | ex
112 | );
113 | res = errVal;
114 | }
115 | if(res != defObj) result = res;
116 | }
117 | return result;
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/core/src/main/java/io/github/krlvm/powertunnel/listener/ProxyListenerCallback.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.listener;
19 |
20 | import io.github.krlvm.powertunnel.sdk.proxy.ProxyListener;
21 |
22 | public interface ProxyListenerCallback {
23 | Object call(ProxyListener listener);
24 |
25 | interface Void extends ProxyListenerCallback {
26 | void callVoid(ProxyListener listener);
27 |
28 | @Override
29 | default Object call(ProxyListener listener) {
30 | callVoid(listener);
31 | return null;
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/core/src/main/java/io/github/krlvm/powertunnel/listener/ProxyListenerInfo.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.listener;
19 |
20 | import io.github.krlvm.powertunnel.sdk.plugin.PluginInfo;
21 |
22 | public class ProxyListenerInfo {
23 |
24 | private final PluginInfo pluginInfo;
25 | private final int priority;
26 |
27 | public ProxyListenerInfo(PluginInfo pluginInfo, int priority) {
28 | this.pluginInfo = pluginInfo;
29 | this.priority = priority;
30 | }
31 |
32 | public PluginInfo getPluginInfo() {
33 | return pluginInfo;
34 | }
35 |
36 | public int getPriority() {
37 | return priority;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/core/src/main/java/io/github/krlvm/powertunnel/listener/ServerListenerCallback.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.listener;
19 |
20 | import io.github.krlvm.powertunnel.sdk.ServerListener;
21 |
22 | public interface ServerListenerCallback {
23 | void call(ServerListener listener);
24 | }
25 |
--------------------------------------------------------------------------------
/core/src/main/java/io/github/krlvm/powertunnel/managers/ProxyAuthenticationManager.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.managers;
19 |
20 | import io.github.krlvm.powertunnel.sdk.proxy.ProxyCredentials;
21 | import org.littleshoot.proxy.ProxyAuthenticator;
22 |
23 | public class ProxyAuthenticationManager implements ProxyAuthenticator {
24 |
25 | private final String username;
26 | private final String password;
27 |
28 | public ProxyAuthenticationManager(ProxyCredentials credentials) {
29 | this(credentials.getUsername(), credentials.getPassword());
30 | }
31 |
32 | public ProxyAuthenticationManager(String username, String password) {
33 | this.username = username;
34 | this.password = password;
35 | }
36 |
37 | @Override
38 | public boolean authenticate(String userName, String password) {
39 | return userName.equals(this.username) && password.equals(this.password);
40 | }
41 |
42 | @Override
43 | public String getRealm() {
44 | return null;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/core/src/main/java/io/github/krlvm/powertunnel/managers/UpstreamProxyChainedProxyManager.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.managers;
19 |
20 | import io.github.krlvm.powertunnel.adapters.UpstreamChainedProxyAdapter;
21 | import io.netty.handler.codec.http.HttpRequest;
22 | import org.jetbrains.annotations.NotNull;
23 | import org.littleshoot.proxy.ChainedProxy;
24 | import org.littleshoot.proxy.ChainedProxyManager;
25 | import org.littleshoot.proxy.impl.ClientDetails;
26 | import java.util.Queue;
27 |
28 | public class UpstreamProxyChainedProxyManager implements ChainedProxyManager {
29 |
30 | private final UpstreamChainedProxyAdapter adapter;
31 |
32 | public UpstreamProxyChainedProxyManager(@NotNull UpstreamChainedProxyAdapter adapter) {
33 | this.adapter = adapter;
34 | }
35 |
36 | @Override
37 | public void lookupChainedProxies(HttpRequest httpRequest, Queue chainedProxies, ClientDetails clientDetails) {
38 | chainedProxies.add(adapter);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/core/src/main/java/io/github/krlvm/powertunnel/mitm/MITMAuthority.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.mitm;
19 |
20 | import org.littleshoot.proxy.mitm.Authority;
21 |
22 | import java.io.File;
23 |
24 | public class MITMAuthority {
25 |
26 | public static final String CERTIFICATE_ALIAS = "powertunnel-root-ca";
27 |
28 | public static Authority create(File certificateDirectory, String password) {
29 | return create(certificateDirectory, password.toCharArray());
30 | }
31 |
32 | public static Authority create(File certificateDirectory, char[] password) {
33 | if(!certificateDirectory.exists()) certificateDirectory.mkdir();
34 | return new Authority(certificateDirectory, CERTIFICATE_ALIAS, password,
35 | "PowerTunnel Root CA",
36 | "PowerTunnel",
37 | "PowerTunnel",
38 | "PowerTunnel",
39 | "PowerTunnel"
40 | );
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/core/src/main/java/io/github/krlvm/powertunnel/plugin/PluginInjector.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.plugin;
19 |
20 | import java.io.File;
21 |
22 | public interface PluginInjector {
23 | Class> inject(File file, String mainClass) throws Exception;
24 | }
25 |
--------------------------------------------------------------------------------
/core/src/main/java/io/github/krlvm/powertunnel/preferences/Preference.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.preferences;
19 |
20 | import java.io.Serializable;
21 | import java.util.List;
22 | import java.util.Map;
23 | import java.util.stream.Collectors;
24 |
25 | public class Preference implements Serializable {
26 |
27 | private final String key;
28 | private final String title;
29 | private final String description;
30 | private final String defaultValue;
31 | private final PreferenceType type;
32 |
33 | private final String dependency;
34 | private final String dependencyValue;
35 |
36 | private final Map items;
37 |
38 | public transient Object binding;
39 |
40 | public Preference(
41 | String key,
42 | String title,
43 | String description,
44 | String defaultValue,
45 | PreferenceType type,
46 | String dependency,
47 | String dependencyValue,
48 | Map items
49 | ) {
50 | this.key = key;
51 | this.title = title;
52 | this.description = description;
53 | this.defaultValue = defaultValue;
54 | this.type = type;
55 |
56 | this.dependency = dependency;
57 | this.dependencyValue = dependencyValue;
58 |
59 | this.items = items;
60 | }
61 |
62 | public String getKey() {
63 | return key;
64 | }
65 |
66 | public String getTitle() {
67 | return title;
68 | }
69 |
70 | public String getDescription() {
71 | return description;
72 | }
73 |
74 | public String getDefaultValue() {
75 | return defaultValue;
76 | }
77 |
78 | public PreferenceType getType() {
79 | return type;
80 | }
81 |
82 | public String getDependency() {
83 | return dependency;
84 | }
85 |
86 | public String getDependencyValue() {
87 | return dependencyValue;
88 | }
89 |
90 | public Map getItems() {
91 | return items;
92 | }
93 |
94 | public List getItemsAsModels() {
95 | return items.entrySet().stream()
96 | .map(entry -> new SelectPreferenceItem(entry.getKey(), entry.getValue()))
97 | .collect(Collectors.toList());
98 | }
99 |
100 | public static class SelectPreferenceItem {
101 |
102 | private final String key;
103 | private final String name;
104 |
105 | public SelectPreferenceItem(String key, String name) {
106 | this.key = key;
107 | this.name = name;
108 | }
109 |
110 | public String getKey() {
111 | return key;
112 | }
113 |
114 | public String getName() {
115 | return name;
116 | }
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/core/src/main/java/io/github/krlvm/powertunnel/preferences/PreferenceGroup.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.preferences;
19 |
20 | import java.io.Serializable;
21 | import java.util.List;
22 |
23 | public class PreferenceGroup implements Serializable {
24 |
25 | private final String title;
26 | private final String description;
27 | private final List preferences;
28 |
29 | public PreferenceGroup(String title, String description, List preferences) {
30 | this.title = title;
31 | this.description = description;
32 | this.preferences = preferences;
33 | }
34 |
35 | public String getTitle() {
36 | return title;
37 | }
38 |
39 | public String getDescription() {
40 | return description;
41 | }
42 |
43 | public List getPreferences() {
44 | return preferences;
45 | }
46 |
47 | public Preference findPreference(String key) {
48 | for (Preference preference : preferences) {
49 | if(key.equals(preference.getKey())) return preference;
50 | }
51 | return null;
52 | }
53 |
54 |
55 | public static Preference findPreference(List groups, String key) {
56 | for (PreferenceGroup group : groups) {
57 | final Preference preference = group.findPreference(key);
58 | if(preference != null) return preference;
59 | }
60 | return null;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/core/src/main/java/io/github/krlvm/powertunnel/preferences/PreferenceType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.preferences;
19 |
20 | public enum PreferenceType {
21 |
22 | CHECKBOX("false"),
23 | SWITCH("false"),
24 | STRING(""),
25 | NUMBER("0"),
26 | SELECT(null);
27 |
28 | final String defaultValue;
29 |
30 | PreferenceType(String defaultValue) {
31 | this.defaultValue = defaultValue;
32 | }
33 |
34 | public String getDefaultValue() {
35 | return defaultValue;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/core/src/main/java/io/github/krlvm/powertunnel/resolver/DNSResolverWrapper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.resolver;
19 |
20 | import io.github.krlvm.powertunnel.sdk.proxy.DNSResolver;
21 | import org.jetbrains.annotations.NotNull;
22 | import org.littleshoot.proxy.HostResolver;
23 |
24 | import java.net.InetSocketAddress;
25 | import java.net.UnknownHostException;
26 |
27 | public class DNSResolverWrapper implements DNSResolver {
28 |
29 | private final HostResolver resolver;
30 |
31 | public DNSResolverWrapper(@NotNull HostResolver resolver) {
32 | this.resolver = resolver;
33 | }
34 |
35 | @Override
36 | public @NotNull InetSocketAddress resolve(@NotNull String host, int port) throws UnknownHostException {
37 | return resolver.resolve(host, port);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/core/src/main/java/io/github/krlvm/powertunnel/resolver/LDNSResolver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.resolver;
19 |
20 | import io.github.krlvm.powertunnel.sdk.proxy.DNSRequest;
21 | import io.github.krlvm.powertunnel.sdk.proxy.ProxyListener;
22 | import org.littleshoot.proxy.DefaultHostResolver;
23 | import org.littleshoot.proxy.HostResolver;
24 | import org.slf4j.Logger;
25 | import org.slf4j.LoggerFactory;
26 |
27 | import java.net.InetSocketAddress;
28 | import java.net.UnknownHostException;
29 |
30 | public class LDNSResolver implements HostResolver {
31 |
32 | private static final Logger LOGGER = LoggerFactory.getLogger(LDNSResolver.class);
33 |
34 | private final ProxyListener listener;
35 | private final boolean allowFallbackResolver;
36 |
37 | private final HostResolver resolver = new DefaultHostResolver();
38 |
39 | public LDNSResolver(ProxyListener listener, boolean allowFallbackResolver) {
40 | this.listener = listener;
41 | this.allowFallbackResolver = allowFallbackResolver;
42 | }
43 |
44 | @Override
45 | public InetSocketAddress resolve(String host, int port) throws UnknownHostException {
46 | final DNSRequest request = new DNSRequest(host, port);
47 | final Boolean result = listener.onResolutionRequest(request);
48 | if(result != null && !result) {
49 | LOGGER.error("Resolution of hostname '{}' failed", host);
50 | if(!this.allowFallbackResolver) throw new UnknownHostException();
51 | }
52 | return request.getResponse() == null ? this.resolver.resolve(host, port) : request.getResponse();
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/core/src/main/java/io/github/krlvm/powertunnel/utilities/JarLoader.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.utilities;
19 |
20 | import io.github.krlvm.powertunnel.callbacks.InputStreamConsumer;
21 |
22 | import java.io.Closeable;
23 | import java.io.File;
24 | import java.io.IOException;
25 | import java.io.InputStream;
26 | import java.util.jar.JarEntry;
27 | import java.util.jar.JarFile;
28 |
29 | public class JarLoader implements Closeable {
30 |
31 | private final JarFile jar;
32 |
33 | public JarLoader(File file) throws IOException {
34 | this.jar = new JarFile(file);
35 | }
36 |
37 | public void open(String entryName, InputStreamConsumer consumer) throws IOException {
38 | open(entryName, consumer, false);
39 | }
40 |
41 | public void open(String entryName, InputStreamConsumer consumer, boolean acceptNull) throws IOException {
42 | final JarEntry entry = this.jar.getJarEntry(entryName);
43 | if (entry == null) {
44 | if(!acceptNull) return;
45 | consumer.accept(null);
46 | return;
47 | }
48 | try(InputStream in = jar.getInputStream(entry)) {
49 | consumer.accept(in);
50 | }
51 | }
52 |
53 | public void close() throws IOException {
54 | this.jar.close();
55 | }
56 |
57 |
58 | public static void open(File file, String entry, InputStreamConsumer consumer) throws IOException {
59 | open(file, entry, consumer, false);
60 | }
61 | public static void open(File file, String entry, InputStreamConsumer consumer, boolean acceptNull) throws IOException {
62 | try(JarLoader loader = new JarLoader(file)) {
63 | loader.open(entry, consumer, acceptNull);
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/desktop/.gitignore:
--------------------------------------------------------------------------------
1 | /build/
2 |
--------------------------------------------------------------------------------
/desktop/build.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | plugins {
19 | id 'application'
20 | id 'distribution'
21 | }
22 |
23 | version '2.5.2'
24 |
25 | run {
26 | workingDir = new File('build/run')
27 | workingDir.mkdirs()
28 |
29 | standardInput = System.in
30 | }
31 |
32 | application {
33 | mainClass = 'io.github.krlvm.powertunnel.desktop.Main'
34 | }
35 |
36 | jar {
37 | if (!project.version.endsWith('SNAPSHOT')) {
38 | exclude 'icon_dev.png'
39 | }
40 | }
41 |
42 | task fatJar(type: Jar, group: 'build', description: 'Assembles a jar archive containing the main classes and all dependencies.') {
43 | archiveClassifier = 'all'
44 | duplicatesStrategy DuplicatesStrategy.EXCLUDE
45 | manifest {
46 | attributes(
47 | 'Main-Class': application.mainClass
48 | )
49 | }
50 | from {
51 | configurations.runtimeClasspath.findAll { it.name.endsWith('jar') }.collect { zipTree(it) }
52 | } {
53 | exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA'
54 | }
55 | with jar
56 | }
57 |
58 | task releaseJar(group: 'build', description: 'Assembles a signed jar archive containing the main classes and all dependencies.') {
59 | dependsOn fatJar
60 | doLast {
61 | println 'Loading signing properties...'
62 | def keystoreProperties = new Properties()
63 | def keystorePropertiesFile = rootProject.file('key.properties')
64 | if(!keystorePropertiesFile.exists()) throw new GradleException('key.properties does not exist')
65 | keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
66 | println 'Signing fatJar...'
67 |
68 | def stdout = new ByteArrayOutputStream()
69 | exec {
70 | workingDir rootProject.rootDir
71 | commandLine 'cmd', '/c', keystoreProperties.getProperty("jarsigner"),
72 | "-keystore", keystoreProperties.getProperty('storeFile'),
73 | "-storepass", keystoreProperties.getProperty('storePassword'),
74 | "-keypass", keystoreProperties.getProperty('keyPassword'),
75 | "-tsa", keystoreProperties.getProperty('tsa'), "-verbose",
76 | "$buildDir/libs/*-all.jar", keystoreProperties.getProperty('keyAlias')
77 | standardOutput = System.out;
78 | }
79 | println stdout
80 | }
81 | }
82 |
83 | dependencies {
84 | implementation fileTree(dir: 'libs', include: ['*.jar'])
85 |
86 | implementation project(':core')
87 | implementation 'commons-cli:commons-cli:1.5.0'
88 | implementation 'net.java.dev.jna:jna:3.2.5'
89 |
90 | implementation 'org.apache.logging.log4j:log4j-api:2.17.1'
91 | implementation 'org.apache.logging.log4j:log4j-core:2.17.1'
92 | implementation 'org.apache.logging.log4j:log4j-slf4j-impl:2.17.1'
93 |
94 | testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2'
95 | testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2'
96 | }
--------------------------------------------------------------------------------
/desktop/libs/swingdpi-1.2.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krlvm/PowerTunnel/3e5df1e6ce4e12628fee4e2b940e4db9067cde3c/desktop/libs/swingdpi-1.2.jar
--------------------------------------------------------------------------------
/desktop/src/main/java/io/github/krlvm/powertunnel/desktop/BuildConstants.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.desktop;
19 |
20 | public class BuildConstants {
21 | public static final String NAME = "PowerTunnel";
22 | public static final String DESCRIPTION = "Powerful and extensible proxy server";
23 | public static final String REPO = "https://github.com/krlvm/PowerTunnel";
24 | public static final String VERSION = "2.5.2";
25 | public static final int VERSION_CODE = 111;
26 |
27 | public static boolean IS_RELEASE = io.github.krlvm.powertunnel.BuildConstants.isReleaseVersion(VERSION);
28 | public static final boolean DEBUG = !IS_RELEASE;
29 | }
30 |
--------------------------------------------------------------------------------
/desktop/src/main/java/io/github/krlvm/powertunnel/desktop/application/ConsoleApp.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.desktop.application;
19 |
20 | import io.github.krlvm.powertunnel.desktop.configuration.ServerConfiguration;
21 |
22 | public class ConsoleApp extends DesktopApp {
23 |
24 | public ConsoleApp(ServerConfiguration configuration) {
25 | super(configuration);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/desktop/src/main/java/io/github/krlvm/powertunnel/desktop/configuration/AdvancedConfiguration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.desktop.configuration;
19 |
20 | import io.github.krlvm.powertunnel.configuration.ConfigurationStore;
21 |
22 | import java.util.*;
23 | import java.util.stream.Collectors;
24 |
25 | public class AdvancedConfiguration extends ConfigurationStore {
26 |
27 | private final Collection immutableKeys = new HashSet<>();
28 | private final Map preImmutableData = new HashMap<>();
29 |
30 | private void saveOriginalKey(String key) {
31 | String originalVal = get(key, null);
32 | if (originalVal != null) {
33 | preImmutableData.put(key, originalVal);
34 | }
35 | }
36 |
37 | public void protect(String key, String value) {
38 | this.immutableKeys.add(key);
39 | saveOriginalKey(key);
40 | set(key, value);
41 | }
42 |
43 | public void protectInt(String key, int value) {
44 | this.immutableKeys.add(key);
45 | saveOriginalKey(key);
46 | setInt(key, value);
47 | }
48 |
49 | public void protectBoolean(String key, boolean value) {
50 | this.immutableKeys.add(key);
51 | saveOriginalKey(key);
52 | setBoolean(key, value);
53 | }
54 |
55 | @Override
56 | protected Set> entries() {
57 | Set> entries = new HashSet<>();
58 |
59 | for (Map.Entry entry : super.entries()) {
60 | if (immutableKeys.contains(entry.getKey())) {
61 | if (!preImmutableData.containsKey(entry.getKey())) continue;
62 | entry = new AbstractMap.SimpleEntry<>(entry.getKey(), preImmutableData.get(entry.getKey()));
63 | }
64 | entries.add(entry);
65 | }
66 |
67 | return entries;
68 | }
69 |
70 | public Collection getImmutableKeys() {
71 | return immutableKeys;
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/desktop/src/main/java/io/github/krlvm/powertunnel/desktop/configuration/ServerConfiguration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.desktop.configuration;
19 |
20 | import io.github.krlvm.powertunnel.desktop.application.DesktopApp;
21 |
22 | import java.io.IOException;
23 |
24 | public class ServerConfiguration extends AdvancedConfiguration {
25 |
26 | public void read() throws IOException {
27 | read(DesktopApp.CONFIGURATION_FILE);
28 | }
29 |
30 | public void save() throws IOException {
31 | save(DesktopApp.CONFIGURATION_FILE);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/desktop/src/main/java/io/github/krlvm/powertunnel/desktop/frames/AppFrame.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.desktop.frames;
19 |
20 | import io.github.krlvm.powertunnel.desktop.BuildConstants;
21 | import io.github.krlvm.powertunnel.desktop.application.GraphicalApp;
22 | import io.github.krlvm.powertunnel.desktop.utilities.UIUtility;
23 | import ru.krlvm.swingdpi.ScalableJFrame;
24 |
25 | import javax.swing.*;
26 | import javax.swing.border.Border;
27 | import java.awt.*;
28 |
29 | /**
30 | * Base implementation of JFrame (SwingDPI/ScalableJFrame)
31 | */
32 | public abstract class AppFrame extends ScalableJFrame {
33 |
34 | public static final int PADDING = 8;
35 | public static final Border BORDER = BorderFactory.createEmptyBorder(PADDING, PADDING, PADDING, PADDING);
36 |
37 | protected final GraphicalApp app;
38 |
39 | private boolean failedToInitialize = false;
40 |
41 | public AppFrame() {
42 | this(null, null);
43 | }
44 |
45 | public AppFrame(GraphicalApp app) {
46 | this(null, app);
47 | }
48 |
49 | public AppFrame(String title) {
50 | this(title, null);
51 | }
52 |
53 | public AppFrame(String title, GraphicalApp app) {
54 | super((title != null ? title + " - " : "") + BuildConstants.NAME);
55 | this.app = app;
56 |
57 | setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
58 | setIconImage(GraphicalApp.ICON);
59 | }
60 |
61 | public void showFrame() {
62 | showFrame(null);
63 | }
64 | public void showFrame(JFrame parent) {
65 | if(failedToInitialize) return;
66 | setLocationRelativeTo((parent == null || UIUtility.isMinimized(parent)) ? null : parent);
67 | setVisible(true);
68 | setState(Frame.NORMAL);
69 | toFront();
70 | requestFocus();
71 | }
72 |
73 | protected void frameInitialized() {
74 | setLocationRelativeTo(null);
75 | }
76 | protected void onFailedToInitialize() {
77 | failedToInitialize = true;
78 | dispose();
79 | //throw new RuntimeException();
80 | }
81 | public boolean isFailedToInitialize() {
82 | return failedToInitialize;
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/desktop/src/main/java/io/github/krlvm/powertunnel/desktop/managers/ApplicationManager.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.desktop.managers;
19 |
20 | import io.github.krlvm.powertunnel.desktop.utilities.Utility;
21 | import io.github.krlvm.powertunnel.plugin.PluginLoader;
22 |
23 | import java.io.File;
24 | import java.io.IOException;
25 | import java.nio.file.Path;
26 | import java.nio.file.Paths;
27 |
28 | public class ApplicationManager {
29 |
30 | private static final String[] PREINSTALLED_PLUGINS = {
31 | "LibertyTunnel.jar",
32 | "DNSResolver.jar"
33 | };
34 |
35 | public static void extractPlugins() throws IOException {
36 | final Path pluginsDir = Paths.get(PluginLoader.PLUGINS_DIR);
37 | final File pluginsDirFile = pluginsDir.toFile();
38 | if(!pluginsDirFile.exists()) pluginsDirFile.mkdir();
39 | for (String plugin : PREINSTALLED_PLUGINS) {
40 | Utility.extractResource(pluginsDir.resolve(plugin), "plugins/" + plugin);
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/desktop/src/main/java/io/github/krlvm/powertunnel/desktop/managers/ConsoleHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.desktop.managers;
19 |
20 | import io.github.krlvm.powertunnel.desktop.system.ConsoleReader;
21 | import io.github.krlvm.powertunnel.desktop.types.ConsoleCommand;
22 |
23 | import java.util.*;
24 | import java.util.function.Consumer;
25 |
26 | public class ConsoleHandler {
27 |
28 | private final Map appCommands = new TreeMap<>((String::compareTo));
29 | private final Map commands = new TreeMap<>(String::compareTo);
30 |
31 | public ConsoleHandler() {
32 | final ConsoleReader reader = ConsoleReader.get();
33 | final Thread thread = new Thread(() -> {
34 | String input;
35 | while ((input = reader.readLine()) != null) {
36 | lookupCommand(input.trim());
37 | }
38 | }, "Console Handler Thread");
39 | thread.setDaemon(true);
40 | thread.start();
41 | }
42 |
43 | private void lookupCommand(String input) {
44 | if ("help".equalsIgnoreCase(input)) {
45 | int longestCommand = Math.max(6, getLongestCommand(appCommands.keySet()) + getLongestCommand(commands.keySet()) + 3);
46 | int longestUsage = Math.max(6, getLongestUsage(appCommands.values()) + getLongestUsage(commands.values()) + 3);
47 |
48 | System.out.println();
49 | System.out.println("List of available commands:");
50 | printHelp(appCommands, longestCommand, longestUsage);
51 | printHelp(commands, longestCommand, longestUsage);
52 | System.out.println();
53 | } else {
54 | final String[] arr = input.split(" ");
55 | for (Map.Entry entry : appCommands.entrySet()) {
56 | if (arr[0].toLowerCase().equals(entry.getKey())) {
57 | entry.getValue().getHandler().accept(Arrays.copyOfRange(arr, 1, arr.length));
58 | return;
59 | }
60 | }
61 | if (arr.length > 1) {
62 | for (Map.Entry entry : commands.entrySet()) {
63 | if ((arr[0] + " " + arr[1]).toLowerCase().equals(entry.getKey())) {
64 | entry.getValue().getHandler().accept(Arrays.copyOfRange(arr, 2, arr.length));
65 | return;
66 | }
67 | }
68 | }
69 | System.err.println(" Unknown command. Type 'help' to view available commands.");
70 | }
71 | }
72 |
73 | public void printHelp(Map commands, int longestCommand, int longestUsage) {
74 | for (Map.Entry entry : commands.entrySet()) {
75 | final String cmd = entry.getKey() + String.join("",
76 | Collections.nCopies(Math.max(0, longestCommand - entry.getKey().length()), " "));
77 | final String usage = entry.getValue().getUsage() + String.join("",
78 | Collections.nCopies(Math.max(0, longestUsage - entry.getValue().getUsage().length()), " "));
79 | System.out.println(" " + cmd + usage + entry.getValue().getDescription());
80 | }
81 | }
82 |
83 | public void registerAppCommand(
84 | String command,
85 | Consumer handler,
86 | String usage,
87 | String description) {
88 | appCommands.put(command, new ConsoleCommand("powertunnel", command, usage, description, handler));
89 | }
90 |
91 | public void registerCommand(
92 | String pluginId,
93 | String command,
94 | Consumer handler,
95 | String usage,
96 | String description) {
97 | if (!command.isEmpty()) throw new IllegalArgumentException("Command cannot be empty");
98 | commands.put(pluginId + " " + command, new ConsoleCommand(pluginId, command, usage, description, handler));
99 | }
100 |
101 | public void reset() {
102 | commands.clear();
103 | System.gc();
104 | }
105 |
106 | private int getLongestCommand(Set commands) {
107 | return commands.stream().max(Comparator.comparingInt(String::length)).orElse("").length();
108 | }
109 | private int getLongestUsage(Collection commands) {
110 | return commands.stream().map(ConsoleCommand::getUsage).max(Comparator.comparingInt(String::length)).orElse("").length();
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/desktop/src/main/java/io/github/krlvm/powertunnel/desktop/managers/TrayManager.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.desktop.managers;
19 |
20 | import io.github.krlvm.powertunnel.desktop.BuildConstants;
21 | import io.github.krlvm.powertunnel.desktop.application.GraphicalApp;
22 | import io.github.krlvm.powertunnel.desktop.ui.I18N;
23 | import ru.krlvm.swingdpi.SwingDPI;
24 |
25 | import java.awt.*;
26 | import java.awt.event.ActionListener;
27 | import java.awt.font.TextAttribute;
28 | import java.util.HashMap;
29 | import java.util.Map;
30 |
31 | public class TrayManager {
32 |
33 | private final GraphicalApp app;
34 |
35 | private TrayIcon trayIcon;
36 |
37 | private Font HEADER_FONT;
38 | private Font FONT;
39 |
40 | public TrayManager(GraphicalApp app) {
41 | this.app = app;
42 | }
43 |
44 | public void load() throws AWTException {
45 | initializeFonts();
46 | final ActionListener openAppListener = e -> app.showFrame();
47 |
48 | PopupMenu popup = new PopupMenu();
49 |
50 | popup.add(getItem(BuildConstants.NAME, null, true));
51 | popup.add(getItem(I18N.get("tray.version") + " " + BuildConstants.VERSION, null, true));
52 | popup.add(getItem("(c) krlvm, 2019-2022", null, true));
53 |
54 | popup.addSeparator();
55 |
56 | popup.add(getItem(I18N.get("tray.open"), openAppListener));
57 |
58 | popup.addSeparator();
59 |
60 | popup.add(getItem(I18N.get("main.plugins"), e -> app.showPluginsFrame()));
61 | popup.add(getItem(I18N.get("main.options"), e -> app.showOptionsFrame()));
62 |
63 | popup.addSeparator();
64 |
65 | popup.add(getItem(I18N.get("tray.exit"), e -> app.dispose()));
66 |
67 | trayIcon = new TrayIcon(GraphicalApp.ICON, BuildConstants.NAME, popup);
68 | trayIcon.setImageAutoSize(true);
69 | trayIcon.setToolTip(BuildConstants.NAME);
70 | trayIcon.addActionListener(openAppListener);
71 |
72 | freeFonts();
73 |
74 | SystemTray.getSystemTray().add(trayIcon);
75 | }
76 |
77 | public void unload() {
78 | SystemTray.getSystemTray().remove(trayIcon);
79 | trayIcon = null;
80 | }
81 |
82 | public void showNotification(String message) {
83 | if(!isLoaded()) return;
84 | trayIcon.displayMessage(BuildConstants.NAME, message, TrayIcon.MessageType.NONE);
85 | }
86 |
87 | public boolean isLoaded() {
88 | return trayIcon != null;
89 | }
90 |
91 |
92 | private MenuItem getItem(String title, ActionListener listener) {
93 | return getItem(title, listener, false);
94 | }
95 |
96 | private MenuItem getItem(String title, ActionListener listener, boolean header) {
97 | final MenuItem item = new MenuItem(title);
98 | if(header) {
99 | item.setFont(HEADER_FONT);
100 | item.setEnabled(false);
101 | } else {
102 | item.setFont(FONT);
103 | }
104 | if(listener != null) item.addActionListener(listener);
105 | return item;
106 | }
107 |
108 |
109 | // region Fonts
110 |
111 | private void initializeFonts() {
112 | Map attributes = new HashMap<>();
113 | attributes.put(TextAttribute.SIZE, 12* SwingDPI.getScaleFactor());
114 | FONT = Font.getFont(attributes);
115 |
116 | attributes.put(TextAttribute.FAMILY, Font.DIALOG);
117 | attributes.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
118 | HEADER_FONT = Font.getFont(attributes);
119 | }
120 |
121 | private void freeFonts() {
122 | FONT = null;
123 | HEADER_FONT = null;
124 | }
125 |
126 | // endregion
127 | }
128 |
--------------------------------------------------------------------------------
/desktop/src/main/java/io/github/krlvm/powertunnel/desktop/system/ConsoleReader.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.desktop.system;
19 |
20 | import java.io.Console;
21 | import java.util.Scanner;
22 |
23 | public interface ConsoleReader {
24 |
25 | String readLine();
26 |
27 | class JavaConsoleWrapper implements ConsoleReader {
28 | private final Console console;
29 | JavaConsoleWrapper(Console console) {
30 | this.console = console;
31 | }
32 | @Override
33 | public String readLine() {
34 | return console.readLine("> ");
35 | }
36 | }
37 | class BufferedConsoleWrapper implements ConsoleReader {
38 | private final Scanner scanner = new Scanner(System.in);
39 | @Override
40 | public String readLine() {
41 | return scanner.nextLine();
42 | }
43 | }
44 |
45 | static ConsoleReader get() {
46 | final Console console = System.console();
47 | return console != null ? new JavaConsoleWrapper(console) : new BufferedConsoleWrapper();
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/desktop/src/main/java/io/github/krlvm/powertunnel/desktop/system/SystemProxy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.desktop.system;
19 |
20 | import io.github.krlvm.powertunnel.desktop.system.windows.WindowsProxyHandler;
21 | import io.github.krlvm.powertunnel.desktop.utilities.SystemUtility;
22 | import io.github.krlvm.powertunnel.sdk.proxy.ProxyAddress;
23 |
24 | public class SystemProxy {
25 |
26 | private static final Handler HANDLER;
27 | static {
28 | if(SystemUtility.IS_WINDOWS) {
29 | HANDLER = new WindowsProxyHandler();
30 | } else {
31 | HANDLER = new DummyHandler();
32 | }
33 | }
34 |
35 | public static boolean isSupported() {
36 | return HANDLER != null && !(HANDLER instanceof DummyHandler);
37 | }
38 |
39 | public static void enableProxy(ProxyAddress address) {
40 | HANDLER.enableProxy(address);
41 | }
42 |
43 | public static void disableProxy() {
44 | HANDLER.disableProxy();
45 | }
46 |
47 | public interface Handler {
48 | void enableProxy(ProxyAddress address);
49 | void disableProxy();
50 | }
51 |
52 | public static final class DummyHandler implements Handler {
53 | @Override
54 | public void enableProxy(ProxyAddress address) {}
55 | @Override
56 | public void disableProxy() {}
57 | }
58 | }
--------------------------------------------------------------------------------
/desktop/src/main/java/io/github/krlvm/powertunnel/desktop/system/windows/WindowsProxyHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.desktop.system.windows;
19 |
20 | import io.github.krlvm.powertunnel.desktop.system.SystemProxy;
21 | import io.github.krlvm.powertunnel.desktop.utilities.SystemUtility;
22 | import io.github.krlvm.powertunnel.sdk.proxy.ProxyAddress;
23 |
24 | import java.io.IOException;
25 |
26 | public class WindowsProxyHandler implements SystemProxy.Handler {
27 |
28 | public static boolean USE_IE = SystemUtility.OLD_OS;
29 |
30 | @Override
31 | public void enableProxy(ProxyAddress address) {
32 | executeAndApply(
33 | "reg add \"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\" /v ProxyEnable /t REG_DWORD /d 1 /f",
34 | "reg add \"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\" /v ProxyServer /t REG_SZ /d " + address.getHost() + ":" + address.getPort() + " /f"
35 | );
36 | }
37 |
38 | @Override
39 | public void disableProxy() {
40 | executeAndApply("reg add \"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\" /v ProxyEnable /t REG_DWORD /d 0 /f");
41 | }
42 |
43 | public static void executeAndApply(final String... commands) {
44 | new Thread(() -> {
45 | try {
46 | for (String command : commands) {
47 | SystemUtility.executeWindowsCommand(command);
48 | }
49 | if (!USE_IE) {
50 | Wininet wininet = Wininet.INSTANCE;
51 | wininet.InternetSetOptionW(0,
52 | wininet.INTERNET_OPTION_SETTINGS_CHANGED, null, 0);
53 | wininet.InternetSetOptionW(0,
54 | wininet.INTERNET_OPTION_REFRESH, null, 0);
55 | } else {
56 | // We need to start Internet Explorer to apply the changes
57 | SystemUtility.executeWindowsCommand("start iexplore && ping -n 5 127.0.0.1 > NUL && taskkill /f /im iexplore.exe");
58 | }
59 | System.out.println("System proxy initialization has been finished");
60 | } catch (IOException ex) {
61 | System.err.println("Failed to setup system proxy: " + ex.getMessage());
62 | ex.printStackTrace();
63 | }
64 | }).start();
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/desktop/src/main/java/io/github/krlvm/powertunnel/desktop/system/windows/Wininet.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.desktop.system.windows;
19 |
20 | import com.sun.jna.Native;
21 | import com.sun.jna.Pointer;
22 | import com.sun.jna.win32.StdCallLibrary;
23 | import com.sun.jna.win32.W32APIOptions;
24 |
25 | public interface Wininet extends StdCallLibrary {
26 |
27 | Wininet INSTANCE = (Wininet)Native.loadLibrary("Wininet", Wininet.class,
28 | W32APIOptions.DEFAULT_OPTIONS);
29 |
30 | int INTERNET_OPTION_SETTINGS_CHANGED = 39;
31 | int INTERNET_OPTION_REFRESH = 37;
32 |
33 | boolean InternetSetOptionW(int unused, int dwOption, Pointer lpBuffer, int dwBufferLength);
34 | }
--------------------------------------------------------------------------------
/desktop/src/main/java/io/github/krlvm/powertunnel/desktop/types/ConsoleCommand.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.desktop.types;
19 |
20 | import java.util.function.Consumer;
21 |
22 | public class ConsoleCommand {
23 |
24 | private final String pluginId;
25 | private final String name;
26 | private final String usage;
27 | private final String description;
28 |
29 | private final Consumer handler;
30 |
31 | public ConsoleCommand(String pluginId, String name, String usage, String description, Consumer handler) {
32 | this.pluginId = pluginId;
33 | this.name = name;
34 | this.usage = usage;
35 | this.description = description;
36 | this.handler = handler;
37 | }
38 |
39 | public String getPluginId() {
40 | return pluginId;
41 | }
42 |
43 | public String getName() {
44 | return name;
45 | }
46 |
47 | public String getUsage() {
48 | return usage;
49 | }
50 |
51 | public String getDescription() {
52 | return description;
53 | }
54 |
55 | public Consumer getHandler() {
56 | return handler;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/desktop/src/main/java/io/github/krlvm/powertunnel/desktop/types/TrayMode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.desktop.types;
19 |
20 | public enum TrayMode {
21 | STANDARD,
22 | MINIMIZED,
23 | DISABLED
24 | }
25 |
--------------------------------------------------------------------------------
/desktop/src/main/java/io/github/krlvm/powertunnel/desktop/ui/ComboBoxScroll.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.desktop.ui;
19 |
20 | import javax.swing.*;
21 | import java.awt.event.MouseWheelEvent;
22 |
23 | public class ComboBoxScroll {
24 |
25 | public static void register(JComboBox> comboBox) {
26 | comboBox.addMouseWheelListener((MouseWheelEvent e) -> {
27 | if(!comboBox.isEnabled()) return;
28 | final int i = comboBox.getSelectedIndex() + (e.getWheelRotation() < 0 ? -1 : 1);
29 | if(i < 0 || i >= comboBox.getItemCount()) return;
30 | comboBox.setSelectedIndex(i);
31 | });
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/desktop/src/main/java/io/github/krlvm/powertunnel/desktop/ui/FieldFilter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.desktop.ui;
19 |
20 | import javax.swing.text.AttributeSet;
21 | import javax.swing.text.BadLocationException;
22 | import javax.swing.text.Document;
23 | import javax.swing.text.DocumentFilter;
24 | import java.awt.*;
25 | import java.util.regex.Pattern;
26 |
27 | public abstract class FieldFilter extends DocumentFilter {
28 |
29 | protected abstract boolean isAllowed(String s);
30 |
31 | @Override
32 | public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException {
33 | final Document doc = fb.getDocument();
34 | final StringBuilder sb = new StringBuilder();
35 | sb.append(doc.getText(0, doc.getLength()));
36 | sb.insert(offset, string);
37 |
38 | if (isAllowed(sb.toString())) {
39 | super.insertString(fb, offset, string, attr);
40 | return;
41 | }
42 | Toolkit.getDefaultToolkit().beep();
43 | }
44 |
45 | @Override
46 | public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
47 | final Document doc = fb.getDocument();
48 | final StringBuilder sb = new StringBuilder();
49 | sb.append(doc.getText(0, doc.getLength()));
50 | sb.replace(offset, offset + length, text);
51 |
52 | if (isAllowed(sb.toString())) {
53 | super.replace(fb, offset, length, text, attrs);
54 | return;
55 | }
56 | Toolkit.getDefaultToolkit().beep();
57 | }
58 |
59 | @Override
60 | public void remove(FilterBypass fb, int offset, int length) throws BadLocationException {
61 | final Document doc = fb.getDocument();
62 | final StringBuilder sb = new StringBuilder();
63 | sb.append(doc.getText(0, doc.getLength()));
64 | sb.delete(offset, offset + length);
65 |
66 | if (isAllowed(sb.toString())) {
67 | super.remove(fb, offset, length);
68 | return;
69 | }
70 | Toolkit.getDefaultToolkit().beep();
71 | }
72 |
73 |
74 | public static class Number extends FieldFilter {
75 | @Override
76 | protected boolean isAllowed(String s) {
77 | try {
78 | Integer.parseInt(s);
79 | return true;
80 | } catch (NumberFormatException ex) {
81 | return false;
82 | }
83 | }
84 | }
85 |
86 | public static class IP extends FieldFilter {
87 | private static final Pattern PATTERN = Pattern.compile("(\\d+\\.?)+");
88 | @Override
89 | protected boolean isAllowed(String s) {
90 | return s.isEmpty() || PATTERN.matcher(s).matches();
91 | }
92 | }
93 | }
--------------------------------------------------------------------------------
/desktop/src/main/java/io/github/krlvm/powertunnel/desktop/ui/I18N.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.desktop.ui;
19 |
20 | import io.github.krlvm.powertunnel.i18n.I18NBundle;
21 | import io.github.krlvm.powertunnel.i18n.UTF8Control;
22 |
23 | import java.util.Locale;
24 | import java.util.MissingResourceException;
25 | import java.util.ResourceBundle;
26 |
27 | public class I18N {
28 |
29 | private static I18NBundle bundle;
30 | private static String lang = null;
31 |
32 | public static String get(String key) {
33 | return bundle.get(key);
34 | }
35 |
36 | public static String get(String key, String defaultValue) {
37 | return bundle.get(key, defaultValue);
38 | }
39 |
40 | public static void load(Locale locale) {
41 | if(bundle != null) throw new IllegalStateException("Bundle is already loaded");
42 | try {
43 | bundle = new I18NBundle(getResourceBundle(locale));
44 | lang = locale.getLanguage();
45 | } catch (MissingResourceException ex) {
46 | System.err.printf("Locale '%s' is not supported%n", locale.getLanguage());
47 | bundle = new I18NBundle(getResourceBundle(Locale.ENGLISH));
48 | }
49 | }
50 |
51 | public static String getLang() {
52 | return lang;
53 | }
54 |
55 |
56 | private static final String NAME = "messages";
57 | public static ResourceBundle getResourceBundle(Locale locale) {
58 | return ResourceBundle.getBundle("locale/" + NAME, locale, new UTF8Control());
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/desktop/src/main/java/io/github/krlvm/powertunnel/desktop/ui/PluginInfoRenderer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.desktop.ui;
19 |
20 | import io.github.krlvm.powertunnel.desktop.utilities.UIUtility;
21 | import io.github.krlvm.powertunnel.sdk.plugin.PluginInfo;
22 | import ru.krlvm.swingdpi.SwingDPI;
23 |
24 | import javax.swing.*;
25 | import javax.swing.border.Border;
26 | import java.awt.*;
27 |
28 | // https://stackoverflow.com/a/26476427
29 | public class PluginInfoRenderer extends JPanel implements ListCellRenderer {
30 |
31 | private final JEditorPane infoLabel = new JEditorPane();
32 |
33 | public PluginInfoRenderer() {
34 | setLayout(new BorderLayout());
35 |
36 | add(infoLabel, BorderLayout.NORTH);
37 |
38 | final JPanel separator = new JPanel();
39 | separator.setBackground(Color.LIGHT_GRAY);
40 | separator.setPreferredSize(new Dimension(separator.getWidth(), 1));
41 |
42 | add(separator, BorderLayout.SOUTH);
43 | }
44 |
45 | @Override
46 | public Dimension getMinimumSize() {
47 | return SwingDPI.scale(100, 76);
48 | }
49 |
50 | @Override
51 | public Dimension getPreferredSize() {
52 | return getMinimumSize();
53 | }
54 |
55 | @Override
56 | public Component getListCellRendererComponent(
57 | JList extends PluginInfo> list,
58 | PluginInfo value,
59 | int index,
60 | boolean isSelected,
61 | boolean cellHasFocus
62 | ) {
63 | setComponentOrientation(list.getComponentOrientation());
64 |
65 | Color backgroundColor = null;
66 | Color foregroundColor = null;
67 |
68 | JList.DropLocation dropLocation = list.getDropLocation();
69 | if (dropLocation != null && !dropLocation.isInsert() && dropLocation.getIndex() == index) {
70 | backgroundColor = UIManager.getColor("List.dropCellBackground");
71 | foregroundColor = UIManager.getColor("List.dropCellForeground");
72 |
73 | isSelected = true;
74 | }
75 |
76 | if (isSelected) {
77 | setBackground(backgroundColor == null ? list.getSelectionBackground() : backgroundColor);
78 | setForeground(foregroundColor == null ? list.getSelectionForeground() : foregroundColor);
79 |
80 | setBackground(Color.LIGHT_GRAY);
81 | } else {
82 | setBackground(list.getBackground());
83 | setForeground(list.getForeground());
84 | }
85 |
86 | UIUtility.setEditorPaneContent(infoLabel, String.format(
87 | "%s
%sVersion %s%s",
88 | value.getName(),
89 | value.getDescription() != null ? value.getDescription() + "
" : "",
90 | value.getVersion(),
91 | value.getAuthor() != null ? "
by " + value.getAuthor() + "" : ""
92 | ), "padding: 5px;", 0, false);
93 | infoLabel.setBackground(getBackground());
94 | infoLabel.setForeground(getForeground());
95 |
96 | setEnabled(list.isEnabled());
97 |
98 | return this;
99 | }
100 | }
--------------------------------------------------------------------------------
/desktop/src/main/java/io/github/krlvm/powertunnel/desktop/ui/SelectPreferenceRenderer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.desktop.ui;
19 |
20 | import io.github.krlvm.powertunnel.preferences.Preference;
21 |
22 | import javax.swing.*;
23 | import java.awt.*;
24 |
25 | public class SelectPreferenceRenderer extends DefaultListCellRenderer {
26 |
27 | public Component getListCellRendererComponent(
28 | JList list,
29 | Object value,
30 | int index,
31 | boolean isSelected,
32 | boolean cellHasFocus) {
33 | if (value instanceof Preference.SelectPreferenceItem) {
34 | value = ((Preference.SelectPreferenceItem)value).getName();
35 | }
36 | super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
37 | return this;
38 | }
39 | }
--------------------------------------------------------------------------------
/desktop/src/main/java/io/github/krlvm/powertunnel/desktop/ui/TextRightClickPopup.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.desktop.ui;
19 |
20 | import javax.swing.*;
21 | import javax.swing.event.PopupMenuEvent;
22 | import javax.swing.event.PopupMenuListener;
23 | import javax.swing.text.JTextComponent;
24 | import javax.swing.undo.UndoManager;
25 | import java.awt.event.ActionEvent;
26 | import java.awt.event.KeyEvent;
27 |
28 | public class TextRightClickPopup {
29 |
30 | public static void register(JTextComponent input) {
31 | final JPopupMenu popup = new JPopupMenu();
32 |
33 | popup.addPopupMenuListener(new PopupMenuListener() {
34 | @Override
35 | public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
36 | input.requestFocus();
37 | input.requestFocusInWindow();
38 | }
39 | @Override
40 | public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {}
41 | @Override
42 | public void popupMenuCanceled(PopupMenuEvent e) {}
43 | });
44 |
45 | final UndoManager undoManager = new UndoManager();
46 | input.getDocument().addUndoableEditListener(undoManager);
47 |
48 | final Action undoAction = new AbstractAction(I18N.get("menu.undo")) {
49 | @Override
50 | public void actionPerformed(ActionEvent e) {
51 | if(undoManager.canUndo()) {
52 | undoManager.undo();
53 | }
54 | }
55 | };
56 | final Action redoAction = new AbstractAction(I18N.get("menu.redo")) {
57 | @Override
58 | public void actionPerformed(ActionEvent e) {
59 | if(undoManager.canRedo()) {
60 | undoManager.redo();
61 | }
62 | }
63 | };
64 |
65 | final Action copyAction = new AbstractAction(I18N.get("menu.copy")) {
66 | @Override
67 | public void actionPerformed(ActionEvent e) {
68 | input.copy();
69 | }
70 | };
71 | final Action cutAction = new AbstractAction(I18N.get("menu.cut")) {
72 | @Override
73 | public void actionPerformed(ActionEvent e) {
74 | input.cut();
75 | }
76 | };
77 | final Action pasteAction = new AbstractAction(I18N.get("menu.paste")) {
78 | @Override
79 | public void actionPerformed(ActionEvent e) {
80 | input.paste();
81 | }
82 | };
83 | final Action deleteAction = new AbstractAction(I18N.get("menu.delete")) {
84 | @Override
85 | public void actionPerformed(ActionEvent e) {
86 | input.replaceSelection("");
87 | }
88 | };
89 |
90 | final Action selectAllAction = new AbstractAction(I18N.get("menu.selectAll")) {
91 | @Override
92 | public void actionPerformed(ActionEvent e) {
93 | input.selectAll();
94 | }
95 | };
96 |
97 |
98 | input.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_Z, KeyEvent.CTRL_MASK), undoAction);
99 | input.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_Z, KeyEvent.SHIFT_MASK | KeyEvent.CTRL_MASK), redoAction);
100 |
101 | input.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_X, KeyEvent.CTRL_MASK), cutAction);
102 | input.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_C, KeyEvent.CTRL_MASK), copyAction);
103 | input.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_V, KeyEvent.CTRL_MASK), pasteAction);
104 | //deleteAction
105 |
106 | input.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_A, KeyEvent.CTRL_MASK), selectAllAction);
107 |
108 | /* ----------------------- */
109 | popup.add(undoAction);
110 | popup.add(redoAction);
111 |
112 | popup.addSeparator();
113 |
114 | popup.add(cutAction);
115 | popup.add(copyAction);
116 | popup.add(pasteAction);
117 | popup.add(deleteAction);
118 |
119 | popup.addSeparator();
120 |
121 | popup.add(selectAllAction);
122 | /* ----------------------- */
123 |
124 | input.setComponentPopupMenu(popup);
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/desktop/src/main/java/io/github/krlvm/powertunnel/desktop/updater/UpdateInfo.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.desktop.updater;
19 |
20 | public class UpdateInfo {
21 |
22 | private final String version;
23 | private final int versionCode;
24 | private final String changelog;
25 |
26 | private final String releasePage;
27 | private final String downloadUrl;
28 |
29 | public UpdateInfo(String version, int versionCode, String changelog, String releasePage, String downloadUrl) {
30 | this.version = version;
31 | this.versionCode = versionCode;
32 | this.changelog = changelog;
33 |
34 | this.releasePage = releasePage;
35 | this.downloadUrl = downloadUrl;
36 | }
37 |
38 | public String getVersion() {
39 | return version;
40 | }
41 |
42 | public int getVersionCode() {
43 | return versionCode;
44 | }
45 |
46 | public String getChangelog() {
47 | return changelog;
48 | }
49 |
50 | public String getReleasePage() {
51 | return releasePage;
52 | }
53 |
54 | public String getDownloadUrl() {
55 | return downloadUrl;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/desktop/src/main/java/io/github/krlvm/powertunnel/desktop/utilities/SystemUtility.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.desktop.utilities;
19 |
20 | import sun.net.dns.ResolverConfiguration;
21 |
22 | import java.awt.*;
23 | import java.io.IOException;
24 | import java.util.ArrayList;
25 | import java.util.List;
26 |
27 | public class SystemUtility {
28 |
29 | public static final String OS = System.getProperty("os.name").toLowerCase();
30 | public static final boolean IS_WINDOWS = OS.contains("windows");
31 | public static final boolean OLD_OS = IS_WINDOWS && (
32 | OS.contains("2003") ||
33 | OS.contains("xp") ||
34 | OS.contains("2000")
35 | );
36 |
37 | public static final boolean IS_TERMINAL = GraphicsEnvironment.isHeadless();
38 |
39 | public static Process executeWindowsCommand(String command) throws IOException {
40 | return executeWindowsCommand("cmd", command);
41 | }
42 |
43 | public static Process executeWindowsCommand(String handler, String command) throws IOException {
44 | return Runtime.getRuntime().exec(handler + ".exe /C " + command);
45 | }
46 |
47 | public static List getDNSServers() {
48 | try {
49 | Class.forName("sun.net.dns.ResolverConfiguration");
50 | List list = null;
51 | try {
52 | list = ResolverConfiguration.open().nameservers();
53 | } catch (Throwable ignored) {}
54 | return list == null ? new ArrayList<>() : new ArrayList<>(list);
55 | } catch (ClassNotFoundException ex) {
56 | return new ArrayList<>();
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/desktop/src/main/java/io/github/krlvm/powertunnel/desktop/utilities/Utility.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.desktop.utilities;
19 |
20 | import io.github.krlvm.powertunnel.desktop.Main;
21 |
22 | import java.awt.*;
23 | import java.io.File;
24 | import java.io.IOException;
25 | import java.io.InputStream;
26 | import java.net.URI;
27 | import java.net.URISyntaxException;
28 | import java.nio.file.Files;
29 | import java.nio.file.Path;
30 | import java.nio.file.StandardCopyOption;
31 |
32 | public class Utility {
33 |
34 | public static void extractResource(Path destination, String src) throws IOException {
35 | try(final InputStream in = Main.class.getResourceAsStream("/" + src)) {
36 | Files.copy(in, destination, StandardCopyOption.REPLACE_EXISTING);
37 | }
38 | }
39 |
40 | public static void launchBrowser(String address) {
41 | if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
42 | final URI url;
43 | try {
44 | url = new URI(address);
45 | } catch (URISyntaxException ex) {
46 | return;
47 | }
48 | try {
49 | Desktop.getDesktop().browse(url);
50 | } catch (IOException ex) {
51 | ex.printStackTrace();
52 | }
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/desktop/src/main/resources/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krlvm/PowerTunnel/3e5df1e6ce4e12628fee4e2b940e4db9067cde3c/desktop/src/main/resources/icon.png
--------------------------------------------------------------------------------
/desktop/src/main/resources/icon_dev.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krlvm/PowerTunnel/3e5df1e6ce4e12628fee4e2b940e4db9067cde3c/desktop/src/main/resources/icon_dev.png
--------------------------------------------------------------------------------
/desktop/src/main/resources/locale/messages_en.properties:
--------------------------------------------------------------------------------
1 | #
2 | # This file is part of PowerTunnel.
3 | #
4 | # PowerTunnel is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # PowerTunnel is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with PowerTunnel. If not, see .
16 | #
17 |
18 | main.status.NOT_RUNNING = Server is not running
19 | main.status.STARTING = Server is starting
20 | main.status.RUNNING = Server is running
21 | main.status.STOPPING = Server is stopping
22 |
23 | main.start = Start server
24 | main.stop = Stop server
25 |
26 | main.plugins = Plugins
27 | main.options = Options
28 | main.about = About
29 |
30 | main.reportBug = Report a bug
31 | main.help = Help
32 |
33 | main.configureAutomaticallyPrompt = Configure system proxy automatically?
34 | main.failedToStartServer=Failed to start server
35 |
36 |
37 | plugins.title = Plugins
38 |
39 | plugins.disable = Disable
40 | plugins.enable = Enable
41 |
42 | plugins.homepage = Homepage
43 | plugins.settings = Settings
44 | plugins.additionalConfiguration=Additional configuration
45 |
46 | plugins.notConfigurable = Plugin is not configurable
47 | plugins.emptyPreferences = Plugin preferences is empty
48 |
49 | plugins.failedToRead = Failed to read plugin preferences
50 | plugins.failedToOpen = Failed to open plugin preferences
51 |
52 | plugins.note = Plugins can't be configured when server is running
Verify before installing as they may be malicious
53 | plugins.visitRegistry = Visit official plugins registry
54 |
55 |
56 | preferences.subtitle = preferences
57 | preferences.failedToSave = Failed to save preferences
58 |
59 | preferences.incorrectConfiguration = Incorrect configuration detected, do you want to reset it?
60 | preferences.exitConfirmation = Do you want to save changes?
61 | preferences.resetConfirmation = Do you want to reset configuration?
62 |
63 | preferences.note = Some preferences may not be available
because they were set from the CLI
64 |
65 |
66 | options.title = Options
67 |
68 | options.recommended = recommended
69 |
70 | options.group.proxyConnection = Proxy connection
71 |
72 | options.auto_proxy_setup = Auto proxy setup
73 | options.auto_proxy_setup.desc = Automatically setting up system proxy server configuration\n\nWindows: Internet Explorer may be started for a few seconds to apply changes.
74 |
75 | options.upstream_proxy_enabled = Connect via upstream proxy server
76 | options.upstream_proxy_enabled.desc = Use a proxy server to connect to the Internet
77 |
78 | options.upstream_proxy_host = Upstream proxy host
79 | options.upstream_proxy_port = Upstream proxy port
80 |
81 | options.upstream_proxy_protocol = Upstream proxy protocol
82 |
83 | options.upstream_proxy_auth_enabled = Upstream proxy authorization
84 | options.upstream_proxy_auth_enabled.desc = Authenticate on upstream proxy server
85 |
86 | options.upstream_proxy_auth_username = Upstream proxy username
87 | options.upstream_proxy_auth_password = Upstream proxy password
88 |
89 | options.group.proxySettings = Proxy settings
90 |
91 | options.transparent_mode = Transparent mode
92 | options.transparent_mode.desc = When proxy server is in transparent mode, it declares that it does not modify requests and responses and does not set 'Via' header
93 |
94 | options.strict_dns = Strict DNS Mode
95 | options.strict_dns.desc=When DNS Mode is not set to Strict, hostname can be resolved with the default DNS Resolver\nif the custom one could not or failed resolve hostname.
96 |
97 | options.allow_requests_to_origin_server = Allow requests to origin server
98 | options.allow_requests_to_origin_server.desc = Experimental option, fixed many connectivity issues
99 |
100 | options.note = NOTE: Some features have been moved to plugins,
so you need to open their settings for configuring
101 |
102 |
103 | updater.checkForUpdates = Check for updates
104 | updater.checkingForUpdates = Checking for updates...
105 | updater.noUpdates = No updates are available
106 | updater.updateAvailable = An update is available
107 | updater.failedToCheck = Failed to check for updates
108 | updater.dialog=%s is ready to update!
Version: %s
Release page: %s
Download: %s
109 |
110 |
111 | yes = Yes
112 | no = No
113 | ok = OK
114 |
115 | reset = Reset
116 | cancel = Cancel
117 | save = Save
118 |
119 |
120 | tray.version = Version
121 |
122 | tray.open = Open
123 | tray.exit = Exit
124 |
125 | tray.stillRunning = is still running in tray mode
126 |
127 |
128 | menu.undo = Undo
129 | menu.redo = Redo
130 |
131 | menu.cut = Cut
132 | menu.copy = Copy
133 | menu.paste = Paste
134 | menu.delete = Delete
135 |
136 | menu.selectAll = Select All
137 | options.proxy_auth_enabled=Require proxy authorization
138 | options.proxy_auth_enabled.desc=Proxy server will require Basic HTTP Proxy Authorization
139 | options.proxy_auth_username=Username
140 | options.proxy_auth_password=Password
141 | preferences.restartProxyPrompt=Changes won't take effect until you restart the proxy, restart it now?
--------------------------------------------------------------------------------
/desktop/src/main/resources/locale/messages_ru.properties:
--------------------------------------------------------------------------------
1 | #
2 | # This file is part of PowerTunnel.
3 | #
4 | # PowerTunnel is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # PowerTunnel is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with PowerTunnel. If not, see .
16 | #
17 | main.status.NOT_RUNNING=Сервер не запущен
18 | main.status.STARTING=Сервер запускается
19 | main.status.RUNNING=Сервер запущен
20 | main.status.STOPPING=Сервер останавливается
21 | main.start=Запустить
22 | main.stop=Остановить
23 | main.plugins=Плагины
24 | main.options=Настройки
25 | main.about=О программе
26 | main.reportBug=Сообщить об ошибке
27 | main.help=Помощь
28 | main.configureAutomaticallyPrompt=Настроить системный прокси-сервер автоматически?
29 | main.failedToStartServer=Ошибка при запуске сервера
30 | plugins.title=Плагины
31 | plugins.disable=Отключить
32 | plugins.enable=Включить
33 | plugins.homepage=Вебсайт
34 | plugins.settings=Настроить
35 | plugins.additionalConfiguration=Дополнительная конфигурация
36 | plugins.notConfigurable=Плагин не имеет настроек
37 | plugins.emptyPreferences=Список настроек плагина пуст
38 | plugins.failedToRead=Ошибка при чтении настроек плагина
39 | plugins.failedToOpen=Ошибка при открытии настроек плагина
40 | plugins.note=Настройки недоступны когда сервер включен
Сторонние плагины могут быть вредоносны
41 | plugins.visitRegistry=Официальный реестр плагинов
42 | preferences.subtitle=- параметры
43 | preferences.failedToSave=Ошибка при сохранении параметров
44 | preferences.incorrectConfiguration=Обнаружена некорректная конфигурация, вы хотите сбросить ее?
45 | preferences.exitConfirmation=Вы хотите сохранить изменения?
46 | preferences.resetConfirmation=Вы действительно хотите сбросить настройки?
47 | preferences.note=Некоторые параметры могут быть недоступны,
так как установлены из CLI
48 | options.title=Настройки
49 | options.recommended=рекомендуется
50 | options.group.proxyConnection=Соединение с прокси
51 | options.auto_proxy_setup=Автоматическая настройка прокси
52 | options.auto_proxy_setup.desc=Автоматически настраивает системный прокси-сервер\n\nWindows: Internet Explorer может быть запущен на несколько секунд для применения изменений
53 | options.upstream_proxy_enabled=Подключаться через внешний прокси-сервер
54 | options.upstream_proxy_enabled.desc=Использовать внешний прокси-сервер для доступа в Интернет
55 | options.upstream_proxy_host=Адрес внешнего прокси-сервера
56 | options.upstream_proxy_port=Порт внешнего прокси-сервера
57 | options.upstream_proxy_protocol = Протокол внешнего прокси-сервера
58 | options.upstream_proxy_auth_enabled=Авторизация на внешнем прокси-сервере
59 | options.upstream_proxy_auth_enabled.desc=Авторизовываться на внешнем прокси-сервере
60 | options.upstream_proxy_auth_username=Имя пользователя внешнего прокси-сервера
61 | options.upstream_proxy_auth_password=Пароль внешнего прокси-сервера
62 | options.group.proxySettings=Настройки прокси
63 | options.transparent_mode=Прозрачный режим
64 | options.transparent_mode.desc=Когда прокси-сервер работает в прозрачном режиме, он декларирует, что не вмешивается в трафик и не добавляет заголовок 'Via'
65 | options.strict_dns=Строгий режим DNS
66 | options.strict_dns.desc=Когда строгий режим отключен, доменное имя может быть разрешено с помощью стандартного DNS-резолвера,\nесли установленный резолвер не смог разрешить доменное имя или в процессе разрешения\nпроизошла ошибка.
67 | options.allow_requests_to_origin_server=Разрешить запросы к исходному серверу
68 | options.allow_requests_to_origin_server.desc=Экспериментальная опция, исправляет множество проблем при соединении
69 | options.note=ПРИМЕЧАНИЕ: Некоторые функции были выделены в плагины,
поэтому необходимо открыть их параметры для настройки
70 | updater.checkForUpdates=Проверить обновления
71 | updater.checkingForUpdates=Проверка обновлений...
72 | updater.noUpdates=Нет доступных обновлений
73 | updater.updateAvailable=Доступно обновление
74 | updater.failedToCheck=При проверке обновлений произошла ошибка
75 | updater.dialog=Доступно обновление %s
Версия: %s
Сведения о версии: %s
Скачать: %s
76 | yes=Да
77 | no=Нет
78 | ok=ОК
79 | reset=Сбросить
80 | cancel=Отмена
81 | save=Сохранить
82 | tray.version=Версия
83 | tray.open=Открыть
84 | tray.exit=Выйти
85 | tray.stillRunning=продолжает работать в трее
86 | menu.undo=Отменить
87 | menu.redo=Вернуть
88 | menu.cut=Вырезать
89 | menu.copy=Копировать
90 | menu.paste=Вставить
91 | menu.delete=Удалить
92 | menu.selectAll=Выделить все
93 | options.proxy_auth_enabled=Запрашивать авторизацию на прокси-сервере
94 | options.proxy_auth_enabled.desc=Прокси-сервер будет запрашивать базовую HTTP авторизацию
95 | options.proxy_auth_username=Имя пользователя
96 | options.proxy_auth_password=Пароль
97 | preferences.restartProxyPrompt=Изменения не вступят в силу до перезапуска прокси-сервера, перезапустить его сейчас?
--------------------------------------------------------------------------------
/desktop/src/main/resources/log4j2.xml:
--------------------------------------------------------------------------------
1 |
2 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/desktop/src/main/resources/plugins/DNSResolver.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krlvm/PowerTunnel/3e5df1e6ce4e12628fee4e2b940e4db9067cde3c/desktop/src/main/resources/plugins/DNSResolver.jar
--------------------------------------------------------------------------------
/desktop/src/main/resources/plugins/LibertyTunnel.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krlvm/PowerTunnel/3e5df1e6ce4e12628fee4e2b940e4db9067cde3c/desktop/src/main/resources/plugins/LibertyTunnel.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krlvm/PowerTunnel/3e5df1e6ce4e12628fee4e2b940e4db9067cde3c/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #
2 | # This file is part of PowerTunnel.
3 | #
4 | # PowerTunnel is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # PowerTunnel is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with PowerTunnel. If not, see .
16 | #
17 |
18 | distributionBase=GRADLE_USER_HOME
19 | distributionPath=wrapper/dists
20 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
21 | zipStoreBase=GRADLE_USER_HOME
22 | zipStorePath=wrapper/dists
23 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/littleproxy/.gitignore:
--------------------------------------------------------------------------------
1 | /build/
2 |
--------------------------------------------------------------------------------
/littleproxy/build.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | plugins {
19 | id 'java-library'
20 | }
21 |
22 | group 'io.github.krlvm.powertunnel.proxy'
23 | version '2.0'
24 |
25 | dependencies {
26 | api 'xyz.rogfam:littleproxy:2.0.5'
27 | api 'org.bouncycastle:bcpkix-jdk15on:1.69'
28 |
29 | testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2'
30 | testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2'
31 | }
--------------------------------------------------------------------------------
/littleproxy/src/main/java/java/nio/charset/StandardCharsets.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | /*
19 | * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
20 | * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
21 | *
22 | *
23 | *
24 | *
25 | *
26 | *
27 | *
28 | *
29 | *
30 | *
31 | *
32 | *
33 | *
34 | *
35 | *
36 | *
37 | *
38 | *
39 | *
40 | *
41 | */
42 | package java.nio.charset;
43 |
44 | import java.nio.charset.Charset;
45 |
46 | /**
47 | * Constant definitions for the standard {@link Charset Charsets}. These
48 | * charsets are guaranteed to be available on every implementation of the Java
49 | * platform.
50 | *
51 | * @see Standard Charsets
52 | * @since 1.7
53 | */
54 | public final class StandardCharsets {
55 |
56 | private StandardCharsets() {
57 | throw new AssertionError("No java.nio.charset.StandardCharsets instances for you!");
58 | }
59 | /**
60 | * Seven-bit ASCII, a.k.a. ISO646-US, a.k.a. the Basic Latin block of the
61 | * Unicode character set
62 | */
63 | public static final Charset US_ASCII = Charset.forName("US-ASCII");
64 | /**
65 | * ISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1
66 | */
67 | public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
68 | /**
69 | * Eight-bit UCS Transformation Format
70 | */
71 | public static final Charset UTF_8 = Charset.forName("UTF-8");
72 | /**
73 | * Sixteen-bit UCS Transformation Format, big-endian byte order
74 | */
75 | public static final Charset UTF_16BE = Charset.forName("UTF-16BE");
76 | /**
77 | * Sixteen-bit UCS Transformation Format, little-endian byte order
78 | */
79 | public static final Charset UTF_16LE = Charset.forName("UTF-16LE");
80 | /**
81 | * Sixteen-bit UCS Transformation Format, byte order identified by an
82 | * optional byte-order mark
83 | */
84 | public static final Charset UTF_16 = Charset.forName("UTF-16");
85 | }
86 |
--------------------------------------------------------------------------------
/littleproxy/src/main/java/org/littleshoot/proxy/mitm/MitmHelper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package org.littleshoot.proxy.mitm;
19 |
20 | import java.io.Closeable;
21 | import java.io.IOException;
22 |
23 | public class MitmHelper {
24 |
25 | // From Apache Commons-IO
26 | public static void closeQuietly(Closeable is) {
27 | if(is == null) return;
28 | try {
29 | is.close();
30 | } catch (IOException ignore) {}
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/sample-plugin/.gitignore:
--------------------------------------------------------------------------------
1 | /build/
2 |
--------------------------------------------------------------------------------
/sample-plugin/build.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | plugins {
19 | id 'java'
20 | }
21 |
22 | group 'io.github.krlvm.powertunnel.plugins'
23 | version '2.0'
24 |
25 | jar {
26 | destinationDirectory.set(file("$rootDir/desktop/build/run/plugins"))
27 | }
28 |
29 | dependencies {
30 | implementation project(':sdk')
31 |
32 | testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
33 | testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
34 | }
--------------------------------------------------------------------------------
/sample-plugin/src/main/java/io/github/krlvm/powertunnel/plugins/sample/SamplePlugin.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.plugins.sample;
19 |
20 | import io.github.krlvm.powertunnel.sdk.http.ProxyRequest;
21 | import io.github.krlvm.powertunnel.sdk.http.ProxyResponse;
22 | import io.github.krlvm.powertunnel.sdk.plugin.PowerTunnelPlugin;
23 | import io.github.krlvm.powertunnel.sdk.proxy.ProxyAdapter;
24 | import io.github.krlvm.powertunnel.sdk.proxy.ProxyServer;
25 | import org.jetbrains.annotations.NotNull;
26 |
27 | import java.nio.charset.StandardCharsets;
28 |
29 | public class SamplePlugin extends PowerTunnelPlugin {
30 |
31 | @Override
32 | public void onProxyInitialization(ProxyServer proxy) {
33 | proxy.setMITMEnabled(true);
34 | proxy.setFullResponse(true);
35 | proxy.setFullRequest(true);
36 |
37 | this.registerProxyListener(new ProxyAdapter() {
38 | @Override
39 | public void onClientToProxyRequest(@NotNull ProxyRequest request) {
40 | if (request.isEncrypted()) return;
41 | if (!request.getHost().equals("github.com")) return;
42 |
43 | final ProxyResponse response = getServer()
44 | .getProxyServer()
45 | .getResponseBuilder("PowerTunnel Test Plugin")
46 | .header("X-PT-Test", "OK")
47 | .build();
48 | request.setResponse(response);
49 | }
50 |
51 | @Override
52 | public void onProxyToClientResponse(@NotNull ProxyResponse response) {
53 | if (!proxy.isMITMEnabled()) return;
54 | if (!response.isDataPacket()) return;
55 |
56 | if (!"text/html; charset=utf-8".equals(response.headers().get("Content-Type"))) return;
57 |
58 | final byte[] raw = response.content();
59 | final String str = new String(raw, StandardCharsets.UTF_8);
60 |
61 | response.setContent(("Injected response part" + str).getBytes(StandardCharsets.UTF_8));
62 | }
63 | });
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/sample-plugin/src/main/resources/locale/messages_en.properties:
--------------------------------------------------------------------------------
1 | #
2 | # This file is part of PowerTunnel.
3 | #
4 | # PowerTunnel is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # PowerTunnel is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with PowerTunnel. If not, see .
16 | #
17 | test-switch=Test Preference (switch)
18 | test-check=Test Preference (check)
19 | test-check.desc=Checkbox Test Preference Description
--------------------------------------------------------------------------------
/sample-plugin/src/main/resources/locale/messages_ru.properties:
--------------------------------------------------------------------------------
1 | #
2 | # This file is part of PowerTunnel.
3 | #
4 | # PowerTunnel is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # PowerTunnel is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with PowerTunnel. If not, see .
16 | #
17 |
18 | test-switch=Тестовая настройка (переключатель)
19 | test-check=Тестовая настройка (флажок)
20 | test-check.desc=Описание тестовой настройки - флажка
--------------------------------------------------------------------------------
/sample-plugin/src/main/resources/plugin.ini:
--------------------------------------------------------------------------------
1 | id: sample-plugin
2 | version: 1.0
3 | versionCode: 1
4 | name: Sample Plugin
5 | description: Sample Plugin for PowerTunnel
6 | author: krlvm
7 | homepage: https://github.com/krlvm/PowerTunnel
8 | mainClass: io.github.krlvm.powertunnel.plugins.sample.SamplePlugin
9 | targetSdkVersion: 90
--------------------------------------------------------------------------------
/sample-plugin/src/main/resources/preferences.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "key": "test-check",
4 | "defaultValue": true,
5 | "type": "checkbox"
6 | },
7 | {
8 | "key": "test-switch",
9 | "description": "Switch Test Preference Description",
10 | "defaultValue": false,
11 | "type": "switch"
12 | },
13 | {
14 | "key": "test-str",
15 | "title": "Test Preference (str)",
16 | "description": "String Test Preference Description",
17 | "defaultValue": "default value of test-str",
18 | "type": "string"
19 | },
20 | {
21 | "key": "test-number",
22 | "title": "Test Preference (number)",
23 | "description": "Number Test Preference Description",
24 | "defaultValue": 5,
25 | "type": "number"
26 | },
27 | {
28 | "key": "test-select",
29 | "title": "Test Preference (select)",
30 | "description": "Select Test Preference Description",
31 | "defaultValue": "opt1",
32 | "type": "select",
33 | "items": [
34 | {
35 | "key": "opt1",
36 | "name": "Option 1 Name"
37 | },
38 | {
39 | "key": "opt2",
40 | "name": "Option 2 Name"
41 | },
42 | {
43 | "key": "opt3",
44 | "name": "Option 3 Name"
45 | }
46 | ]
47 | },
48 |
49 | {
50 | "group": "dependent-preferences",
51 | "title": "Dependent preferences",
52 | "description": "Dependent preferences group description",
53 | "preferences": [
54 | {
55 | "key": "test-number-d",
56 | "title": "Test Preference (number) dependent on 'test-check'",
57 | "description": "Number Test-C Preference Description",
58 | "type": "number",
59 | "dependency": "test-check"
60 | },
61 | {
62 | "key": "test-number-d",
63 | "title": "Test Preference (number) dependent on 'test-str' (val='value')",
64 | "description": "Number Test-S Preference Description",
65 | "type": "number",
66 | "dependency": "test-str",
67 | "dependencyValue": "value"
68 | },
69 | {
70 | "key": "test-number-n",
71 | "title": "Test Preference (number) dependent on 'test-number' (val='5')",
72 | "description": "Number Test-N Preference Description",
73 | "type": "number",
74 | "dependency": "test-number",
75 | "dependencyValue": 5
76 | },
77 | {
78 | "key": "test-number-n",
79 | "title": "Test Preference (number) dependent on 'test-select' (val='opt2')",
80 | "description": "Number Test-SEL Preference Description",
81 | "type": "number",
82 | "dependency": "test-select",
83 | "dependencyValue": "opt2"
84 | }
85 | ]
86 | }
87 | ]
--------------------------------------------------------------------------------
/sdk/.gitignore:
--------------------------------------------------------------------------------
1 | /build/
2 |
--------------------------------------------------------------------------------
/sdk/build.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | plugins {
19 | id 'java-library'
20 | }
21 |
22 | version '2.0'
23 |
24 | dependencies {
25 | // Include single class from Android SDK (Base64) as a runtime dependency
26 | // to avoid using reflection and speed up performance by using direct calls
27 | implementation fileTree(dir: 'libs', include: ['*.jar'])
28 |
29 | api 'org.jetbrains:annotations:23.0.0'
30 | api 'org.slf4j:slf4j-api:1.7.35'
31 |
32 | testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2'
33 | testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2'
34 | }
35 |
36 | task fatJar(type: Jar, group: 'build', description: 'Assembles a jar archive containing the main classes and all dependencies.') {
37 | archiveClassifier = 'all'
38 | duplicatesStrategy DuplicatesStrategy.EXCLUDE
39 |
40 | from {
41 | configurations.runtimeClasspath.findAll {it.name.endsWith('jar') }.collect { zipTree(it) }
42 | } {
43 | exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA'
44 | }
45 |
46 | with jar
47 | }
--------------------------------------------------------------------------------
/sdk/libs/android-base64.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/krlvm/PowerTunnel/3e5df1e6ce4e12628fee4e2b940e4db9067cde3c/sdk/libs/android-base64.jar
--------------------------------------------------------------------------------
/sdk/src/main/java/io/github/krlvm/powertunnel/sdk/PowerTunnelServer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.sdk;
19 |
20 | import io.github.krlvm.powertunnel.sdk.configuration.Configuration;
21 | import io.github.krlvm.powertunnel.sdk.exceptions.ProxyStartException;
22 | import io.github.krlvm.powertunnel.sdk.plugin.PluginInfo;
23 | import io.github.krlvm.powertunnel.sdk.plugin.PowerTunnelPlugin;
24 | import io.github.krlvm.powertunnel.sdk.proxy.ProxyListener;
25 | import io.github.krlvm.powertunnel.sdk.proxy.ProxyServer;
26 | import io.github.krlvm.powertunnel.sdk.proxy.ProxyStatus;
27 | import io.github.krlvm.powertunnel.sdk.types.PowerTunnelPlatform;
28 | import io.github.krlvm.powertunnel.sdk.types.VersionInfo;
29 | import org.jetbrains.annotations.NotNull;
30 |
31 | import java.io.File;
32 | import java.io.IOException;
33 |
34 | public interface PowerTunnelServer {
35 |
36 | /**
37 | * Starts proxy server
38 | * @throws ProxyStartException if proxy server failed to start
39 | */
40 | void start() throws ProxyStartException;
41 |
42 | /**
43 | * Stops proxy server
44 | */
45 | void stop();
46 |
47 | /**
48 | * Check whether proxy server is running
49 | *
50 | * @return whether proxy server is currently running
51 | */
52 | boolean isRunning();
53 |
54 | /**
55 | * Returns proxy server status
56 | *
57 | * @return proxy server status
58 | */
59 | @NotNull ProxyStatus getStatus();
60 |
61 | /**
62 | * Registers proxy server listener
63 | *
64 | * @param pluginInfo registrant plugin
65 | * @param listener proxy server listener
66 | * @return ID of registered listener
67 | */
68 | void registerProxyListener(@NotNull PluginInfo pluginInfo, @NotNull ProxyListener listener);
69 |
70 | /**
71 | * Registers proxy server listener
72 | *
73 | * @param pluginInfo registrant plugin
74 | * @param listener proxy server listeners
75 | * @param priority proxy server listener priority
76 | */
77 | void registerProxyListener(@NotNull PluginInfo pluginInfo, @NotNull ProxyListener listener, int priority);
78 |
79 | /**
80 | * Unregisters proxy server listener
81 | * @param listener registered proxy server listener
82 | */
83 | void unregisterProxyListener(@NotNull ProxyListener listener);
84 |
85 | /**
86 | * Registers server listener
87 | *
88 | * @param pluginInfo registrant plugin
89 | * @param listener proxy listener
90 | */
91 | void registerServerListener(@NotNull PluginInfo pluginInfo, @NotNull ServerListener listener);
92 |
93 | /**
94 | * Unregisters server listener
95 | * @param listener registered server listener
96 | */
97 | void unregisterServerListener(@NotNull ServerListener listener);
98 |
99 | /**
100 | * Reads plugin configuration
101 | *
102 | * @param pluginInfo plugin info
103 | * @return configuration store
104 | */
105 | @NotNull Configuration readConfiguration(@NotNull PluginInfo pluginInfo);
106 |
107 | /**
108 | * Saves plugin configuration
109 | *
110 | * @param pluginInfo plugin info
111 | * @param configuration configuration store
112 | */
113 | void saveConfiguration(@NotNull PluginInfo pluginInfo, @NotNull Configuration configuration);
114 |
115 | /**
116 | * Reads file in configurations directory as plain text
117 | *
118 | * @param filename file name
119 | * @return plain text
120 | * @throws IOException on file read error
121 | */
122 | @NotNull String readTextFile(@NotNull String filename) throws IOException;
123 |
124 | /**
125 | * Saves file in configurations directory as plain text
126 | *
127 | * @param filename file name
128 | * @param text plain text to write
129 | * @throws IOException on file read error
130 | */
131 | @NotNull void saveTextFile(@NotNull String filename, @NotNull String text) throws IOException;
132 |
133 | /**
134 | * Returns proxy server
135 | * If proxy server was not created, returns null
136 | *
137 | * @return proxy server
138 | */
139 | ProxyServer getProxyServer();
140 |
141 | /**
142 | * Returns PowerTunnel platform
143 | * @return PowerTunnel platform
144 | */
145 | PowerTunnelPlatform getPlatform();
146 |
147 | /**
148 | * Returns PowerTunnel Core version info
149 | * @return Core version info
150 | */
151 | VersionInfo getVersion();
152 | }
153 |
--------------------------------------------------------------------------------
/sdk/src/main/java/io/github/krlvm/powertunnel/sdk/ServerAdapter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.sdk;
19 |
20 | import io.github.krlvm.powertunnel.sdk.proxy.ProxyStatus;
21 | import org.jetbrains.annotations.NotNull;
22 |
23 | public abstract class ServerAdapter implements ServerListener {
24 |
25 | @Override
26 | public void beforeProxyStatusChanged(@NotNull ProxyStatus status) {}
27 |
28 | @Override
29 | public void onProxyStatusChanged(@NotNull ProxyStatus status) {}
30 | }
31 |
--------------------------------------------------------------------------------
/sdk/src/main/java/io/github/krlvm/powertunnel/sdk/ServerListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.sdk;
19 |
20 | import io.github.krlvm.powertunnel.sdk.proxy.ProxyServer;
21 | import io.github.krlvm.powertunnel.sdk.proxy.ProxyStatus;
22 | import org.jetbrains.annotations.NotNull;
23 |
24 | public interface ServerListener {
25 |
26 | /**
27 | * Called before server status changing,
28 | * e.g. after user stopped the server
29 | *
30 | * @param status new server status
31 | */
32 | void beforeProxyStatusChanged(@NotNull ProxyStatus status);
33 |
34 | /**
35 | * Called after server status has changed,
36 | * e.g. server stopped
37 | *
38 | * @param status new server status
39 | */
40 | void onProxyStatusChanged(@NotNull ProxyStatus status);
41 | }
42 |
--------------------------------------------------------------------------------
/sdk/src/main/java/io/github/krlvm/powertunnel/sdk/configuration/Configuration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.sdk.configuration;
19 |
20 | import java.util.Collection;
21 | import java.util.Map;
22 |
23 | public interface Configuration {
24 |
25 | String get(String key, String defaultValue);
26 | void set(String key, String value);
27 |
28 | int getInt(String key, int defaultValue);
29 | void setInt(String key, int value);
30 |
31 | long getLong(String key, long defaultValue);
32 | void setLong(String key, long value);
33 |
34 | boolean getBoolean(String key, boolean defaultValue);
35 | void setBoolean(String key, boolean value);
36 |
37 | boolean contains(String key);
38 | void remove(String key);
39 |
40 | Map toMap();
41 | Collection keys();
42 | void clear();
43 |
44 | String EXTENSION = ".ini";
45 | }
46 |
--------------------------------------------------------------------------------
/sdk/src/main/java/io/github/krlvm/powertunnel/sdk/exceptions/ConfigurationLoadException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.sdk.exceptions;
19 |
20 | public class ConfigurationLoadException extends Exception {
21 |
22 | public ConfigurationLoadException(Throwable cause) {
23 | super(cause);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/sdk/src/main/java/io/github/krlvm/powertunnel/sdk/exceptions/PluginLoadException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.sdk.exceptions;
19 |
20 | public class PluginLoadException extends ProxyStartException {
21 |
22 | private final String jarFile;
23 |
24 | public PluginLoadException(String jarFile, String message, Throwable cause) {
25 | super(message, cause);
26 | this.jarFile = jarFile;
27 | }
28 |
29 | public PluginLoadException(String jarFile, String message) {
30 | super(message + " [" + jarFile + "]");
31 | this.jarFile = jarFile;
32 | }
33 |
34 | public String getJarFile() {
35 | return jarFile;
36 | }
37 |
38 | @Override
39 | public String getMessage() {
40 | return super.getMessage() + " (" + jarFile + ")";
41 | }
42 |
43 | @Override
44 | public String getLocalizedMessage() {
45 | return super.getLocalizedMessage() + " (" + jarFile + ")";
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/sdk/src/main/java/io/github/krlvm/powertunnel/sdk/exceptions/ProxyStartException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.sdk.exceptions;
19 |
20 | public class ProxyStartException extends Exception {
21 |
22 | public ProxyStartException(String message) {
23 | super(message);
24 | }
25 |
26 | public ProxyStartException(Throwable cause) {
27 | super(cause);
28 | }
29 |
30 | public ProxyStartException(String message, Throwable cause) {
31 | super(message, cause);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/sdk/src/main/java/io/github/krlvm/powertunnel/sdk/http/HttpHeaders.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.sdk.http;
19 |
20 | import org.jetbrains.annotations.NotNull;
21 | import org.jetbrains.annotations.Nullable;
22 |
23 | import java.util.Set;
24 |
25 | public interface HttpHeaders {
26 |
27 | @Nullable String get(String name);
28 | void set(@NotNull String name, @NotNull String value);
29 |
30 | @Nullable Integer getInt(String name);
31 | void setInt(@NotNull String name, int value);
32 |
33 | @Nullable Short getShort(String name);
34 | void setShort(@NotNull String name, short value);
35 |
36 | @NotNull Set names();
37 | boolean contains(@NotNull String name);
38 | void remove(@NotNull String name);
39 |
40 | boolean isEmpty();
41 | int size();
42 | }
43 |
--------------------------------------------------------------------------------
/sdk/src/main/java/io/github/krlvm/powertunnel/sdk/http/HttpMethod.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.sdk.http;
19 |
20 | public enum HttpMethod {
21 | OPTIONS,
22 | GET,
23 | HEAD,
24 | POST,
25 | PUT,
26 | PATCH,
27 | DELETE,
28 | TRACE,
29 | CONNECT,
30 | }
--------------------------------------------------------------------------------
/sdk/src/main/java/io/github/krlvm/powertunnel/sdk/http/ProxyMessage.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.sdk.http;
19 |
20 | import io.github.krlvm.powertunnel.sdk.types.FullAddress;
21 | import org.jetbrains.annotations.NotNull;
22 | import org.jetbrains.annotations.Nullable;
23 |
24 | public interface ProxyMessage {
25 |
26 | @Nullable FullAddress address();
27 |
28 | @NotNull HttpHeaders headers();
29 |
30 | byte[] content();
31 | }
--------------------------------------------------------------------------------
/sdk/src/main/java/io/github/krlvm/powertunnel/sdk/http/ProxyRequest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.sdk.http;
19 |
20 | import io.github.krlvm.powertunnel.sdk.types.FullAddress;
21 | import org.jetbrains.annotations.NotNull;
22 | import org.jetbrains.annotations.Nullable;
23 |
24 | public interface ProxyRequest extends ProxyMessage {
25 |
26 | @NotNull HttpMethod getMethod();
27 | void setMethod(@NotNull HttpMethod method);
28 | void setMethod(@NotNull String method);
29 |
30 | default boolean isEncrypted() {
31 | return getMethod() == HttpMethod.CONNECT;
32 | }
33 |
34 | default String getHost() {
35 | if (address() != null) {
36 | return address().getHost();
37 | } else if (isEncrypted() && getUri() != null) {
38 | return FullAddress.fromString(getUri()).getHost();
39 | } else if (headers().contains("Host")) {
40 | return headers().get("Host");
41 | }
42 | return null;
43 | }
44 |
45 | boolean isDataPacket();
46 |
47 | void setBlocked(boolean blocked);
48 | boolean isBlocked();
49 |
50 | @NotNull String getUri();
51 | void setUri(@NotNull String uri);
52 |
53 | @Nullable ProxyResponse getResponse();
54 | void setResponse(@NotNull ProxyResponse response);
55 |
56 | @NotNull
57 | void setContent(byte[] content);
58 | }
--------------------------------------------------------------------------------
/sdk/src/main/java/io/github/krlvm/powertunnel/sdk/http/ProxyResponse.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.sdk.http;
19 |
20 | import org.jetbrains.annotations.NotNull;
21 |
22 | public interface ProxyResponse extends ProxyMessage {
23 |
24 | int code();
25 | void setCode(int code);
26 |
27 | boolean isDataPacket();
28 |
29 | void setContent(byte[] content);
30 |
31 | interface Builder {
32 | Builder code(int code);
33 | Builder contentType(String contentType);
34 | Builder header(String name, String value);
35 | Builder header(String name, int value);
36 | Builder header(String name, short value);
37 | ProxyResponse build();
38 | }
39 | }
--------------------------------------------------------------------------------
/sdk/src/main/java/io/github/krlvm/powertunnel/sdk/plugin/IPowerTunnelPlugin.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.sdk.plugin;
19 |
20 | import io.github.krlvm.powertunnel.sdk.ServerListener;
21 | import org.jetbrains.annotations.NotNull;
22 |
23 | public interface IPowerTunnelPlugin {
24 |
25 | int addListener(@NotNull ServerListener listener);
26 | }
27 |
--------------------------------------------------------------------------------
/sdk/src/main/java/io/github/krlvm/powertunnel/sdk/plugin/PluginInfo.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.sdk.plugin;
19 |
20 | import java.io.Serializable;
21 |
22 | public class PluginInfo implements Serializable {
23 |
24 | private final String id;
25 | private final String version;
26 | private final int versionCode;
27 |
28 | private final String name;
29 | private final String description;
30 | private final String author;
31 | private final String homepage;
32 |
33 | private final String[] configurationFiles;
34 |
35 | private final String mainClass;
36 | private final int targetSdkVersion;
37 |
38 | private final String source;
39 |
40 | /**
41 | * @param name plugin name
42 | * @param description plugin description
43 | * @param version plugin version
44 | * @param author plugin author
45 | * @param homepage plugin homepage
46 | * @param configurationFiles plugin additional configuration files
47 | * @param mainClass plugin main class
48 | * @param targetSdkVersion plugin target SDK version
49 | * @param source source jar
50 | */
51 | public PluginInfo(
52 | String id,
53 | String version,
54 | int versionCode,
55 | String name,
56 | String description,
57 | String author,
58 | String homepage,
59 | String[] configurationFiles,
60 | String mainClass,
61 | int targetSdkVersion,
62 | String source
63 | ) {
64 | this.id = id;
65 | this.version = version;
66 | this.versionCode = versionCode;
67 | this.name = name;
68 | this.description = description;
69 | this.author = author;
70 | this.homepage = homepage;
71 |
72 | this.configurationFiles = configurationFiles;
73 |
74 | this.mainClass = mainClass;
75 | this.targetSdkVersion = targetSdkVersion;
76 |
77 | this.source = source;
78 | }
79 |
80 | public String getId() {
81 | return id;
82 | }
83 |
84 | public String getVersion() {
85 | return version;
86 | }
87 |
88 | public int getVersionCode() {
89 | return versionCode;
90 | }
91 |
92 | public String getName() {
93 | return name;
94 | }
95 |
96 | public String getDescription() {
97 | return description;
98 | }
99 |
100 | public String getAuthor() {
101 | return author;
102 | }
103 |
104 | public String getHomepage() {
105 | return homepage;
106 | }
107 |
108 | public String[] getConfigurationFiles() {
109 | return configurationFiles;
110 | }
111 |
112 | public String getMainClass() {
113 | return mainClass;
114 | }
115 |
116 | public int getTargetSdkVersion() {
117 | return targetSdkVersion;
118 | }
119 |
120 | public String getSource() {
121 | return source;
122 | }
123 | }
--------------------------------------------------------------------------------
/sdk/src/main/java/io/github/krlvm/powertunnel/sdk/plugin/PowerTunnelPlugin.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.sdk.plugin;
19 |
20 | import io.github.krlvm.powertunnel.sdk.PowerTunnelServer;
21 | import io.github.krlvm.powertunnel.sdk.ServerListener;
22 | import io.github.krlvm.powertunnel.sdk.configuration.Configuration;
23 | import io.github.krlvm.powertunnel.sdk.proxy.ProxyListener;
24 | import io.github.krlvm.powertunnel.sdk.proxy.ProxyServer;
25 | import org.jetbrains.annotations.NotNull;
26 |
27 | import java.io.File;
28 | import java.io.IOException;
29 |
30 | public abstract class PowerTunnelPlugin {
31 |
32 | private PowerTunnelServer server;
33 | private PluginInfo info;
34 |
35 | private Configuration configuration;
36 |
37 | /**
38 | * Attaches PowerTunnel server instance to current server instance
39 | * Should be called only once after plugin initialization
40 | *
41 | * @param server PowerTunnel server instance
42 | */
43 | public final void attachServer(@NotNull PowerTunnelServer server) {
44 | if(this.server != null) throw new IllegalStateException("A server is already attached");
45 | this.server = server;
46 | }
47 |
48 | /**
49 | * Attaches plugin info to current plugin instance
50 | * @param info plugin info
51 | */
52 | public void attachInfo(@NotNull PluginInfo info) {
53 | if(this.info != null) throw new IllegalStateException("PluginInfo is already attached");
54 | this.info = info;
55 | }
56 |
57 | /**
58 | * Returns attached PowerTunnel server instance
59 | * @return attached PowerTunnel server instance
60 | */
61 | public PowerTunnelServer getServer() {
62 | return this.server;
63 | }
64 |
65 | /**
66 | * Returns information about the plugin
67 | * @return plugin information
68 | */
69 | public PluginInfo getInfo() {
70 | return info;
71 | }
72 |
73 | /**
74 | * Throws an exception if PowerTunnel server is not initialized
75 | */
76 | protected void validateServer() {
77 | if(getServer() == null) throw new IllegalStateException("Server is not initialized yet");
78 | }
79 |
80 | public void registerProxyListener(@NotNull ProxyListener listener) {
81 | validateServer();
82 | getServer().registerProxyListener(getInfo(), listener);
83 | }
84 | public void registerProxyListener(@NotNull ProxyListener listener, int priority) {
85 | validateServer();
86 | getServer().registerProxyListener(getInfo(), listener, priority);
87 | }
88 |
89 | public void registerServerListener(@NotNull ServerListener listener) {
90 | validateServer();
91 | getServer().registerServerListener(getInfo(), listener);
92 | }
93 |
94 | public Configuration readConfiguration() {
95 | validateServer();
96 | if(configuration == null) configuration = getServer().readConfiguration(getInfo());
97 | return configuration;
98 | }
99 |
100 | public void saveConfiguration() throws IOException {
101 | if(configuration == null) return;
102 | getServer().saveConfiguration(getInfo(), configuration);
103 | }
104 |
105 | public String readTextFile(@NotNull String filename) throws IOException {
106 | validateServer();
107 | return getServer().readTextFile(filename);
108 | }
109 |
110 | public void saveTextFile(@NotNull String filename, @NotNull String content) throws IOException {
111 | validateServer();
112 | getServer().saveTextFile(filename, content);
113 | }
114 |
115 |
116 | /**
117 | * Called after proxy server creation
118 | * and before proxy server start
119 | *
120 | * @param proxy PowerTunnel Proxy Server
121 | */
122 | public void onProxyInitialization(@NotNull ProxyServer proxy) {}
123 |
124 | @Override
125 | public String toString() {
126 | return "PowerTunnelPlugin{" +
127 | "info=" + info +
128 | '}';
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/sdk/src/main/java/io/github/krlvm/powertunnel/sdk/proxy/DNSRequest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.sdk.proxy;
19 |
20 | import org.jetbrains.annotations.Nullable;
21 |
22 | import java.net.InetSocketAddress;
23 |
24 | public class DNSRequest {
25 |
26 | private final String host;
27 | private final int port;
28 |
29 | private InetSocketAddress response;
30 |
31 | public DNSRequest(String host, int port) {
32 | this.host = host;
33 | this.port = port;
34 | }
35 |
36 | public String getHost() {
37 | return host;
38 | }
39 |
40 | public int getPort() {
41 | return port;
42 | }
43 |
44 |
45 | /**
46 | * Returns response
47 | * If there's no DNS Resolvers registered, returns null
48 | *
49 | * @return response
50 | */
51 | public @Nullable InetSocketAddress getResponse() {
52 | return response;
53 | }
54 |
55 | /**
56 | * Sets response
57 | * If response is set to null, the request will be resolved
58 | * using default DNS Resolver
59 | *
60 | * @param response
61 | */
62 | public void setResponse(@Nullable InetSocketAddress response) {
63 | this.response = response;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/sdk/src/main/java/io/github/krlvm/powertunnel/sdk/proxy/DNSResolver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.sdk.proxy;
19 |
20 | import org.jetbrains.annotations.NotNull;
21 |
22 | import java.net.InetSocketAddress;
23 | import java.net.UnknownHostException;
24 |
25 | public interface DNSResolver {
26 | @NotNull InetSocketAddress resolve(@NotNull String host, int port) throws UnknownHostException;
27 | }
28 |
--------------------------------------------------------------------------------
/sdk/src/main/java/io/github/krlvm/powertunnel/sdk/proxy/ProxyAdapter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.sdk.proxy;
19 |
20 | import io.github.krlvm.powertunnel.sdk.http.ProxyRequest;
21 | import io.github.krlvm.powertunnel.sdk.http.ProxyResponse;
22 | import io.github.krlvm.powertunnel.sdk.types.FullAddress;
23 | import org.jetbrains.annotations.NotNull;
24 |
25 | public abstract class ProxyAdapter implements ProxyListener {
26 |
27 | @Override
28 | public void onClientToProxyRequest(@NotNull ProxyRequest request) {}
29 |
30 | @Override
31 | public void onProxyToServerRequest(@NotNull ProxyRequest request) {}
32 |
33 | @Override
34 | public void onServerToProxyResponse(@NotNull ProxyResponse response) {}
35 |
36 | @Override
37 | public void onProxyToClientResponse(@NotNull ProxyResponse response) {}
38 |
39 | @Override
40 | public Boolean onResolutionRequest(@NotNull DNSRequest request) {
41 | return null;
42 | }
43 |
44 | @Override
45 | public Integer onGetChunkSize(@NotNull FullAddress address) {
46 | return null;
47 | }
48 |
49 | @Override
50 | public Boolean isFullChunking(@NotNull FullAddress address) {
51 | return null;
52 | }
53 |
54 | @Override
55 | public Boolean isMITMAllowed(@NotNull FullAddress address) {
56 | return null;
57 | }
58 |
59 | @Override
60 | public Object onGetSNI(@NotNull String hostname) {
61 | return Void.TYPE;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/sdk/src/main/java/io/github/krlvm/powertunnel/sdk/proxy/ProxyAddress.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.sdk.proxy;
19 |
20 | import io.github.krlvm.powertunnel.sdk.types.FullAddress;
21 | import org.jetbrains.annotations.NotNull;
22 |
23 | public class ProxyAddress extends FullAddress {
24 |
25 | public ProxyAddress(@NotNull String host, int port) {
26 | super(host, port);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/sdk/src/main/java/io/github/krlvm/powertunnel/sdk/proxy/ProxyCredentials.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.sdk.proxy;
19 |
20 | import io.github.krlvm.powertunnel.sdk.utiities.Base64Compat;
21 | import org.jetbrains.annotations.NotNull;
22 |
23 | import java.nio.charset.StandardCharsets;
24 |
25 | public class ProxyCredentials {
26 |
27 | private final String username;
28 | private final String password;
29 |
30 | public ProxyCredentials(@NotNull String username, @NotNull String password) {
31 | this.username = username;
32 | this.password = password;
33 | }
34 |
35 | public String getUsername() {
36 | return username;
37 | }
38 |
39 | public String getPassword() {
40 | return password;
41 | }
42 |
43 | public String toAuthorizationCode() {
44 | final String credential = this.username + ":" + this.password;
45 | final byte[] data = credential.getBytes(StandardCharsets.UTF_8);
46 | return Base64Compat.encodeToString(data).trim();
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/sdk/src/main/java/io/github/krlvm/powertunnel/sdk/proxy/ProxyListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.sdk.proxy;
19 |
20 | import io.github.krlvm.powertunnel.sdk.http.ProxyRequest;
21 | import io.github.krlvm.powertunnel.sdk.http.ProxyResponse;
22 | import io.github.krlvm.powertunnel.sdk.types.FullAddress;
23 | import org.jetbrains.annotations.NotNull;
24 |
25 | public interface ProxyListener {
26 |
27 | void onClientToProxyRequest(@NotNull ProxyRequest request);
28 | void onProxyToServerRequest(@NotNull ProxyRequest request);
29 |
30 | void onServerToProxyResponse(@NotNull ProxyResponse response);
31 | void onProxyToClientResponse(@NotNull ProxyResponse response);
32 |
33 | Boolean onResolutionRequest(@NotNull DNSRequest request);
34 |
35 | Integer onGetChunkSize(@NotNull FullAddress address);
36 | Boolean isFullChunking(@NotNull FullAddress address);
37 |
38 | Boolean isMITMAllowed(@NotNull FullAddress address);
39 | Object onGetSNI(@NotNull String hostname);
40 |
41 | int PRIORITY_HIGH = -5;
42 | int PRIORITY_NORMAL = 0;
43 | int PRIORITY_LOW = 5;
44 | }
45 |
--------------------------------------------------------------------------------
/sdk/src/main/java/io/github/krlvm/powertunnel/sdk/proxy/ProxyStatus.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.sdk.proxy;
19 |
20 | public enum ProxyStatus {
21 | NOT_RUNNING,
22 | STARTING,
23 | RUNNING,
24 | STOPPING
25 | }
--------------------------------------------------------------------------------
/sdk/src/main/java/io/github/krlvm/powertunnel/sdk/proxy/UpstreamProxyServer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.sdk.proxy;
19 |
20 | import io.github.krlvm.powertunnel.sdk.types.UpstreamProxyType;
21 | import org.jetbrains.annotations.NotNull;
22 | import org.jetbrains.annotations.Nullable;
23 |
24 | import java.net.InetSocketAddress;
25 | import java.net.UnknownHostException;
26 |
27 | public class UpstreamProxyServer {
28 |
29 | private ProxyAddress address;
30 | private ProxyCredentials credentials;
31 | private UpstreamProxyType type;
32 |
33 | private InetSocketAddress inetSocketAddress;
34 |
35 | public UpstreamProxyServer(@NotNull ProxyAddress address) {
36 | this(address, null);
37 | }
38 |
39 | public UpstreamProxyServer(@NotNull ProxyAddress address, @Nullable ProxyCredentials credentials) {
40 | this(address, credentials, null);
41 | }
42 |
43 | public UpstreamProxyServer(@NotNull ProxyAddress address, @Nullable ProxyCredentials credentials, @Nullable UpstreamProxyType type) {
44 | this.address = address;
45 | this.credentials = credentials;
46 | this.type = type != null ? type : UpstreamProxyType.HTTP;
47 | }
48 |
49 | public @NotNull ProxyAddress getAddress() {
50 | return address;
51 | }
52 |
53 | public void setAddress(@NotNull ProxyAddress address) {
54 | this.address = address;
55 | }
56 |
57 | public void setAddress(@NotNull InetSocketAddress inetSocketAddress) {
58 | this.inetSocketAddress = inetSocketAddress;
59 | }
60 |
61 | public @Nullable ProxyCredentials getCredentials() {
62 | return credentials;
63 | }
64 |
65 | public void setCredentials(@Nullable ProxyCredentials credentials) {
66 | this.credentials = credentials;
67 | }
68 |
69 | @NotNull
70 | public UpstreamProxyType getType() {
71 | return type;
72 | }
73 |
74 | public void setType(@NotNull UpstreamProxyType type) {
75 | this.type = type;
76 | }
77 |
78 | public InetSocketAddress resolve() throws UnknownHostException {
79 | return this.isResolved() ? this.inetSocketAddress : this.address.resolve();
80 | }
81 |
82 | public boolean isResolved() {
83 | return this.inetSocketAddress != null;
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/sdk/src/main/java/io/github/krlvm/powertunnel/sdk/types/FullAddress.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.sdk.types;
19 |
20 | import org.jetbrains.annotations.NotNull;
21 | import org.jetbrains.annotations.Nullable;
22 |
23 | import java.net.InetAddress;
24 | import java.net.InetSocketAddress;
25 | import java.net.UnknownHostException;
26 |
27 | public class FullAddress implements Cloneable {
28 |
29 | private final String host;
30 | private final int port;
31 |
32 | public FullAddress(@NotNull String host, int port) {
33 | this.host = host;
34 | this.port = port;
35 | }
36 |
37 | public String getHost() {
38 | return host;
39 | }
40 |
41 | public int getPort() {
42 | return port;
43 | }
44 |
45 | public InetSocketAddress resolve() throws UnknownHostException {
46 | return new InetSocketAddress(InetAddress.getByName(this.host), this.port);
47 | }
48 |
49 | @Override
50 | public String toString() {
51 | return host + ":" + port;
52 | }
53 |
54 | @Nullable
55 | public static FullAddress fromString(String input, int defaultPort) {
56 | if(!input.contains(":")) return new FullAddress(input, defaultPort);
57 |
58 | final String[] arr = input.split(":");
59 | try {
60 | return new FullAddress(arr[0], Integer.parseInt(arr[1]));
61 | } catch (NumberFormatException ex) {
62 | return null;
63 | }
64 | }
65 |
66 | @Nullable
67 | public static FullAddress fromString(String input) {
68 | return fromString(input, -1);
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/sdk/src/main/java/io/github/krlvm/powertunnel/sdk/types/PowerTunnelPlatform.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.sdk.types;
19 |
20 | public enum PowerTunnelPlatform {
21 | DESKTOP, ANDROID
22 | }
23 |
--------------------------------------------------------------------------------
/sdk/src/main/java/io/github/krlvm/powertunnel/sdk/types/UpstreamProxyType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.sdk.types;
19 |
20 | public enum UpstreamProxyType {
21 | HTTP,
22 | SOCKS4,
23 | SOCKS5
24 | }
25 |
--------------------------------------------------------------------------------
/sdk/src/main/java/io/github/krlvm/powertunnel/sdk/types/VersionInfo.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.sdk.types;
19 |
20 | public class VersionInfo {
21 |
22 | private final String versionName;
23 | private final int versionCode;
24 |
25 | public VersionInfo(String versionName, int versionCode) {
26 | this.versionName = versionName;
27 | this.versionCode = versionCode;
28 | }
29 |
30 | public String getVersionName() {
31 | return versionName;
32 | }
33 |
34 | public int getVersionCode() {
35 | return versionCode;
36 | }
37 | }
--------------------------------------------------------------------------------
/sdk/src/main/java/io/github/krlvm/powertunnel/sdk/utiities/Base64Compat.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.sdk.utiities;
19 |
20 | import java.util.Base64;
21 |
22 | public final class Base64Compat {
23 |
24 | public static String encodeToString(byte[] data) {
25 | return provider.encodeToString(data);
26 | }
27 | public static String encodeURLToString(byte[] data) {
28 | return provider.encodeURLToString(data);
29 | }
30 |
31 | private static Base64Provider provider;
32 | private interface Base64Provider {
33 | String encodeToString(byte[] data);
34 | String encodeURLToString(byte[] data);
35 | }
36 | private static final class Java8Base64Provider implements Base64Provider {
37 | @Override
38 | public String encodeToString(byte[] data) {
39 | return Base64.getEncoder().encodeToString(data);
40 | }
41 | @Override
42 | public String encodeURLToString(byte[] data) {
43 | return Base64.getUrlEncoder().withoutPadding().encodeToString(data);
44 | }
45 | }
46 | private static final class AndroidBase64Provider implements Base64Provider {
47 | @Override
48 | public String encodeToString(byte[] data) {
49 | return android.util.Base64.encodeToString(data, 0);
50 | }
51 | @Override
52 | public String encodeURLToString(byte[] data) {
53 | return android.util.Base64.encodeToString(data,
54 | android.util.Base64.URL_SAFE |
55 | android.util.Base64.NO_PADDING |
56 | android.util.Base64.NO_WRAP
57 | );
58 | }
59 | }
60 | private static final class DummyBase64Provider implements Base64Provider {
61 | @Override
62 | public String encodeToString(byte[] data) {
63 | throw new RuntimeException("Not supported on your platform");
64 | }
65 | @Override
66 | public String encodeURLToString(byte[] data) {
67 | throw new RuntimeException("Not supported on your platform");
68 | }
69 | }
70 | static {
71 | try {
72 | Class.forName("java.util.Base64");
73 | provider = new Java8Base64Provider();
74 | } catch (ClassNotFoundException ex) {
75 | try {
76 | Class.forName("android.util.Base64");
77 | provider = new AndroidBase64Provider();
78 | } catch (ReflectiveOperationException aex) {
79 | System.err.println("Base64 is not supported on your platform\nSome functionality can be unavailable");
80 | provider = new DummyBase64Provider();
81 | }
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/sdk/src/main/java/io/github/krlvm/powertunnel/sdk/utiities/TextReader.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | package io.github.krlvm.powertunnel.sdk.utiities;
19 |
20 | import java.io.*;
21 |
22 | public class TextReader {
23 |
24 | public static String read(File file) throws IOException {
25 | return read(new FileReader(file));
26 | }
27 |
28 | public static String read(InputStream in) throws IOException {
29 | return read(new InputStreamReader(in));
30 | }
31 |
32 | public static String read(Reader r) throws IOException {
33 | final StringBuilder builder = new StringBuilder();
34 | try(BufferedReader reader = new BufferedReader(r)) {
35 | String line;
36 | while ((line = reader.readLine()) != null) {
37 | builder.append(line).append('\n');
38 | }
39 | }
40 | if(builder.length() > 2) {
41 | return builder.substring(0, builder.lastIndexOf("\n"));
42 | } else {
43 | return builder.toString();
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of PowerTunnel.
3 | *
4 | * PowerTunnel is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * PowerTunnel is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with PowerTunnel. If not, see .
16 | */
17 |
18 | rootProject.name = 'PowerTunnel'
19 |
20 | include 'sdk'
21 | include 'littleproxy', 'core'
22 | include 'desktop'
23 | include 'sample-plugin'
24 |
--------------------------------------------------------------------------------
/version.txt:
--------------------------------------------------------------------------------
1 | 31;1.14
--------------------------------------------------------------------------------