mirror of
https://github.com/MetaCubeX/mihomo.git
synced 2025-12-19 16:30:07 +08:00
chore: rebuild vless encryption string parsing
Some checks are pending
Test / test (1.20, macos-13) (push) Waiting to run
Test / test (1.20, macos-latest) (push) Waiting to run
Test / test (1.20, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.20, ubuntu-latest) (push) Waiting to run
Test / test (1.20, windows-latest) (push) Waiting to run
Test / test (1.21, macos-13) (push) Waiting to run
Test / test (1.21, macos-latest) (push) Waiting to run
Test / test (1.21, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.21, ubuntu-latest) (push) Waiting to run
Test / test (1.21, windows-latest) (push) Waiting to run
Test / test (1.22, macos-13) (push) Waiting to run
Test / test (1.22, macos-latest) (push) Waiting to run
Test / test (1.22, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.22, ubuntu-latest) (push) Waiting to run
Test / test (1.22, windows-latest) (push) Waiting to run
Test / test (1.23, macos-13) (push) Waiting to run
Test / test (1.23, macos-latest) (push) Waiting to run
Test / test (1.23, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.23, ubuntu-latest) (push) Waiting to run
Test / test (1.23, windows-latest) (push) Waiting to run
Test / test (1.24, macos-13) (push) Waiting to run
Test / test (1.24, macos-latest) (push) Waiting to run
Test / test (1.24, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.24, ubuntu-latest) (push) Waiting to run
Test / test (1.24, windows-latest) (push) Waiting to run
Trigger CMFA Update / trigger-CMFA-update (push) Waiting to run
Some checks are pending
Test / test (1.20, macos-13) (push) Waiting to run
Test / test (1.20, macos-latest) (push) Waiting to run
Test / test (1.20, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.20, ubuntu-latest) (push) Waiting to run
Test / test (1.20, windows-latest) (push) Waiting to run
Test / test (1.21, macos-13) (push) Waiting to run
Test / test (1.21, macos-latest) (push) Waiting to run
Test / test (1.21, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.21, ubuntu-latest) (push) Waiting to run
Test / test (1.21, windows-latest) (push) Waiting to run
Test / test (1.22, macos-13) (push) Waiting to run
Test / test (1.22, macos-latest) (push) Waiting to run
Test / test (1.22, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.22, ubuntu-latest) (push) Waiting to run
Test / test (1.22, windows-latest) (push) Waiting to run
Test / test (1.23, macos-13) (push) Waiting to run
Test / test (1.23, macos-latest) (push) Waiting to run
Test / test (1.23, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.23, ubuntu-latest) (push) Waiting to run
Test / test (1.23, windows-latest) (push) Waiting to run
Test / test (1.24, macos-13) (push) Waiting to run
Test / test (1.24, macos-latest) (push) Waiting to run
Test / test (1.24, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.24, ubuntu-latest) (push) Waiting to run
Test / test (1.24, windows-latest) (push) Waiting to run
Trigger CMFA Update / trigger-CMFA-update (push) Waiting to run
This commit is contained in:
parent
eca5a27774
commit
a0bdb861a9
@ -3,14 +3,11 @@ package outbound
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"encoding/base64"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/metacubex/mihomo/common/convert"
|
"github.com/metacubex/mihomo/common/convert"
|
||||||
N "github.com/metacubex/mihomo/common/net"
|
N "github.com/metacubex/mihomo/common/net"
|
||||||
@ -456,41 +453,11 @@ func NewVless(option VlessOption) (*Vless, error) {
|
|||||||
option: &option,
|
option: &option,
|
||||||
}
|
}
|
||||||
|
|
||||||
if s := strings.SplitN(option.Encryption, "-", 4); len(s) == 4 && s[2] == "mlkem768client" {
|
v.encryption, err = encryption.NewClient(option.Encryption)
|
||||||
var minutes uint32
|
if err != nil {
|
||||||
if s[0] != "1rtt" {
|
return nil, err
|
||||||
t := strings.TrimSuffix(s[0], "min")
|
}
|
||||||
if t == s[0] {
|
if v.encryption != nil {
|
||||||
return nil, fmt.Errorf("invaild vless encryption value: %s", option.Encryption)
|
|
||||||
}
|
|
||||||
var i int
|
|
||||||
i, err = strconv.Atoi(t)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("invaild vless encryption value: %s", option.Encryption)
|
|
||||||
}
|
|
||||||
minutes = uint32(i)
|
|
||||||
}
|
|
||||||
var xor uint32
|
|
||||||
switch s[1] {
|
|
||||||
case "vless":
|
|
||||||
case "aes128xor":
|
|
||||||
xor = 1
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("invaild vless encryption value: %s", option.Encryption)
|
|
||||||
}
|
|
||||||
var b []byte
|
|
||||||
b, err = base64.RawURLEncoding.DecodeString(s[3])
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("invaild vless encryption value: %s", option.Encryption)
|
|
||||||
}
|
|
||||||
if len(b) == encryption.MLKEM768ClientLength {
|
|
||||||
v.encryption = &encryption.ClientInstance{}
|
|
||||||
if err = v.encryption.Init(b, xor, time.Duration(minutes)*time.Minute); err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to use mlkem768seed: %w", err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return nil, fmt.Errorf("invaild vless encryption value: %s", option.Encryption)
|
|
||||||
}
|
|
||||||
if option.Flow != "" {
|
if option.Flow != "" {
|
||||||
return nil, errors.New(`vless "encryption" doesn't support "flow" yet`)
|
return nil, errors.New(`vless "encryption" doesn't support "flow" yet`)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,15 +2,11 @@ package sing_vless
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/base64"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/metacubex/mihomo/adapter/inbound"
|
"github.com/metacubex/mihomo/adapter/inbound"
|
||||||
@ -88,42 +84,11 @@ func New(config LC.VlessServer, tunnel C.Tunnel, additions ...inbound.Addition)
|
|||||||
|
|
||||||
sl = &Listener{config: config, service: service}
|
sl = &Listener{config: config, service: service}
|
||||||
|
|
||||||
if s := strings.SplitN(config.Decryption, "-", 4); len(s) == 4 && s[2] == "mlkem768seed" {
|
sl.decryption, err = encryption.NewServer(config.Decryption)
|
||||||
var minutes uint32
|
if err != nil {
|
||||||
if s[0] != "1rtt" {
|
return nil, err
|
||||||
t := strings.TrimSuffix(s[0], "min")
|
}
|
||||||
if t == s[0] {
|
if sl.decryption != nil {
|
||||||
return nil, fmt.Errorf("invaild vless decryption value: %s", config.Decryption)
|
|
||||||
}
|
|
||||||
var i int
|
|
||||||
i, err = strconv.Atoi(t)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("invaild vless decryption value: %s", config.Decryption)
|
|
||||||
}
|
|
||||||
minutes = uint32(i)
|
|
||||||
}
|
|
||||||
var xor uint32
|
|
||||||
switch s[1] {
|
|
||||||
case "vless":
|
|
||||||
case "aes128xor":
|
|
||||||
xor = 1
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("invaild vless decryption value: %s", config.Decryption)
|
|
||||||
}
|
|
||||||
var b []byte
|
|
||||||
b, err = base64.RawURLEncoding.DecodeString(s[3])
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("invaild vless decryption value: %s", config.Decryption)
|
|
||||||
}
|
|
||||||
if len(b) == encryption.MLKEM768SeedLength {
|
|
||||||
sl.decryption = &encryption.ServerInstance{}
|
|
||||||
if err = sl.decryption.Init(b, xor, time.Duration(minutes)*time.Minute); err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to use mlkem768seed: %w", err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return nil, fmt.Errorf("invaild vless decryption value: %s", config.Decryption)
|
|
||||||
}
|
|
||||||
|
|
||||||
defer func() { // decryption must be closed to avoid the goroutine leak
|
defer func() { // decryption must be closed to avoid the goroutine leak
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = sl.decryption.Close()
|
_ = sl.decryption.Close()
|
||||||
|
|||||||
99
transport/vless/encryption/factory.go
Normal file
99
transport/vless/encryption/factory.go
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
package encryption
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewClient new client from encryption string
|
||||||
|
// maybe return a nil *ClientInstance without any error, that means don't need to encrypt
|
||||||
|
func NewClient(encryption string) (*ClientInstance, error) {
|
||||||
|
switch encryption {
|
||||||
|
case "", "none": // We will not reject empty string like xray-core does, because we need to ensure compatibility
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
if s := strings.SplitN(encryption, "-", 4); len(s) == 4 && s[2] == "mlkem768client" {
|
||||||
|
var minutes uint32
|
||||||
|
if s[0] != "1rtt" {
|
||||||
|
t := strings.TrimSuffix(s[0], "min")
|
||||||
|
if t == s[0] {
|
||||||
|
return nil, fmt.Errorf("invaild vless encryption value: %s", encryption)
|
||||||
|
}
|
||||||
|
i, err := strconv.Atoi(t)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("invaild vless encryption value: %s", encryption)
|
||||||
|
}
|
||||||
|
minutes = uint32(i)
|
||||||
|
}
|
||||||
|
var xor uint32
|
||||||
|
switch s[1] {
|
||||||
|
case "vless":
|
||||||
|
case "aes128xor":
|
||||||
|
xor = 1
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("invaild vless encryption value: %s", encryption)
|
||||||
|
}
|
||||||
|
b, err := base64.RawURLEncoding.DecodeString(s[3])
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("invaild vless encryption value: %s", encryption)
|
||||||
|
}
|
||||||
|
if len(b) == MLKEM768ClientLength {
|
||||||
|
client := &ClientInstance{}
|
||||||
|
if err = client.Init(b, xor, time.Duration(minutes)*time.Minute); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to use mlkem768seed: %w", err)
|
||||||
|
}
|
||||||
|
return client, nil
|
||||||
|
} else {
|
||||||
|
return nil, fmt.Errorf("invaild vless encryption value: %s", encryption)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("invaild vless encryption value: %s", encryption)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewServer new server from decryption string
|
||||||
|
// maybe return a nil *ServerInstance without any error, that means don't need to decrypt
|
||||||
|
func NewServer(decryption string) (*ServerInstance, error) {
|
||||||
|
switch decryption {
|
||||||
|
case "", "none": // We will not reject empty string like xray-core does, because we need to ensure compatibility
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
if s := strings.SplitN(decryption, "-", 4); len(s) == 4 && s[2] == "mlkem768seed" {
|
||||||
|
var minutes uint32
|
||||||
|
if s[0] != "1rtt" {
|
||||||
|
t := strings.TrimSuffix(s[0], "min")
|
||||||
|
if t == s[0] {
|
||||||
|
return nil, fmt.Errorf("invaild vless decryption value: %s", decryption)
|
||||||
|
}
|
||||||
|
i, err := strconv.Atoi(t)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("invaild vless decryption value: %s", decryption)
|
||||||
|
}
|
||||||
|
minutes = uint32(i)
|
||||||
|
}
|
||||||
|
var xor uint32
|
||||||
|
switch s[1] {
|
||||||
|
case "vless":
|
||||||
|
case "aes128xor":
|
||||||
|
xor = 1
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("invaild vless decryption value: %s", decryption)
|
||||||
|
}
|
||||||
|
b, err := base64.RawURLEncoding.DecodeString(s[3])
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("invaild vless decryption value: %s", decryption)
|
||||||
|
}
|
||||||
|
if len(b) == MLKEM768SeedLength {
|
||||||
|
server := &ServerInstance{}
|
||||||
|
if err = server.Init(b, xor, time.Duration(minutes)*time.Minute); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to use mlkem768seed: %w", err)
|
||||||
|
}
|
||||||
|
return server, nil
|
||||||
|
} else {
|
||||||
|
return nil, fmt.Errorf("invaild vless decryption value: %s", decryption)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("invaild vless decryption value: %s", decryption)
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user