From f3becd165e38cc229686563a3a7d8b874238fd1c Mon Sep 17 00:00:00 2001 From: Naraku J <74468372+Narakuku@users.noreply.github.com> Date: Sun, 31 Jul 2022 19:33:44 +0200 Subject: [PATCH] Add VLESS/XTLS support in GUI --- V2RayX/AdvancedWindow.xib | 12 +- V2RayX/ConfigImporter.m | 2 +- V2RayX/ConfigWindow.xib | 307 +++++++++++++++++------------ V2RayX/ServerProfile.h | 44 +++-- V2RayX/ServerProfile.m | 18 +- V2RayX/TransportWindow.xib | 71 ++++--- V2RayX/TransportWindowController.h | 2 +- V2RayX/TransportWindowController.m | 17 +- V2RayX/dlcorex.sh | 2 +- V2RayX/utilities.h | 5 +- V2RayXS.xcodeproj/project.pbxproj | 19 +- 11 files changed, 304 insertions(+), 195 deletions(-) diff --git a/V2RayX/AdvancedWindow.xib b/V2RayX/AdvancedWindow.xib index d450033..afcb9e9 100644 --- a/V2RayX/AdvancedWindow.xib +++ b/V2RayX/AdvancedWindow.xib @@ -1,8 +1,8 @@ - + - + @@ -62,7 +62,7 @@ - + @@ -247,7 +247,7 @@ Gw - + - + - + @@ -204,7 +203,7 @@ - + @@ -213,7 +212,7 @@ - + @@ -221,17 +220,8 @@ - - - - - - - - - - + @@ -250,7 +240,7 @@ - + @@ -269,9 +259,9 @@ - - - + + + @@ -290,7 +280,7 @@ - + @@ -299,7 +289,7 @@ - + @@ -318,7 +308,7 @@ - + @@ -326,83 +316,45 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - - - + + + + + + + + - + - + - + @@ -433,7 +385,7 @@ - + @@ -441,11 +393,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -489,7 +525,7 @@ - + @@ -498,7 +534,7 @@ - - - - - - - - - + - + - - - - - + + + + + - + - + @@ -623,14 +678,14 @@ Gw - + - + diff --git a/V2RayX/ServerProfile.h b/V2RayX/ServerProfile.h index d893fb1..f95d003 100644 --- a/V2RayX/ServerProfile.h +++ b/V2RayX/ServerProfile.h @@ -9,13 +9,28 @@ #import "AppDelegate.h" #import "utilities.h" +typedef enum ProtocolType : NSUInteger { + vmess, + vless +} ProtocolType; + typedef enum SecurityType : NSUInteger { - auto_, + none_security, + auto_security, aes_128_gcm, - chacha20_poly130, - none + chacha20_poly130 } SecurityType; +typedef enum FlowType : NSUInteger { + none_flow, + xtls_rprx_direct, + xtls_rprx_direct_udp443, + xtls_rprx_origin, + xtls_rprx_origin_udp443, + xtls_rprx_splice, + xtls_rprx_splice_udp443 +} FlowType; + typedef enum NetWorkType : NSUInteger { tcp, kcp, @@ -25,21 +40,22 @@ typedef enum NetWorkType : NSUInteger { } NetWorkType; @interface ServerProfile : NSObject -- (NSMutableDictionary*)outboundProfile; -+ (ServerProfile* _Nullable )readFromAnOutboundDic:(NSDictionary*)outDict; -+ (NSArray*)profilesFromJson:(NSDictionary*)outboundJson; --(ServerProfile*)deepCopy; +- (NSMutableDictionary* _Null_unspecified)outboundProfile; ++ (ServerProfile* _Nullable)readFromAnOutboundDic:(NSDictionary* _Null_unspecified)outDict; ++ (NSArray* _Null_unspecified)profilesFromJson:(NSDictionary* _Null_unspecified)outboundJson; +-(ServerProfile* _Null_unspecified)deepCopy; -@property (nonatomic) NSString* address; -@property (nonatomic) NSString* protocol; +@property (nonatomic) NSString* _Null_unspecified address; +@property (nonatomic) ProtocolType protocol; @property (nonatomic) NSUInteger port; -@property (nonatomic) NSString* userId; +@property (nonatomic) NSString* _Null_unspecified userId; @property (nonatomic) NSUInteger alterId; @property (nonatomic) NSUInteger level; -@property (nonatomic) NSString* outboundTag; +@property (nonatomic) NSString* _Null_unspecified outboundTag; +@property (nonatomic) FlowType flow; @property (nonatomic) SecurityType security; @property (nonatomic) NetWorkType network; -@property (nonatomic) NSString* sendThrough; -@property (nonatomic) NSDictionary* streamSettings; // except network type. -@property (nonatomic) NSDictionary* muxSettings; +@property (nonatomic) NSString* _Null_unspecified sendThrough; +@property (nonatomic) NSDictionary* _Null_unspecified streamSettings; // except network type. +@property (nonatomic) NSDictionary* _Null_unspecified muxSettings; @end diff --git a/V2RayX/ServerProfile.m b/V2RayX/ServerProfile.m index fa51706..9f04e34 100644 --- a/V2RayX/ServerProfile.m +++ b/V2RayX/ServerProfile.m @@ -12,14 +12,15 @@ @implementation ServerProfile - (ServerProfile*)init { self = [super init]; if (self) { - [self setProtocol:@"vmess"]; + [self setProtocol:vmess]; [self setAddress:@"server.cc"]; [self setPort:10086]; [self setUserId:@"00000000-0000-0000-0000-000000000000"]; [self setAlterId:64]; [self setLevel:0]; [self setOutboundTag:@"test server"]; - [self setSecurity:auto_]; + [self setFlow:none_flow]; + [self setSecurity:none_security]; [self setNetwork:tcp]; [self setSendThrough:@"0.0.0.0"]; [self setStreamSettings:@{ @@ -30,6 +31,9 @@ - (ServerProfile*)init { @"allowInsecure": [NSNumber numberWithBool:NO], @"allowInsecureCiphers": [NSNumber numberWithBool:NO] }, + @"xtlsSettings": @{ + @"allowInsecure": [NSNumber numberWithBool:NO] + }, @"tcpSettings": @{ @"header": @{ @"type": @"none" @@ -87,7 +91,7 @@ + (NSArray*)profilesFromJson:(NSDictionary*)outboundJson { } for (NSDictionary* vnext in [outboundJson valueForKeyPath:@"settings.vnext"]) { ServerProfile* profile = [[ServerProfile alloc] init]; - profile.protocol = nilCoalescing(outboundJson[@"protocol"], @"vmess"); + profile.protocol = searchInArray(outboundJson[@"protocol"], PROTOCOL_LIST); profile.address = nilCoalescing(vnext[@"address"], @"127.0.0.1"); profile.outboundTag = nilCoalescing(outboundJson[@"tag"], @""); profile.port = [vnext[@"port"] unsignedIntegerValue]; @@ -97,6 +101,7 @@ + (NSArray*)profilesFromJson:(NSDictionary*)outboundJson { profile.userId = nilCoalescing(vnext[@"users"][0][@"id"], @"23ad6b10-8d1a-40f7-8ad0-e3e35cd38287"); profile.alterId = [vnext[@"users"][0][@"alterId"] unsignedIntegerValue]; profile.level = [vnext[@"users"][0][@"level"] unsignedIntegerValue]; + profile.flow = searchInArray(vnext[@"users"][0][@"flow"], VLESS_FLOW_LIST); profile.security = searchInArray(vnext[@"users"][0][@"security"], VMESS_SECURITY_LIST); if (outboundJson[@"streamSettings"] != nil) { profile.streamSettings = outboundJson[@"streamSettings"]; @@ -122,13 +127,14 @@ + (ServerProfile* _Nullable )readFromAnOutboundDic:(NSDictionary*)outDict { -(ServerProfile*)deepCopy { ServerProfile* aCopy = [[ServerProfile alloc] init]; - aCopy.protocol = [NSString stringWithString:nilCoalescing(self.protocol, @"")]; + aCopy.protocol = self.protocol; aCopy.address = [NSString stringWithString:nilCoalescing(self.address, @"")]; aCopy.port = self.port; aCopy.userId = [NSString stringWithString:nilCoalescing(self.userId, @"")]; aCopy.alterId = self.alterId; aCopy.level = self.level; aCopy.outboundTag = [NSString stringWithString:nilCoalescing(self.outboundTag, @"")]; + aCopy.flow = self.flow; aCopy.security = self.security; aCopy.network = self.network; aCopy.sendThrough = [NSString stringWithString:nilCoalescing(self.sendThrough, @"")]; @@ -144,7 +150,7 @@ - (NSMutableDictionary*)outboundProfile { @{ @"sendThrough": sendThrough, @"tag": nilCoalescing(outboundTag, @""), - @"protocol": nilCoalescing(protocol, @"vmess"), + @"protocol": PROTOCOL_LIST[protocol], @"settings": [@{ @"vnext": @[ @{ @@ -154,6 +160,7 @@ - (NSMutableDictionary*)outboundProfile { @{ @"id": userId != nil ? [userId stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]: @"", @"alterId": [NSNumber numberWithUnsignedInteger:alterId], + @"flow": VLESS_FLOW_LIST[flow], @"security": VMESS_SECURITY_LIST[security], @"level": [NSNumber numberWithUnsignedInteger:level], @"encryption": @"none" @@ -181,6 +188,7 @@ - (NSMutableDictionary*)outboundProfile { @synthesize alterId; @synthesize level; @synthesize outboundTag; +@synthesize flow; @synthesize security; @synthesize network; @synthesize sendThrough; diff --git a/V2RayX/TransportWindow.xib b/V2RayX/TransportWindow.xib index 80a0d22..276e427 100644 --- a/V2RayX/TransportWindow.xib +++ b/V2RayX/TransportWindow.xib @@ -1,8 +1,8 @@ - + - + @@ -26,11 +26,11 @@ - + + - @@ -42,10 +42,10 @@ - + - + @@ -236,11 +236,11 @@ - + - + - + @@ -325,11 +325,11 @@ - + - + @@ -415,7 +415,7 @@ - + @@ -494,7 +494,7 @@ - + - + @@ -554,6 +543,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/V2RayX/TransportWindowController.h b/V2RayX/TransportWindowController.h index 69f4e93..678b682 100644 --- a/V2RayX/TransportWindowController.h +++ b/V2RayX/TransportWindowController.h @@ -45,7 +45,7 @@ NS_ASSUME_NONNULL_BEGIN //tls fields -@property (weak) IBOutlet NSButton *tlsUseButton; +@property (weak) IBOutlet NSPopUpButton *tlsSecurityButton; @property (weak) IBOutlet NSButton *tlsAiButton; @property (weak) IBOutlet NSButton *tlsAllowInsecureCiphersButton; @property (weak) IBOutlet NSTextField *tlsAlpnField; diff --git a/V2RayX/TransportWindowController.m b/V2RayX/TransportWindowController.m index f2a6e76..192ee57 100644 --- a/V2RayX/TransportWindowController.m +++ b/V2RayX/TransportWindowController.m @@ -99,7 +99,7 @@ - (void)fillStream:(NSDictionary*)streamSettings andMuxSettings:(NSDictionary*)m [_quicHeaderButton selectItemAtIndex:searchInArray(streamSettings[@"quicSettings"][@"header"][@"type"], OBFU_LIST)]; //tls - [_tlsUseButton setState:[[streamSettings objectForKey:@"security"] boolValue]]; + [_tlsSecurityButton selectItemAtIndex:searchInArray(streamSettings[@"security"], TLS_SECURITY_LIST)]; NSDictionary* tlsSettings = [streamSettings objectForKey:@"tlsSettings"]; [_tlsAiButton setState:[tlsSettings[@"allowInsecure"] boolValue]]; [_tlsAllowInsecureCiphersButton setState:[tlsSettings[@"allowInsecureCiphers"] boolValue]]; @@ -108,7 +108,10 @@ - (void)fillStream:(NSDictionary*)streamSettings andMuxSettings:(NSDictionary*)m [_tlsAlpnField setStringValue:nilCoalescing(alpnString, @"http/1.1")]; [_tlsServerNameField setStringValue:streamSettings[@"tlsSettings"][@"serverName"]]; - [self useTLS:nil]; + //xtls + NSDictionary* xtlsSettings = [streamSettings objectForKey:@"xtlsSettings"]; + [_tlsAiButton setState:[xtlsSettings[@"allowInsecure"] boolValue]]; + // mux [_muxEnableButton setState:[nilCoalescing(muxSettings[@"enabled"], @NO) boolValue]]; [_muxConcurrencyField setIntegerValue:[nilCoalescing(muxSettings[@"concurrency"], @8) integerValue]]; @@ -117,11 +120,6 @@ - (void)fillStream:(NSDictionary*)streamSettings andMuxSettings:(NSDictionary*)m [_tfoEnableButton setState:[tfoSettings[@"tcpFastOpen"] boolValue]]; } -- (IBAction)useTLS:(id)sender { - [_tlsAiButton setEnabled:[_tlsUseButton state]]; - [_tlsAllowInsecureCiphersButton setEnabled:[_tlsUseButton state]]; -} - - (IBAction)tReset:(id)sender { ServerProfile *p = [[ServerProfile alloc] init]; [self fillStream:p.streamSettings andMuxSettings:p.muxSettings]; @@ -220,13 +218,16 @@ - (NSArray*)generateSettings { @"type": [[self->_quicHeaderButton selectedItem] title] } }, - @"security": [self->_tlsUseButton state] ? @"tls" : @"none", + @"security": [[self->_tlsSecurityButton selectedItem] title], @"tlsSettings": @{ @"serverName": [_tlsServerNameField stringValue], @"allowInsecure": [NSNumber numberWithBool:[self->_tlsAiButton state]==1], @"allowInsecureCiphers": [NSNumber numberWithBool:[self->_tlsAllowInsecureCiphersButton state]==1], @"alpn": [[[_tlsAlpnField stringValue] stringByReplacingOccurrencesOfString:@" " withString:@""] componentsSeparatedByString:@","] }, + @"xtlsSettings": @{ + @"allowInsecure": [NSNumber numberWithBool:[self->_tlsAiButton state]==1] + }, @"httpSettings": httpSettings }; NSMutableDictionary *streamSettings = [streamSettingsImmutable mutableCopy]; diff --git a/V2RayX/dlcorex.sh b/V2RayX/dlcorex.sh index 2fe7aaf..a237266 100755 --- a/V2RayX/dlcorex.sh +++ b/V2RayX/dlcorex.sh @@ -1,4 +1,4 @@ -VERSION="1.5.3" +VERSION="1.5.5" RED='\033[0;31m' GREEN='\033[0;32m' BOLD='\033[1m' diff --git a/V2RayX/utilities.h b/V2RayX/utilities.h index 7d5c768..8cd1746 100644 --- a/V2RayX/utilities.h +++ b/V2RayX/utilities.h @@ -10,13 +10,16 @@ #import #import "MutableDeepCopying.h" +#define PROTOCOL_LIST (@[@"vmess", @"vless"]) #define DOMAIN_STRATEGY_LIST (@[@"AsIs", @"IPIfNonMatch", @"IPOnDemand"]) #define ROUTING_NETWORK_LIST (@[@"tcp", @"udp", @"tcp,udp"]) #define OBFU_LIST (@[@"none", @"srtp", @"utp", @"wechat-video", @"dtls", @"wireguard"]) -#define VMESS_SECURITY_LIST (@[@"auto", @"aes-128-gcm", @"chacha20-poly1305", @"none"]) +#define VLESS_FLOW_LIST (@[@"", @"xtls-rprx-direct", @"xtls-rprx-direct-udp443", @"xtls-rprx-origin", @"xtls-rprx-origin-udp443", @"xtls-rprx-splice", @"xtls-rprx-splice-udp443"]) +#define VMESS_SECURITY_LIST (@[@"none", @"auto", @"aes-128-gcm", @"chacha20-poly1305"]) #define NETWORK_LIST (@[@"tcp", @"kcp", @"ws", @"http", @"quic"]) #define QUIC_SECURITY_LIST (@[@"none", @"aes-128-gcm", @"chacha20-poly1305"]) +#define TLS_SECURITY_LIST (@[@"none", @"tls", @"xtls"]) #define nilCoalescing(a,b) ( (a != nil) ? (a) : (b) ) // equivalent to ?? operator in Swift #define TCP_NONE_HEADER_OBJECT (@"{\"type\": \"none\"}") diff --git a/V2RayXS.xcodeproj/project.pbxproj b/V2RayXS.xcodeproj/project.pbxproj index 30685f7..d3287dc 100644 --- a/V2RayXS.xcodeproj/project.pbxproj +++ b/V2RayXS.xcodeproj/project.pbxproj @@ -446,7 +446,7 @@ 9504C0701C662C3000352520 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0930; + LastUpgradeCheck = 1340; ORGANIZATIONNAME = "Project V2Ray"; TargetAttributes = { 9504C0771C662C3000352520 = { @@ -463,10 +463,9 @@ }; buildConfigurationList = 9504C0731C662C3000352520 /* Build configuration list for PBXProject "V2RayXS" */; compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( - English, en, Base, "zh-Hans", @@ -665,6 +664,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; @@ -683,6 +683,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -718,6 +719,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; @@ -736,6 +738,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -764,11 +767,12 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "-"; COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 1; INFOPLIST_FILE = V2RayX/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; - MARKETING_VERSION = 1.5.2; + MARKETING_VERSION = 1.5.3; PRODUCT_BUNDLE_IDENTIFIER = cenmrev.V2RayXS; PRODUCT_NAME = "$(TARGET_NAME)"; }; @@ -778,11 +782,12 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "-"; COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 1; INFOPLIST_FILE = V2RayX/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; - MARKETING_VERSION = 1.5.2; + MARKETING_VERSION = 1.5.3; PRODUCT_BUNDLE_IDENTIFIER = cenmrev.V2RayXS; PRODUCT_NAME = "$(TARGET_NAME)"; }; @@ -791,6 +796,7 @@ 9504C0CB1C662DB500352520 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "-"; MACOSX_DEPLOYMENT_TARGET = 12.0; PRODUCT_NAME = "$(TARGET_NAME)"; }; @@ -799,6 +805,7 @@ 9504C0CC1C662DB500352520 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "-"; MACOSX_DEPLOYMENT_TARGET = 12.0; PRODUCT_NAME = "$(TARGET_NAME)"; }; @@ -810,6 +817,7 @@ CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CODE_SIGN_IDENTITY = "-"; MACOSX_DEPLOYMENT_TARGET = 10.12; PRODUCT_NAME = "$(TARGET_NAME)"; }; @@ -821,6 +829,7 @@ CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CODE_SIGN_IDENTITY = "-"; MACOSX_DEPLOYMENT_TARGET = 10.12; PRODUCT_NAME = "$(TARGET_NAME)"; };