拦截 tls。Conn 的 read() 和 write(),同时保留 tls。连接功能



我有以下代码:

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(以及此名称)。

@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)
}

最新更新