Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions main/commands/all/api/inbound_user_add.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,16 @@ var cmdAddInboundUsers = &base.Command{
Short: "Add users to inbounds",
Long: `
Add users to inbounds.
Arguments:
-s, -server
The API server address. Default 127.0.0.1:8080
-t, -timeout
Timeout seconds to call API. Default 3
Example:
{{.Exec}} {{.LongName}} --server=127.0.0.1:8080 c1.json c2.json
`,
Run: executeAddInboundUsers,
Expand Down
9 changes: 3 additions & 6 deletions main/commands/all/api/inbound_user_remove.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,10 @@ func executeRemoveUsers(cmd *base.Command, args []string) {
success := 0
for _, email := range emails {
fmt.Println("remove user:", email)
tmsg := cserial.ToTypedMessage(&handlerService.RemoveUserOperation{Email: email})
_, err := client.AlterInbound(ctx, &handlerService.AlterInboundRequest{
Tag: tag,
Operation: cserial.ToTypedMessage(
&handlerService.RemoveUserOperation{
Email: email,
},
),
Tag: tag,
Operation: tmsg,
})
if err == nil {
success += 1
Expand Down
6 changes: 2 additions & 4 deletions main/commands/all/api/inbounds_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,15 @@ Example:

func executeListInbounds(cmd *base.Command, args []string) {
setSharedFlags(cmd)
var isOnlyTagsStr string
cmd.Flag.StringVar(&isOnlyTagsStr, "isOnlyTags", "", "")
isOnlyTags := cmd.Flag.Bool("isOnlyTags", false, "")
cmd.Flag.Parse(args)
isOnlyTags := isOnlyTagsStr == "true"

conn, ctx, close := dialAPIServer()
defer close()

client := handlerService.NewHandlerServiceClient(conn)

resp, err := client.ListInbounds(ctx, &handlerService.ListInboundsRequest{IsOnlyTags: isOnlyTags})
resp, err := client.ListInbounds(ctx, &handlerService.ListInboundsRequest{IsOnlyTags: *isOnlyTags})
if err != nil {
base.Fatalf("failed to list inbounds: %s", err)
}
Expand Down
3 changes: 0 additions & 3 deletions main/commands/all/api/rules_add.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,6 @@ func executeAddRules(cmd *base.Command, args []string) {
base.Fatalf("failed to build conf: %s", err)
}
tmsg := cserial.ToTypedMessage(config)
if tmsg == nil {
base.Fatalf("failed to format config to TypedMessage.")
}

ra := &routerService.AddRuleRequest{
Config: tmsg,
Expand Down
24 changes: 12 additions & 12 deletions main/commands/all/api/source_ip_block.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ var cmdSourceIpBlock = &base.Command{
Long: `
Block connections by source IP address.

> Before using it, please ensure that there is an outbound pointing to blackhole.

Arguments:

-s, -server <server:port>
Expand All @@ -41,20 +43,20 @@ Arguments:
Example:

{{.Exec}} {{.LongName}} --server=127.0.0.1:8080 -outbound=blocked -inbound=socks 1.2.3.4
{{.Exec}} {{.LongName}} --server=127.0.0.1:8080 -outbound=blocked -inbound=socks 1.2.3.4 -reset
{{.Exec}} {{.LongName}} --server=127.0.0.1:8080 -outbound=blocked -inbound=socks -inbound=http 1.2.3.4 -reset
`,
Run: executeSourceIpBlock,
}

func executeSourceIpBlock(cmd *base.Command, args []string) {
var (
inbound string
inbound base.OptionList
outbound string
ruletag string
reset bool
)
setSharedFlags(cmd)
cmd.Flag.StringVar(&inbound, "inbound", "", "")
cmd.Flag.Var(&inbound, "inbound", "")
cmd.Flag.StringVar(&outbound, "outbound", "", "")
cmd.Flag.StringVar(&ruletag, "ruletag", "sourceIpBlock", "")
cmd.Flag.BoolVar(&reset, "reset", false, "")
Expand All @@ -63,8 +65,7 @@ func executeSourceIpBlock(cmd *base.Command, args []string) {

unnamedArgs := cmd.Flag.Args()
if len(unnamedArgs) == 0 {
fmt.Println("reading from stdin:")
unnamedArgs = []string{"stdin:"}
base.Fatalf("No source ip specified.")
}
conn, ctx, close := dialAPIServer()
defer close()
Expand All @@ -77,14 +78,16 @@ func executeSourceIpBlock(cmd *base.Command, args []string) {
return
}

jsonInbound, err := json.Marshal([]string{inbound})
if inbound == "" {
jsonInbound, err = json.Marshal([]string{})
jsonInbound := []string(inbound)
if jsonInbound == nil {
jsonInbound = []string{}
}
jsonInboundBytes, err := json.Marshal(jsonInbound)
if err != nil {
fmt.Println("Error marshaling JSON:", err)
return
}

stringConfig := fmt.Sprintf(`
{
"routing": {
Expand All @@ -99,7 +102,7 @@ func executeSourceIpBlock(cmd *base.Command, args []string) {
}
}

`, ruletag, string(jsonInbound), outbound, string(jsonIps))
`, ruletag, string(jsonInboundBytes), outbound, string(jsonIps))

conf, err := serial.DecodeJSONConfig(strings.NewReader(stringConfig))
if err != nil {
Expand All @@ -112,9 +115,6 @@ func executeSourceIpBlock(cmd *base.Command, args []string) {
base.Fatalf("failed to build conf: %s", err)
}
tmsg := cserial.ToTypedMessage(config)
if tmsg == nil {
base.Fatalf("failed to format config to TypedMessage.")
}

if reset {
rr := &routerService.RemoveRuleRequest{
Expand Down
2 changes: 1 addition & 1 deletion main/commands/all/curve25519.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (

func Curve25519Genkey(StdEncoding bool, input_base64 string) {
var encoding *base64.Encoding
if *input_stdEncoding || StdEncoding {
if StdEncoding {
encoding = base64.StdEncoding
} else {
encoding = base64.RawURLEncoding
Expand Down
24 changes: 14 additions & 10 deletions main/commands/all/mldsa65.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,28 @@ import (
)

var cmdMLDSA65 = &base.Command{
UsageLine: `{{.Exec}} mldsa65 [-i "seed (base64.RawURLEncoding)"]`,
Short: `Generate key pair for ML-DSA-65 post-quantum signature (REALITY)`,
CustomFlags: true,
UsageLine: `{{.Exec}} mldsa65 [-i "seed (base64.RawURLEncoding)"]`,
Short: `Generate key pair for ML-DSA-65 post-quantum signature (REALITY)`,
Long: `
Generate key pair for ML-DSA-65 post-quantum signature (REALITY).

Random: {{.Exec}} mldsa65
Arguments:

From seed: {{.Exec}} mldsa65 -i "seed (base64.RawURLEncoding)"
`,
}
-i
Generate key pair from seed (base64.RawURLEncoding).

func init() {
cmdMLDSA65.Run = executeMLDSA65 // break init loop
}
Example:

var input_mldsa65 = cmdMLDSA65.Flag.String("i", "", "")
Random: {{.Exec}} {{.LongName}}
From seed: {{.Exec}} {{.LongName}} -i "seed (base64.RawURLEncoding)"
`,
Run: executeMLDSA65,
}

func executeMLDSA65(cmd *base.Command, args []string) {
var input_mldsa65 = cmd.Flag.String("i", "", "")
cmd.Flag.Parse(args)
var seed [32]byte
if len(*input_mldsa65) > 0 {
s, _ := base64.RawURLEncoding.DecodeString(*input_mldsa65)
Expand Down
24 changes: 14 additions & 10 deletions main/commands/all/mlkem768.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,28 @@ import (
)

var cmdMLKEM768 = &base.Command{
UsageLine: `{{.Exec}} mlkem768 [-i "seed (base64.RawURLEncoding)"]`,
Short: `Generate key pair for ML-KEM-768 post-quantum key exchange (VLESS Encryption)`,
CustomFlags: true,
UsageLine: `{{.Exec}} mlkem768 [-i "seed (base64.RawURLEncoding)"]`,
Short: `Generate key pair for ML-KEM-768 post-quantum key exchange (VLESS Encryption)`,
Long: `
Generate key pair for ML-KEM-768 post-quantum key exchange (VLESS Encryption).

Random: {{.Exec}} mlkem768
Arguments:

From seed: {{.Exec}} mlkem768 -i "seed (base64.RawURLEncoding)"
`,
}
-i
Generate key pair from seed (base64.RawURLEncoding).

func init() {
cmdMLKEM768.Run = executeMLKEM768 // break init loop
}
Example:

var input_mlkem768 = cmdMLKEM768.Flag.String("i", "", "")
Random: {{.Exec}} {{.LongName}}
From seed: {{.Exec}} {{.LongName}} -i "seed (base64.RawURLEncoding)"
`,
Run: executeMLKEM768,
}

func executeMLKEM768(cmd *base.Command, args []string) {
var input_mlkem768 = cmd.Flag.String("i", "", "")
cmd.Flag.Parse(args)
var seed [64]byte
if len(*input_mlkem768) > 0 {
s, _ := base64.RawURLEncoding.DecodeString(*input_mlkem768)
Expand Down
52 changes: 15 additions & 37 deletions main/commands/all/tls/cert.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ import (

// cmdCert is the tls cert command
var cmdCert = &base.Command{
UsageLine: "{{.Exec}} tls cert [--ca] [--domain=example.com] [--expire=240h]",
Short: "Generate TLS certificates",
CustomFlags: true,
UsageLine: "{{.Exec}} tls cert [--ca] [--domain=example.com] [--expire=240h]",
Short: "Generate TLS certificates",
Long: `
Generate TLS certificates.

Expand All @@ -33,39 +34,30 @@ Arguments:
The organization name for the certificate.

-ca
Whether this certificate is a CA
Whether this certificate is a CA.

-json
The output of certificate to JSON
The output of certificate to JSON.

-file
The certificate path to save.

-expire
Expire time of the certificate. Default value 3 months.
`,
Run: executeCert,
}

func init() {
cmdCert.Run = executeCert // break init loop
}

var (
certDomainNames stringList
_ = func() bool {
cmdCert.Flag.Var(&certDomainNames, "domain", "Domain name for the certificate")
return true
}()

certCommonName = cmdCert.Flag.String("name", "Xray Inc", "The common name of this certificate")
certOrganization = cmdCert.Flag.String("org", "Xray Inc", "Organization of the certificate")
certIsCA = cmdCert.Flag.Bool("ca", false, "Whether this certificate is a CA")
certJSONOutput = cmdCert.Flag.Bool("json", true, "Print certificate in JSON format")
certFileOutput = cmdCert.Flag.String("file", "", "Save certificate in file.")
certExpire = cmdCert.Flag.Duration("expire", time.Hour*24*90 /* 90 days */, "Time until the certificate expires. Default value 3 months.")
)

func executeCert(cmd *base.Command, args []string) {
var certDomainNames base.OptionList
cmd.Flag.Var(&certDomainNames, "domain", "Domain name for the certificate")
certCommonName := cmd.Flag.String("name", "Xray Inc", "The common name of this certificate")
certOrganization := cmd.Flag.String("org", "Xray Inc", "Organization of the certificate")
certIsCA := cmd.Flag.Bool("ca", false, "Whether this certificate is a CA")
certJSONOutput := cmd.Flag.Bool("json", true, "Print certificate in JSON format")
certFileOutput := cmd.Flag.String("file", "", "Save certificate in file.")
certExpire := cmd.Flag.Duration("expire", time.Hour*24*90 /* 90 days */, "Time until the certificate expires. Default value 3 months.")
cmd.Flag.Parse(args)
var opts []cert.Option
if *certIsCA {
opts = append(opts, cert.Authority(*certIsCA))
Expand Down Expand Up @@ -126,20 +118,6 @@ func printFile(certificate *cert.Certificate, name string) error {
})
}

type stringList []string

func (l *stringList) String() string {
return "String list"
}

func (l *stringList) Set(v string) error {
if v == "" {
base.Fatalf("empty value")
}
*l = append(*l, v)
return nil
}

type jsonCert struct {
Certificate []string `json:"certificate"`
Key []string `json:"key"`
Expand Down
54 changes: 28 additions & 26 deletions main/commands/all/tls/ech.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,43 +16,45 @@ import (
)

var cmdECH = &base.Command{
UsageLine: `{{.Exec}} tls ech [--serverName (string)] [--pem] [-i "ECHServerKeys (base64.StdEncoding)"]`,
Short: `Generate TLS-ECH certificates`,
CustomFlags: true,
UsageLine: `{{.Exec}} tls ech [--serverName (string)] [--pem] [-i "ECHServerKeys (base64.StdEncoding)"]`,
Short: `Generate TLS-ECH certificates`,
Long: `
Generate TLS-ECH certificates.

Set serverName to your custom string: {{.Exec}} tls ech --serverName (string)
Generate into pem format: {{.Exec}} tls ech --pem
Restore ECHConfigs from ECHServerKeys: {{.Exec}} tls ech -i "ECHServerKeys (base64.StdEncoding)"
`, // Enable PQ signature schemes: {{.Exec}} tls ech --pq-signature-schemes-enabled
}

func init() {
cmdECH.Run = executeECH
}
Arguments:

var input_echServerKeys = cmdECH.Flag.String("i", "", "ECHServerKeys (base64.StdEncoding)")
-serverName
Set serverName to your custom string.

-pem
Generate into pem format.

// var input_pqSignatureSchemesEnabled = cmdECH.Flag.Bool("pqSignatureSchemesEnabled", false, "")
var (
input_serverName = cmdECH.Flag.String("serverName", "cloudflare-ech.com", "")
input_pem = cmdECH.Flag.Bool("pem", false, "True == turn on pem output")
)
-i
Restore ECHConfigs from ECHServerKeys.
`,
// --pq-signature-schemes-enabled
// Enable PQ signature schemes.
Run: executeECH,
}

func executeECH(cmd *base.Command, args []string) {
var input_echServerKeys = cmd.Flag.String("i", "", "ECHServerKeys (base64.StdEncoding)")
// var input_pqSignatureSchemesEnabled = cmdECH.Flag.Bool("pqSignatureSchemesEnabled", false, "")
var input_serverName = cmd.Flag.String("serverName", "cloudflare-ech.com", "")
var input_pem = cmd.Flag.Bool("pem", false, "True == turn on pem output")
cmd.Flag.Parse(args)
var kem uint16

// if *input_pqSignatureSchemesEnabled {
// kem = 0x30 // hpke.KEM_X25519_KYBER768_DRAFT00
// } else {
kem = hpke.DHKEM(ecdh.X25519()).ID()
// }

echConfig, priv, err := generateECHKeySet(0, *input_serverName, kem)
common.Must(err)

var configBuffer, keyBuffer []byte
if *input_echServerKeys == "" {
// if *input_pqSignatureSchemesEnabled {
// kem = 0x30 // hpke.KEM_X25519_KYBER768_DRAFT00
// } else {
kem = hpke.DHKEM(ecdh.X25519()).ID()
// }
echConfig, priv, err := generateECHKeySet(0, *input_serverName, kem)
common.Must(err)
configBytes, _ := marshalBinary(echConfig)
var b cryptobyte.Builder
b.AddUint16LengthPrefixed(func(child *cryptobyte.Builder) {
Expand Down
Loading