Faketls works now

This commit is contained in:
9seconds
2021-03-26 12:15:26 +03:00
parent 6d92d5fe21
commit f0efa4697e
4 changed files with 82 additions and 9 deletions
+70
View File
@@ -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
View File
@@ -2,6 +2,8 @@ package record
import "fmt"
const TLSMaxRecordSize = 65535 // max uint16
type Type uint8
const (
+2 -4
View File
@@ -9,11 +9,10 @@ type conn struct {
}
func (c conn) Read(p []byte) (int, error) {
ctx := c.relay.ctx
n, err := c.ReadWriteCloser.Read(p)
select {
case <-ctx.Done():
case <-c.relay.ctx.Done():
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) {
ctx := c.relay.ctx
n, err := c.ReadWriteCloser.Write(p)
select {
case <-ctx.Done():
case <-c.relay.ctx.Done():
case c.relay.tickChannel <- struct{}{}:
}
+8 -5
View File
@@ -4,7 +4,6 @@ import (
"context"
"errors"
"fmt"
"io"
"net"
"sync"
"time"
@@ -59,7 +58,7 @@ func (p *Proxy) ServeConn(conn net.Conn) {
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)
return
@@ -122,11 +121,11 @@ func (p *Proxy) Shutdown() {
p.workerPool.Release()
}
func (p *Proxy) doFakeTLSHandshake(ctx *streamContext, conn io.ReadWriter) error {
func (p *Proxy) doFakeTLSHandshake(ctx *streamContext) error {
rec := record.AcquireRecord()
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)
}
@@ -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())
}
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)
}
ctx.clientConn = &faketls.Conn{
Conn: ctx.clientConn,
}
return nil
}