Skip to content

Commit

Permalink
Merge pull request #35 from segfault-bilibili/master
Browse files Browse the repository at this point in the history
@segfault-bilibili 贡献的一些功能更新
  • Loading branch information
xausky authored Feb 15, 2022
2 parents ec8403f + 78746ba commit e13daa4
Show file tree
Hide file tree
Showing 18 changed files with 1,304 additions and 264 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ jobs:
run: ./gradlew assembleRelease
env:
KEY_PASS: ${{secrets.KEY_PASS}}
- name: Upload artifacts
uses: actions/upload-artifact@v2
with:
name: ShadowsocksGostPlugin.apk
path: app/build/outputs/apk/release/app-release.apk
- name: Release Build
uses: meeDamian/[email protected]
with:
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "gost"]
path = gost
url = https://github.com/segfault-bilibili/gost.git
33 changes: 24 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,45 @@

> [Gost](https://github.com/ginuerzh/gost)[Shadowsocks Android](https://github.com/shadowsocks/shadowsocks-android) 插件,可以直接在Shadowsocks安卓客户端上连接 Gost 服务器
## 🚀 安装
> [Gost](https://github.com/ginuerzh/gost) Plugin for [Shadowsocks Android](https://github.com/shadowsocks/shadowsocks-android), which allows directly connecting to a Gost server from Shadowsocks-Android client
## 🚀 安装 Install

下载 [Release](https://github.com/xausky/ShadowsocksGostPlugin/releases) 内预编译好的APK安装到设备,同时也要安装 [Shadowsocks Android](https://github.com/shadowsocks/shadowsocks-android)

## 🔧 使用
Download prebuilt APK here [Release](https://github.com/xausky/ShadowsocksGostPlugin/releases) and then install it to the device, at same time [Shadowsocks Android](https://github.com/shadowsocks/shadowsocks-android) is required to be installed as well

## 🔧 使用 Usage

* 在 Shadowsocks 客户端选中本插件,即可在参数配置除了 `-L` 参数之外的 Gost 参数以连接远程服务器或者多段代理
* `-L` 参数会自动添加,只需要在 Shadowsocks 界面配置 `rc4-md5` 加密和 `gost` 密码即可
* Gost 的参数配置里面可以用`#SS_HOST``#SS_PORT`代替 Shadowsocks 配置的主机和端口
* `-L` 参数会自动添加,只需要在 Shadowsocks 界面配置 `none` 无加密和空密码即可
* Gost 的命令行参数配置里面可以用`#SS_HOST``#SS_PORT`代替 Shadowsocks 配置的主机和端口

* Pick this plugin in Shadowsocks client, then Gost can be configured (except `-L` parameter) to connect to a remote server, or multi-hop proxies
* `-L` will be automatically added, just configure Shadowsocks to use `none` encryption and empty password
* In Gost's command-line parameters, `#SS_HOST``#SS_PORT` represents host and port configured in Shadowsocks

## ❗ 注意
## ❗ 注意 Notices

* 使用#SS_HOST参数会先对填写的主机名进行DNS解析后才传递
* 如果是与主机名相关的远程协议比如ws协议必须直接在参数里配置域名
* 在参数里面配置的域名会忽略手机系统的DNS配置固定使用 Public DNS+
* 如果插件参数里面使用 `-F=` 形式的参数传递则后续参数不能含有 `=` 号,推荐使用 `-F ` 形式代替
* ~如果插件参数里面使用 `-F=` 形式的参数传递则后续参数不能含有 `=` 号,推荐使用 `-F ` 形式代替~ 使用新版配置格式(CFGBLOB)即可避开这个问题

## ❤ 关注我
* Host specified by #SS_HOST will be firstly resolved with DNS before being passed on
* If the hostname is tied to the protocol, like WebSocket (ws), you must directly use domain name in configuration parameters
* The domain name(s) appeared in configuration parameters is/are hard-coded to be resolved with Public DNS+, in other words, ignoring the OS's DNS configurations
* ~If you configure a parameter in the form of `-F=`, then the subsequent parameters can no longer contain `=`, so it's recommended to use the form of `-F ` instead~ This issue can be avoided simply by using new config format (CFGBLOB)

## ❤ 关注我 Follow me

* Github: [@xausky](https://github.com/xausky)
* BiliBili: [@xausky](https://space.bilibili.com/8419077)

## 🤝 贡献
## 🤝 贡献 Contribution

欢迎各种问题,需求,BUG报告和代码PR!<br />提交到这里就可以 [问题页面](https://github.com/xausky/ShadowsocksGostPlugin/issues).

### ⭐ 如果这个项目帮到你的话欢迎点个星
Any kind of questions, feature requests, bug reports or pull requests are welcomed!<br />Simply submit it here [issues](https://github.com/xausky/ShadowsocksGostPlugin/issues).

### ⭐ 如果这个项目帮到你的话欢迎点个星 If you feel this project can help you, you are welcomed to tick a star
8 changes: 5 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ android {
applicationId "com.github.shadowsocks.plugin.gost"
minSdkVersion 21
targetSdkVersion 29
versionCode 2110
versionName "2.11.0-1"
versionCode 2111
versionName "2.11.1"
}
signingConfigs {
releaseConfig {
Expand All @@ -28,6 +28,8 @@ android {

dependencies {
implementation 'com.github.shadowsocks:plugin:1.2.0'
implementation 'androidx.appcompat:appcompat:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
}

task buildGoLibrary(type: Exec) {
Expand All @@ -41,4 +43,4 @@ tasks.whenTaskAdded { theTask ->
if (theTask.name.equals("preDebugBuild") || theTask.name.equals("preReleaseBuild")) {
theTask.dependsOn "buildGoLibrary"
}
}
}
72 changes: 44 additions & 28 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,28 +1,44 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.github.shadowsocks.plugin.gost">

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true">
<provider android:name=".BinaryProvider"
android:exported="true"
android:authorities="com.github.shadowsocks.plugin.gost.BinaryProvider">
<intent-filter>
<action android:name="com.github.shadowsocks.plugin.ACTION_NATIVE_PLUGIN"/>
</intent-filter>
<intent-filter>
<action android:name="com.github.shadowsocks.plugin.ACTION_NATIVE_PLUGIN"/>
<data android:scheme="plugin"
android:host="com.github.shadowsocks"
android:pathPrefix="/gost"/>
</intent-filter>
<meta-data android:name="com.github.shadowsocks.plugin.id"
android:value="gost"/>
<meta-data android:name="com.github.shadowsocks.plugin.default_config"
android:value="-F ss+mws://chacha20:ss123456@#SS_HOST:#SS_PORT"/>
</provider>
</application>
</manifest>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.github.shadowsocks.plugin.gost">

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true">
<activity
android:name=".ConfigActivity">
<intent-filter>
<action android:name="com.github.shadowsocks.plugin.ACTION_CONFIGURE"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="plugin"
android:host="com.github.shadowsocks"
android:path="/gost"/>
</intent-filter>
</activity>

<provider
android:name=".BinaryProvider"
android:authorities="com.github.shadowsocks.plugin.gost.BinaryProvider"
android:exported="true">
<intent-filter>
<action android:name="com.github.shadowsocks.plugin.ACTION_NATIVE_PLUGIN" />
</intent-filter>
<intent-filter>
<action android:name="com.github.shadowsocks.plugin.ACTION_NATIVE_PLUGIN" />

<data
android:host="com.github.shadowsocks"
android:path="/gost"
android:scheme="plugin" />
</intent-filter>

<meta-data
android:name="com.github.shadowsocks.plugin.id"
android:value="gost" />
</provider>
</application>

</manifest>
106 changes: 106 additions & 0 deletions app/src/main/java/com/github/shadowsocks/plugin/gost/Base64.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package com.github.shadowsocks.plugin.gost;

public class Base64 {
private char paddingChar = '=';

public void setPaddingChar(char c) throws Base64Exception {
if (
(c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
(c >= '0' && c <= '9') ||
c == '+' || c == '/'
) throw new Base64Exception("INVALID_PADDING_CHAR");
this.paddingChar = c;
}

public static class Base64Exception extends Exception {
String msg;
@Override
public String getMessage() {
return this.msg;
}
Base64Exception(String msg) {
this.msg = msg;
}
}

public byte[] decode(String encoded) throws Base64Exception {
char[] input = new char[encoded.length()];
encoded.getChars(0, encoded.length(), input, 0);
return this.decode(input);
}
public byte[] decode(char[] input) throws Base64Exception {
if (input.length % 4 != 0)
throw new Base64Exception("BASE64_DECODE_INVALID_LENGTH");
if (input.length == 0) return new byte[0];
int endPos = 0;
for (int i = input.length - 1; i >= input.length - 4; i--) {
char c = input[i];
if (
(c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
(c >= '0' && c <= '9') ||
c == '+' || c == '/'
) {
endPos = i + 1;
break;
} else if (c != this.paddingChar) {
throw new Base64Exception("BASE64_DECODE_INVALID_CHAR");
} else if (i == input.length - 4) {
throw new Base64Exception("BASE64_DECODE_INVALID_PADDING");
}
}
int resultLen = (endPos * 6 + 8 - 1) / 8;
byte[] result = new byte[resultLen];
for (int i = 0, o = 0, buf = 0; i < endPos; i++) {
char c = input[i];
if (c >= 'A' && c <= 'Z') {
c -= 'A';
} else if (c >= 'a' && c <= 'z') {
c += 26 - 'a';
} else if (c >= '0' && c <= '9') {
c += 26 + 26 - '0';
} else if (c == '+') {
c = 26 + 26 + 10;
} else if (c == '/') {
c = 26 + 26 + 10 + 1;
} else throw new Base64Exception("BASE64_DECODE_INVALID_CHAR");
buf |= (((int) c) & 0xFF) << (3 - (i % 4)) * 6;
if ((i + 1) % 4 == 0 || i == endPos - 1) {
for (int j = 0; j < 3 && o < resultLen; j++, o++) {
result[o] = (byte) ((buf >> (2 - j) * 8) & 0xFF);
}
buf = 0;
}
}
return result;
}
public String encode(byte[] bin) {
int resultLen = (bin.length * 8 + 6 - 1) / 6;
int outputLen = (resultLen + 4 - 1) / 4;
outputLen *= 4;
char[] output = new char[outputLen];
for (int i = 0, o = 0, buf = 0; i < bin.length; i++) {
buf |= (((int) bin[i]) & 0xFF) << (2 - (i % 3)) * 8;
if ((i + 1) % 3 == 0 || i == bin.length - 1) {
for (int j = 0; j < 4 && o < resultLen; j++, o++) {
int c = (buf >> (3 - j) * 6) & 0x3F;
if (c < 26) {
output[o] = (char) ('A' + c);
} else if (c < 26 + 26) {
output[o] = (char) ('a' + c - 26);
} else if (c < 26 + 26 + 10) {
output[o] = (char) ('0' + c - (26 + 26));
} else if (c == 26 + 26 + 10) {
output[o] = '+';
} else { // always (c == 26 + 26 + 10 + 1)
output[o] = '/';
}
}
buf = 0;
}
}
for (int i = resultLen; i < outputLen; i++) {
output[i] = this.paddingChar;
}
return new String(output);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.github.shadowsocks.plugin.gost;

import android.content.pm.Signature;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import com.github.shadowsocks.plugin.NativePluginProvider;
Expand Down
Loading

0 comments on commit e13daa4

Please sign in to comment.