package main
import( // / . "fmt" // Unix networks sockets, including TCP/IP, UDP . // TCP . "net" // "os" // / "bufio" // "crypto/rsa" // "crypto/rand" // sha1 "crypto/sha1" // "strconv" // "big" )
Further access to the package will occur by its name through a dot.fmt
. Println()
, os
. Exit()
, etc. const( // tcp tcpProtocol = "tcp4" // rsa keySize = 1024 // readWriterSize = keySize/8 )
type remoteConn struct { c *net.TCPConn pubK *rsa.PublicKey }
An asterisk "*", before the variable type, means that the variable is a link to the data of the declared typeerr
whose type is os.Error .os.Error
). func checkErr(err os.Error){ if err != nil { // fmt.Println(err) // os.Exit(1) } }
listenAddr
declare the global variable listenAddr
which will be a reference to the structure of type net.TCPAddr var listenAddr = &net.TCPAddr{IP: net.IPv4(192,168,0,4), Port: 0}
Ampersand "&" before net.TCPAddr will return a reference to this type.remoteConn
structure.remoteConn
and not the value. func getRemoteConn(c *net.TCPConn) *remoteConn{ return &remoteConn{c: c, pubK: waitPubKey(bufio.NewReader())} }
bufio.NewReader()
- creates a buffer byte from the connection "c". Return type *bufio.Reader
(link to bufio.Reader
)waitPubKey()
- expects from the "client" when he in a certain sequence passes PublicKey
*bufio.Reader
) which in turn contains all the bytes coming from the connection "c" // rsa.PublicKey func waitPubKey(buf *bufio.Reader) (*rsa.PublicKey) { // line, _, err := buf.ReadLine(); checkErr(err) // line - []byte ( ) // <code><b>line</b></code> if string(line) == "CONNECT" { // , line, _, err := buf.ReadLine(); checkErr(err) // PublicKey.N // rsa.PublicKey pubKey := rsa.PublicKey{N: big.NewInt(0)} // pubKey.N == 0 // pubKey.N big.Int http://golang.org/pkg/big/#Int // pubKey.N big.Int pubKey.N.SetString(string(line), 10) // SetString() 2 : // string(line) - // 10 - // (2 , 8 , 10 , 16 ...) // pubKey.E line, _, err = buf.ReadLine(); checkErr(err) // strconv string int pubKey.E, err = strconv.Atoi(string(line)); checkErr(err) // rsa.PublicKey return &pubKey } else { // . : // fmt.Println("Error: unkown command ", string(line)) os.Exit(1) // } return nil }
remoteConn
func (rConn *remoteConn) sendCommand(comm string) { // eComm, err := rsa.EncryptOAEP(sha1.New(), rand.Reader, rConn.pubK, []byte(comm), nil) // sha1.New() hash.Hash // sha512.New() sha256.New() ... // rand.Reader io.Reader // /dev/unrandom Linux CryptGenRandom API Windows // rConn.pubK - func waitPubKey // []byte(comm) - comm ([]byte) checkErr(err) // // rConn.c.Write(eComm) // rConn.c ? - net.TCPConn Write() // http://golang.org/pkg/net/#TCPConn.Write }
func listen() { // l, err := net.ListenTCP(tcpProtocol, listenAddr); checkErr(err) // fmt.Println("Listen port: ", l.Addr().(*net.TCPAddr).Port) // l == *net.TCPListener == // .Addr() http://golang.org/pkg/net/#TCPListener.Addr == *net.TCPListener "" // net.Addr http://golang.org/pkg/net/#Addr TCPAddr - *net.TCPAddr // Network() String() c, err := l.AcceptTCP(); checkErr(err) // // AcceptTCP() - *net.TCPListener http://golang.org/pkg/net/#TCPListener.AcceptTCP // fmt.Println("Connect from:", c.RemoteAddr()) // 3 fmt.Print[f|ln]() // 1. c.RemoteAddr() // 2. c.RemoteAddr().(*net.TCPAddr) // 3. c.RemoteAddr().String() // : fmt.Println(), fmt.Print(), fmt.Printf() String() // // rConn := getRemoteConn() // rConn.sendCommand("Go Language Server v0.1 for learning") rConn.sendCommand("!") rConn.sendCommand("і!") rConn.sendCommand("і!") rConn.sendCommand("Hello!") rConn.sendCommand("Salut!") rConn.sendCommand("ハイ!") rConn.sendCommand("您好!") rConn.sendCommand("안녕!") rConn.sendCommand("Hej!") }
func main() { listen() }
package main import( "fmt" "net" "os" "bufio" "crypto/rsa" "crypto/rand" "crypto/sha1" "strconv" ) const( tcpProtocol = "tcp4" keySize = 1024 readWriterSize = keySize/8 ) func checkErr(err os.Error){ if err != nil { fmt.Println(err) os.Exit(1) } } var connectAddr = &net.TCPAddr{IP: net.IPv4(192,168,0,2), Port: 0} // func connectTo() *net.TCPConn{ // "Enter port:" fmt.Print("Enter port:") // "%d" fmt.Scanf("%d", &connectAddr.Port) // Scanf fmt.Println("Connect to", connectAddr) // c ,err := net.DialTCP(tcpProtocol, nil, connectAddr); checkErr(err) return c } // PublicKey func sendKey(c *net.TCPConn, k *rsa.PrivateKey) { // PublicKey c.Write([]byte("CONNECT\n")) // N *big.Int c.Write([]byte(k.PublicKey.N.String() + "\n")) // String() *big.Int string // E int c.Write([]byte(strconv.Itoa(k.PublicKey.E) + "\n")) // strconv.Itoa() int string // []byte() "" } // // func getBytes(buf *bufio.Reader, n int) []byte { // n bytes, err:= buf.Peek(n); checkErr(err) // n skipBytes(buf, n) return bytes } // , func skipBytes(buf *bufio.Reader, skipCount int){ for i:=0; i<skipCount; i++ { buf.ReadByte() } } func main() { // c := connectTo() // "c" buf := bufio.NewReader() // k, err := rsa.GenerateKey(rand.Reader, keySize); checkErr(err) // sendKey(c, k) // for { // cryptMsg := getBytes(buf, readWriterSize) // msg, err := rsa.DecryptOAEP(sha1.New(), rand.Reader, k, cryptMsg, nil) // checkErr(err) // fmt.Println(string(msg)) } }
Source: https://habr.com/ru/post/126461/
All Articles