Browse Source

Clean legacy vmess (#2199)

* Remove legacy Vmess

* validators

* protos
yuhan6665 2 years ago
parent
commit
9112cfd39c

+ 1 - 2
.github/docker/files/config.json

@@ -6,8 +6,7 @@
       "clients": [
       "clients": [
         {
         {
           "id": "1eb6e917-774b-4a84-aff6-b058577c60a5",
           "id": "1eb6e917-774b-4a84-aff6-b058577c60a5",
-          "level": 1,
-          "alterId": 64
+          "level": 1
         }
         }
       ]
       ]
     }
     }

+ 2 - 4
common/protocol/headers.go

@@ -30,11 +30,10 @@ func (c RequestCommand) TransferType() TransferType {
 }
 }
 
 
 const (
 const (
-	// RequestOptionChunkStream indicates request payload is chunked. Each chunk consists of length, authentication and payload.
+	// [DEPRECATED 2023-06] RequestOptionChunkStream indicates request payload is chunked. Each chunk consists of length, authentication and payload.
 	RequestOptionChunkStream bitmask.Byte = 0x01
 	RequestOptionChunkStream bitmask.Byte = 0x01
 
 
-	// RequestOptionConnectionReuse indicates client side expects to reuse the connection.
-	RequestOptionConnectionReuse bitmask.Byte = 0x02
+	// 0x02 legacy setting
 
 
 	RequestOptionChunkMasking bitmask.Byte = 0x04
 	RequestOptionChunkMasking bitmask.Byte = 0x04
 
 
@@ -76,7 +75,6 @@ type CommandSwitchAccount struct {
 	Port     net.Port
 	Port     net.Port
 	ID       uuid.UUID
 	ID       uuid.UUID
 	Level    uint32
 	Level    uint32
-	AlterIds uint16
 	ValidMin byte
 	ValidMin byte
 }
 }
 
 

+ 13 - 17
common/protocol/headers.pb.go

@@ -24,7 +24,6 @@ type SecurityType int32
 
 
 const (
 const (
 	SecurityType_UNKNOWN           SecurityType = 0
 	SecurityType_UNKNOWN           SecurityType = 0
-	SecurityType_LEGACY            SecurityType = 1
 	SecurityType_AUTO              SecurityType = 2
 	SecurityType_AUTO              SecurityType = 2
 	SecurityType_AES128_GCM        SecurityType = 3
 	SecurityType_AES128_GCM        SecurityType = 3
 	SecurityType_CHACHA20_POLY1305 SecurityType = 4
 	SecurityType_CHACHA20_POLY1305 SecurityType = 4
@@ -36,7 +35,6 @@ const (
 var (
 var (
 	SecurityType_name = map[int32]string{
 	SecurityType_name = map[int32]string{
 		0: "UNKNOWN",
 		0: "UNKNOWN",
-		1: "LEGACY",
 		2: "AUTO",
 		2: "AUTO",
 		3: "AES128_GCM",
 		3: "AES128_GCM",
 		4: "CHACHA20_POLY1305",
 		4: "CHACHA20_POLY1305",
@@ -45,7 +43,6 @@ var (
 	}
 	}
 	SecurityType_value = map[string]int32{
 	SecurityType_value = map[string]int32{
 		"UNKNOWN":           0,
 		"UNKNOWN":           0,
-		"LEGACY":            1,
 		"AUTO":              2,
 		"AUTO":              2,
 		"AES128_GCM":        3,
 		"AES128_GCM":        3,
 		"CHACHA20_POLY1305": 4,
 		"CHACHA20_POLY1305": 4,
@@ -139,20 +136,19 @@ var file_common_protocol_headers_proto_rawDesc = []byte{
 	0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d,
 	0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d,
 	0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x53, 0x65, 0x63,
 	0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x53, 0x65, 0x63,
 	0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x2a,
 	0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x2a,
-	0x6c, 0x0a, 0x0c, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12,
-	0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06,
-	0x4c, 0x45, 0x47, 0x41, 0x43, 0x59, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x41, 0x55, 0x54, 0x4f,
-	0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x41, 0x45, 0x53, 0x31, 0x32, 0x38, 0x5f, 0x47, 0x43, 0x4d,
-	0x10, 0x03, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x48, 0x41, 0x43, 0x48, 0x41, 0x32, 0x30, 0x5f, 0x50,
-	0x4f, 0x4c, 0x59, 0x31, 0x33, 0x30, 0x35, 0x10, 0x04, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e,
-	0x45, 0x10, 0x05, 0x12, 0x08, 0x0a, 0x04, 0x5a, 0x45, 0x52, 0x4f, 0x10, 0x06, 0x42, 0x5e, 0x0a,
-	0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
-	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x50, 0x01, 0x5a, 0x29, 0x67, 0x69, 0x74,
-	0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61,
-	0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72,
-	0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0xaa, 0x02, 0x14, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x43, 0x6f,
-	0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x62, 0x06, 0x70,
-	0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x60, 0x0a, 0x0c, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12,
+	0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04,
+	0x41, 0x55, 0x54, 0x4f, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x41, 0x45, 0x53, 0x31, 0x32, 0x38,
+	0x5f, 0x47, 0x43, 0x4d, 0x10, 0x03, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x48, 0x41, 0x43, 0x48, 0x41,
+	0x32, 0x30, 0x5f, 0x50, 0x4f, 0x4c, 0x59, 0x31, 0x33, 0x30, 0x35, 0x10, 0x04, 0x12, 0x08, 0x0a,
+	0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x05, 0x12, 0x08, 0x0a, 0x04, 0x5a, 0x45, 0x52, 0x4f, 0x10,
+	0x06, 0x42, 0x5e, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f,
+	0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x50, 0x01, 0x5a,
+	0x29, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73,
+	0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
+	0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0xaa, 0x02, 0x14, 0x58, 0x72, 0x61,
+	0x79, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f,
+	0x6c, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 }
 
 
 var (
 var (

+ 1 - 2
common/protocol/headers.proto

@@ -8,11 +8,10 @@ option java_multiple_files = true;
 
 
 enum SecurityType {
 enum SecurityType {
   UNKNOWN = 0;
   UNKNOWN = 0;
-  LEGACY = 1;
   AUTO = 2;
   AUTO = 2;
   AES128_GCM = 3;
   AES128_GCM = 3;
   CHACHA20_POLY1305 = 4;
   CHACHA20_POLY1305 = 4;
-  NONE = 5;
+  NONE = 5; // [DEPRECATED 2023-06] 
   ZERO = 6;
   ZERO = 6;
 }
 }
 
 

+ 0 - 33
common/protocol/id.go

@@ -1,9 +1,7 @@
 package protocol
 package protocol
 
 
 import (
 import (
-	"crypto/hmac"
 	"crypto/md5"
 	"crypto/md5"
-	"hash"
 
 
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common/uuid"
 	"github.com/xtls/xray-core/common/uuid"
@@ -13,12 +11,6 @@ const (
 	IDBytesLen = 16
 	IDBytesLen = 16
 )
 )
 
 
-type IDHash func(key []byte) hash.Hash
-
-func DefaultIDHash(key []byte) hash.Hash {
-	return hmac.New(md5.New, key)
-}
-
 // The ID of en entity, in the form of a UUID.
 // The ID of en entity, in the form of a UUID.
 type ID struct {
 type ID struct {
 	uuid   uuid.UUID
 	uuid   uuid.UUID
@@ -55,28 +47,3 @@ func NewID(uuid uuid.UUID) *ID {
 	md5hash.Sum(id.cmdKey[:0])
 	md5hash.Sum(id.cmdKey[:0])
 	return id
 	return id
 }
 }
-
-func nextID(u *uuid.UUID) uuid.UUID {
-	md5hash := md5.New()
-	common.Must2(md5hash.Write(u.Bytes()))
-	common.Must2(md5hash.Write([]byte("16167dc8-16b6-4e6d-b8bb-65dd68113a81")))
-	var newid uuid.UUID
-	for {
-		md5hash.Sum(newid[:0])
-		if !newid.Equals(u) {
-			return newid
-		}
-		common.Must2(md5hash.Write([]byte("533eff8a-4113-4b10-b5ce-0f5d76b98cd2")))
-	}
-}
-
-func NewAlterIDs(primary *ID, alterIDCount uint16) []*ID {
-	alterIDs := make([]*ID, alterIDCount)
-	prevID := primary.UUID()
-	for idx := range alterIDs {
-		newid := nextID(&prevID)
-		alterIDs[idx] = NewID(newid)
-		prevID = newid
-	}
-	return alterIDs
-}

+ 1 - 8
infra/conf/vmess.go

@@ -15,7 +15,6 @@ import (
 
 
 type VMessAccount struct {
 type VMessAccount struct {
 	ID          string `json:"id"`
 	ID          string `json:"id"`
-	AlterIds    uint16 `json:"alterId"`
 	Security    string `json:"security"`
 	Security    string `json:"security"`
 	Experiments string `json:"experiments"`
 	Experiments string `json:"experiments"`
 }
 }
@@ -39,7 +38,6 @@ func (a *VMessAccount) Build() *vmess.Account {
 	}
 	}
 	return &vmess.Account{
 	return &vmess.Account{
 		Id:      a.ID,
 		Id:      a.ID,
-		AlterId: uint32(a.AlterIds),
 		SecuritySettings: &protocol.SecurityConfig{
 		SecuritySettings: &protocol.SecurityConfig{
 			Type: st,
 			Type: st,
 		},
 		},
@@ -63,14 +61,12 @@ type FeaturesConfig struct {
 }
 }
 
 
 type VMessDefaultConfig struct {
 type VMessDefaultConfig struct {
-	AlterIDs uint16 `json:"alterId"`
 	Level    byte   `json:"level"`
 	Level    byte   `json:"level"`
 }
 }
 
 
 // Build implements Buildable
 // Build implements Buildable
 func (c *VMessDefaultConfig) Build() *inbound.DefaultConfig {
 func (c *VMessDefaultConfig) Build() *inbound.DefaultConfig {
 	config := new(inbound.DefaultConfig)
 	config := new(inbound.DefaultConfig)
-	config.AlterId = uint32(c.AlterIDs)
 	config.Level = uint32(c.Level)
 	config.Level = uint32(c.Level)
 	return config
 	return config
 }
 }
@@ -80,14 +76,11 @@ type VMessInboundConfig struct {
 	Features     *FeaturesConfig     `json:"features"`
 	Features     *FeaturesConfig     `json:"features"`
 	Defaults     *VMessDefaultConfig `json:"default"`
 	Defaults     *VMessDefaultConfig `json:"default"`
 	DetourConfig *VMessDetourConfig  `json:"detour"`
 	DetourConfig *VMessDetourConfig  `json:"detour"`
-	SecureOnly   bool                `json:"disableInsecureEncryption"`
 }
 }
 
 
 // Build implements Buildable
 // Build implements Buildable
 func (c *VMessInboundConfig) Build() (proto.Message, error) {
 func (c *VMessInboundConfig) Build() (proto.Message, error) {
-	config := &inbound.Config{
-		SecureEncryptionOnly: c.SecureOnly,
-	}
+	config := &inbound.Config{}
 
 
 	if c.Defaults != nil {
 	if c.Defaults != nil {
 		config.Default = c.Defaults.Build()
 		config.Default = c.Defaults.Build()

+ 0 - 1
infra/conf/vmess_test.go

@@ -105,7 +105,6 @@ func TestVMessInbound(t *testing.T) {
 				Detour: &inbound.DetourConfig{
 				Detour: &inbound.DetourConfig{
 					To: "tag_to_detour",
 					To: "tag_to_detour",
 				},
 				},
-				SecureEncryptionOnly: true,
 			},
 			},
 		},
 		},
 	})
 	})

+ 0 - 13
proxy/vmess/account.go

@@ -3,7 +3,6 @@ package vmess
 import (
 import (
 	"strings"
 	"strings"
 
 
-	"github.com/xtls/xray-core/common/dice"
 	"github.com/xtls/xray-core/common/protocol"
 	"github.com/xtls/xray-core/common/protocol"
 	"github.com/xtls/xray-core/common/uuid"
 	"github.com/xtls/xray-core/common/uuid"
 )
 )
@@ -12,8 +11,6 @@ import (
 type MemoryAccount struct {
 type MemoryAccount struct {
 	// ID is the main ID of the account.
 	// ID is the main ID of the account.
 	ID *protocol.ID
 	ID *protocol.ID
-	// AlterIDs are the alternative IDs of the account.
-	AlterIDs []*protocol.ID
 	// Security type of the account. Used for client connections.
 	// Security type of the account. Used for client connections.
 	Security protocol.SecurityType
 	Security protocol.SecurityType
 
 
@@ -21,21 +18,12 @@ type MemoryAccount struct {
 	NoTerminationSignal           bool
 	NoTerminationSignal           bool
 }
 }
 
 
-// AnyValidID returns an ID that is either the main ID or one of the alternative IDs if any.
-func (a *MemoryAccount) AnyValidID() *protocol.ID {
-	if len(a.AlterIDs) == 0 {
-		return a.ID
-	}
-	return a.AlterIDs[dice.Roll(len(a.AlterIDs))]
-}
-
 // Equals implements protocol.Account.
 // Equals implements protocol.Account.
 func (a *MemoryAccount) Equals(account protocol.Account) bool {
 func (a *MemoryAccount) Equals(account protocol.Account) bool {
 	vmessAccount, ok := account.(*MemoryAccount)
 	vmessAccount, ok := account.(*MemoryAccount)
 	if !ok {
 	if !ok {
 		return false
 		return false
 	}
 	}
-	// TODO: handle AlterIds difference
 	return a.ID.Equals(vmessAccount.ID)
 	return a.ID.Equals(vmessAccount.ID)
 }
 }
 
 
@@ -55,7 +43,6 @@ func (a *Account) AsAccount() (protocol.Account, error) {
 	}
 	}
 	return &MemoryAccount{
 	return &MemoryAccount{
 		ID:                            protoID,
 		ID:                            protoID,
-		AlterIDs:                      protocol.NewAlterIDs(protoID, uint16(a.AlterId)),
 		Security:                      a.SecuritySettings.GetSecurityType(),
 		Security:                      a.SecuritySettings.GetSecurityType(),
 		AuthenticatedLengthExperiment: AuthenticatedLength,
 		AuthenticatedLengthExperiment: AuthenticatedLength,
 		NoTerminationSignal:           NoTerminationSignal,
 		NoTerminationSignal:           NoTerminationSignal,

+ 15 - 26
proxy/vmess/account.pb.go

@@ -29,8 +29,6 @@ type Account struct {
 	// ID of the account, in the form of a UUID, e.g.,
 	// ID of the account, in the form of a UUID, e.g.,
 	// "66ad4540-b58c-4ad2-9926-ea63445a9b57".
 	// "66ad4540-b58c-4ad2-9926-ea63445a9b57".
 	Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
 	Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
-	// Number of alternative IDs. Client and server must share the same number.
-	AlterId uint32 `protobuf:"varint,2,opt,name=alter_id,json=alterId,proto3" json:"alter_id,omitempty"`
 	// Security settings. Only applies to client side.
 	// Security settings. Only applies to client side.
 	SecuritySettings *protocol.SecurityConfig `protobuf:"bytes,3,opt,name=security_settings,json=securitySettings,proto3" json:"security_settings,omitempty"`
 	SecuritySettings *protocol.SecurityConfig `protobuf:"bytes,3,opt,name=security_settings,json=securitySettings,proto3" json:"security_settings,omitempty"`
 	// Define tests enabled for this account
 	// Define tests enabled for this account
@@ -76,13 +74,6 @@ func (x *Account) GetId() string {
 	return ""
 	return ""
 }
 }
 
 
-func (x *Account) GetAlterId() uint32 {
-	if x != nil {
-		return x.AlterId
-	}
-	return 0
-}
-
 func (x *Account) GetSecuritySettings() *protocol.SecurityConfig {
 func (x *Account) GetSecuritySettings() *protocol.SecurityConfig {
 	if x != nil {
 	if x != nil {
 		return x.SecuritySettings
 		return x.SecuritySettings
@@ -104,24 +95,22 @@ var file_proxy_vmess_account_proto_rawDesc = []byte{
 	0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x10, 0x78, 0x72, 0x61,
 	0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x10, 0x78, 0x72, 0x61,
 	0x79, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x76, 0x6d, 0x65, 0x73, 0x73, 0x1a, 0x1d, 0x63,
 	0x79, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x76, 0x6d, 0x65, 0x73, 0x73, 0x1a, 0x1d, 0x63,
 	0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x68,
 	0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x68,
-	0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xac, 0x01, 0x0a,
+	0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x91, 0x01, 0x0a,
 	0x07, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01,
 	0x07, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x6c, 0x74, 0x65,
-	0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x61, 0x6c, 0x74, 0x65,
-	0x72, 0x49, 0x64, 0x12, 0x51, 0x0a, 0x11, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x5f,
-	0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24,
-	0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f,
-	0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x43, 0x6f,
-	0x6e, 0x66, 0x69, 0x67, 0x52, 0x10, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x53, 0x65,
-	0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x65, 0x73, 0x74, 0x73, 0x5f,
-	0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x74,
-	0x65, 0x73, 0x74, 0x73, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x42, 0x52, 0x0a, 0x14, 0x63,
-	0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x76, 0x6d,
-	0x65, 0x73, 0x73, 0x50, 0x01, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
-	0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65,
-	0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x76, 0x6d, 0x65, 0x73, 0x73, 0xaa, 0x02, 0x10, 0x58,
-	0x72, 0x61, 0x79, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x56, 0x6d, 0x65, 0x73, 0x73, 0x62,
-	0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x51, 0x0a, 0x11, 0x73, 0x65, 0x63, 0x75,
+	0x72, 0x69, 0x74, 0x79, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x03, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
+	0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72,
+	0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x10, 0x73, 0x65, 0x63, 0x75, 0x72,
+	0x69, 0x74, 0x79, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x74,
+	0x65, 0x73, 0x74, 0x73, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x73, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64,
+	0x42, 0x52, 0x0a, 0x14, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f,
+	0x78, 0x79, 0x2e, 0x76, 0x6d, 0x65, 0x73, 0x73, 0x50, 0x01, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68,
+	0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79,
+	0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x76, 0x6d, 0x65, 0x73,
+	0x73, 0xaa, 0x02, 0x10, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x56,
+	0x6d, 0x65, 0x73, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 }
 
 
 var (
 var (

+ 0 - 2
proxy/vmess/account.proto

@@ -12,8 +12,6 @@ message Account {
   // ID of the account, in the form of a UUID, e.g.,
   // ID of the account, in the form of a UUID, e.g.,
   // "66ad4540-b58c-4ad2-9926-ea63445a9b57".
   // "66ad4540-b58c-4ad2-9926-ea63445a9b57".
   string id = 1;
   string id = 1;
-  // Number of alternative IDs. Client and server must share the same number.
-  uint32 alter_id = 2;
   // Security settings. Only applies to client side.
   // Security settings. Only applies to client side.
   xray.common.protocol.SecurityConfig security_settings = 3;
   xray.common.protocol.SecurityConfig security_settings = 3;
   // Define tests enabled for this account
   // Define tests enabled for this account

+ 1 - 28
proxy/vmess/encoding/auth.go

@@ -17,6 +17,7 @@ func Authenticate(b []byte) uint32 {
 	return fnv1hash.Sum32()
 	return fnv1hash.Sum32()
 }
 }
 
 
+// [DEPRECATED 2023-06] 
 type NoOpAuthenticator struct{}
 type NoOpAuthenticator struct{}
 
 
 func (NoOpAuthenticator) NonceSize() int {
 func (NoOpAuthenticator) NonceSize() int {
@@ -37,34 +38,6 @@ func (NoOpAuthenticator) Open(dst, nonce, ciphertext, additionalData []byte) ([]
 	return append(dst[:0], ciphertext...), nil
 	return append(dst[:0], ciphertext...), nil
 }
 }
 
 
-// FnvAuthenticator is an AEAD based on Fnv hash.
-type FnvAuthenticator struct{}
-
-// NonceSize implements AEAD.NonceSize().
-func (*FnvAuthenticator) NonceSize() int {
-	return 0
-}
-
-// Overhead impelements AEAD.Overhead().
-func (*FnvAuthenticator) Overhead() int {
-	return 4
-}
-
-// Seal implements AEAD.Seal().
-func (*FnvAuthenticator) Seal(dst, nonce, plaintext, additionalData []byte) []byte {
-	dst = append(dst, 0, 0, 0, 0)
-	binary.BigEndian.PutUint32(dst, Authenticate(plaintext))
-	return append(dst, plaintext...)
-}
-
-// Open implements AEAD.Open().
-func (*FnvAuthenticator) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
-	if binary.BigEndian.Uint32(ciphertext[:4]) != Authenticate(ciphertext[4:]) {
-		return dst, newError("invalid authentication")
-	}
-	return append(dst, ciphertext[4:]...), nil
-}
-
 // GenerateChacha20Poly1305Key generates a 32-byte key from a given 16-byte array.
 // GenerateChacha20Poly1305Key generates a 32-byte key from a given 16-byte array.
 func GenerateChacha20Poly1305Key(b []byte) []byte {
 func GenerateChacha20Poly1305Key(b []byte) []byte {
 	key := make([]byte, 32)
 	key := make([]byte, 32)

+ 0 - 26
proxy/vmess/encoding/auth_test.go

@@ -1,26 +0,0 @@
-package encoding_test
-
-import (
-	"crypto/rand"
-	"testing"
-
-	"github.com/google/go-cmp/cmp"
-	"github.com/xtls/xray-core/common"
-	. "github.com/xtls/xray-core/proxy/vmess/encoding"
-)
-
-func TestFnvAuth(t *testing.T) {
-	fnvAuth := new(FnvAuthenticator)
-
-	expectedText := make([]byte, 256)
-	_, err := rand.Read(expectedText)
-	common.Must(err)
-
-	buffer := make([]byte, 512)
-	b := fnvAuth.Seal(buffer[:0], nil, expectedText, nil)
-	b, err = fnvAuth.Open(buffer[:0], nil, b, nil)
-	common.Must(err)
-	if r := cmp.Diff(b, expectedText); r != "" {
-		t.Error(r)
-	}
-}

+ 49 - 114
proxy/vmess/encoding/client.go

@@ -5,11 +5,9 @@ import (
 	"context"
 	"context"
 	"crypto/aes"
 	"crypto/aes"
 	"crypto/cipher"
 	"crypto/cipher"
-	"crypto/md5"
 	"crypto/rand"
 	"crypto/rand"
 	"crypto/sha256"
 	"crypto/sha256"
 	"encoding/binary"
 	"encoding/binary"
-	"hash"
 	"hash/fnv"
 	"hash/fnv"
 	"io"
 	"io"
 
 
@@ -20,24 +18,13 @@ import (
 	"github.com/xtls/xray-core/common/dice"
 	"github.com/xtls/xray-core/common/dice"
 	"github.com/xtls/xray-core/common/drain"
 	"github.com/xtls/xray-core/common/drain"
 	"github.com/xtls/xray-core/common/protocol"
 	"github.com/xtls/xray-core/common/protocol"
-	"github.com/xtls/xray-core/common/serial"
 	"github.com/xtls/xray-core/proxy/vmess"
 	"github.com/xtls/xray-core/proxy/vmess"
 	vmessaead "github.com/xtls/xray-core/proxy/vmess/aead"
 	vmessaead "github.com/xtls/xray-core/proxy/vmess/aead"
 	"golang.org/x/crypto/chacha20poly1305"
 	"golang.org/x/crypto/chacha20poly1305"
 )
 )
 
 
-func hashTimestamp(h hash.Hash, t protocol.Timestamp) []byte {
-	common.Must2(serial.WriteUint64(h, uint64(t)))
-	common.Must2(serial.WriteUint64(h, uint64(t)))
-	common.Must2(serial.WriteUint64(h, uint64(t)))
-	common.Must2(serial.WriteUint64(h, uint64(t)))
-	return h.Sum(nil)
-}
-
 // ClientSession stores connection session info for VMess client.
 // ClientSession stores connection session info for VMess client.
 type ClientSession struct {
 type ClientSession struct {
-	isAEAD          bool
-	idHash          protocol.IDHash
 	requestBodyKey  [16]byte
 	requestBodyKey  [16]byte
 	requestBodyIV   [16]byte
 	requestBodyIV   [16]byte
 	responseBodyKey [16]byte
 	responseBodyKey [16]byte
@@ -49,11 +36,8 @@ type ClientSession struct {
 }
 }
 
 
 // NewClientSession creates a new ClientSession.
 // NewClientSession creates a new ClientSession.
-func NewClientSession(ctx context.Context, isAEAD bool, idHash protocol.IDHash, behaviorSeed int64) *ClientSession {
-	session := &ClientSession{
-		isAEAD: isAEAD,
-		idHash: idHash,
-	}
+func NewClientSession(ctx context.Context, behaviorSeed int64) *ClientSession {
+	session := &ClientSession{}
 
 
 	randomBytes := make([]byte, 33) // 16 + 16 + 1
 	randomBytes := make([]byte, 33) // 16 + 16 + 1
 	common.Must2(rand.Read(randomBytes))
 	common.Must2(rand.Read(randomBytes))
@@ -61,15 +45,10 @@ func NewClientSession(ctx context.Context, isAEAD bool, idHash protocol.IDHash,
 	copy(session.requestBodyIV[:], randomBytes[16:32])
 	copy(session.requestBodyIV[:], randomBytes[16:32])
 	session.responseHeader = randomBytes[32]
 	session.responseHeader = randomBytes[32]
 
 
-	if !session.isAEAD {
-		session.responseBodyKey = md5.Sum(session.requestBodyKey[:])
-		session.responseBodyIV = md5.Sum(session.requestBodyIV[:])
-	} else {
-		BodyKey := sha256.Sum256(session.requestBodyKey[:])
-		copy(session.responseBodyKey[:], BodyKey[:16])
-		BodyIV := sha256.Sum256(session.requestBodyIV[:])
-		copy(session.responseBodyIV[:], BodyIV[:16])
-	}
+	BodyKey := sha256.Sum256(session.requestBodyKey[:])
+	copy(session.responseBodyKey[:], BodyKey[:16])
+	BodyIV := sha256.Sum256(session.requestBodyIV[:])
+	copy(session.responseBodyIV[:], BodyIV[:16])
 	{
 	{
 		var err error
 		var err error
 		session.readDrainer, err = drain.NewBehaviorSeedLimitedDrainer(behaviorSeed, 18, 3266, 64)
 		session.readDrainer, err = drain.NewBehaviorSeedLimitedDrainer(behaviorSeed, 18, 3266, 64)
@@ -83,13 +62,7 @@ func NewClientSession(ctx context.Context, isAEAD bool, idHash protocol.IDHash,
 }
 }
 
 
 func (c *ClientSession) EncodeRequestHeader(header *protocol.RequestHeader, writer io.Writer) error {
 func (c *ClientSession) EncodeRequestHeader(header *protocol.RequestHeader, writer io.Writer) error {
-	timestamp := protocol.NewTimestampGenerator(protocol.NowTime(), 30)()
 	account := header.User.Account.(*vmess.MemoryAccount)
 	account := header.User.Account.(*vmess.MemoryAccount)
-	if !c.isAEAD {
-		idHash := c.idHash(account.AnyValidID().Bytes())
-		common.Must2(serial.WriteUint64(idHash, uint64(timestamp)))
-		common.Must2(writer.Write(idHash.Sum(nil)))
-	}
 
 
 	buffer := buf.New()
 	buffer := buf.New()
 	defer buffer.Release()
 	defer buffer.Release()
@@ -121,17 +94,10 @@ func (c *ClientSession) EncodeRequestHeader(header *protocol.RequestHeader, writ
 		fnv1a.Sum(hashBytes[:0])
 		fnv1a.Sum(hashBytes[:0])
 	}
 	}
 
 
-	if !c.isAEAD {
-		iv := hashTimestamp(md5.New(), timestamp)
-		aesStream := crypto.NewAesEncryptionStream(account.ID.CmdKey(), iv)
-		aesStream.XORKeyStream(buffer.Bytes(), buffer.Bytes())
-		common.Must2(writer.Write(buffer.Bytes()))
-	} else {
-		var fixedLengthCmdKey [16]byte
-		copy(fixedLengthCmdKey[:], account.ID.CmdKey())
-		vmessout := vmessaead.SealVMessAEADHeader(fixedLengthCmdKey, buffer.Bytes())
-		common.Must2(io.Copy(writer, bytes.NewReader(vmessout)))
-	}
+	var fixedLengthCmdKey [16]byte
+	copy(fixedLengthCmdKey[:], account.ID.CmdKey())
+	vmessout := vmessaead.SealVMessAEADHeader(fixedLengthCmdKey, buffer.Bytes())
+	common.Must2(io.Copy(writer, bytes.NewReader(vmessout)))
 
 
 	return nil
 	return nil
 }
 }
@@ -165,19 +131,6 @@ func (c *ClientSession) EncodeRequestBody(request *protocol.RequestHeader, write
 		}
 		}
 
 
 		return buf.NewWriter(writer), nil
 		return buf.NewWriter(writer), nil
-	case protocol.SecurityType_LEGACY:
-		aesStream := crypto.NewAesEncryptionStream(c.requestBodyKey[:], c.requestBodyIV[:])
-		cryptionWriter := crypto.NewCryptionWriter(aesStream, writer)
-		if request.Option.Has(protocol.RequestOptionChunkStream) {
-			auth := &crypto.AEADAuthenticator{
-				AEAD:                    new(FnvAuthenticator),
-				NonceGenerator:          crypto.GenerateEmptyBytes(),
-				AdditionalDataGenerator: crypto.GenerateEmptyBytes(),
-			}
-			return crypto.NewAuthenticationWriter(auth, sizeParser, cryptionWriter, request.Command.TransferType(), padding), nil
-		}
-
-		return &buf.SequentialWriter{Writer: cryptionWriter}, nil
 	case protocol.SecurityType_AES128_GCM:
 	case protocol.SecurityType_AES128_GCM:
 		aead := crypto.NewAesGcm(c.requestBodyKey[:])
 		aead := crypto.NewAesGcm(c.requestBodyKey[:])
 		auth := &crypto.AEADAuthenticator{
 		auth := &crypto.AEADAuthenticator{
@@ -225,53 +178,48 @@ func (c *ClientSession) EncodeRequestBody(request *protocol.RequestHeader, write
 }
 }
 
 
 func (c *ClientSession) DecodeResponseHeader(reader io.Reader) (*protocol.ResponseHeader, error) {
 func (c *ClientSession) DecodeResponseHeader(reader io.Reader) (*protocol.ResponseHeader, error) {
-	if !c.isAEAD {
-		aesStream := crypto.NewAesDecryptionStream(c.responseBodyKey[:], c.responseBodyIV[:])
-		c.responseReader = crypto.NewCryptionReader(aesStream, reader)
-	} else {
-		aeadResponseHeaderLengthEncryptionKey := vmessaead.KDF16(c.responseBodyKey[:], vmessaead.KDFSaltConstAEADRespHeaderLenKey)
-		aeadResponseHeaderLengthEncryptionIV := vmessaead.KDF(c.responseBodyIV[:], vmessaead.KDFSaltConstAEADRespHeaderLenIV)[:12]
-
-		aeadResponseHeaderLengthEncryptionKeyAESBlock := common.Must2(aes.NewCipher(aeadResponseHeaderLengthEncryptionKey)).(cipher.Block)
-		aeadResponseHeaderLengthEncryptionAEAD := common.Must2(cipher.NewGCM(aeadResponseHeaderLengthEncryptionKeyAESBlock)).(cipher.AEAD)
-
-		var aeadEncryptedResponseHeaderLength [18]byte
-		var decryptedResponseHeaderLength int
-		var decryptedResponseHeaderLengthBinaryDeserializeBuffer uint16
-
-		if n, err := io.ReadFull(reader, aeadEncryptedResponseHeaderLength[:]); err != nil {
-			c.readDrainer.AcknowledgeReceive(n)
-			return nil, drain.WithError(c.readDrainer, reader, newError("Unable to Read Header Len").Base(err))
-		} else { // nolint: golint
-			c.readDrainer.AcknowledgeReceive(n)
-		}
-		if decryptedResponseHeaderLengthBinaryBuffer, err := aeadResponseHeaderLengthEncryptionAEAD.Open(nil, aeadResponseHeaderLengthEncryptionIV, aeadEncryptedResponseHeaderLength[:], nil); err != nil {
-			return nil, drain.WithError(c.readDrainer, reader, newError("Failed To Decrypt Length").Base(err))
-		} else { // nolint: golint
-			common.Must(binary.Read(bytes.NewReader(decryptedResponseHeaderLengthBinaryBuffer), binary.BigEndian, &decryptedResponseHeaderLengthBinaryDeserializeBuffer))
-			decryptedResponseHeaderLength = int(decryptedResponseHeaderLengthBinaryDeserializeBuffer)
-		}
+	aeadResponseHeaderLengthEncryptionKey := vmessaead.KDF16(c.responseBodyKey[:], vmessaead.KDFSaltConstAEADRespHeaderLenKey)
+	aeadResponseHeaderLengthEncryptionIV := vmessaead.KDF(c.responseBodyIV[:], vmessaead.KDFSaltConstAEADRespHeaderLenIV)[:12]
 
 
-		aeadResponseHeaderPayloadEncryptionKey := vmessaead.KDF16(c.responseBodyKey[:], vmessaead.KDFSaltConstAEADRespHeaderPayloadKey)
-		aeadResponseHeaderPayloadEncryptionIV := vmessaead.KDF(c.responseBodyIV[:], vmessaead.KDFSaltConstAEADRespHeaderPayloadIV)[:12]
+	aeadResponseHeaderLengthEncryptionKeyAESBlock := common.Must2(aes.NewCipher(aeadResponseHeaderLengthEncryptionKey)).(cipher.Block)
+	aeadResponseHeaderLengthEncryptionAEAD := common.Must2(cipher.NewGCM(aeadResponseHeaderLengthEncryptionKeyAESBlock)).(cipher.AEAD)
 
 
-		aeadResponseHeaderPayloadEncryptionKeyAESBlock := common.Must2(aes.NewCipher(aeadResponseHeaderPayloadEncryptionKey)).(cipher.Block)
-		aeadResponseHeaderPayloadEncryptionAEAD := common.Must2(cipher.NewGCM(aeadResponseHeaderPayloadEncryptionKeyAESBlock)).(cipher.AEAD)
+	var aeadEncryptedResponseHeaderLength [18]byte
+	var decryptedResponseHeaderLength int
+	var decryptedResponseHeaderLengthBinaryDeserializeBuffer uint16
 
 
-		encryptedResponseHeaderBuffer := make([]byte, decryptedResponseHeaderLength+16)
+	if n, err := io.ReadFull(reader, aeadEncryptedResponseHeaderLength[:]); err != nil {
+		c.readDrainer.AcknowledgeReceive(n)
+		return nil, drain.WithError(c.readDrainer, reader, newError("Unable to Read Header Len").Base(err))
+	} else { // nolint: golint
+		c.readDrainer.AcknowledgeReceive(n)
+	}
+	if decryptedResponseHeaderLengthBinaryBuffer, err := aeadResponseHeaderLengthEncryptionAEAD.Open(nil, aeadResponseHeaderLengthEncryptionIV, aeadEncryptedResponseHeaderLength[:], nil); err != nil {
+		return nil, drain.WithError(c.readDrainer, reader, newError("Failed To Decrypt Length").Base(err))
+	} else { // nolint: golint
+		common.Must(binary.Read(bytes.NewReader(decryptedResponseHeaderLengthBinaryBuffer), binary.BigEndian, &decryptedResponseHeaderLengthBinaryDeserializeBuffer))
+		decryptedResponseHeaderLength = int(decryptedResponseHeaderLengthBinaryDeserializeBuffer)
+	}
 
 
-		if n, err := io.ReadFull(reader, encryptedResponseHeaderBuffer); err != nil {
-			c.readDrainer.AcknowledgeReceive(n)
-			return nil, drain.WithError(c.readDrainer, reader, newError("Unable to Read Header Data").Base(err))
-		} else { // nolint: golint
-			c.readDrainer.AcknowledgeReceive(n)
-		}
+	aeadResponseHeaderPayloadEncryptionKey := vmessaead.KDF16(c.responseBodyKey[:], vmessaead.KDFSaltConstAEADRespHeaderPayloadKey)
+	aeadResponseHeaderPayloadEncryptionIV := vmessaead.KDF(c.responseBodyIV[:], vmessaead.KDFSaltConstAEADRespHeaderPayloadIV)[:12]
 
 
-		if decryptedResponseHeaderBuffer, err := aeadResponseHeaderPayloadEncryptionAEAD.Open(nil, aeadResponseHeaderPayloadEncryptionIV, encryptedResponseHeaderBuffer, nil); err != nil {
-			return nil, drain.WithError(c.readDrainer, reader, newError("Failed To Decrypt Payload").Base(err))
-		} else { // nolint: golint
-			c.responseReader = bytes.NewReader(decryptedResponseHeaderBuffer)
-		}
+	aeadResponseHeaderPayloadEncryptionKeyAESBlock := common.Must2(aes.NewCipher(aeadResponseHeaderPayloadEncryptionKey)).(cipher.Block)
+	aeadResponseHeaderPayloadEncryptionAEAD := common.Must2(cipher.NewGCM(aeadResponseHeaderPayloadEncryptionKeyAESBlock)).(cipher.AEAD)
+
+	encryptedResponseHeaderBuffer := make([]byte, decryptedResponseHeaderLength+16)
+
+	if n, err := io.ReadFull(reader, encryptedResponseHeaderBuffer); err != nil {
+		c.readDrainer.AcknowledgeReceive(n)
+		return nil, drain.WithError(c.readDrainer, reader, newError("Unable to Read Header Data").Base(err))
+	} else { // nolint: golint
+		c.readDrainer.AcknowledgeReceive(n)
+	}
+
+	if decryptedResponseHeaderBuffer, err := aeadResponseHeaderPayloadEncryptionAEAD.Open(nil, aeadResponseHeaderPayloadEncryptionIV, encryptedResponseHeaderBuffer, nil); err != nil {
+		return nil, drain.WithError(c.readDrainer, reader, newError("Failed To Decrypt Payload").Base(err))
+	} else { // nolint: golint
+		c.responseReader = bytes.NewReader(decryptedResponseHeaderBuffer)
 	}
 	}
 
 
 	buffer := buf.StackNew()
 	buffer := buf.StackNew()
@@ -302,10 +250,8 @@ func (c *ClientSession) DecodeResponseHeader(reader io.Reader) (*protocol.Respon
 			header.Command = command
 			header.Command = command
 		}
 		}
 	}
 	}
-	if c.isAEAD {
-		aesStream := crypto.NewAesDecryptionStream(c.responseBodyKey[:], c.responseBodyIV[:])
-		c.responseReader = crypto.NewCryptionReader(aesStream, reader)
-	}
+	aesStream := crypto.NewAesDecryptionStream(c.responseBodyKey[:], c.responseBodyIV[:])
+	c.responseReader = crypto.NewCryptionReader(aesStream, reader)
 	return header, nil
 	return header, nil
 }
 }
 
 
@@ -340,17 +286,6 @@ func (c *ClientSession) DecodeResponseBody(request *protocol.RequestHeader, read
 		}
 		}
 
 
 		return buf.NewReader(reader), nil
 		return buf.NewReader(reader), nil
-	case protocol.SecurityType_LEGACY:
-		if request.Option.Has(protocol.RequestOptionChunkStream) {
-			auth := &crypto.AEADAuthenticator{
-				AEAD:                    new(FnvAuthenticator),
-				NonceGenerator:          crypto.GenerateEmptyBytes(),
-				AdditionalDataGenerator: crypto.GenerateEmptyBytes(),
-			}
-			return crypto.NewAuthenticationReader(auth, sizeParser, c.responseReader, request.Command.TransferType(), padding), nil
-		}
-
-		return buf.NewReader(c.responseReader), nil
 	case protocol.SecurityType_AES128_GCM:
 	case protocol.SecurityType_AES128_GCM:
 		aead := crypto.NewAesGcm(c.responseBodyKey[:])
 		aead := crypto.NewAesGcm(c.responseBodyKey[:])
 
 

+ 2 - 7
proxy/vmess/encoding/commands.go

@@ -101,7 +101,7 @@ func (f *CommandSwitchAccountFactory) Marshal(command interface{}, writer io.Wri
 
 
 	idBytes := cmd.ID.Bytes()
 	idBytes := cmd.ID.Bytes()
 	common.Must2(writer.Write(idBytes))
 	common.Must2(writer.Write(idBytes))
-	common.Must2(serial.WriteUint16(writer, cmd.AlterIds))
+	common.Must2(serial.WriteUint16(writer, 0)) // compatible with legacy alterId
 	common.Must2(writer.Write([]byte{byte(cmd.Level)}))
 	common.Must2(writer.Write([]byte{byte(cmd.Level)}))
 
 
 	common.Must2(writer.Write([]byte{cmd.ValidMin}))
 	common.Must2(writer.Write([]byte{cmd.ValidMin}))
@@ -130,12 +130,7 @@ func (f *CommandSwitchAccountFactory) Unmarshal(data []byte) (interface{}, error
 		return nil, ErrInsufficientLength
 		return nil, ErrInsufficientLength
 	}
 	}
 	cmd.ID, _ = uuid.ParseBytes(data[idStart : idStart+16])
 	cmd.ID, _ = uuid.ParseBytes(data[idStart : idStart+16])
-	alterIDStart := idStart + 16
-	if len(data) < alterIDStart+2 {
-		return nil, ErrInsufficientLength
-	}
-	cmd.AlterIds = binary.BigEndian.Uint16(data[alterIDStart : alterIDStart+2])
-	levelStart := alterIDStart + 2
+	levelStart := idStart + 16 + 2
 	if len(data) < levelStart+1 {
 	if len(data) < levelStart+1 {
 		return nil, ErrInsufficientLength
 		return nil, ErrInsufficientLength
 	}
 	}

+ 0 - 2
proxy/vmess/encoding/commands_test.go

@@ -16,7 +16,6 @@ func TestSwitchAccount(t *testing.T) {
 	sa := &protocol.CommandSwitchAccount{
 	sa := &protocol.CommandSwitchAccount{
 		Port:     1234,
 		Port:     1234,
 		ID:       uuid.New(),
 		ID:       uuid.New(),
-		AlterIds: 1024,
 		Level:    128,
 		Level:    128,
 		ValidMin: 16,
 		ValidMin: 16,
 	}
 	}
@@ -40,7 +39,6 @@ func TestSwitchAccountBugOffByOne(t *testing.T) {
 	sa := &protocol.CommandSwitchAccount{
 	sa := &protocol.CommandSwitchAccount{
 		Port:     1234,
 		Port:     1234,
 		ID:       uuid.New(),
 		ID:       uuid.New(),
-		AlterIds: 1024,
 		Level:    128,
 		Level:    128,
 		ValidMin: 16,
 		ValidMin: 16,
 	}
 	}

+ 6 - 6
proxy/vmess/encoding/encoding_test.go

@@ -41,7 +41,7 @@ func TestRequestSerialization(t *testing.T) {
 	}
 	}
 
 
 	buffer := buf.New()
 	buffer := buf.New()
-	client := NewClientSession(context.TODO(), true, protocol.DefaultIDHash, 0)
+	client := NewClientSession(context.TODO(), 0)
 	common.Must(client.EncodeRequestHeader(expectedRequest, buffer))
 	common.Must(client.EncodeRequestHeader(expectedRequest, buffer))
 
 
 	buffer2 := buf.New()
 	buffer2 := buf.New()
@@ -50,7 +50,7 @@ func TestRequestSerialization(t *testing.T) {
 	sessionHistory := NewSessionHistory()
 	sessionHistory := NewSessionHistory()
 	defer common.Close(sessionHistory)
 	defer common.Close(sessionHistory)
 
 
-	userValidator := vmess.NewTimedUserValidator(protocol.DefaultIDHash)
+	userValidator := vmess.NewTimedUserValidator()
 	userValidator.Add(user)
 	userValidator.Add(user)
 	defer common.Close(userValidator)
 	defer common.Close(userValidator)
 
 
@@ -90,7 +90,7 @@ func TestInvalidRequest(t *testing.T) {
 	}
 	}
 
 
 	buffer := buf.New()
 	buffer := buf.New()
-	client := NewClientSession(context.TODO(), true, protocol.DefaultIDHash, 0)
+	client := NewClientSession(context.TODO(), 0)
 	common.Must(client.EncodeRequestHeader(expectedRequest, buffer))
 	common.Must(client.EncodeRequestHeader(expectedRequest, buffer))
 
 
 	buffer2 := buf.New()
 	buffer2 := buf.New()
@@ -99,7 +99,7 @@ func TestInvalidRequest(t *testing.T) {
 	sessionHistory := NewSessionHistory()
 	sessionHistory := NewSessionHistory()
 	defer common.Close(sessionHistory)
 	defer common.Close(sessionHistory)
 
 
-	userValidator := vmess.NewTimedUserValidator(protocol.DefaultIDHash)
+	userValidator := vmess.NewTimedUserValidator()
 	userValidator.Add(user)
 	userValidator.Add(user)
 	defer common.Close(userValidator)
 	defer common.Close(userValidator)
 
 
@@ -130,7 +130,7 @@ func TestMuxRequest(t *testing.T) {
 	}
 	}
 
 
 	buffer := buf.New()
 	buffer := buf.New()
-	client := NewClientSession(context.TODO(), true, protocol.DefaultIDHash, 0)
+	client := NewClientSession(context.TODO(), 0)
 	common.Must(client.EncodeRequestHeader(expectedRequest, buffer))
 	common.Must(client.EncodeRequestHeader(expectedRequest, buffer))
 
 
 	buffer2 := buf.New()
 	buffer2 := buf.New()
@@ -139,7 +139,7 @@ func TestMuxRequest(t *testing.T) {
 	sessionHistory := NewSessionHistory()
 	sessionHistory := NewSessionHistory()
 	defer common.Close(sessionHistory)
 	defer common.Close(sessionHistory)
 
 
-	userValidator := vmess.NewTimedUserValidator(protocol.DefaultIDHash)
+	userValidator := vmess.NewTimedUserValidator()
 	userValidator.Add(user)
 	userValidator.Add(user)
 	defer common.Close(userValidator)
 	defer common.Close(userValidator)
 
 

+ 23 - 119
proxy/vmess/encoding/server.go

@@ -4,7 +4,6 @@ import (
 	"bytes"
 	"bytes"
 	"crypto/aes"
 	"crypto/aes"
 	"crypto/cipher"
 	"crypto/cipher"
-	"crypto/md5"
 	"crypto/sha256"
 	"crypto/sha256"
 	"encoding/binary"
 	"encoding/binary"
 	"hash/fnv"
 	"hash/fnv"
@@ -102,10 +101,6 @@ type ServerSession struct {
 	responseBodyIV  [16]byte
 	responseBodyIV  [16]byte
 	responseWriter  io.Writer
 	responseWriter  io.Writer
 	responseHeader  byte
 	responseHeader  byte
-
-	isAEADRequest bool
-
-	isAEADForced bool
 }
 }
 
 
 // NewServerSession creates a new ServerSession, using the given UserValidator.
 // NewServerSession creates a new ServerSession, using the given UserValidator.
@@ -117,17 +112,12 @@ func NewServerSession(validator *vmess.TimedUserValidator, sessionHistory *Sessi
 	}
 	}
 }
 }
 
 
-// SetAEADForced sets isAEADForced for a ServerSession.
-func (s *ServerSession) SetAEADForced(isAEADForced bool) {
-	s.isAEADForced = isAEADForced
-}
-
 func parseSecurityType(b byte) protocol.SecurityType {
 func parseSecurityType(b byte) protocol.SecurityType {
 	if _, f := protocol.SecurityType_name[int32(b)]; f {
 	if _, f := protocol.SecurityType_name[int32(b)]; f {
 		st := protocol.SecurityType(b)
 		st := protocol.SecurityType(b)
 		// For backward compatibility.
 		// For backward compatibility.
 		if st == protocol.SecurityType_UNKNOWN {
 		if st == protocol.SecurityType_UNKNOWN {
-			st = protocol.SecurityType_LEGACY
+			st = protocol.SecurityType_AUTO
 		}
 		}
 		return st
 		return st
 	}
 	}
@@ -183,26 +173,6 @@ func (s *ServerSession) DecodeRequestHeader(reader io.Reader, isDrain bool) (*pr
 			}
 			}
 		}
 		}
 		decryptor = bytes.NewReader(aeadData)
 		decryptor = bytes.NewReader(aeadData)
-		s.isAEADRequest = true
-
-	case errorAEAD == vmessaead.ErrNotFound:
-		userLegacy, timestamp, valid, userValidationError := s.userValidator.Get(buffer.Bytes())
-		if !valid || userValidationError != nil {
-			return nil, drainConnection(newError("invalid user").Base(userValidationError))
-		}
-		if s.isAEADForced {
-			return nil, drainConnection(newError("invalid user: VMessAEAD is enforced and a non VMessAEAD connection is received. You can still disable this security feature with environment variable xray.vmess.aead.forced = false . You will not be able to enable legacy header workaround in the future."))
-		}
-		if s.userValidator.ShouldShowLegacyWarn() {
-			newError("Critical Warning: potentially invalid user: a non VMessAEAD connection is received. From 2022 Jan 1st, this kind of connection will be rejected by default. You should update or replace your client software now. This message will not be shown for further violation on this inbound.").AtWarning().WriteToLog()
-		}
-		user = userLegacy
-		iv := hashTimestamp(md5.New(), timestamp)
-		vmessAccount = userLegacy.Account.(*vmess.MemoryAccount)
-
-		aesStream := crypto.NewAesDecryptionStream(vmessAccount.ID.CmdKey(), iv)
-		decryptor = crypto.NewCryptionReader(aesStream, reader)
-
 	default:
 	default:
 		return nil, drainConnection(newError("invalid user").Base(errorAEAD))
 		return nil, drainConnection(newError("invalid user").Base(errorAEAD))
 	}
 	}
@@ -225,15 +195,7 @@ func (s *ServerSession) DecodeRequestHeader(reader io.Reader, isDrain bool) (*pr
 	sid.key = s.requestBodyKey
 	sid.key = s.requestBodyKey
 	sid.nonce = s.requestBodyIV
 	sid.nonce = s.requestBodyIV
 	if !s.sessionHistory.addIfNotExits(sid) {
 	if !s.sessionHistory.addIfNotExits(sid) {
-		if !s.isAEADRequest {
-			drainErr := s.userValidator.BurnTaintFuse(fixedSizeAuthID[:])
-			if drainErr != nil {
-				return nil, drainConnection(newError("duplicated session id, possibly under replay attack, and failed to taint userHash").Base(drainErr))
-			}
-			return nil, drainConnection(newError("duplicated session id, possibly under replay attack, userHash tainted"))
-		} else {
-			return nil, newError("duplicated session id, possibly under replay attack, but this is a AEAD request")
-		}
+		return nil, newError("duplicated session id, possibly under replay attack, but this is a AEAD request")
 	}
 	}
 
 
 	s.responseHeader = buffer.Byte(33)             // 1 byte
 	s.responseHeader = buffer.Byte(33)             // 1 byte
@@ -257,25 +219,11 @@ func (s *ServerSession) DecodeRequestHeader(reader io.Reader, isDrain bool) (*pr
 
 
 	if paddingLen > 0 {
 	if paddingLen > 0 {
 		if _, err := buffer.ReadFullFrom(decryptor, int32(paddingLen)); err != nil {
 		if _, err := buffer.ReadFullFrom(decryptor, int32(paddingLen)); err != nil {
-			if !s.isAEADRequest {
-				burnErr := s.userValidator.BurnTaintFuse(fixedSizeAuthID[:])
-				if burnErr != nil {
-					return nil, newError("failed to read padding, failed to taint userHash").Base(burnErr).Base(err)
-				}
-				return nil, newError("failed to read padding, userHash tainted").Base(err)
-			}
 			return nil, newError("failed to read padding").Base(err)
 			return nil, newError("failed to read padding").Base(err)
 		}
 		}
 	}
 	}
 
 
 	if _, err := buffer.ReadFullFrom(decryptor, 4); err != nil {
 	if _, err := buffer.ReadFullFrom(decryptor, 4); err != nil {
-		if !s.isAEADRequest {
-			burnErr := s.userValidator.BurnTaintFuse(fixedSizeAuthID[:])
-			if burnErr != nil {
-				return nil, newError("failed to read checksum, failed to taint userHash").Base(burnErr).Base(err)
-			}
-			return nil, newError("failed to read checksum, userHash tainted").Base(err)
-		}
 		return nil, newError("failed to read checksum").Base(err)
 		return nil, newError("failed to read checksum").Base(err)
 	}
 	}
 
 
@@ -285,17 +233,7 @@ func (s *ServerSession) DecodeRequestHeader(reader io.Reader, isDrain bool) (*pr
 	expectedHash := binary.BigEndian.Uint32(buffer.BytesFrom(-4))
 	expectedHash := binary.BigEndian.Uint32(buffer.BytesFrom(-4))
 
 
 	if actualHash != expectedHash {
 	if actualHash != expectedHash {
-		if !s.isAEADRequest {
-			Autherr := newError("invalid auth, legacy userHash tainted")
-			burnErr := s.userValidator.BurnTaintFuse(fixedSizeAuthID[:])
-			if burnErr != nil {
-				Autherr = newError("invalid auth, can't taint legacy userHash").Base(burnErr)
-			}
-			// It is possible that we are under attack described in https://github.com/xray/xray-core/issues/2523
-			return nil, drainConnection(Autherr)
-		} else {
-			return nil, newError("invalid auth, but this is a AEAD request")
-		}
+		return nil, newError("invalid auth, but this is a AEAD request")
 	}
 	}
 
 
 	if request.Address == nil {
 	if request.Address == nil {
@@ -340,19 +278,6 @@ func (s *ServerSession) DecodeRequestBody(request *protocol.RequestHeader, reade
 		}
 		}
 		return buf.NewReader(reader), nil
 		return buf.NewReader(reader), nil
 
 
-	case protocol.SecurityType_LEGACY:
-		aesStream := crypto.NewAesDecryptionStream(s.requestBodyKey[:], s.requestBodyIV[:])
-		cryptionReader := crypto.NewCryptionReader(aesStream, reader)
-		if request.Option.Has(protocol.RequestOptionChunkStream) {
-			auth := &crypto.AEADAuthenticator{
-				AEAD:                    new(FnvAuthenticator),
-				NonceGenerator:          crypto.GenerateEmptyBytes(),
-				AdditionalDataGenerator: crypto.GenerateEmptyBytes(),
-			}
-			return crypto.NewAuthenticationReader(auth, sizeParser, cryptionReader, request.Command.TransferType(), padding), nil
-		}
-		return buf.NewReader(cryptionReader), nil
-
 	case protocol.SecurityType_AES128_GCM:
 	case protocol.SecurityType_AES128_GCM:
 		aead := crypto.NewAesGcm(s.requestBodyKey[:])
 		aead := crypto.NewAesGcm(s.requestBodyKey[:])
 		auth := &crypto.AEADAuthenticator{
 		auth := &crypto.AEADAuthenticator{
@@ -403,25 +328,17 @@ func (s *ServerSession) DecodeRequestBody(request *protocol.RequestHeader, reade
 // EncodeResponseHeader writes encoded response header into the given writer.
 // EncodeResponseHeader writes encoded response header into the given writer.
 func (s *ServerSession) EncodeResponseHeader(header *protocol.ResponseHeader, writer io.Writer) {
 func (s *ServerSession) EncodeResponseHeader(header *protocol.ResponseHeader, writer io.Writer) {
 	var encryptionWriter io.Writer
 	var encryptionWriter io.Writer
-	if !s.isAEADRequest {
-		s.responseBodyKey = md5.Sum(s.requestBodyKey[:])
-		s.responseBodyIV = md5.Sum(s.requestBodyIV[:])
-	} else {
-		BodyKey := sha256.Sum256(s.requestBodyKey[:])
-		copy(s.responseBodyKey[:], BodyKey[:16])
-		BodyIV := sha256.Sum256(s.requestBodyIV[:])
-		copy(s.responseBodyIV[:], BodyIV[:16])
-	}
+	BodyKey := sha256.Sum256(s.requestBodyKey[:])
+	copy(s.responseBodyKey[:], BodyKey[:16])
+	BodyIV := sha256.Sum256(s.requestBodyIV[:])
+	copy(s.responseBodyIV[:], BodyIV[:16])
 
 
 	aesStream := crypto.NewAesEncryptionStream(s.responseBodyKey[:], s.responseBodyIV[:])
 	aesStream := crypto.NewAesEncryptionStream(s.responseBodyKey[:], s.responseBodyIV[:])
 	encryptionWriter = crypto.NewCryptionWriter(aesStream, writer)
 	encryptionWriter = crypto.NewCryptionWriter(aesStream, writer)
 	s.responseWriter = encryptionWriter
 	s.responseWriter = encryptionWriter
 
 
 	aeadEncryptedHeaderBuffer := bytes.NewBuffer(nil)
 	aeadEncryptedHeaderBuffer := bytes.NewBuffer(nil)
-
-	if s.isAEADRequest {
-		encryptionWriter = aeadEncryptedHeaderBuffer
-	}
+	encryptionWriter = aeadEncryptedHeaderBuffer
 
 
 	common.Must2(encryptionWriter.Write([]byte{s.responseHeader, byte(header.Option)}))
 	common.Must2(encryptionWriter.Write([]byte{s.responseHeader, byte(header.Option)}))
 	err := MarshalCommand(header.Command, encryptionWriter)
 	err := MarshalCommand(header.Command, encryptionWriter)
@@ -429,31 +346,29 @@ func (s *ServerSession) EncodeResponseHeader(header *protocol.ResponseHeader, wr
 		common.Must2(encryptionWriter.Write([]byte{0x00, 0x00}))
 		common.Must2(encryptionWriter.Write([]byte{0x00, 0x00}))
 	}
 	}
 
 
-	if s.isAEADRequest {
-		aeadResponseHeaderLengthEncryptionKey := vmessaead.KDF16(s.responseBodyKey[:], vmessaead.KDFSaltConstAEADRespHeaderLenKey)
-		aeadResponseHeaderLengthEncryptionIV := vmessaead.KDF(s.responseBodyIV[:], vmessaead.KDFSaltConstAEADRespHeaderLenIV)[:12]
+	aeadResponseHeaderLengthEncryptionKey := vmessaead.KDF16(s.responseBodyKey[:], vmessaead.KDFSaltConstAEADRespHeaderLenKey)
+	aeadResponseHeaderLengthEncryptionIV := vmessaead.KDF(s.responseBodyIV[:], vmessaead.KDFSaltConstAEADRespHeaderLenIV)[:12]
 
 
-		aeadResponseHeaderLengthEncryptionKeyAESBlock := common.Must2(aes.NewCipher(aeadResponseHeaderLengthEncryptionKey)).(cipher.Block)
-		aeadResponseHeaderLengthEncryptionAEAD := common.Must2(cipher.NewGCM(aeadResponseHeaderLengthEncryptionKeyAESBlock)).(cipher.AEAD)
+	aeadResponseHeaderLengthEncryptionKeyAESBlock := common.Must2(aes.NewCipher(aeadResponseHeaderLengthEncryptionKey)).(cipher.Block)
+	aeadResponseHeaderLengthEncryptionAEAD := common.Must2(cipher.NewGCM(aeadResponseHeaderLengthEncryptionKeyAESBlock)).(cipher.AEAD)
 
 
-		aeadResponseHeaderLengthEncryptionBuffer := bytes.NewBuffer(nil)
+	aeadResponseHeaderLengthEncryptionBuffer := bytes.NewBuffer(nil)
 
 
-		decryptedResponseHeaderLengthBinaryDeserializeBuffer := uint16(aeadEncryptedHeaderBuffer.Len())
+	decryptedResponseHeaderLengthBinaryDeserializeBuffer := uint16(aeadEncryptedHeaderBuffer.Len())
 
 
-		common.Must(binary.Write(aeadResponseHeaderLengthEncryptionBuffer, binary.BigEndian, decryptedResponseHeaderLengthBinaryDeserializeBuffer))
+	common.Must(binary.Write(aeadResponseHeaderLengthEncryptionBuffer, binary.BigEndian, decryptedResponseHeaderLengthBinaryDeserializeBuffer))
 
 
-		AEADEncryptedLength := aeadResponseHeaderLengthEncryptionAEAD.Seal(nil, aeadResponseHeaderLengthEncryptionIV, aeadResponseHeaderLengthEncryptionBuffer.Bytes(), nil)
-		common.Must2(io.Copy(writer, bytes.NewReader(AEADEncryptedLength)))
+	AEADEncryptedLength := aeadResponseHeaderLengthEncryptionAEAD.Seal(nil, aeadResponseHeaderLengthEncryptionIV, aeadResponseHeaderLengthEncryptionBuffer.Bytes(), nil)
+	common.Must2(io.Copy(writer, bytes.NewReader(AEADEncryptedLength)))
 
 
-		aeadResponseHeaderPayloadEncryptionKey := vmessaead.KDF16(s.responseBodyKey[:], vmessaead.KDFSaltConstAEADRespHeaderPayloadKey)
-		aeadResponseHeaderPayloadEncryptionIV := vmessaead.KDF(s.responseBodyIV[:], vmessaead.KDFSaltConstAEADRespHeaderPayloadIV)[:12]
+	aeadResponseHeaderPayloadEncryptionKey := vmessaead.KDF16(s.responseBodyKey[:], vmessaead.KDFSaltConstAEADRespHeaderPayloadKey)
+	aeadResponseHeaderPayloadEncryptionIV := vmessaead.KDF(s.responseBodyIV[:], vmessaead.KDFSaltConstAEADRespHeaderPayloadIV)[:12]
 
 
-		aeadResponseHeaderPayloadEncryptionKeyAESBlock := common.Must2(aes.NewCipher(aeadResponseHeaderPayloadEncryptionKey)).(cipher.Block)
-		aeadResponseHeaderPayloadEncryptionAEAD := common.Must2(cipher.NewGCM(aeadResponseHeaderPayloadEncryptionKeyAESBlock)).(cipher.AEAD)
+	aeadResponseHeaderPayloadEncryptionKeyAESBlock := common.Must2(aes.NewCipher(aeadResponseHeaderPayloadEncryptionKey)).(cipher.Block)
+	aeadResponseHeaderPayloadEncryptionAEAD := common.Must2(cipher.NewGCM(aeadResponseHeaderPayloadEncryptionKeyAESBlock)).(cipher.AEAD)
 
 
-		aeadEncryptedHeaderPayload := aeadResponseHeaderPayloadEncryptionAEAD.Seal(nil, aeadResponseHeaderPayloadEncryptionIV, aeadEncryptedHeaderBuffer.Bytes(), nil)
-		common.Must2(io.Copy(writer, bytes.NewReader(aeadEncryptedHeaderPayload)))
-	}
+	aeadEncryptedHeaderPayload := aeadResponseHeaderPayloadEncryptionAEAD.Seal(nil, aeadResponseHeaderPayloadEncryptionIV, aeadEncryptedHeaderBuffer.Bytes(), nil)
+	common.Must2(io.Copy(writer, bytes.NewReader(aeadEncryptedHeaderPayload)))
 }
 }
 
 
 // EncodeResponseBody returns a Writer that auto-encrypt content written by caller.
 // EncodeResponseBody returns a Writer that auto-encrypt content written by caller.
@@ -487,17 +402,6 @@ func (s *ServerSession) EncodeResponseBody(request *protocol.RequestHeader, writ
 		}
 		}
 		return buf.NewWriter(writer), nil
 		return buf.NewWriter(writer), nil
 
 
-	case protocol.SecurityType_LEGACY:
-		if request.Option.Has(protocol.RequestOptionChunkStream) {
-			auth := &crypto.AEADAuthenticator{
-				AEAD:                    new(FnvAuthenticator),
-				NonceGenerator:          crypto.GenerateEmptyBytes(),
-				AdditionalDataGenerator: crypto.GenerateEmptyBytes(),
-			}
-			return crypto.NewAuthenticationWriter(auth, sizeParser, s.responseWriter, request.Command.TransferType(), padding), nil
-		}
-		return &buf.SequentialWriter{Writer: s.responseWriter}, nil
-
 	case protocol.SecurityType_AES128_GCM:
 	case protocol.SecurityType_AES128_GCM:
 		aead := crypto.NewAesGcm(s.responseBodyKey[:])
 		aead := crypto.NewAesGcm(s.responseBodyKey[:])
 		auth := &crypto.AEADAuthenticator{
 		auth := &crypto.AEADAuthenticator{

+ 27 - 48
proxy/vmess/inbound/config.pb.go

@@ -73,8 +73,7 @@ type DefaultConfig struct {
 	sizeCache     protoimpl.SizeCache
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 	unknownFields protoimpl.UnknownFields
 
 
-	AlterId uint32 `protobuf:"varint,1,opt,name=alter_id,json=alterId,proto3" json:"alter_id,omitempty"`
-	Level   uint32 `protobuf:"varint,2,opt,name=level,proto3" json:"level,omitempty"`
+	Level uint32 `protobuf:"varint,2,opt,name=level,proto3" json:"level,omitempty"`
 }
 }
 
 
 func (x *DefaultConfig) Reset() {
 func (x *DefaultConfig) Reset() {
@@ -109,13 +108,6 @@ func (*DefaultConfig) Descriptor() ([]byte, []int) {
 	return file_proxy_vmess_inbound_config_proto_rawDescGZIP(), []int{1}
 	return file_proxy_vmess_inbound_config_proto_rawDescGZIP(), []int{1}
 }
 }
 
 
-func (x *DefaultConfig) GetAlterId() uint32 {
-	if x != nil {
-		return x.AlterId
-	}
-	return 0
-}
-
 func (x *DefaultConfig) GetLevel() uint32 {
 func (x *DefaultConfig) GetLevel() uint32 {
 	if x != nil {
 	if x != nil {
 		return x.Level
 		return x.Level
@@ -128,10 +120,9 @@ type Config struct {
 	sizeCache     protoimpl.SizeCache
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 	unknownFields protoimpl.UnknownFields
 
 
-	User                 []*protocol.User `protobuf:"bytes,1,rep,name=user,proto3" json:"user,omitempty"`
-	Default              *DefaultConfig   `protobuf:"bytes,2,opt,name=default,proto3" json:"default,omitempty"`
-	Detour               *DetourConfig    `protobuf:"bytes,3,opt,name=detour,proto3" json:"detour,omitempty"`
-	SecureEncryptionOnly bool             `protobuf:"varint,4,opt,name=secure_encryption_only,json=secureEncryptionOnly,proto3" json:"secure_encryption_only,omitempty"`
+	User    []*protocol.User `protobuf:"bytes,1,rep,name=user,proto3" json:"user,omitempty"`
+	Default *DefaultConfig   `protobuf:"bytes,2,opt,name=default,proto3" json:"default,omitempty"`
+	Detour  *DetourConfig    `protobuf:"bytes,3,opt,name=detour,proto3" json:"detour,omitempty"` // 4 is for legacy setting
 }
 }
 
 
 func (x *Config) Reset() {
 func (x *Config) Reset() {
@@ -187,13 +178,6 @@ func (x *Config) GetDetour() *DetourConfig {
 	return nil
 	return nil
 }
 }
 
 
-func (x *Config) GetSecureEncryptionOnly() bool {
-	if x != nil {
-		return x.SecureEncryptionOnly
-	}
-	return false
-}
-
 var File_proxy_vmess_inbound_config_proto protoreflect.FileDescriptor
 var File_proxy_vmess_inbound_config_proto protoreflect.FileDescriptor
 
 
 var file_proxy_vmess_inbound_config_proto_rawDesc = []byte{
 var file_proxy_vmess_inbound_config_proto_rawDesc = []byte{
@@ -204,34 +188,29 @@ var file_proxy_vmess_inbound_config_proto_rawDesc = []byte{
 	0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x75, 0x73,
 	0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x75, 0x73,
 	0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x1e, 0x0a, 0x0c, 0x44, 0x65, 0x74, 0x6f,
 	0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x1e, 0x0a, 0x0c, 0x44, 0x65, 0x74, 0x6f,
 	0x75, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x01,
 	0x75, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x74, 0x6f, 0x22, 0x40, 0x0a, 0x0d, 0x44, 0x65, 0x66, 0x61,
-	0x75, 0x6c, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x6c, 0x74,
-	0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x61, 0x6c, 0x74,
-	0x65, 0x72, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x02, 0x20,
-	0x01, 0x28, 0x0d, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x22, 0xf1, 0x01, 0x0a, 0x06, 0x43,
-	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2e, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20,
-	0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
-	0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52,
-	0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x41, 0x0a, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74,
-	0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x70, 0x72,
-	0x6f, 0x78, 0x79, 0x2e, 0x76, 0x6d, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e,
-	0x64, 0x2e, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52,
-	0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x12, 0x3e, 0x0a, 0x06, 0x64, 0x65, 0x74, 0x6f,
-	0x75, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e,
-	0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x76, 0x6d, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6e, 0x62, 0x6f,
-	0x75, 0x6e, 0x64, 0x2e, 0x44, 0x65, 0x74, 0x6f, 0x75, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
-	0x52, 0x06, 0x64, 0x65, 0x74, 0x6f, 0x75, 0x72, 0x12, 0x34, 0x0a, 0x16, 0x73, 0x65, 0x63, 0x75,
-	0x72, 0x65, 0x5f, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x6e,
-	0x6c, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65,
-	0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x6e, 0x6c, 0x79, 0x42, 0x6a,
-	0x0a, 0x1c, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79,
-	0x2e, 0x76, 0x6d, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x50, 0x01,
-	0x5a, 0x2d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c,
-	0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x78,
-	0x79, 0x2f, 0x76, 0x6d, 0x65, 0x73, 0x73, 0x2f, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0xaa,
-	0x02, 0x18, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x56, 0x6d, 0x65,
-	0x73, 0x73, 0x2e, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
-	0x6f, 0x33,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x74, 0x6f, 0x22, 0x25, 0x0a, 0x0d, 0x44, 0x65, 0x66, 0x61,
+	0x75, 0x6c, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x65, 0x76,
+	0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x22,
+	0xbb, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2e, 0x0a, 0x04, 0x75, 0x73,
+	0x65, 0x72, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e,
+	0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e,
+	0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x41, 0x0a, 0x07, 0x64, 0x65,
+	0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x78, 0x72,
+	0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x76, 0x6d, 0x65, 0x73, 0x73, 0x2e, 0x69,
+	0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x2e, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x43, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x52, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x12, 0x3e, 0x0a,
+	0x06, 0x64, 0x65, 0x74, 0x6f, 0x75, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e,
+	0x78, 0x72, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x76, 0x6d, 0x65, 0x73, 0x73,
+	0x2e, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x2e, 0x44, 0x65, 0x74, 0x6f, 0x75, 0x72, 0x43,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x64, 0x65, 0x74, 0x6f, 0x75, 0x72, 0x42, 0x6a, 0x0a,
+	0x1c, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e,
+	0x76, 0x6d, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x50, 0x01, 0x5a,
+	0x2d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73,
+	0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79,
+	0x2f, 0x76, 0x6d, 0x65, 0x73, 0x73, 0x2f, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0xaa, 0x02,
+	0x18, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x56, 0x6d, 0x65, 0x73,
+	0x73, 0x2e, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x33,
 }
 }
 
 
 var (
 var (

+ 1 - 2
proxy/vmess/inbound/config.proto

@@ -13,7 +13,6 @@ message DetourConfig {
 }
 }
 
 
 message DefaultConfig {
 message DefaultConfig {
-  uint32 alter_id = 1;
   uint32 level = 2;
   uint32 level = 2;
 }
 }
 
 
@@ -21,5 +20,5 @@ message Config {
   repeated xray.common.protocol.User user = 1;
   repeated xray.common.protocol.User user = 1;
   DefaultConfig default = 2;
   DefaultConfig default = 2;
   DetourConfig detour = 3;
   DetourConfig detour = 3;
-  bool secure_encryption_only = 4;
+  // 4 is for legacy setting
 }
 }

+ 1 - 44
proxy/vmess/inbound/inbound.go

@@ -14,7 +14,6 @@ import (
 	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/log"
 	"github.com/xtls/xray-core/common/log"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/net"
-	"github.com/xtls/xray-core/common/platform"
 	"github.com/xtls/xray-core/common/protocol"
 	"github.com/xtls/xray-core/common/protocol"
 	"github.com/xtls/xray-core/common/session"
 	"github.com/xtls/xray-core/common/session"
 	"github.com/xtls/xray-core/common/signal"
 	"github.com/xtls/xray-core/common/signal"
@@ -29,23 +28,16 @@ import (
 	"github.com/xtls/xray-core/transport/internet/stat"
 	"github.com/xtls/xray-core/transport/internet/stat"
 )
 )
 
 
-var (
-	aeadForced     = false
-	aeadForced2022 = false
-)
-
 type userByEmail struct {
 type userByEmail struct {
 	sync.Mutex
 	sync.Mutex
 	cache           map[string]*protocol.MemoryUser
 	cache           map[string]*protocol.MemoryUser
 	defaultLevel    uint32
 	defaultLevel    uint32
-	defaultAlterIDs uint16
 }
 }
 
 
 func newUserByEmail(config *DefaultConfig) *userByEmail {
 func newUserByEmail(config *DefaultConfig) *userByEmail {
 	return &userByEmail{
 	return &userByEmail{
 		cache:           make(map[string]*protocol.MemoryUser),
 		cache:           make(map[string]*protocol.MemoryUser),
 		defaultLevel:    config.Level,
 		defaultLevel:    config.Level,
-		defaultAlterIDs: uint16(config.AlterId),
 	}
 	}
 }
 }
 
 
@@ -77,7 +69,6 @@ func (v *userByEmail) Get(email string) (*protocol.MemoryUser, bool) {
 		id := uuid.New()
 		id := uuid.New()
 		rawAccount := &vmess.Account{
 		rawAccount := &vmess.Account{
 			Id:      id.String(),
 			Id:      id.String(),
-			AlterId: uint32(v.defaultAlterIDs),
 		}
 		}
 		account, err := rawAccount.AsAccount()
 		account, err := rawAccount.AsAccount()
 		common.Must(err)
 		common.Must(err)
@@ -112,7 +103,6 @@ type Handler struct {
 	usersByEmail          *userByEmail
 	usersByEmail          *userByEmail
 	detours               *DetourConfig
 	detours               *DetourConfig
 	sessionHistory        *encoding.SessionHistory
 	sessionHistory        *encoding.SessionHistory
-	secure                bool
 }
 }
 
 
 // New creates a new VMess inbound handler.
 // New creates a new VMess inbound handler.
@@ -121,11 +111,10 @@ func New(ctx context.Context, config *Config) (*Handler, error) {
 	handler := &Handler{
 	handler := &Handler{
 		policyManager:         v.GetFeature(policy.ManagerType()).(policy.Manager),
 		policyManager:         v.GetFeature(policy.ManagerType()).(policy.Manager),
 		inboundHandlerManager: v.GetFeature(feature_inbound.ManagerType()).(feature_inbound.Manager),
 		inboundHandlerManager: v.GetFeature(feature_inbound.ManagerType()).(feature_inbound.Manager),
-		clients:               vmess.NewTimedUserValidator(protocol.DefaultIDHash),
+		clients:               vmess.NewTimedUserValidator(),
 		detours:               config.Detour,
 		detours:               config.Detour,
 		usersByEmail:          newUserByEmail(config.GetDefaultValue()),
 		usersByEmail:          newUserByEmail(config.GetDefaultValue()),
 		sessionHistory:        encoding.NewSessionHistory(),
 		sessionHistory:        encoding.NewSessionHistory(),
-		secure:                config.SecureEncryptionOnly,
 	}
 	}
 
 
 	for _, user := range config.User {
 	for _, user := range config.User {
@@ -145,7 +134,6 @@ func New(ctx context.Context, config *Config) (*Handler, error) {
 // Close implements common.Closable.
 // Close implements common.Closable.
 func (h *Handler) Close() error {
 func (h *Handler) Close() error {
 	return errors.Combine(
 	return errors.Combine(
-		h.clients.Close(),
 		h.sessionHistory.Close(),
 		h.sessionHistory.Close(),
 		common.Close(h.usersByEmail))
 		common.Close(h.usersByEmail))
 }
 }
@@ -219,10 +207,6 @@ func transferResponse(timer signal.ActivityUpdater, session *encoding.ServerSess
 	return nil
 	return nil
 }
 }
 
 
-func isInsecureEncryption(s protocol.SecurityType) bool {
-	return s == protocol.SecurityType_NONE || s == protocol.SecurityType_LEGACY || s == protocol.SecurityType_UNKNOWN
-}
-
 // Process implements proxy.Inbound.Process().
 // Process implements proxy.Inbound.Process().
 func (h *Handler) Process(ctx context.Context, network net.Network, connection stat.Connection, dispatcher routing.Dispatcher) error {
 func (h *Handler) Process(ctx context.Context, network net.Network, connection stat.Connection, dispatcher routing.Dispatcher) error {
 	sessionPolicy := h.policyManager.ForLevel(0)
 	sessionPolicy := h.policyManager.ForLevel(0)
@@ -241,7 +225,6 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s
 
 
 	reader := &buf.BufferedReader{Reader: buf.NewReader(connection)}
 	reader := &buf.BufferedReader{Reader: buf.NewReader(connection)}
 	svrSession := encoding.NewServerSession(h.clients, h.sessionHistory)
 	svrSession := encoding.NewServerSession(h.clients, h.sessionHistory)
-	svrSession.SetAEADForced(aeadForced)
 	request, err := svrSession.DecodeRequestHeader(reader, isDrain)
 	request, err := svrSession.DecodeRequestHeader(reader, isDrain)
 	if err != nil {
 	if err != nil {
 		if errors.Cause(err) != io.EOF {
 		if errors.Cause(err) != io.EOF {
@@ -256,17 +239,6 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s
 		return err
 		return err
 	}
 	}
 
 
-	if h.secure && isInsecureEncryption(request.Security) {
-		log.Record(&log.AccessMessage{
-			From:   connection.RemoteAddr(),
-			To:     "",
-			Status: log.AccessRejected,
-			Reason: "Insecure encryption",
-			Email:  request.User.Email,
-		})
-		return newError("client is using insecure encryption: ", request.Security)
-	}
-
 	if request.Command != protocol.RequestCommandMux {
 	if request.Command != protocol.RequestCommandMux {
 		ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{
 		ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{
 			From:   connection.RemoteAddr(),
 			From:   connection.RemoteAddr(),
@@ -361,7 +333,6 @@ func (h *Handler) generateCommand(ctx context.Context, request *protocol.Request
 				return &protocol.CommandSwitchAccount{
 				return &protocol.CommandSwitchAccount{
 					Port:     port,
 					Port:     port,
 					ID:       account.ID.UUID(),
 					ID:       account.ID.UUID(),
-					AlterIds: uint16(len(account.AlterIDs)),
 					Level:    user.Level,
 					Level:    user.Level,
 					ValidMin: byte(availableMin),
 					ValidMin: byte(availableMin),
 				}
 				}
@@ -376,18 +347,4 @@ func init() {
 	common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
 	common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
 		return New(ctx, config.(*Config))
 		return New(ctx, config.(*Config))
 	}))
 	}))
-
-	defaultFlagValue := "NOT_DEFINED_AT_ALL"
-
-	if time.Now().Year() >= 2022 {
-		defaultFlagValue = "true_by_default_2022"
-	}
-
-	isAeadForced := platform.NewEnvFlag("xray.vmess.aead.forced").GetValue(func() string { return defaultFlagValue })
-	aeadForced = (isAeadForced == "true")
-
-	if isAeadForced == "true_by_default_2022" {
-		aeadForced = true
-		aeadForced2022 = true
-	}
 }
 }

+ 1 - 2
proxy/vmess/outbound/command.go

@@ -12,9 +12,8 @@ import (
 func (h *Handler) handleSwitchAccount(cmd *protocol.CommandSwitchAccount) {
 func (h *Handler) handleSwitchAccount(cmd *protocol.CommandSwitchAccount) {
 	rawAccount := &vmess.Account{
 	rawAccount := &vmess.Account{
 		Id:      cmd.ID.String(),
 		Id:      cmd.ID.String(),
-		AlterId: uint32(cmd.AlterIds),
 		SecuritySettings: &protocol.SecurityConfig{
 		SecuritySettings: &protocol.SecurityConfig{
-			Type: protocol.SecurityType_LEGACY,
+			Type: protocol.SecurityType_AUTO,
 		},
 		},
 	}
 	}
 
 

+ 1 - 12
proxy/vmess/outbound/outbound.go

@@ -128,11 +128,6 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
 	input := link.Reader
 	input := link.Reader
 	output := link.Writer
 	output := link.Writer
 
 
-	isAEAD := false
-	if !aeadDisabled && len(account.AlterIDs) == 0 {
-		isAEAD = true
-	}
-
 	hashkdf := hmac.New(sha256.New, []byte("VMessBF"))
 	hashkdf := hmac.New(sha256.New, []byte("VMessBF"))
 	hashkdf.Write(account.ID.Bytes())
 	hashkdf.Write(account.ID.Bytes())
 
 
@@ -144,7 +139,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
 		newCtx, newCancel = context.WithCancel(context.Background())
 		newCtx, newCancel = context.WithCancel(context.Background())
 	}
 	}
 
 
-	session := encoding.NewClientSession(ctx, isAEAD, protocol.DefaultIDHash, int64(behaviorSeed))
+	session := encoding.NewClientSession(ctx, int64(behaviorSeed))
 	sessionPolicy := h.policyManager.ForLevel(request.User.Level)
 	sessionPolicy := h.policyManager.ForLevel(request.User.Level)
 
 
 	ctx, cancel := context.WithCancel(ctx)
 	ctx, cancel := context.WithCancel(ctx)
@@ -233,7 +228,6 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
 
 
 var (
 var (
 	enablePadding = false
 	enablePadding = false
-	aeadDisabled  = false
 )
 )
 
 
 func shouldEnablePadding(s protocol.SecurityType) bool {
 func shouldEnablePadding(s protocol.SecurityType) bool {
@@ -251,9 +245,4 @@ func init() {
 	if paddingValue != defaultFlagValue {
 	if paddingValue != defaultFlagValue {
 		enablePadding = true
 		enablePadding = true
 	}
 	}
-
-	isAeadDisabled := platform.NewEnvFlag("xray.vmess.aead.disabled").GetValue(func() string { return defaultFlagValue })
-	if isAeadDisabled == "true" {
-		aeadDisabled = true
-	}
 }
 }

+ 7 - 168
proxy/vmess/validator.go

@@ -6,146 +6,39 @@ import (
 	"hash/crc64"
 	"hash/crc64"
 	"strings"
 	"strings"
 	"sync"
 	"sync"
-	"sync/atomic"
-	"time"
 
 
-	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common/dice"
 	"github.com/xtls/xray-core/common/dice"
 	"github.com/xtls/xray-core/common/protocol"
 	"github.com/xtls/xray-core/common/protocol"
-	"github.com/xtls/xray-core/common/serial"
-	"github.com/xtls/xray-core/common/task"
 	"github.com/xtls/xray-core/proxy/vmess/aead"
 	"github.com/xtls/xray-core/proxy/vmess/aead"
 )
 )
 
 
-const (
-	updateInterval   = 10 * time.Second
-	cacheDurationSec = 120
-)
-
-type user struct {
-	user    protocol.MemoryUser
-	lastSec protocol.Timestamp
-}
-
 // TimedUserValidator is a user Validator based on time.
 // TimedUserValidator is a user Validator based on time.
 type TimedUserValidator struct {
 type TimedUserValidator struct {
 	sync.RWMutex
 	sync.RWMutex
-	users    []*user
-	userHash map[[16]byte]indexTimePair
-	hasher   protocol.IDHash
-	baseTime protocol.Timestamp
-	task     *task.Periodic
+	users    []*protocol.MemoryUser
 
 
 	behaviorSeed  uint64
 	behaviorSeed  uint64
 	behaviorFused bool
 	behaviorFused bool
 
 
 	aeadDecoderHolder *aead.AuthIDDecoderHolder
 	aeadDecoderHolder *aead.AuthIDDecoderHolder
-
-	legacyWarnShown bool
-}
-
-type indexTimePair struct {
-	user    *user
-	timeInc uint32
-
-	taintedFuse *uint32
 }
 }
 
 
 // NewTimedUserValidator creates a new TimedUserValidator.
 // NewTimedUserValidator creates a new TimedUserValidator.
-func NewTimedUserValidator(hasher protocol.IDHash) *TimedUserValidator {
+func NewTimedUserValidator() *TimedUserValidator {
 	tuv := &TimedUserValidator{
 	tuv := &TimedUserValidator{
-		users:             make([]*user, 0, 16),
-		userHash:          make(map[[16]byte]indexTimePair, 1024),
-		hasher:            hasher,
-		baseTime:          protocol.Timestamp(time.Now().Unix() - cacheDurationSec*2),
+		users:             make([]*protocol.MemoryUser, 0, 16),
 		aeadDecoderHolder: aead.NewAuthIDDecoderHolder(),
 		aeadDecoderHolder: aead.NewAuthIDDecoderHolder(),
 	}
 	}
-	tuv.task = &task.Periodic{
-		Interval: updateInterval,
-		Execute: func() error {
-			tuv.updateUserHash()
-			return nil
-		},
-	}
-	common.Must(tuv.task.Start())
 	return tuv
 	return tuv
 }
 }
 
 
-// visible for testing
-func (v *TimedUserValidator) GetBaseTime() protocol.Timestamp {
-	return v.baseTime
-}
-
-func (v *TimedUserValidator) generateNewHashes(nowSec protocol.Timestamp, user *user) {
-	var hashValue [16]byte
-	genEndSec := nowSec + cacheDurationSec
-	genHashForID := func(id *protocol.ID) {
-		idHash := v.hasher(id.Bytes())
-		genBeginSec := user.lastSec
-		if genBeginSec < nowSec-cacheDurationSec {
-			genBeginSec = nowSec - cacheDurationSec
-		}
-		for ts := genBeginSec; ts <= genEndSec; ts++ {
-			common.Must2(serial.WriteUint64(idHash, uint64(ts)))
-			idHash.Sum(hashValue[:0])
-			idHash.Reset()
-
-			v.userHash[hashValue] = indexTimePair{
-				user:        user,
-				timeInc:     uint32(ts - v.baseTime),
-				taintedFuse: new(uint32),
-			}
-		}
-	}
-
-	account := user.user.Account.(*MemoryAccount)
-
-	genHashForID(account.ID)
-	for _, id := range account.AlterIDs {
-		genHashForID(id)
-	}
-	user.lastSec = genEndSec
-}
-
-func (v *TimedUserValidator) removeExpiredHashes(expire uint32) {
-	for key, pair := range v.userHash {
-		if pair.timeInc < expire {
-			delete(v.userHash, key)
-		}
-	}
-}
-
-func (v *TimedUserValidator) updateUserHash() {
-	now := time.Now()
-	nowSec := protocol.Timestamp(now.Unix())
-
-	v.Lock()
-	defer v.Unlock()
-
-	for _, user := range v.users {
-		v.generateNewHashes(nowSec, user)
-	}
-
-	expire := protocol.Timestamp(now.Unix() - cacheDurationSec)
-	if expire > v.baseTime {
-		v.removeExpiredHashes(uint32(expire - v.baseTime))
-	}
-}
-
 func (v *TimedUserValidator) Add(u *protocol.MemoryUser) error {
 func (v *TimedUserValidator) Add(u *protocol.MemoryUser) error {
 	v.Lock()
 	v.Lock()
 	defer v.Unlock()
 	defer v.Unlock()
 
 
-	nowSec := time.Now().Unix()
-
-	uu := &user{
-		user:    *u,
-		lastSec: protocol.Timestamp(nowSec - cacheDurationSec),
-	}
-	v.users = append(v.users, uu)
-	v.generateNewHashes(protocol.Timestamp(nowSec), uu)
+	v.users = append(v.users, u)
 
 
-	account := uu.user.Account.(*MemoryAccount)
+	account := u.Account.(*MemoryAccount)
 	if !v.behaviorFused {
 	if !v.behaviorFused {
 		hashkdf := hmac.New(sha256.New, []byte("VMESSBSKDF"))
 		hashkdf := hmac.New(sha256.New, []byte("VMESSBSKDF"))
 		hashkdf.Write(account.ID.Bytes())
 		hashkdf.Write(account.ID.Bytes())
@@ -159,25 +52,6 @@ func (v *TimedUserValidator) Add(u *protocol.MemoryUser) error {
 	return nil
 	return nil
 }
 }
 
 
-func (v *TimedUserValidator) Get(userHash []byte) (*protocol.MemoryUser, protocol.Timestamp, bool, error) {
-	v.RLock()
-	defer v.RUnlock()
-
-	v.behaviorFused = true
-
-	var fixedSizeHash [16]byte
-	copy(fixedSizeHash[:], userHash)
-	pair, found := v.userHash[fixedSizeHash]
-	if found {
-		user := pair.user.user
-		if atomic.LoadUint32(pair.taintedFuse) == 0 {
-			return &user, protocol.Timestamp(pair.timeInc) + v.baseTime, true, nil
-		}
-		return nil, 0, false, ErrTainted
-	}
-	return nil, 0, false, ErrNotFound
-}
-
 func (v *TimedUserValidator) GetAEAD(userHash []byte) (*protocol.MemoryUser, bool, error) {
 func (v *TimedUserValidator) GetAEAD(userHash []byte) (*protocol.MemoryUser, bool, error) {
 	v.RLock()
 	v.RLock()
 	defer v.RUnlock()
 	defer v.RUnlock()
@@ -199,10 +73,10 @@ func (v *TimedUserValidator) Remove(email string) bool {
 	email = strings.ToLower(email)
 	email = strings.ToLower(email)
 	idx := -1
 	idx := -1
 	for i, u := range v.users {
 	for i, u := range v.users {
-		if strings.EqualFold(u.user.Email, email) {
+		if strings.EqualFold(u.Email, email) {
 			idx = i
 			idx = i
 			var cmdkeyfl [16]byte
 			var cmdkeyfl [16]byte
-			copy(cmdkeyfl[:], u.user.Account.(*MemoryAccount).ID.CmdKey())
+			copy(cmdkeyfl[:], u.Account.(*MemoryAccount).ID.CmdKey())
 			v.aeadDecoderHolder.RemoveUser(cmdkeyfl)
 			v.aeadDecoderHolder.RemoveUser(cmdkeyfl)
 			break
 			break
 		}
 		}
@@ -219,11 +93,6 @@ func (v *TimedUserValidator) Remove(email string) bool {
 	return true
 	return true
 }
 }
 
 
-// Close implements common.Closable.
-func (v *TimedUserValidator) Close() error {
-	return v.task.Close()
-}
-
 func (v *TimedUserValidator) GetBehaviorSeed() uint64 {
 func (v *TimedUserValidator) GetBehaviorSeed() uint64 {
 	v.Lock()
 	v.Lock()
 	defer v.Unlock()
 	defer v.Unlock()
@@ -235,36 +104,6 @@ func (v *TimedUserValidator) GetBehaviorSeed() uint64 {
 	return v.behaviorSeed
 	return v.behaviorSeed
 }
 }
 
 
-func (v *TimedUserValidator) BurnTaintFuse(userHash []byte) error {
-	v.RLock()
-	defer v.RUnlock()
-
-	var userHashFL [16]byte
-	copy(userHashFL[:], userHash)
-
-	pair, found := v.userHash[userHashFL]
-	if found {
-		if atomic.CompareAndSwapUint32(pair.taintedFuse, 0, 1) {
-			return nil
-		}
-		return ErrTainted
-	}
-	return ErrNotFound
-}
-
-/*
-	ShouldShowLegacyWarn will return whether a Legacy Warning should be shown
-
-Not guaranteed to only return true once for every inbound, but it is okay.
-*/
-func (v *TimedUserValidator) ShouldShowLegacyWarn() bool {
-	if v.legacyWarnShown {
-		return false
-	}
-	v.legacyWarnShown = true
-	return true
-}
-
 var ErrNotFound = newError("Not Found")
 var ErrNotFound = newError("Not Found")
 
 
 var ErrTainted = newError("ErrTainted")
 var ErrTainted = newError("ErrTainted")

+ 1 - 74
proxy/vmess/validator_test.go

@@ -5,7 +5,6 @@ import (
 
 
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common/protocol"
 	"github.com/xtls/xray-core/common/protocol"
-	"github.com/xtls/xray-core/common/serial"
 	"github.com/xtls/xray-core/common/uuid"
 	"github.com/xtls/xray-core/common/uuid"
 	. "github.com/xtls/xray-core/proxy/vmess"
 	. "github.com/xtls/xray-core/proxy/vmess"
 )
 )
@@ -16,81 +15,9 @@ func toAccount(a *Account) protocol.Account {
 	return account
 	return account
 }
 }
 
 
-func TestUserValidator(t *testing.T) {
-	hasher := protocol.DefaultIDHash
-	v := NewTimedUserValidator(hasher)
-	defer common.Close(v)
-
-	id := uuid.New()
-	user := &protocol.MemoryUser{
-		Email: "test",
-		Account: toAccount(&Account{
-			Id: id.String(),
-		}),
-	}
-	common.Must(v.Add(user))
-
-	{
-		testSmallLag := func(lag int64) {
-			ts := int64(v.GetBaseTime()) + lag + 240
-			idHash := hasher(id.Bytes())
-			common.Must2(serial.WriteUint64(idHash, uint64(ts)))
-			userHash := idHash.Sum(nil)
-
-			euser, ets, found, _ := v.Get(userHash)
-			if !found {
-				t.Fatal("user not found")
-			}
-			if euser.Email != user.Email {
-				t.Error("unexpected user email: ", euser.Email, " want ", user.Email)
-			}
-			if int64(ets) != ts {
-				t.Error("unexpected timestamp: ", ets, " want ", ts)
-			}
-		}
-
-		testSmallLag(0)
-		testSmallLag(40)
-		testSmallLag(-40)
-		testSmallLag(80)
-		testSmallLag(-80)
-		testSmallLag(120)
-		testSmallLag(-120)
-	}
-
-	{
-		testBigLag := func(lag int64) {
-			ts := int64(v.GetBaseTime()) + lag + 240
-			idHash := hasher(id.Bytes())
-			common.Must2(serial.WriteUint64(idHash, uint64(ts)))
-			userHash := idHash.Sum(nil)
-
-			euser, _, found, _ := v.Get(userHash)
-			if found || euser != nil {
-				t.Error("unexpected user")
-			}
-		}
-
-		testBigLag(121)
-		testBigLag(-121)
-		testBigLag(310)
-		testBigLag(-310)
-		testBigLag(500)
-		testBigLag(-500)
-	}
-
-	if v := v.Remove(user.Email); !v {
-		t.Error("unable to remove user")
-	}
-	if v := v.Remove(user.Email); v {
-		t.Error("remove user twice")
-	}
-}
-
 func BenchmarkUserValidator(b *testing.B) {
 func BenchmarkUserValidator(b *testing.B) {
 	for i := 0; i < b.N; i++ {
 	for i := 0; i < b.N; i++ {
-		hasher := protocol.DefaultIDHash
-		v := NewTimedUserValidator(hasher)
+		v := NewTimedUserValidator()
 
 
 		for j := 0; j < 1500; j++ {
 		for j := 0; j < 1500; j++ {
 			id := uuid.New()
 			id := uuid.New()

+ 0 - 4
proxy/vmess/vmessCtxInterface.go

@@ -1,4 +0,0 @@
-package vmess
-
-// example
-const AlterID = "VMessCtxInterface_AlterID"