diff --git a/proxy/vmess/account.go b/proxy/vmess/account.go index 38dbef2cc..809ece58e 100644 --- a/proxy/vmess/account.go +++ b/proxy/vmess/account.go @@ -10,6 +10,7 @@ import ( type InternalAccount struct { ID *protocol.ID AlterIDs []*protocol.ID + Security protocol.Security } func (v *InternalAccount) AnyValidID() *protocol.ID { @@ -38,5 +39,6 @@ func (v *Account) AsAccount() (protocol.Account, error) { return &InternalAccount{ ID: protoId, AlterIDs: protocol.NewAlterIDs(protoId, uint16(v.AlterId)), + Security: protocol.Security(v.Security), }, nil } diff --git a/proxy/vmess/account.pb.go b/proxy/vmess/account.pb.go index 5cbd26599..f6d5bcc6e 100644 --- a/proxy/vmess/account.pb.go +++ b/proxy/vmess/account.pb.go @@ -16,6 +16,7 @@ package vmess import proto "github.com/golang/protobuf/proto" import fmt "fmt" import math "math" +import v2ray_core_common_protocol "v2ray.com/core/common/protocol" // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal @@ -29,8 +30,9 @@ var _ = math.Inf const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package type Account struct { - Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` - AlterId uint32 `protobuf:"varint,2,opt,name=alter_id,json=alterId" json:"alter_id,omitempty"` + Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` + AlterId uint32 `protobuf:"varint,2,opt,name=alter_id,json=alterId" json:"alter_id,omitempty"` + Security v2ray_core_common_protocol.SecurityType `protobuf:"varint,3,opt,name=security,enum=v2ray.core.common.protocol.SecurityType" json:"security,omitempty"` } func (m *Account) Reset() { *m = Account{} } @@ -45,15 +47,19 @@ func init() { func init() { proto.RegisterFile("v2ray.com/core/proxy/vmess/account.proto", fileDescriptor0) } var fileDescriptor0 = []byte{ - // 152 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xd2, 0x28, 0x33, 0x2a, 0x4a, - 0xac, 0xd4, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xce, 0x2f, 0x4a, 0xd5, 0x2f, 0x28, 0xca, 0xaf, 0xa8, - 0xd4, 0x2f, 0xcb, 0x4d, 0x2d, 0x2e, 0xd6, 0x4f, 0x4c, 0x4e, 0xce, 0x2f, 0xcd, 0x2b, 0xd1, 0x2b, - 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x83, 0xa9, 0x2c, 0x4a, 0xd5, 0x03, 0xab, 0xd2, 0x03, 0xab, - 0x52, 0x32, 0xe1, 0x62, 0x77, 0x84, 0x28, 0x14, 0xe2, 0xe3, 0x62, 0xca, 0x4c, 0x91, 0x60, 0x54, - 0x60, 0xd4, 0xe0, 0x0c, 0x62, 0xca, 0x4c, 0x11, 0x92, 0xe4, 0xe2, 0x48, 0xcc, 0x29, 0x49, 0x2d, - 0x8a, 0xcf, 0x4c, 0x91, 0x60, 0x52, 0x60, 0xd4, 0xe0, 0x0d, 0x62, 0x07, 0xf3, 0x3d, 0x53, 0x9c, - 0x0c, 0xb9, 0xa4, 0x92, 0xf3, 0x73, 0xf5, 0xb0, 0x9b, 0xe9, 0xc4, 0x03, 0x35, 0x31, 0x00, 0x64, - 0x73, 0x14, 0x2b, 0x58, 0x30, 0x89, 0x0d, 0xec, 0x0e, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, - 0x4b, 0xb5, 0x6b, 0xdd, 0xb3, 0x00, 0x00, 0x00, + // 217 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x6c, 0x8f, 0x41, 0x4b, 0x03, 0x31, + 0x10, 0x85, 0xd9, 0x15, 0x6d, 0x0d, 0xda, 0xc3, 0x1e, 0x64, 0xed, 0x69, 0xf1, 0x94, 0x83, 0x4c, + 0xb0, 0xfe, 0x02, 0x8b, 0x17, 0x6f, 0xb2, 0x7a, 0xf2, 0x22, 0x71, 0x32, 0x60, 0xa0, 0xe9, 0x2c, + 0x93, 0xb4, 0x18, 0x7f, 0xbd, 0x98, 0xed, 0x8a, 0x88, 0xc7, 0x84, 0xef, 0x7d, 0xef, 0x8d, 0xd2, + 0xfb, 0x95, 0xd8, 0x0c, 0xc8, 0xc1, 0x20, 0x0b, 0x99, 0x41, 0xf8, 0x23, 0x9b, 0x7d, 0xa0, 0x18, + 0x8d, 0x45, 0xe4, 0xdd, 0x36, 0xc1, 0x20, 0x9c, 0xb8, 0xb9, 0x98, 0x48, 0x21, 0x28, 0x14, 0x14, + 0x6a, 0x79, 0xfd, 0xc7, 0x80, 0x1c, 0x02, 0x6f, 0x4d, 0x09, 0x21, 0x6f, 0xcc, 0x3b, 0x59, 0x47, + 0x12, 0x47, 0xcb, 0xd5, 0xa7, 0x9a, 0xdd, 0x8d, 0xda, 0x66, 0xa1, 0x6a, 0xef, 0xda, 0xaa, 0xab, + 0xf4, 0x69, 0x5f, 0x7b, 0xd7, 0x5c, 0xaa, 0xb9, 0xdd, 0x24, 0x92, 0x57, 0xef, 0xda, 0xba, 0xab, + 0xf4, 0x79, 0x3f, 0x2b, 0xef, 0x07, 0xd7, 0xdc, 0xab, 0x79, 0x24, 0xdc, 0x89, 0x4f, 0xb9, 0x3d, + 0xea, 0x2a, 0xbd, 0x58, 0x69, 0xf8, 0x35, 0x67, 0xac, 0x84, 0xa9, 0x12, 0x9e, 0x0e, 0xec, 0x73, + 0x1e, 0xa8, 0xff, 0x49, 0xae, 0x6f, 0xd4, 0x12, 0x39, 0xc0, 0xff, 0x77, 0xac, 0xcf, 0x0e, 0xbb, + 0x1e, 0xbf, 0x2d, 0x2f, 0xc7, 0xe5, 0xf3, 0xed, 0xa4, 0x38, 0x6f, 0xbf, 0x02, 0x00, 0x00, 0xff, + 0xff, 0x9c, 0x9c, 0x82, 0x1b, 0x27, 0x01, 0x00, 0x00, } diff --git a/proxy/vmess/account.proto b/proxy/vmess/account.proto index 751dfd0e0..ffcecb81f 100644 --- a/proxy/vmess/account.proto +++ b/proxy/vmess/account.proto @@ -6,7 +6,10 @@ option go_package = "vmess"; option java_package = "com.v2ray.core.proxy.vmess"; option java_outer_classname = "AccountProto"; +import "v2ray.com/core/common/protocol/headers.proto"; + message Account { string id = 1; uint32 alter_id = 2; + v2ray.core.common.protocol.SecurityType security = 3; } diff --git a/proxy/vmess/encoding/auth.go b/proxy/vmess/encoding/auth.go index 22e22b475..ffc7762dd 100644 --- a/proxy/vmess/encoding/auth.go +++ b/proxy/vmess/encoding/auth.go @@ -3,6 +3,7 @@ package encoding import ( "hash/fnv" + "crypto/md5" "v2ray.com/core/common/crypto" "v2ray.com/core/common/serial" ) @@ -35,3 +36,12 @@ func (v *FnvAuthenticator) Open(dst, nonce, ciphertext, additionalData []byte) ( } return append(dst[:0], ciphertext[4:]...), nil } + +func GenerateChacha20Poly1305Key(b []byte) []byte { + key := make([]byte, 32) + t := md5.Sum(b) + copy(key, t[:]) + t = md5.Sum(key[:16]) + copy(key[16:], t[:]) + return key +} diff --git a/proxy/vmess/encoding/client.go b/proxy/vmess/encoding/client.go index 2b0d34d76..71d9a361d 100644 --- a/proxy/vmess/encoding/client.go +++ b/proxy/vmess/encoding/client.go @@ -149,7 +149,7 @@ func (v *ClientSession) EncodeRequestBody(request *protocol.RequestHeader, write } authWriter = crypto.NewAuthenticationWriter(auth, writer) } else if request.Security.Is(protocol.SecurityType_CHACHA20_POLY1305) { - aead, _ := chacha20poly1305.New(v.responseBodyKey) + aead, _ := chacha20poly1305.New(GenerateChacha20Poly1305Key(v.responseBodyKey)) auth := &crypto.AEADAuthenticator{ AEAD: aead, @@ -243,7 +243,7 @@ func (v *ClientSession) DecodeResponseBody(request *protocol.RequestHeader, read } authReader = crypto.NewAuthenticationReader(auth, reader, aggressive) } else if request.Security.Is(protocol.SecurityType_CHACHA20_POLY1305) { - aead, _ := chacha20poly1305.New(v.responseBodyKey) + aead, _ := chacha20poly1305.New(GenerateChacha20Poly1305Key(v.responseBodyKey)) auth := &crypto.AEADAuthenticator{ AEAD: aead, diff --git a/proxy/vmess/encoding/server.go b/proxy/vmess/encoding/server.go index 2c066acae..6cd12fb49 100644 --- a/proxy/vmess/encoding/server.go +++ b/proxy/vmess/encoding/server.go @@ -196,7 +196,7 @@ func (v *ServerSession) DecodeRequestBody(request *protocol.RequestHeader, reade } authReader = crypto.NewAuthenticationReader(auth, reader, aggressive) } else if request.Security.Is(protocol.SecurityType_CHACHA20_POLY1305) { - aead, _ := chacha20poly1305.New(v.responseBodyKey) + aead, _ := chacha20poly1305.New(GenerateChacha20Poly1305Key(v.responseBodyKey)) auth := &crypto.AEADAuthenticator{ AEAD: aead, @@ -267,7 +267,7 @@ func (v *ServerSession) EncodeResponseBody(request *protocol.RequestHeader, writ } authWriter = crypto.NewAuthenticationWriter(auth, writer) } else if request.Security.Is(protocol.SecurityType_CHACHA20_POLY1305) { - aead, _ := chacha20poly1305.New(v.responseBodyKey) + aead, _ := chacha20poly1305.New(GenerateChacha20Poly1305Key(v.responseBodyKey)) auth := &crypto.AEADAuthenticator{ AEAD: aead, diff --git a/proxy/vmess/outbound/outbound.go b/proxy/vmess/outbound/outbound.go index 90683185a..1f2b143e0 100644 --- a/proxy/vmess/outbound/outbound.go +++ b/proxy/vmess/outbound/outbound.go @@ -13,6 +13,7 @@ import ( "v2ray.com/core/common/retry" "v2ray.com/core/proxy" "v2ray.com/core/proxy/registry" + "v2ray.com/core/proxy/vmess" "v2ray.com/core/proxy/vmess/encoding" "v2ray.com/core/transport/internet" "v2ray.com/core/transport/ray" @@ -60,6 +61,13 @@ func (v *VMessOutboundHandler) Dispatch(target v2net.Destination, payload *alloc Option: protocol.RequestOptionChunkStream, } + rawAccount, err := request.User.GetTypedAccount() + if err != nil { + log.Warning("VMess|Outbound: Failed to get user account: ", err) + } + account := rawAccount.(*vmess.InternalAccount) + request.Security = account.Security + defer conn.Close() conn.SetReusable(true) diff --git a/tools/conf/vmess.go b/tools/conf/vmess.go index 03db3524d..b18eec724 100644 --- a/tools/conf/vmess.go +++ b/tools/conf/vmess.go @@ -2,6 +2,8 @@ package conf import ( "encoding/json" + "strings" + "v2ray.com/core/common/errors" "v2ray.com/core/common/loader" v2net "v2ray.com/core/common/net" @@ -15,12 +17,25 @@ import ( type VMessAccount struct { ID string `json:"id"` AlterIds uint16 `json:"alterId"` + Security string `json:"security"` } func (v *VMessAccount) Build() *vmess.Account { + var st protocol.SecurityType + switch strings.ToLower(v.Security) { + case "aes-128-gcm": + st = protocol.SecurityType_AES128_GCM + case "chacha20-poly1305": + st = protocol.SecurityType_CHACHA20_POLY1305 + case "none": + st = protocol.SecurityType_NONE + default: + st = protocol.SecurityType_LEGACY + } return &vmess.Account{ - Id: v.ID, - AlterId: uint32(v.AlterIds), + Id: v.ID, + AlterId: uint32(v.AlterIds), + Security: st, } }