diff --git a/app/api/api.go b/app/api/api.go new file mode 100644 index 00000000..f8e54727 --- /dev/null +++ b/app/api/api.go @@ -0,0 +1,12 @@ +package api + +import ( + "github.com/v2ray/v2ray-core/app" +) + +const ( + APP_ID = app.ID(5) +) + +type ApiServer struct { +} diff --git a/app/api/config.go b/app/api/config.go new file mode 100644 index 00000000..8c5fe81c --- /dev/null +++ b/app/api/config.go @@ -0,0 +1,9 @@ +package api + +import ( + v2net "github.com/v2ray/v2ray-core/common/net" +) + +type Config struct { + DirectPort v2net.Port +} diff --git a/common/protocol/raw/client.go b/common/protocol/raw/client.go new file mode 100644 index 00000000..18ba229a --- /dev/null +++ b/common/protocol/raw/client.go @@ -0,0 +1,99 @@ +package raw + +import ( + "crypto/md5" + "crypto/rand" + "hash/fnv" + "io" + + "github.com/v2ray/v2ray-core/common/alloc" + "github.com/v2ray/v2ray-core/common/crypto" + "github.com/v2ray/v2ray-core/common/protocol" +) + +func hashTimestamp(t protocol.Timestamp) []byte { + once := t.Bytes() + bytes := make([]byte, 0, 32) + bytes = append(bytes, once...) + bytes = append(bytes, once...) + bytes = append(bytes, once...) + bytes = append(bytes, once...) + return bytes +} + +type ClientSession struct { + requestBodyKey []byte + requestBodyIV []byte + responseHeader byte + responseBodyKey []byte + responseBodyIV []byte + idHash protocol.IDHash +} + +func NewClientSession(idHash protocol.IDHash) *ClientSession { + randomBytes := make([]byte, 33) // 16 + 16 + 1 + rand.Read(randomBytes) + + session := &ClientSession{} + session.requestBodyKey = randomBytes[:16] + session.requestBodyIV = randomBytes[16:32] + session.responseHeader = randomBytes[32] + session.idHash = idHash + + return session +} + +func (this *ClientSession) EncodeRequestHeader(header *protocol.RequestHeader, writer io.Writer) { + buffer := alloc.NewSmallBuffer().Clear() + defer buffer.Release() + + timestamp := protocol.NewTimestampGenerator(protocol.NowTime(), 30)() + idHash := this.idHash(header.User.AnyValidID().Bytes()) + idHash.Write(timestamp.Bytes()) + idHash.Sum(buffer.Value) + + encryptionBegin := buffer.Len() + + buffer.AppendBytes(Version) + buffer.Append(this.requestBodyIV) + buffer.Append(this.requestBodyKey) + buffer.AppendBytes(this.responseHeader, byte(header.Option), byte(0), byte(0)) + buffer.AppendBytes(byte(header.Command)) + buffer.Append(header.Port.Bytes()) + + switch { + case header.Address.IsIPv4(): + buffer.AppendBytes(AddrTypeIPv4) + buffer.Append(header.Address.IP()) + case header.Address.IsIPv6(): + buffer.AppendBytes(AddrTypeIPv6) + buffer.Append(header.Address.IP()) + case header.Address.IsDomain(): + buffer.AppendBytes(AddrTypeDomain, byte(len(header.Address.Domain()))) + buffer.Append([]byte(header.Address.Domain())) + } + + encryptionEnd := buffer.Len() + + fnv1a := fnv.New32a() + fnv1a.Write(buffer.Value[encryptionBegin:encryptionEnd]) + + fnvHash := fnv1a.Sum32() + buffer.AppendBytes(byte(fnvHash>>24), byte(fnvHash>>16), byte(fnvHash>>8), byte(fnvHash)) + encryptionEnd += 4 + + timestampHash := md5.New() + timestampHash.Write(hashTimestamp(timestamp)) + iv := timestampHash.Sum(nil) + aesStream := crypto.NewAesEncryptionStream(header.User.ID.CmdKey(), iv) + aesStream.XORKeyStream(buffer.Value[encryptionBegin:encryptionEnd], buffer.Value[encryptionBegin:encryptionEnd]) + writer.Write(buffer.Value) + + return +} + +func (this *ClientSession) EncodeRequestBody(writer io.Writer) io.Writer { + aesStream := crypto.NewAesEncryptionStream(this.requestBodyKey, this.requestBodyIV) + return crypto.NewCryptionWriter(aesStream, writer) +} + diff --git a/common/protocol/raw/const.go b/common/protocol/raw/const.go new file mode 100644 index 00000000..6731f5c3 --- /dev/null +++ b/common/protocol/raw/const.go @@ -0,0 +1,9 @@ +package raw + +const ( + Version = byte(1) + + AddrTypeIPv4 = byte(0x01) + AddrTypeIPv6 = byte(0x03) + AddrTypeDomain = byte(0x02) +) diff --git a/common/protocol/raw/request.go b/common/protocol/raw/request.go deleted file mode 100644 index 364b42d6..00000000 --- a/common/protocol/raw/request.go +++ /dev/null @@ -1,13 +0,0 @@ -package raw - -type RequestEncoder struct { -} - -type RequestDecoder struct { -} - -type ResponseEncoder struct { -} - -type ResponseDecoder struct { -} diff --git a/common/web/hooks/input.go b/common/web/hooks/input.go new file mode 100644 index 00000000..75925f9b --- /dev/null +++ b/common/web/hooks/input.go @@ -0,0 +1,6 @@ +package hooks + +type Input struct { + Action string + Value string +} diff --git a/common/web/service.go b/common/web/service.go new file mode 100644 index 00000000..d2da33d3 --- /dev/null +++ b/common/web/service.go @@ -0,0 +1,10 @@ +package web + +import ( + "github.com/v2ray/v2ray-core/common/protocol" +) + +type Authenciation struct { + Required bool + User *protocol.User +}