From 28fcddd69b891c0075c21b5f41101b24d8f48cde Mon Sep 17 00:00:00 2001 From: Calvin Cramer Date: Fri, 1 Dec 2023 12:28:28 -0800 Subject: [PATCH] Allow arbitrary connection protocols --- conn.go | 32 ++++++++++++-------------------- data_writer.go | 11 ++--------- 2 files changed, 14 insertions(+), 29 deletions(-) diff --git a/conn.go b/conn.go index 31a9659..b30fa87 100644 --- a/conn.go +++ b/conn.go @@ -1,12 +1,10 @@ package telnet - import ( "crypto/tls" "net" ) - type Conn struct { conn interface { Read(b []byte) (n int, err error) @@ -19,7 +17,6 @@ type Conn struct { dataWriter *internalDataWriter } - // Dial makes a (un-secure) TELNET client connection to the system's 'loopback address' // (also known as "localhost" or 127.0.0.1). // @@ -33,9 +30,10 @@ func Dial() (*Conn, error) { // // If a secure connection is desired, use `DialToTLS` instead. func DialTo(addr string) (*Conn, error) { + return DialToNetwork("tcp", addr) +} - const network = "tcp" - +func DialToNetwork(network string, addr string) (*Conn, error) { if "" == addr { addr = "127.0.0.1:telnet" } @@ -49,15 +47,14 @@ func DialTo(addr string) (*Conn, error) { dataWriter := newDataWriter(conn) clientConn := Conn{ - conn:conn, - dataReader:dataReader, - dataWriter:dataWriter, + conn: conn, + dataReader: dataReader, + dataWriter: dataWriter, } return &clientConn, nil } - // DialTLS makes a (secure) TELNETS client connection to the system's 'loopback address' // (also known as "localhost" or 127.0.0.1). func DialTLS(tlsConfig *tls.Config) (*Conn, error) { @@ -67,9 +64,10 @@ func DialTLS(tlsConfig *tls.Config) (*Conn, error) { // DialToTLS makes a (secure) TELNETS client connection to the the address specified by // 'addr'. func DialToTLS(addr string, tlsConfig *tls.Config) (*Conn, error) { + return DialToNetworkTLS("tcp", addr, tlsConfig) +} - const network = "tcp" - +func DialToNetworkTLS(network string, addr string, tlsConfig *tls.Config) (*Conn, error) { if "" == addr { addr = "127.0.0.1:telnets" } @@ -83,16 +81,14 @@ func DialToTLS(addr string, tlsConfig *tls.Config) (*Conn, error) { dataWriter := newDataWriter(conn) clientConn := Conn{ - conn:conn, - dataReader:dataReader, - dataWriter:dataWriter, + conn: conn, + dataReader: dataReader, + dataWriter: dataWriter, } return &clientConn, nil } - - // Close closes the client connection. // // Typical usage might look like: @@ -107,7 +103,6 @@ func (clientConn *Conn) Close() error { return clientConn.conn.Close() } - // Read receives `n` bytes sent from the server to the client, // and "returns" into `p`. // @@ -122,7 +117,6 @@ func (clientConn *Conn) Read(p []byte) (n int, err error) { return clientConn.dataReader.Read(p) } - // Write sends `n` bytes from 'p' to the server. // // Note that Write can only be used for sending TELNET (and TELNETS) data to the server. @@ -135,13 +129,11 @@ func (clientConn *Conn) Write(p []byte) (n int, err error) { return clientConn.dataWriter.Write(p) } - // LocalAddr returns the local network address. func (clientConn *Conn) LocalAddr() net.Addr { return clientConn.conn.LocalAddr() } - // RemoteAddr returns the remote network address. func (clientConn *Conn) RemoteAddr() net.Addr { return clientConn.conn.RemoteAddr() diff --git a/data_writer.go b/data_writer.go index af99557..583e0ec 100644 --- a/data_writer.go +++ b/data_writer.go @@ -1,6 +1,5 @@ package telnet - import ( "github.com/reiver/go-oi" @@ -9,13 +8,11 @@ import ( "io" ) - var iaciac []byte = []byte{255, 255} var errOverflow = errors.New("Overflow") var errPartialIACIACWrite = errors.New("Partial IAC IAC write.") - // An internalDataWriter deals with "escaping" according to the TELNET (and TELNETS) protocol. // // In the TELNET (and TELNETS) protocol byte value 255 is special. @@ -24,7 +21,7 @@ var errPartialIACIACWrite = errors.New("Partial IAC IAC write.") // // The TELNET (and TELNETS) protocol also has a distinction between 'data' and 'commands'. // -//(DataWriter is targetted toward TELNET (and TELNETS) 'data', not TELNET (and TELNETS) 'commands'.) +// (DataWriter is targeted toward TELNET (and TELNETS) 'data', not TELNET (and TELNETS) 'commands'.) // // If a byte with value 255 (=IAC) appears in the data, then it must be escaped. // @@ -49,7 +46,6 @@ type internalDataWriter struct { wrapped io.Writer } - // newDataWriter creates a new internalDataWriter writing to 'w'. // // 'w' receives what is written to the *internalDataWriter but escaped according to @@ -70,13 +66,12 @@ type internalDataWriter struct { // *internalDataWriter takes care of all this for you, so you do not have to do it. func newDataWriter(w io.Writer) *internalDataWriter { writer := internalDataWriter{ - wrapped:w, + wrapped: w, } return &writer } - // Write writes the TELNET (and TELNETS) escaped data for of the data in 'data' to the wrapped io.Writer. func (w *internalDataWriter) Write(data []byte) (n int, err error) { var n64 int64 @@ -90,7 +85,6 @@ func (w *internalDataWriter) Write(data []byte) (n int, err error) { return n, err } - func (w *internalDataWriter) write64(data []byte) (n int64, err error) { if len(data) <= 0 { @@ -115,7 +109,6 @@ func (w *internalDataWriter) write64(data []byte) (n int64, err error) { buffer.Reset() } - var numWritten int64 //@TODO: Should we worry about "iaciac" potentially being modified by the .Write()? numWritten, err = oi.LongWrite(w.wrapped, iaciac)