Deprecate legacy VMess header with a planned decommission (#712)

* Deprecate legacy VMess header with a planned decommission
* show legacy warning only once

Co-authored-by: Xiaokang Wang <xiaokangwang@outlook.com>
Co-authored-by: hmol233 <82594500+hmol233@users.noreply.github.com>
This commit is contained in:
yuhan6665 2021-09-20 02:46:05 -04:00 committed by GitHub
parent dbcbb519e3
commit f2cb13a8ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 31 additions and 2 deletions

View File

@ -191,11 +191,17 @@ func (s *ServerSession) DecodeRequestHeader(reader io.Reader, isDrain bool) (*pr
decryptor = bytes.NewReader(aeadData) decryptor = bytes.NewReader(aeadData)
s.isAEADRequest = true s.isAEADRequest = true
case !s.isAEADForced && errorAEAD == vmessaead.ErrNotFound: case errorAEAD == vmessaead.ErrNotFound:
userLegacy, timestamp, valid, userValidationError := s.userValidator.Get(buffer.Bytes()) userLegacy, timestamp, valid, userValidationError := s.userValidator.Get(buffer.Bytes())
if !valid || userValidationError != nil { if !valid || userValidationError != nil {
return nil, drainConnection(newError("invalid user").Base(userValidationError)) 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 user = userLegacy
iv := hashTimestamp(md5.New(), timestamp) iv := hashTimestamp(md5.New(), timestamp)
vmessAccount = userLegacy.Account.(*vmess.MemoryAccount) vmessAccount = userLegacy.Account.(*vmess.MemoryAccount)

View File

@ -31,6 +31,7 @@ import (
var ( var (
aeadForced = false aeadForced = false
aeadForced2022 = false
) )
type userByEmail struct { type userByEmail struct {
@ -368,8 +369,17 @@ func init() {
return New(ctx, config.(*Config)) return New(ctx, config.(*Config))
})) }))
const defaultFlagValue = "NOT_DEFINED_AT_ALL" var 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 }) isAeadForced := platform.NewEnvFlag("xray.vmess.aead.forced").GetValue(func() string { return defaultFlagValue })
aeadForced = (isAeadForced == "true") aeadForced = (isAeadForced == "true")
if isAeadForced == "true_by_default_2022" {
aeadForced = true
aeadForced2022 = true
}
} }

View File

@ -40,6 +40,8 @@ type TimedUserValidator struct {
behaviorFused bool behaviorFused bool
aeadDecoderHolder *aead.AuthIDDecoderHolder aeadDecoderHolder *aead.AuthIDDecoderHolder
legacyWarnShown bool
} }
type indexTimePair struct { type indexTimePair struct {
@ -245,6 +247,17 @@ func (v *TimedUserValidator) BurnTaintFuse(userHash []byte) error {
return ErrNotFound 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")