mirror of
https://github.com/ScuroNeko/mtg.git
synced 2026-08-31 20:24:03 +03:00
Faketls works now
This commit is contained in:
@@ -0,0 +1,70 @@
|
|||||||
|
package faketls
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
|
||||||
|
"github.com/9seconds/mtg/v2/mtglib/internal/faketls/record"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Conn struct {
|
||||||
|
net.Conn
|
||||||
|
|
||||||
|
readBuffer bytes.Buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Conn) Read(p []byte) (int, error) {
|
||||||
|
if n, _ := c.readBuffer.Read(p); n > 0 {
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
rec := record.AcquireRecord()
|
||||||
|
defer record.ReleaseRecord(rec)
|
||||||
|
|
||||||
|
for {
|
||||||
|
if err := rec.Read(c.Conn); err != nil {
|
||||||
|
return 0, err // nolint: wrapcheck
|
||||||
|
}
|
||||||
|
|
||||||
|
switch rec.Type { // nolint: exhaustive
|
||||||
|
case record.TypeChangeCipherSpec:
|
||||||
|
case record.TypeApplicationData:
|
||||||
|
rec.Payload.WriteTo(&c.readBuffer)
|
||||||
|
|
||||||
|
n, err := c.readBuffer.Read(p)
|
||||||
|
|
||||||
|
return n, err
|
||||||
|
default:
|
||||||
|
return 0, fmt.Errorf("unsupported record type %v", rec.Type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Conn) Write(p []byte) (int, error) {
|
||||||
|
rec := record.AcquireRecord()
|
||||||
|
defer record.ReleaseRecord(rec)
|
||||||
|
|
||||||
|
rec.Type = record.TypeApplicationData
|
||||||
|
rec.Version = record.Version12
|
||||||
|
written := 0
|
||||||
|
|
||||||
|
for len(p) > 0 {
|
||||||
|
chunkSize := record.TLSMaxRecordSize
|
||||||
|
if chunkSize > len(p) {
|
||||||
|
chunkSize = len(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
rec.Payload.Reset()
|
||||||
|
rec.Payload.Write(p[:chunkSize])
|
||||||
|
|
||||||
|
if err := rec.Dump(c.Conn); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
written += chunkSize
|
||||||
|
p = p[chunkSize:]
|
||||||
|
}
|
||||||
|
|
||||||
|
return written, nil
|
||||||
|
}
|
||||||
@@ -2,6 +2,8 @@ package record
|
|||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
|
const TLSMaxRecordSize = 65535 // max uint16
|
||||||
|
|
||||||
type Type uint8
|
type Type uint8
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|||||||
@@ -9,11 +9,10 @@ type conn struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c conn) Read(p []byte) (int, error) {
|
func (c conn) Read(p []byte) (int, error) {
|
||||||
ctx := c.relay.ctx
|
|
||||||
n, err := c.ReadWriteCloser.Read(p)
|
n, err := c.ReadWriteCloser.Read(p)
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-c.relay.ctx.Done():
|
||||||
case c.relay.tickChannel <- struct{}{}:
|
case c.relay.tickChannel <- struct{}{}:
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -21,11 +20,10 @@ func (c conn) Read(p []byte) (int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c conn) Write(p []byte) (int, error) {
|
func (c conn) Write(p []byte) (int, error) {
|
||||||
ctx := c.relay.ctx
|
|
||||||
n, err := c.ReadWriteCloser.Write(p)
|
n, err := c.ReadWriteCloser.Write(p)
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-c.relay.ctx.Done():
|
||||||
case c.relay.tickChannel <- struct{}{}:
|
case c.relay.tickChannel <- struct{}{}:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-5
@@ -4,7 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@@ -59,7 +58,7 @@ func (p *Proxy) ServeConn(conn net.Conn) {
|
|||||||
ctx.logger.Info("Stream has been finished")
|
ctx.logger.Info("Stream has been finished")
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if err := p.doFakeTLSHandshake(ctx, ctx.clientConn); err != nil {
|
if err := p.doFakeTLSHandshake(ctx); err != nil {
|
||||||
p.logger.InfoError("faketls handshake is failed", err)
|
p.logger.InfoError("faketls handshake is failed", err)
|
||||||
|
|
||||||
return
|
return
|
||||||
@@ -122,11 +121,11 @@ func (p *Proxy) Shutdown() {
|
|||||||
p.workerPool.Release()
|
p.workerPool.Release()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Proxy) doFakeTLSHandshake(ctx *streamContext, conn io.ReadWriter) error {
|
func (p *Proxy) doFakeTLSHandshake(ctx *streamContext) error {
|
||||||
rec := record.AcquireRecord()
|
rec := record.AcquireRecord()
|
||||||
defer record.ReleaseRecord(rec)
|
defer record.ReleaseRecord(rec)
|
||||||
|
|
||||||
if err := rec.Read(conn); err != nil {
|
if err := rec.Read(ctx.clientConn); err != nil {
|
||||||
return fmt.Errorf("cannot read client hello: %w", err)
|
return fmt.Errorf("cannot read client hello: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,10 +144,14 @@ func (p *Proxy) doFakeTLSHandshake(ctx *streamContext, conn io.ReadWriter) error
|
|||||||
return fmt.Errorf("anti replay attack from %s", ctx.ClientIP().String())
|
return fmt.Errorf("anti replay attack from %s", ctx.ClientIP().String())
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := faketls.SendWelcomePacket(conn, p.secret.Key[:], hello); err != nil {
|
if err := faketls.SendWelcomePacket(ctx.clientConn, p.secret.Key[:], hello); err != nil {
|
||||||
return fmt.Errorf("cannot send a welcome packet: %w", err)
|
return fmt.Errorf("cannot send a welcome packet: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctx.clientConn = &faketls.Conn{
|
||||||
|
Conn: ctx.clientConn,
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user