更新记录
1.0.2(2022-12-01)
新版首发
平台兼容性
Android | Android CPU类型 | iOS |
---|---|---|
适用版本区间:5.0 - 12.0 | armeabi-v7a:支持,arm64-v8a:未测试,x86:未测试 | 适用版本区间:11 - 16 |
原生插件通用使用流程:
- 购买插件,选择该插件绑定的项目。
- 在HBuilderX里找到项目,在manifest的app原生插件配置中勾选模块,如需要填写参数则参考插件作者的文档添加。
- 根据插件作者的提供的文档开发代码,在代码中引用插件,调用插件功能。
- 打包自定义基座,选择插件,得到自定义基座,然后运行时选择自定义基座,进行log输出测试。
- 开发完毕后正式云打包
付费原生插件目前不支持离线打包。
Android 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/android
iOS 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/ios
注意事项:使用HBuilderX2.7.14以下版本,如果同一插件且同一appid下购买并绑定了多个包名,提交云打包界面提示包名绑定不一致时,需要在HBuilderX项目中manifest.json->“App原生插件配置”->”云端插件“列表中删除该插件重新选择
KJ-SangforSDK
深信服双域VPN最新完整版(ios、andorid)
使用
<template>
<view class="content">
<view class="title">----初始化----</view>
<view class="btns">
<button type="primary" @click="initSDK">初始化SDK</button>
<button type="primary" @click="setSDKOption">设置高级配置选项(ios)</button>
<button type="primary" @click="getSDKOption">获取高级配置选项(ios)</button>
<button type="primary" @click="getInternalConf">获取内部配置(ios)</button>
<button type="primary" @click="clearAllData">清除所有数据(ios)</button>
</view>
<view class="title">----选路----</view>
<view class="btns">
<button type="primary" @click="startSelectLine">进行选路(ios)</button>
</view>
<view class="title">----认证----</view>
<view class="btns">
<button type="primary" @click="onAuth">认证回调监听</button>
<button type="primary" @click="startPasswordAuth">用户名密码主认证方式</button>
<button type="primary" @click="startCertAuth">证书主认证方式</button>
<button type="primary" @click="startDingTalkAuth">钉钉/微信认证方式</button>
<button type="primary" @click="startPrimaryAuth">通用定制认证方式</button>
<button type="primary" @click="doSecondaryAuth">辅助认证方式</button>
<button type="primary" @click="supportTicketAuth">是否支持免密认证</button>
<button type="primary" @click="startTicketAuth">免密主认证方式</button>
<button type="primary" @click="cancelAuth">取消验证</button>
</view>
<view class="title">----密码----</view>
<view class="btns">
<button type="primary" @click="resetPassword">修改VPN账号密码</button>
</view>
<view class="title">----重新获取验证码----</view>
<view class="btns">
<button type="primary" @click="regetSmsCode">重新获取短信验证码</button>
<button type="primary" @click="regetRandCode">重新获取图形校验码</button>
<image :src="filePath" mode="aspectFit" style="width: 200px; height: 50px;"></image>
</view>
<view class="title">----注销----</view>
<view class="btns">
<button type="primary" @click="onLogout">监听注销回调</button>
<button type="primary" @click="logout">注销VPN</button>
<button type="primary" @click="clearLogoutCallBack">清空VPN注销回调</button>
</view>
<view class="title">----状态----</view>
<view class="btns">
<button type="primary" @click="getAuthStatus">获取认证状态信息</button>
</view>
<view class="title">----沙箱----</view>
<view class="btns">
<button type="primary" @click="setWhiteAppList">设置白名单</button>
<button type="primary" @click="getWhiteAppList">获取白名单</button>
<button type="primary" @click="getWhiteSignatureList">获取白签名(andorid)</button>
<button type="primary" @click="updatePolicy">外部更新全局安全策略</button>
<button type="primary" @click="setNetworkWhitelist">设置自定义网络隔离白名单</button>
</view>
<view class="title">----工具方法----</view>
<view class="btns">
<button type="primary" @click="isDeviceRooted">设备是否已经越狱</button>
<button type="primary" @click="clearApplicationData">清除应用所有私有数据</button>
<button type="primary" @click="isDevicePasswordOn">设备是否开启密码(ios)</button>
<button type="primary" @click="isRunOnEmulator">是否在模拟器上运行(andorid)</button>
<button type="primary" @click="isKeyguardSecure">是否是密钥保护安全(andorid)</button>
<button type="primary" @click="isNeedMigrateData">是否需要迁移数据(andorid)</button>
</view>
</view>
</template>
<script>
const KJSangforSDK = uni.requireNativePlugin('KJ-SangforSDK');
export default {
data() {
return {
url: "https://ip:端口", //VPN地址
userName: "test", //用户名
password: "123456", //密码
filePath: null
}
},
onLoad() {
this.initSDK();
this.onAuth();
},
methods: {
initSDK() {
/**
* sdkMode - SDK模式 Vpn(SDK启用VPN功能) Sandbox(SDK启用安全沙箱功能) VpnSandbox(SDK启动VPN和安全沙箱功能)
* sdkFlags - SDK配置选项 None(初始化值) VpnModeTcp(TCP模式) VpnModeL3VPN(L3VPN模式)
* HostApplication(主应用) SubApplication(子应用模式) EnableFileIsolation(启用文件隔离)
* SupportManagePolicy(SDK支持外部(第三方)更新策略)
* external - 额外配置,补充属性 iOS当前不生效
* 相关key kExtraFileIsolation kExtraAworkCurrentVersion kInjectAppId kExtraEnableAppStoreKey
* */
var dic = {
sdkMode: "VpnSandbox",
sdkFlags: ["HostApplication", "SupportManagePolicy"],
external: null, //格式字典
}
console.log(JSON.stringify(dic));
KJSangforSDK.initSDK(dic, (res) => {
console.log("initSDK:" + JSON.stringify(res));
})
},
setSDKOption() {
/**
* key - SDK Option选项
* TimeOut(设置认证连接超时时间) Language(设置语言环境) LogReport(设置日志提交选项)
* CapturePackage(设置开启抓包) AworkDisplayName(awork的名称)
* */
var dic = {
key: "TimeOut",
value: "30" //若没有设置则使用默认超时时间30秒
}
KJSangforSDK.setSDKOption(dic, (res) => {
console.log("setSDKOption:" + JSON.stringify(res));
})
},
getSDKOption() {
var dic = {
key: "TimeOut"
}
KJSangforSDK.getSDKOption(dic, (res) => {
console.log("getSDKOption:" + JSON.stringify(res));
})
},
getInternalConf() {
var dic = {
key: ""
}
KJSangforSDK.getInternalConf(dic, (res) => {
console.log("getInternalConf:" + JSON.stringify(res));
})
},
clearAllData() {
KJSangforSDK.clearAllData()
},
startSelectLine() {
var dic = {
url: this.url
}
KJSangforSDK.startSelectLine(dic, (res) => {
console.log("startSelectLine:" + JSON.stringify(res));
})
},
onAuth() {
KJSangforSDK.onAuth((res) => {
console.log("onAuth:" + JSON.stringify(res));
/**
* 返回json说明:{"baseMessage":{"errCode":1000,"serverInfo":"","errStr":null},"method":"onAuthSuccess"}
* errCode - 错误码 更多参考插件首页
* serverInfo - 服务端透传字符串
* errStr - 错误提示字符串
* */
if (res.method == "onAuthSuccess") {
console.log("认证成功");
} else if (res.method == "onAuthProcess") {
console.log("认证过程");
} else if (res.method == "onAuthFailed") {
console.log("认证失败");
}
})
},
startPasswordAuth() {
var dic = {
url: this.url,
userName: this.userName,
password: this.password
}
KJSangforSDK.startPasswordAuth(dic, (res) => {
console.log("startPasswordAuth:" + JSON.stringify(res));
})
},
startCertAuth() {
var dic = {
url: this.url,
certPath: plus.io.convertLocalFileSystemURL("static/cert.p12"),
password: "123456"
}
KJSangforSDK.startCertAuth(dic, (res) => {
console.log("startCertAuth:" + JSON.stringify(res));
})
},
startDingTalkAuth() {
var dic = {
url: this.url,
code: "",
}
KJSangforSDK.startDingTalkAuth(dic, (res) => {
console.log("startDingTalkAuth:" + JSON.stringify(res));
})
},
startPrimaryAuth() {
var dic = {
url: this.url,
path: "", //认证路径
data: "{}" //json字符串
}
KJSangforSDK.startPrimaryAuth(dic, (res) => {
console.log("startPrimaryAuth:" + JSON.stringify(res));
})
},
doSecondaryAuth() {
/**
* authType - 定义支持的认证类型 0(证书认证) 1(用户名密码认证) 2(短信认证) 4(硬件特征码认证, 内部认证)
* 6(挑战认证或者Radius认证) 7(令牌认证) 10(授权认证,内部认证) 11(钉钉code认证)
* 16(Session认证) 17(无认证) 18(强制修改密码认证) 20(强制修改密码认证,处理之前没有输入密码的情况。 不支持)
* 22(图形校验码认证) 2048(Ticket认证) -1(未知认证类型)
* data - 辅助认证数据对象
* 相关可以为:svpn_name(用户名密码认证用户名信息) svpn_password(用户名密码认证密码信息)
* svpn_cert_path(证书认证路径信息) svpn_cert_password(证书认证密码信息)
* svpn_rand_code(图形校验认证码)
* svpn_inputsms(短信验证码)
* svpn_inputtoken(动态令牌认证码)
* svpn_inputradius(Radius认证码)
* pripsw(更新密码认证旧密码) newpsw(更新密码认证新密码)
* kAuthKeyUserContentData(用户透传数据)
* */
var dic = {
authType: 2, // 短信认证
data: {
"svpn_inputsms": "123" //短信认证的辅助认证数据对象
}
}
KJSangforSDK.doSecondaryAuth(dic, (res) => {
console.log("doSecondaryAuth:" + JSON.stringify(res));
})
},
supportTicketAuth() {
KJSangforSDK.supportTicketAuth((res) => {
console.log("supportTicketAuth:" + JSON.stringify(res));
})
},
startTicketAuth() {
KJSangforSDK.startTicketAuth()
},
cancelAuth() {
KJSangforSDK.cancelAuth()
},
onLogout() {
KJSangforSDK.onLogout((res) => {
/**
* 返回json说明:{"serverInfo":null,"logoutType":0,"errStr":"","errCode":0}
* logoutType - 注销原因类型 0(用户注销) 1(免密失败) 2(服务端shutdown) 3(授权失败)
* errCode - 错误码 更多参考插件首页
* serverInfo - 服务端透传字符串
* errStr - 错误提示字符串
* */
console.log("onLogout:" + JSON.stringify(res));
})
},
logout() {
this.onLogout();
setTimeout(() => {
KJSangforSDK.logout()
}, 1000); //ios需要延迟调用,要不然会闪退
},
clearLogoutCallBack() {
KJSangforSDK.clearLogoutCallBack()
},
getAuthStatus() {
KJSangforSDK.getAuthStatus((res) => {
console.log("getAuthStatus:" + JSON.stringify(res));
/**
* 返回字段说明:{"result":5}
* result - 认证状态 0(未认证) 1(正在认证) 2(主认证成功) 3(认证成功) 4(正在注销) 5(已经注销)
* */
})
},
setWhiteAppList() {
var dic = {
whiteApps: ["xxxx"], //ios为bundleId andorid为包名
whiteSignatures: ["xxxx"] //andorid有效
}
KJSangforSDK.setWhiteAppList()
},
getWhiteAppList() {
KJSangforSDK.getWhiteAppList((res) => {
console.log("getWhiteAppList:" + JSON.stringify(res));
})
},
getWhiteSignatureList() {
KJSangforSDK.getWhiteSignatureList((res) => {
console.log("getWhiteSignatureList:" + JSON.stringify(res));
})
},
updatePolicy() {
var dic = {
jsonPolicy: "{}"
}
KJSangforSDK.updatePolicy(dic, (res) => {
/**
* 返回json说明:{"result":1}
* result - 定义更新策略返回值类型
* 0(更新成功) 1(策略格式错误) 2(未通过认证) 3(内部错误)
* */
console.log("updatePolicy:" + JSON.stringify(res));
})
},
setNetworkWhitelist() {
var dic = {
jsonRules: "{}"
}
KJSangforSDK.setNetworkWhitelist(dic, (res) => {
console.log("getWhiteApplist:" + JSON.stringify(res));
})
},
resetPassword() {
var dic = {
oldPwd: "",
newPwd: ""
}
KJSangforSDK.resetPassword(dic, (res) => {
console.log("resetPassword:" + JSON.stringify(res));
/**
* 返回json说明:ios:{"result":false,"errStr":"未能完成操作。(密码输入错误,请重新输入错误3004。)"}
* adnorid:{"baseMessage":{"errStr":"密码输入错误,请重新输入","errCode":3004,"serverInfo":""},"result":false}
* 注意:由于sdk原因,ios和andorid,返回的东西不一样
* errCode - 错误码 更多参考插件首页
* serverInfo - 服务端透传字符串
* errStr - 错误提示字符串
* */
})
},
regetSmsCode() {
KJSangforSDK.regetSmsCode((res) => {
console.log("regetSmsCode:" + JSON.stringify(res));
/**
* 返回json说明:ios:{"result":false,"error":"未能完成操作。(错误1401。)",
* "smsMessage":{"errStr":null,"countDown":0,"errCode":0,"smsApps":null,"phoneNum":null,"stillValid":false,"serverInfo":null}
* adnorid:{"smsMessage":{"phoneNum":"","smsApps":"","errStr":"","errCode":1401,"stillValid":false,"countDown":0,"serverInfo":""},"result":false}
* 注意:由于sdk原因,ios和andorid,返回的东西不一样
* phoneNum - 短信认证的手机号码
* countDown - 重新发送短信倒计时时间
* stillValid - 上次发送的短信验证码是否在有效期
* smsApps - 网关类型,用于判断短信验证码是否发往moa
* errCode - 错误码 更多参考插件首页
* serverInfo - 服务端透传字符串
* errStr - 错误提示字符串
* */
})
},
regetRandCode() {
var dic = {
savePath: plus.io.convertLocalFileSystemURL("_doc/KJ-SangforSDK"),
format: "jpeg", //保存的图片格式 有效值:png、jpeg 注意:andorid只能使用jpeg
quality: 100, //保存的图片质量,取值1-100, ios png 无效
}
KJSangforSDK.regetRandCode(dic, (res) => {
console.log("regetRandCode:" + JSON.stringify(res));
this.filePath = res.filePath;
})
},
isDeviceRooted() {
KJSangforSDK.isDeviceRooted((res) => {
console.log("isDeviceRooted:" + JSON.stringify(res));
})
},
clearApplicationData() {
KJSangforSDK.clearApplicationData()
},
isDevicePasswordOn() {
KJSangforSDK.isDevicePasswordOn((res) => {
console.log("isDevicePasswordOn:" + JSON.stringify(res));
})
},
isRunOnEmulator() {
KJSangforSDK.isRunOnEmulator((res) => {
console.log("isRunOnEmulator:" + JSON.stringify(res));
})
},
isKeyguardSecure() {
KJSangforSDK.isKeyguardSecure((res) => {
console.log("isKeyguardSecure:" + JSON.stringify(res));
})
},
isNeedMigrateData() {
KJSangforSDK.isNeedMigrateData((res) => {
console.log("isNeedMigrateData:" + JSON.stringify(res));
})
}
}
}
</script>
<style>
.title {
text-align: center;
margin-top: 4px;
margin-bottom: 4px;
color: red;
}
button {
font-size: 12px;
margin-top: 4px;
}
.btns {
display: flex;
flex-wrap: wrap;
flex-direction: row;
align-items: center;
justify-content: start;
}
</style>
错误码
/// 错误码
typedef NS_ENUM(NSInteger, SF_ERROR_CODE)
{
/** 成功的标记 */
SF_ERROR_CODE_NONE = 1000, //成功
/** 认证服务端返回的错误 */
SF_ERROR_SERVER_BUSY = 1001, //操作失败,可能服务器太忙
SF_ERROR_TIME_DENY = 1002, //非允许时间段,禁止登录
SF_ERROR_AUTH_TYPE_DISABLE = 1003, //未启用此认证,访问被拒绝
SF_ERROR_NOT_SAME_USER = 1004, //登录失败,前一认证与当前认证非同一用户
SF_ERROR_AUTH_COMBINATION_INVALID = 1005, //不支持此种认证组合方式
SF_ERROR_LICENSED_USER_LIMIT = 1006, //系统已到达最大授权用户限制
SF_ERROR_GROUP_USER_LIMIT = 1007, //您所在用户组已达到最大在线用户限制
SF_ERROR_ACCOUNT_LOCKED = 1008, //用户尝试暴破登录,已被系统锁定
SF_ERROR_IP_LOCKED = 1009, //ip地址尝试暴破登录,已被系统锁定
SF_ERROR_IP_NEED_WORD_VERIFICATION = 1010, //ip地址尝试暴破登录,启用图形校验码
SF_ERROR_SESSION_TIMEOUT = 1011, //session timeout
/**用户名认证*/
SF_ERROR_PASSWOR_INVALID = 1101, //用户名或者密码错误
SF_ERROR_USER_EXPIRE = 1102, //用户已过期
SF_ERROR_USER_DISABLE = 1103, //用户被禁用
SF_ERROR_USER_TIMEOUT = 1104, //用户已超时或注销
SF_ERROR_CHARACTERS_INCORRECT = 1105, //校验码错误或校验码已过期
SF_ERROR_USER_NEED_WORD_VERIFICATION = 1106, //用户名或密码错误,启用图形校验码
SF_ERROR_LDAP_SERVER_FAILED = 1107, //LDAP连接服务器失败
/**证书认证*/
SF_ERROR_CERTIFICATE_INVALID = 1201, //证书不合法
SF_ERROR_CERTIFICATE_AUTH_DISABLE = 1202, //证书认证被禁用
SF_ERROR_CERTIFICATE_REVOKED = 1203, //证书已经被撤消
SF_ERROR_CERTIFICATE_CODE_ERR = 1204, //证书编码设置有误,请联系管理员
SF_ERROR_CERTIFICATE_SIGN_INVALID = 1205, //证书签名无效
SF_ERROR_CERTIFICATE_NOT_EFFECT = 1206, //证书还未生效
SF_ERROR_CERTIFICATE_EXPIRE = 1207, //证书已经过期
SF_ERROR_CERTIFICATE_NO_PERMISSION = 1208, //证书读取失败,请检查证书文件权限
/**免密认证*/
SF_ERROR_TICKET_MOBID_INVALID = 1301, //免密认证无效的手机ID
SF_ERROR_TICKET_CODEID_INVALID = 1302, //免密认证无效的code
SF_ERROR_TICKET_PASS_CLOSE = 1303, //免密认证功能未开启
SF_ERROR_TICKET_UNKOWN = 1304, //未知错误
/**短信校验码认证*/
SF_ERROR_SEND_SMS_MESSAGE = 1401, //发送短信失败
SF_ERROR_SMS_PASSWORD_INVALID = 1402, //短信验证码错误
SF_ERROR_NOT_SET_PHONE_NUMBER = 1403, //用户未设置手机号码,无法进行短信认证
SF_ERROR_PHONE_NUMBER_INCORRECT = 1404, //提交的手机号码错误,无法进行短信认证
SF_ERROR_SMS_PASSWORD_EXPIRE = 1405, //短信验证码已过期
/**EMM授权认证*/
SF_ERROR_EMM_NOT_AUTHORZATION = 1501, //EMM授权不通过,请联系管理员更新授权
SF_ERROR_EMM_DEVICE_LIMIT = 1502, //EMM授权达到最大数
SF_ERROR_EMM_DEVICE_FROZEN = 1503, //EMM授权被冻结
SF_ERROR_EMM_FAILED = 1504, //EMM授权认证失败
SF_ERROR_EMM_NETWORK_ERROR = 1505, //EMM授权网络链接错误
SF_ERROR_EMM_CRYPTO_KEY = 1506, //EMM授权加密key错误
/**硬件特征码认证*/
SF_ERROR_HID_VERIFY_FAILED = 1601, //硬件特征码验证失败
SF_ERROR_HID_EXIST_NOTPASSED = 1602, //存在未审批的硬件特征码,等待管理员审批
SF_ERROR_HID_INVALID = 1603, //用户超时或硬件特征码无效输入
SF_ERROR_HID_LIMIT = 1604, //硬件特征数达到最大值
SF_ERROR_HID_UPDATE_FAILED = 1605, //更新硬件特征码失败
SF_ERROR_HID_GROUP_LIMIT = 1606, //硬件特征码达到组用户最大限制
SF_ERROR_HID_SN_LIMIT = 1607, //硬件特征码达到授权限制
SF_ERROR_HID_FAILED = 1608, //当前终端未经过硬件特征码验证,请等待管理员审批
SF_ERROR_HID_SUBMIT_FAILED = 1609, //提交硬件特征码失败
SF_ERRPR_HID_CELLNUM_INVALID = 1610, //硬件特征码短信审批,用户未设置手机号码
SF_ERROR_HID_COLLECT_FAILED = 1611, //硬件特征码收集失败
/**外部认证等*/
SF_ERROR_NO_EXTERNAL_SERVER = 1701, //没有对应的外部认证服务器,认证失败
SF_ERROR_TOKEN_PASSWORD_INCORRECT = 1702, //动态令牌密码错误,认证失败
SF_ERROR_CHALLENGE_FAILED = 1703, //挑战认证失败
SF_ERROR_CHALLENGE_TIMEOUT = 1704, //radius挑战超时
/** 本地认证的错误 */
SF_ERROR_CONNECT_VPN_FAILED = 2001, //连接VPN服务器错误,请检查网络
SF_ERROR_URL_INVALID = 2002, //VPN的URL为空
SF_ERROR_DOMAN_RESOLVE_FAILED = 2003, //域名解析失败
SF_ERROR_CRACKED_PHONE = 2004, //越狱手机禁止登陆
SF_ERROR_SELECT_LINE_FAILED = 2005, //VPN选路失败
SF_ERROR_NET_INVALID = 2006, //网络不可用
SF_ERROR_ADDRESS_FORMAT = 2007, //vpn地址格式有误
SF_ERROR_CONN_TIMEOUT = 2008, //连接服务器超时
SF_ERROR_AUTH_PARAM_EMPTY = 2101, //认证参数为空
SF_ERROR_AUTH_TYPE_INVALID = 2102, //调用的方法与当前认证方式不一致
SF_ERROR_CERTIFICATE_NOT_EXIST = 2103, //证书不存在
SF_ERROR_CERTIFICATE_TYPE_ERROR = 2104, //证书类型获取失败
SF_ERROR_TICKET_AUTH_DISABLE = 2105, //免密认证不可用
SF_ERROR_BUILD_REQUEST = 2106, //构建请求失败
SF_ERROR_SESSION_INVALID = 2107, //session无效
SF_ERROR_AUTH_TYPE_UNSPPORT = 2108, //认证类型不支持
SF_ERROR_STATUS_ERROR = 2109, //登录VPN状态错误,注销后再进行登录
SF_ERROR_HID_GET_ERROR = 2110, //读取硬件特征码失败
SF_ERROR_AUTH_INIT_ERROR = 2111, //VPN初始化失败
SF_ERROR_AUTH_PARAM_ERROR = 2112, //认证参数错误
SF_ERROR_CERTIFICATE_WRONG_PWD = 2113,
SF_ERROR_START_L3VPN_FAILED = 2201, //启动L3VPN失败
/** 非认证产生的错误 */
SF_ERROR_CHPWD_TIMEOUT = 3001, //用户超时
SF_ERROR_CHPWD_NO_PERMISSION = 3002, //不属于本地密码认证用户
SF_ERROR_CHPWD_GETINFO_FAIL = 3003, //获取用户信息失败
SF_ERROR_CHPWD_WRONG_PWD = 3004, //密码输入错误
SF_ERROR_CHPWD_SYSTEM_BUSY = 3005, //更新用户信息失败,可能服务器忙!
SF_ERROR_CHPWD_FORBID_CHGPWD = 3006, //您的帐号没有通过密码认证,不能修改密码
SF_ERROR_VPN_NOT_LOGIN = 3007, //VPN未登录导致修改密码失败
SF_ERROR_NEW_PASSWORD_SAME_AS_OLD = 3008, //新密码与原密码相同
SF_ERROR_CHPWD_SAFE_POLICY = 3009, //不符合密码策略
SF_ERROR_CHPWD_FAILED = 3010, //修改密码失败
SF_ERROR_CHPWD_RIGHT_CHGPWD = 3013, //对不起,您不具有更改密码的权限,请与管理员联系
SF_ERROR_CHPWD_RIGHT_CHGNOTE = 3014, //对不起,您不具有更改用户描述的权限,请与管理员联系
SF_ERROR_CHPWD_NEWPWD_TOO_LONG = 3015, //密码的长度最长不能超过48个字符
SF_ERROR_UPLAOD_DEVICE_INFO_FAILED = 3016, //上报设备信息失败
SF_ERROR_IPV6_TO_TPV4_ONLY = 3017, //本地是纯ipv6场景不能对接ipv4的服务端
SF_ERROR_IPV4_TO_TPV6_ONLY = 3018, //本地是纯ipv4场景不能对接ipv6的服务端
SF_ERROR_FORWARD_FAILED = 3101, //转发线程启动失败
SF_ERROR_OUT_OF_MEMORY = 3201, //内存不足
/** 其它错误 */
SF_ERROR_OTHER_ERROR = 4001, //其它错误
/** 注销错误 **/
SF_ERROR_IP = 5001, //ip错误注销
SF_ERROR_IP_CONFLIC = 5005, //虚拟ip冲突
SF_ERROR_IP_SHORTAGE = 5006, //虚拟ip短缺
SF_ERROR_IP_KICK = 5007, //虚拟ip被高权限用户踢掉
SF_ERROR_IP_OTHER = 5008, //虚拟ip其他错误
SF_ERROR_IP_QUIT = 5009, //服务端命令客户端退出
SF_ERROR_IP_RECV = 5010, //接收到服务端下发的ip
SF_ERROR_IP_RESET = 5011, //ip服务服务端重置了
SF_ERROR_IP_RECONNECT = 5012, //ip服务读、写隧道重连成功
} ;