簡體   English   中英

在保留 tls.Conn 功能的同時攔截 tls.Conn 的 Read() 和 Write()

[英]Intercept tls.Conn's Read() and Write() while retaining tls.Conn functionality

我有以下代碼:

l, err := tls.Listen("tcp", "localhost:0", cfg)
dieIf(err)
c, err := l.Accept()
dieIf(err)
err = c.(*tls.Conn).Handshake()
dieIf(err)

它工作得很好,但我想攔截tls.Conn的讀寫。

我想過這樣做:

type MitmConn struct {
  net.Conn
}

func (self *MitmConn) Read(b []byte) (n int, err error) {
  ...
}

func (self *MitmConn) Write(b []byte) (n int, err error) {
  ...
}

l, err := tls.Listen("tcp", "localhost:0", cfg)
dieIf(err)
c, err := l.Accept()
dieIf(err)
c = &MitmConn{c}

但是,這會失敗:

// panic: interface conversion: net.Conn is *MitmConn, not *tls.Conn
err = c.(*tls.Conn).Handshake()
dieIf(err)

有任何想法嗎?

package main

import "crypto/tls"

func dieIf(err error) {
    if err != nil {
        panic(err)
    }
}

type mitmConn struct {
    *tls.Conn
}

func (mc *mitmConn) Read(b []byte) (n int, err error) {
  return 0, nil
}

func (mc *mitmConn) Write(b []byte) (n int, err error) {
  return 0, nil
}

func main() {
    l, err := tls.Listen("tcp", "localhost:0", nil)
    dieIf(err)
    c, err := l.Accept()
    dieIf(err)
    mc := mitmConn{c.(*tls.Conn)}
    err = mc.Handshake()
    dieIf(err)
}

考慮取消學習命名接收者self (以及this )。

@kostix 的回答在大多數情況下都足夠了,但是如果你想攔截tls.Conn.Handshake()的讀寫,你需要在下面一層注入你的mitmConn包裝器。

這是一個工作示例:

package main

import "crypto/tls"

func dieIf(err error) {
    if err != nil {
        panic(err)
    }
}

type mitmConn struct {
    // Since we went one level beneath, no need for *tls.Conn here
    net.Conn
}

func (mc *mitmConn) Read(b []byte) (n int, err error) {
  return 0, nil
}

func (mc *mitmConn) Write(b []byte) (n int, err error) {
  return 0, nil
}

func main() {
    // Don't use tls.Listen
    l, err := net.Listen("tcp", "localhost:0")
    dieIf(err)
    c, err := l.Accept()
    dieIf(err)
    // Make a new tls.Conn. 
    // After the tls.Server() call, the nesting of Conn 
    // objects looks will be:
    // - *tls.Conn
    //  - mitmConn
    //   - *net.TCPConn
    c = tls.Server(mitmConn{c}, nil)
    // Since tls.Server returns a net.Conn, not a *tls.Conn, we need to cast
    err = c.(*tls.Conn).Handshake()
    dieIf(err)
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM