Highly-opinionated (ex-bullshit-free) MTPROTO proxy for Telegram. If you use v1.0 or upgrade broke you proxy, please read the chapter Version 2
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

certificate_server.go 1.8KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. package faketls
  2. import (
  3. "bytes"
  4. "container/ring"
  5. "context"
  6. "crypto/tls"
  7. "errors"
  8. "fmt"
  9. "net"
  10. "strconv"
  11. "time"
  12. "go.uber.org/zap"
  13. "mtg/config"
  14. )
  15. type connectionServer struct {
  16. nextWriteItem *ring.Ring
  17. nextReadItem *ring.Ring
  18. ctx context.Context
  19. channelGet chan chan<- []byte
  20. }
  21. func (c *connectionServer) get() ([]byte, error) {
  22. resp := make(chan []byte)
  23. select {
  24. case <-c.ctx.Done():
  25. return nil, errors.New("context closed")
  26. case c.channelGet <- resp:
  27. return <-resp, nil
  28. }
  29. }
  30. func (c *connectionServer) fetch() ([]byte, error) {
  31. addr := net.JoinHostPort(config.C.CloakHost, strconv.Itoa(config.C.CloakPort))
  32. conn, err := tls.Dial("tcp", addr, &tls.Config{InsecureSkipVerify: true}) // nolint: gosec
  33. if err != nil {
  34. return nil, fmt.Errorf("cannot connect to the masked host: %w", err)
  35. }
  36. defer conn.Close()
  37. if err = conn.Handshake(); err != nil {
  38. return nil, fmt.Errorf("cannot perform tls handshake: %w", err)
  39. }
  40. certificates := conn.ConnectionState().PeerCertificates
  41. if len(certificates) == 0 {
  42. return nil, errors.New("no certificates is found")
  43. }
  44. var buf bytes.Buffer
  45. for _, v := range certificates {
  46. buf.Write(v.Raw)
  47. }
  48. return buf.Bytes(), nil
  49. }
  50. func (c *connectionServer) run(tickEvery time.Duration) {
  51. logger := zap.S().Named("tls-connection-server")
  52. ticker := time.NewTicker(tickEvery)
  53. defer ticker.Stop()
  54. for {
  55. select {
  56. case <-c.ctx.Done():
  57. return
  58. case resp := <-c.channelGet:
  59. resp <- c.nextReadItem.Value.([]byte)
  60. close(resp)
  61. c.nextReadItem = c.nextReadItem.Next()
  62. case <-ticker.C:
  63. cert, err := c.fetch()
  64. switch err {
  65. case nil:
  66. c.nextWriteItem.Value = cert
  67. c.nextWriteItem = c.nextWriteItem.Next()
  68. default:
  69. logger.Warnw("cannot fetch certificates", "error", err)
  70. }
  71. }
  72. }
  73. }