From 0ae08fd92c982952042ed636045465b69dcd609c Mon Sep 17 00:00:00 2001 From: free will <2647778488@qq.com> Date: Thu, 5 Aug 2021 10:30:53 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0VMS=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E5=99=A8=E4=BF=A1=E6=81=AF=E7=9A=84=E7=BD=91?= =?UTF-8?q?=E7=BB=9C=E8=AF=B7=E6=B1=82=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + .../pkusz/min_vpn_client/GlobalSetting.java | 2 +- .../OriginalGetVpnInfoRequest.java | 16 +++++ .../model/Response/VpnServerInfo.java | 60 ++++++++++++++++++ .../model/Response/VpnServerInfoList.java | 50 +++++++++++++++ .../min_vpn_client/model/VMSRequestAPI.java | 62 +++++++++++++++++++ .../services/MINVpnConnection.java | 2 +- 7 files changed, 191 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/com/pkusz/min_vpn_client/model/OriginalRequest/OriginalGetVpnInfoRequest.java create mode 100644 app/src/main/java/com/pkusz/min_vpn_client/model/Response/VpnServerInfo.java create mode 100644 app/src/main/java/com/pkusz/min_vpn_client/model/Response/VpnServerInfoList.java diff --git a/README.md b/README.md index ef88824..5188e36 100644 --- a/README.md +++ b/README.md @@ -42,4 +42,5 @@ ## 用户名及密码说明V2 经过简化,用户输入的username将直接作为注册、登录及连接VPN时发送给后台的username而存在, 证书则是"/"+username,完全去除Base64编解码化。 + 密码:代码运行时候的密码passwd是用户输入的原始密码RawPasswd经过md5哈希之后得到。 diff --git a/app/src/main/java/com/pkusz/min_vpn_client/GlobalSetting.java b/app/src/main/java/com/pkusz/min_vpn_client/GlobalSetting.java index 0a29b7f..49ef740 100644 --- a/app/src/main/java/com/pkusz/min_vpn_client/GlobalSetting.java +++ b/app/src/main/java/com/pkusz/min_vpn_client/GlobalSetting.java @@ -6,5 +6,5 @@ public class GlobalSetting { // public static boolean openBiometric = false; // 控制与VPNServer的对称加密通信方法,true表示使用sm4,false表示使用AES - public static boolean isSM4 =false; + public static boolean isSM4 =false; } diff --git a/app/src/main/java/com/pkusz/min_vpn_client/model/OriginalRequest/OriginalGetVpnInfoRequest.java b/app/src/main/java/com/pkusz/min_vpn_client/model/OriginalRequest/OriginalGetVpnInfoRequest.java new file mode 100644 index 0000000..2d9d453 --- /dev/null +++ b/app/src/main/java/com/pkusz/min_vpn_client/model/OriginalRequest/OriginalGetVpnInfoRequest.java @@ -0,0 +1,16 @@ +package com.pkusz.min_vpn_client.model.OriginalRequest; +/* + * @Author: Wang Feng + * @Description: 获取VPN服务器信息的请求的原始属性 + * @Version: 1.0.0 + * @Date: 17:22 2021/6/23 + * @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室 + */ + +public class OriginalGetVpnInfoRequest { + public String username; + + public OriginalGetVpnInfoRequest(String username){ + this.username=username; + } +} diff --git a/app/src/main/java/com/pkusz/min_vpn_client/model/Response/VpnServerInfo.java b/app/src/main/java/com/pkusz/min_vpn_client/model/Response/VpnServerInfo.java new file mode 100644 index 0000000..3d47a11 --- /dev/null +++ b/app/src/main/java/com/pkusz/min_vpn_client/model/Response/VpnServerInfo.java @@ -0,0 +1,60 @@ +package com.pkusz.min_vpn_client.model.Response; + +import VMSConnection.TCPNet.Message.BaseStruct; + +import java.util.ArrayList; + +/* + * @Author: Wang Feng + * @Description: + * @Version: 1.0.0 + * @Date: 17:26 2021/8/4 + * @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室 + */ +public class VpnServerInfo extends BaseStruct { + public int ID; + public String Name; + public String ClientPrefix; + public boolean IsInner; + public int Mtu; + public String IP; + public int Port; + public String RemotePrefix; + public String InnerIP; + public int UGroupID; + public String TimeStamp; + + /** + * 解析并获取InnerIP列表 + * 例子:"10.0.0.0/24, 172.16.0.0/12, 192.168.0.0/16" + * @return + */ + public ArrayList getInnerIPList(){ + ArrayList res=new ArrayList<>(); + if(InnerIP.equals("")){ + return res; + } + for (String ipAndMask: + InnerIP.split(", ")) { + res.add(ipAndMask); + } + return res; + } + + @Override + public String toString() { + return "VpnServerInfo{" + + "ID=" + ID + + ", Name='" + Name + '\'' + + ", ClientPrefix='" + ClientPrefix + '\'' + + ", IsInner=" + IsInner + + ", Mtu=" + Mtu + + ", IP='" + IP + '\'' + + ", Port=" + Port + + ", RemotePrefix='" + RemotePrefix + '\'' + + ", InnerIP='" + InnerIP + '\'' + + ", UGroupID=" + UGroupID + + ", TimeStamp='" + TimeStamp + '\'' + + '}'; + } +} diff --git a/app/src/main/java/com/pkusz/min_vpn_client/model/Response/VpnServerInfoList.java b/app/src/main/java/com/pkusz/min_vpn_client/model/Response/VpnServerInfoList.java new file mode 100644 index 0000000..4ee5f63 --- /dev/null +++ b/app/src/main/java/com/pkusz/min_vpn_client/model/Response/VpnServerInfoList.java @@ -0,0 +1,50 @@ +package com.pkusz.min_vpn_client.model.Response; + +import com.alibaba.fastjson.JSONArray; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; + +/* + * @Author: Wang Feng + * @Description: + * @Version: 1.0.0 + * @Date: 17:28 2021/8/4 + * @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室 + */ +public class VpnServerInfoList { + private ArrayList vpnServerInfoList=new ArrayList<>(); + + /** + * 将json数组解析为VPNInfoList + * @param data + * @return + */ + public boolean parseToVpnInfoList(byte[] data){ + try { + vpnServerInfoList.clear(); + JSONArray jsonArray = JSONArray.parseArray(new String(data)); + for (int i = 0; i < jsonArray.size(); i++) { + VpnServerInfo vpnserverinfo = new VpnServerInfo(); + vpnserverinfo.unJson(jsonArray.get(i).toString().getBytes(StandardCharsets.UTF_8), + vpnserverinfo); + vpnServerInfoList.add(vpnserverinfo); + } + return true; + }catch (Exception e){ + e.printStackTrace(); + return false; + } + } + + public ArrayList getVpnServerInfoList(){ + return this.vpnServerInfoList; + } + + @Override + public String toString() { + return "VpnServerInfoList{" + + "vpnServerInfoList=" + vpnServerInfoList + + '}'; + } +} diff --git a/app/src/main/java/com/pkusz/min_vpn_client/model/VMSRequestAPI.java b/app/src/main/java/com/pkusz/min_vpn_client/model/VMSRequestAPI.java index 2160763..df46af9 100644 --- a/app/src/main/java/com/pkusz/min_vpn_client/model/VMSRequestAPI.java +++ b/app/src/main/java/com/pkusz/min_vpn_client/model/VMSRequestAPI.java @@ -8,8 +8,10 @@ package com.pkusz.min_vpn_client.model; * @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室 */ +import com.pkusz.min_vpn_client.model.OriginalRequest.OriginalGetVpnInfoRequest; import com.pkusz.min_vpn_client.model.OriginalRequest.OriginalLoginRequest; import com.pkusz.min_vpn_client.model.OriginalRequest.OriginalRegisterRequest; +import com.pkusz.min_vpn_client.model.Response.VpnServerInfoList; import com.pkusz.min_vpn_client.utils.KeyManager; import org.bouncycastle.crypto.CryptoException; @@ -28,6 +30,7 @@ import javax.crypto.NoSuchPaddingException; import VMSConnection.BC_API; import VMSConnection.Model.LoginWithSignRequest; import VMSConnection.Model.RegisterWithSignRequest; +import VMSConnection.Model.VpnServerInfoRequest; import VMSConnection.TCPNet.Message.NetworkResponse; import VMSConnection.Utils.Base64Helper; import minsecurity.certificate.cert.CertException; @@ -162,6 +165,65 @@ public enum VMSRequestAPI { return networkResponse.get().Code; } + /** + * 构造并发送VMS获取VPN服务器信息的请求,返回解析后的服务器信息(列表) + * @param original + * @return + */ + public VpnServerInfoList getVPNServerInfoList(OriginalGetVpnInfoRequest original){ + // 1. 生成用户的公钥私钥(有则直接取出) + this.generateForeverIdentity(original.username); + + // 2. 构造vpnserver信息请求包 + VpnServerInfoRequest vpnServerInfoRequest=new VpnServerInfoRequest(1, original.username); + try { + System.out.println("getVpnInfo request: "+vpnServerInfoRequest.toJson()); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + + // 4. 调用bc-api,发送获取信息请求到VMS:ip tcpPort sslPort VMSPubkey(可选,有默认key) + AtomicReference networkResponse = new AtomicReference<>(); + Thread netRequestThread = new Thread(() -> { + BC_API bc_api = new BC_API(MINVpnSettingAPI.INSTANCE.getBlockChainIpAddress(), + MINVpnSettingAPI.INSTANCE.getBcTcpPort(), MINVpnSettingAPI.INSTANCE.getBcSslPort()); + networkResponse.set(bc_api.getVpnServerInfo(vpnServerInfoRequest)); + }); + netRequestThread.start(); + // 等待五秒,五秒内收不到包就放弃,收到包就停止等待 + long startTime=System.currentTimeMillis(); + while ((System.currentTimeMillis()-startTime)/1000<5){ + if(networkResponse.get()!=null){ + break; + } + try { + Thread.sleep(500); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + if(networkResponse.get()==null){ + System.out.println("获取VPN信息未收到合法应答信息"); + return null; + } + // 输出getVpnServerInfo应答信息 + try { + System.out.println("获取vpn信息的应答: "+networkResponse.get().toJson()); + System.out.println("获取到的vpn信息: "+new String(networkResponse.get().Data)); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + + // 4. 解析应答信息,并返回 + VpnServerInfoList list=new VpnServerInfoList(); + boolean flag=list.parseToVpnInfoList(networkResponse.get().Data); + if(flag){ + return list; + }else{ + return null; + } + } + /** * 生成本地密钥,持久化存储到本地硬盘 * @param username diff --git a/app/src/main/java/com/pkusz/min_vpn_client/services/MINVpnConnection.java b/app/src/main/java/com/pkusz/min_vpn_client/services/MINVpnConnection.java index 533048c..ce102b4 100644 --- a/app/src/main/java/com/pkusz/min_vpn_client/services/MINVpnConnection.java +++ b/app/src/main/java/com/pkusz/min_vpn_client/services/MINVpnConnection.java @@ -69,7 +69,7 @@ public class MINVpnConnection implements Runnable{ private final VpnService mService; private final int mConnectionId; // face的注册前缀 格式为:/{边界路由器的服务前缀}/{用户名}/{当前系统时间}, - // 如:"/min/gdcni19/Base64Util.Base64PlusEncode(wefree)/"+System.currentTimeMillis(); + // 如:"/min/gdcni19/wefree/"+System.currentTimeMillis(); // 在执行initFace的时候初始化 private String localFacePrefix;