Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

socket.go 2.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. // Copyright (c) 2012-2014 Jeremy Latt
  2. // Copyright (c) 2016- Daniel Oaks <daniel@danieloaks.net>
  3. // released under the MIT license
  4. package irc
  5. import (
  6. "bufio"
  7. "crypto/sha256"
  8. "crypto/tls"
  9. "encoding/hex"
  10. "errors"
  11. "io"
  12. "net"
  13. "strings"
  14. "time"
  15. )
  16. var (
  17. errNotTLS = errors.New("Not a TLS connection")
  18. errNoPeerCerts = errors.New("Client did not provide a certificate")
  19. handshakeTimeout, _ = time.ParseDuration("5s")
  20. )
  21. // Socket represents an IRC socket.
  22. type Socket struct {
  23. Closed bool
  24. conn net.Conn
  25. reader *bufio.Reader
  26. }
  27. // NewSocket returns a new Socket.
  28. func NewSocket(conn net.Conn) Socket {
  29. return Socket{
  30. conn: conn,
  31. reader: bufio.NewReader(conn),
  32. }
  33. }
  34. // Close stops a Socket from being able to send/receive any more data.
  35. func (socket *Socket) Close() {
  36. if socket.Closed {
  37. return
  38. }
  39. socket.Closed = true
  40. socket.conn.Close()
  41. }
  42. // CertFP returns the fingerprint of the certificate provided by the client.
  43. func (socket *Socket) CertFP() (string, error) {
  44. var tlsConn, isTLS = socket.conn.(*tls.Conn)
  45. if !isTLS {
  46. return "", errNotTLS
  47. }
  48. // ensure handehake is performed, and timeout after a few seconds
  49. tlsConn.SetDeadline(time.Now().Add(handshakeTimeout))
  50. err := tlsConn.Handshake()
  51. tlsConn.SetDeadline(time.Time{})
  52. if err != nil {
  53. return "", err
  54. }
  55. peerCerts := tlsConn.ConnectionState().PeerCertificates
  56. if len(peerCerts) < 1 {
  57. return "", errNoPeerCerts
  58. }
  59. rawCert := sha256.Sum256(peerCerts[0].Raw)
  60. fingerprint := hex.EncodeToString(rawCert[:])
  61. return fingerprint, nil
  62. }
  63. // Read returns a single IRC line from a Socket.
  64. func (socket *Socket) Read() (string, error) {
  65. if socket.Closed {
  66. return "", io.EOF
  67. }
  68. lineBytes, err := socket.reader.ReadBytes('\n')
  69. // convert bytes to string
  70. line := string(lineBytes[:])
  71. // read last message properly (such as ERROR/QUIT/etc), just fail next reads/writes
  72. if err == io.EOF {
  73. socket.Close()
  74. }
  75. if err == io.EOF && strings.TrimSpace(line) != "" {
  76. // don't do anything
  77. } else if err != nil {
  78. return "", err
  79. }
  80. return strings.TrimRight(line, "\r\n"), nil
  81. }
  82. // Write sends the given string out of Socket.
  83. func (socket *Socket) Write(data string) error {
  84. if socket.Closed {
  85. return io.EOF
  86. }
  87. // write data
  88. _, err := socket.conn.Write([]byte(data))
  89. if err != nil {
  90. socket.Close()
  91. return err
  92. }
  93. return nil
  94. }
  95. // WriteLine writes the given line out of Socket.
  96. func (socket *Socket) WriteLine(line string) error {
  97. return socket.Write(line + "\r\n")
  98. }