diff options
| author | Jonathan <jonathan@mullvad.net> | 2024-01-03 14:39:12 +0100 |
|---|---|---|
| committer | Jonathan <jonathan@mullvad.net> | 2024-01-03 14:39:12 +0100 |
| commit | 711d4e439866ab12e03d33d5efae3c2355c0c229 (patch) | |
| tree | 80d3a23c1a96bd3d80e05ac66b530e39c252d48a /gui | |
| parent | c510df96772b1e4ab7998e739ced42806c78e931 (diff) | |
| parent | 4fdc34acbba60d5092e45ce3e513d30ec996c317 (diff) | |
| download | mullvadvpn-711d4e439866ab12e03d33d5efae3c2355c0c229.tar.xz mullvadvpn-711d4e439866ab12e03d33d5efae3c2355c0c229.zip | |
Merge branch 'implement-custom-openvpn-socks5-bridge-client-in-daemon-des-430'
Diffstat (limited to 'gui')
| -rw-r--r-- | gui/src/main/daemon-rpc.ts | 138 | ||||
| -rw-r--r-- | gui/src/main/default-settings.ts | 2 | ||||
| -rw-r--r-- | gui/src/renderer/app.tsx | 18 | ||||
| -rw-r--r-- | gui/src/renderer/components/select-location/select-location-hooks.ts | 14 | ||||
| -rw-r--r-- | gui/src/renderer/lib/utilityHooks.ts | 2 | ||||
| -rw-r--r-- | gui/src/renderer/redux/settings/reducers.ts | 15 | ||||
| -rw-r--r-- | gui/src/shared/bridge-settings-builder.ts | 2 | ||||
| -rw-r--r-- | gui/src/shared/daemon-rpc-types.ts | 24 |
8 files changed, 144 insertions, 71 deletions
diff --git a/gui/src/main/daemon-rpc.ts b/gui/src/main/daemon-rpc.ts index ad7b60dec2..d5d29ad709 100644 --- a/gui/src/main/daemon-rpc.ts +++ b/gui/src/main/daemon-rpc.ts @@ -15,6 +15,7 @@ import { AuthFailedError, BridgeSettings, BridgeState, + BridgeType, ConnectionConfig, Constraint, CustomListError, @@ -51,7 +52,6 @@ import { ObfuscationSettings, ObfuscationType, Ownership, - ProxySettings, ProxyType, RelayEndpointType, RelayLocation, @@ -341,13 +341,52 @@ export class DaemonRpc { public async setBridgeSettings(bridgeSettings: BridgeSettings): Promise<void> { const grpcBridgeSettings = new grpcTypes.BridgeSettings(); - if ('normal' in bridgeSettings) { - const normalSettings = convertToNormalBridgeSettings(bridgeSettings.normal); - grpcBridgeSettings.setNormal(normalSettings); + if (bridgeSettings.type === 'custom') { + throw configNotSupported; } - if ('custom' in bridgeSettings) { - throw configNotSupported; + grpcBridgeSettings.setBridgeType(grpcTypes.BridgeSettings.BridgeType.NORMAL); + + const normalSettings = convertToNormalBridgeSettings(bridgeSettings.normal); + grpcBridgeSettings.setNormal(normalSettings); + + if (bridgeSettings.custom) { + const customProxy = new grpcTypes.CustomProxy(); + + const customSettings = bridgeSettings.custom; + + if ('local' in customSettings) { + const local = customSettings.local; + const socks5Local = new grpcTypes.Socks5Local(); + socks5Local.setLocalPort(local.localPort); + socks5Local.setRemoteIp(local.remoteIp); + socks5Local.setRemotePort(local.remotePort); + customProxy.setSocks5local(socks5Local); + } + if ('remote' in customSettings) { + const remote = customSettings.remote; + const socks5Remote = new grpcTypes.Socks5Remote(); + if (remote.auth) { + const auth = new grpcTypes.SocksAuth(); + auth.setUsername(remote.auth.username); + auth.setPassword(remote.auth.password); + socks5Remote.setAuth(auth); + } + socks5Remote.setIp(remote.ip); + socks5Remote.setPort(remote.port); + customProxy.setSocks5remote(socks5Remote); + } + if ('shadowsocks' in customSettings) { + const shadowsocks = customSettings.shadowsocks; + const shadowOut = new grpcTypes.Shadowsocks(); + shadowOut.setCipher(shadowsocks.cipher); + shadowOut.setIp(shadowsocks.ip); + shadowOut.setPort(shadowsocks.port); + shadowOut.setPassword(shadowsocks.password); + customProxy.setShadowsocks(shadowOut); + } + + grpcBridgeSettings.setCustom(customProxy); } await this.call<grpcTypes.BridgeSettings, Empty>( @@ -1140,49 +1179,64 @@ function convertFromRelaySettings( function convertFromBridgeSettings(bridgeSettings: grpcTypes.BridgeSettings): BridgeSettings { const bridgeSettingsObject = bridgeSettings.toObject(); + + const detailsMap: Record<grpcTypes.BridgeSettings.BridgeType, BridgeType> = { + [grpcTypes.BridgeSettings.BridgeType.NORMAL]: 'normal', + [grpcTypes.BridgeSettings.BridgeType.CUSTOM]: 'custom', + }; + const type = detailsMap[bridgeSettingsObject.bridgeType]; + const normalSettings = bridgeSettingsObject.normal; - if (normalSettings) { - const locationConstraint = convertFromLocationConstraint( - bridgeSettings.getNormal()?.getLocation(), - ); - const location = wrapConstraint(locationConstraint); - const providers = normalSettings.providersList; - const ownership = convertFromOwnership(normalSettings.ownership); - return { - normal: { - location, - providers, - ownership, - }, - }; - } + const locationConstraint = convertFromLocationConstraint( + bridgeSettings.getNormal()?.getLocation(), + ); + const location = wrapConstraint(locationConstraint); + const providers = normalSettings!.providersList; + const ownership = convertFromOwnership(normalSettings!.ownership); - const customSettings = (settings: ProxySettings): BridgeSettings => { - return { custom: settings }; + const normal = { + location, + providers, + ownership, }; - const localSettings = bridgeSettingsObject.local; - if (localSettings) { - return customSettings({ - port: localSettings.port, - peer: localSettings.peer, - }); - } + let custom = undefined; - const remoteSettings = bridgeSettingsObject.remote; - if (remoteSettings) { - return customSettings({ - address: remoteSettings.address, - auth: remoteSettings.auth && { ...remoteSettings.auth }, - }); + if (bridgeSettingsObject.custom) { + const localSettings = bridgeSettingsObject.custom.socks5local; + if (localSettings) { + custom = { + local: { + localPort: localSettings.localPort, + remoteIp: localSettings.remoteIp, + remotePort: localSettings.remotePort, + }, + }; + } + const remoteSettings = bridgeSettingsObject.custom.socks5remote; + if (remoteSettings) { + custom = { + remote: { + ip: remoteSettings.ip, + port: remoteSettings.port, + auth: remoteSettings.auth && { ...remoteSettings.auth }, + }, + }; + } + const shadowsocksSettings = bridgeSettingsObject.custom.shadowsocks; + if (shadowsocksSettings) { + custom = { + shadowsocks: { + ip: shadowsocksSettings.ip, + port: shadowsocksSettings.port, + password: shadowsocksSettings.password, + cipher: shadowsocksSettings.cipher, + }, + }; + } } - const shadowsocksSettings = bridgeSettingsObject.shadowsocks!; - return customSettings({ - peer: shadowsocksSettings.peer!, - password: shadowsocksSettings.password!, - cipher: shadowsocksSettings.cipher!, - }); + return { type, normal, custom }; } function convertFromConnectionConfig( diff --git a/gui/src/main/default-settings.ts b/gui/src/main/default-settings.ts index 55f420b659..fea88e4c27 100644 --- a/gui/src/main/default-settings.ts +++ b/gui/src/main/default-settings.ts @@ -29,11 +29,13 @@ export function getDefaultSettings(): ISettings { }, }, bridgeSettings: { + type: 'normal', normal: { location: 'any', providers: [], ownership: Ownership.any, }, + custom: undefined, }, bridgeState: 'auto', tunnelOptions: { diff --git a/gui/src/renderer/app.tsx b/gui/src/renderer/app.tsx index b5eacf17b3..3806c12413 100644 --- a/gui/src/renderer/app.tsx +++ b/gui/src/renderer/app.tsx @@ -624,17 +624,13 @@ export default class AppRenderer { private setBridgeSettings(bridgeSettings: BridgeSettings) { const actions = this.reduxActions; - if ('normal' in bridgeSettings) { - actions.settings.updateBridgeSettings({ - normal: { - location: liftConstraint(bridgeSettings.normal.location), - }, - }); - } else if ('custom' in bridgeSettings) { - actions.settings.updateBridgeSettings({ - custom: bridgeSettings.custom, - }); - } + actions.settings.updateBridgeSettings({ + type: bridgeSettings.type, + normal: { + location: liftConstraint(bridgeSettings.normal.location), + }, + custom: bridgeSettings.custom, + }); } private onDaemonConnected() { diff --git a/gui/src/renderer/components/select-location/select-location-hooks.ts b/gui/src/renderer/components/select-location/select-location-hooks.ts index 48d81e594c..b795f4a74f 100644 --- a/gui/src/renderer/components/select-location/select-location-hooks.ts +++ b/gui/src/renderer/components/select-location/select-location-hooks.ts @@ -11,6 +11,7 @@ import log from '../../../shared/logging'; import { useAppContext } from '../../context'; import { useRelaySettingsModifier } from '../../lib/constraint-updater'; import { useHistory } from '../../lib/history'; +import { useSelector } from '../../redux/store'; import { LocationType, SpecialBridgeLocationType } from './select-location-types'; import { useSelectLocationContext } from './SelectLocationContainer'; @@ -88,6 +89,7 @@ function useOnSelectLocation() { export function useOnSelectBridgeLocation() { const { updateBridgeSettings } = useAppContext(); const { setLocationType } = useSelectLocationContext(); + const bridgeSettings = useSelector((state) => state.settings.bridgeSettings); const setLocation = useCallback(async (bridgeUpdate: BridgeSettings) => { if (bridgeUpdate) { @@ -101,10 +103,14 @@ export function useOnSelectBridgeLocation() { } }, []); - const onSelectRelay = useCallback((location: RelayLocation) => { - const bridgeUpdate = new BridgeSettingsBuilder().location.fromRaw(location).build(); - return setLocation(bridgeUpdate); - }, []); + const onSelectRelay = useCallback( + (location: RelayLocation) => { + const bridgeUpdate = new BridgeSettingsBuilder().location.fromRaw(location).build(); + bridgeUpdate.custom = bridgeSettings.custom; + return setLocation(bridgeUpdate); + }, + [bridgeSettings], + ); const onSelectSpecial = useCallback((location: SpecialBridgeLocationType) => { switch (location) { diff --git a/gui/src/renderer/lib/utilityHooks.ts b/gui/src/renderer/lib/utilityHooks.ts index 49f508a883..8c3925762e 100644 --- a/gui/src/renderer/lib/utilityHooks.ts +++ b/gui/src/renderer/lib/utilityHooks.ts @@ -67,5 +67,5 @@ export function useNormalRelaySettings() { export function useNormalBridgeSettings() { const bridgeSettings = useSelector((state) => state.settings.bridgeSettings); - return 'normal' in bridgeSettings ? bridgeSettings.normal : undefined; + return bridgeSettings.normal; } diff --git a/gui/src/renderer/redux/settings/reducers.ts b/gui/src/renderer/redux/settings/reducers.ts index b400799095..3d03093e0a 100644 --- a/gui/src/renderer/redux/settings/reducers.ts +++ b/gui/src/renderer/redux/settings/reducers.ts @@ -1,6 +1,7 @@ import { IWindowsApplication } from '../../../shared/application-types'; import { BridgeState, + BridgeType, CustomLists, IDnsOptions, IpVersion, @@ -51,13 +52,11 @@ export type RelaySettingsRedux = }; }; -export type BridgeSettingsRedux = - | { - normal: NormalBridgeSettingsRedux; - } - | { - custom: ProxySettings; - }; +export type BridgeSettingsRedux = { + type: BridgeType; + normal: NormalBridgeSettingsRedux; + custom?: ProxySettings; +}; export interface IRelayLocationRelayRedux { hostname: string; @@ -140,9 +139,11 @@ const initialState: ISettingsReduxState = { allowLan: false, enableIpv6: true, bridgeSettings: { + type: 'normal', normal: { location: 'any', }, + custom: undefined, }, bridgeState: 'auto', blockWhenDisconnected: false, diff --git a/gui/src/shared/bridge-settings-builder.ts b/gui/src/shared/bridge-settings-builder.ts index 858bea055d..2ee5469707 100644 --- a/gui/src/shared/bridge-settings-builder.ts +++ b/gui/src/shared/bridge-settings-builder.ts @@ -7,11 +7,13 @@ export default class BridgeSettingsBuilder { public build(): BridgeSettings { if (this.payload.location) { return { + type: 'normal', normal: { location: this.payload.location, providers: this.payload.providers ?? [], ownership: this.payload.ownership ?? Ownership.any, }, + custom: undefined, }; } else { throw new Error('Unsupported configuration'); diff --git a/gui/src/shared/daemon-rpc-types.ts b/gui/src/shared/daemon-rpc-types.ts index e83f9e5afc..48a4110e13 100644 --- a/gui/src/shared/daemon-rpc-types.ts +++ b/gui/src/shared/daemon-rpc-types.ts @@ -345,15 +345,20 @@ export interface IDnsOptions { }; } -export type ProxySettings = ILocalProxySettings | IRemoteProxySettings | IShadowsocksProxySettings; +export type ProxySettings = + | { local: ILocalProxySettings } + | { remote: IRemoteProxySettings } + | { shadowsocks: IShadowsocksProxySettings }; export interface ILocalProxySettings { - port: number; - peer: string; + localPort: number; + remoteIp: string; + remotePort: number; } export interface IRemoteProxySettings { - address: string; + ip: string; + port: number; auth?: IRemoteProxyAuth; } @@ -363,7 +368,8 @@ export interface IRemoteProxyAuth { } export interface IShadowsocksProxySettings { - peer: string; + ip: string; + port: number; password: string; cipher: string; } @@ -451,7 +457,13 @@ export interface IBridgeConstraints { ownership: Ownership; } -export type BridgeSettings = { normal: IBridgeConstraints } | { custom: ProxySettings }; +export type BridgeType = 'normal' | 'custom'; + +export interface BridgeSettings { + type: BridgeType; + normal: IBridgeConstraints; + custom?: ProxySettings; +} export interface ISocketAddress { host: string; |
