auth_sha1_v4.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. package protocol
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "hash/adler32"
  6. "hash/crc32"
  7. "math/rand"
  8. "net"
  9. "github.com/Dreamacro/clash/common/pool"
  10. "github.com/Dreamacro/clash/transport/ssr/tools"
  11. )
  12. func init() {
  13. register("auth_sha1_v4", newAuthSHA1V4, 7)
  14. }
  15. type authSHA1V4 struct {
  16. *Base
  17. *authData
  18. iv []byte
  19. hasSentHeader bool
  20. rawTrans bool
  21. }
  22. func newAuthSHA1V4(b *Base) Protocol {
  23. return &authSHA1V4{Base: b, authData: &authData{}}
  24. }
  25. func (a *authSHA1V4) StreamConn(c net.Conn, iv []byte) net.Conn {
  26. p := &authSHA1V4{Base: a.Base, authData: a.next()}
  27. p.iv = iv
  28. return &Conn{Conn: c, Protocol: p}
  29. }
  30. func (a *authSHA1V4) PacketConn(c net.PacketConn) net.PacketConn {
  31. return c
  32. }
  33. func (a *authSHA1V4) Decode(dst, src *bytes.Buffer) error {
  34. if a.rawTrans {
  35. dst.ReadFrom(src)
  36. return nil
  37. }
  38. for src.Len() > 4 {
  39. if uint16(crc32.ChecksumIEEE(src.Bytes()[:2])&0xffff) != binary.LittleEndian.Uint16(src.Bytes()[2:4]) {
  40. src.Reset()
  41. return errAuthSHA1V4CRC32Error
  42. }
  43. length := int(binary.BigEndian.Uint16(src.Bytes()[:2]))
  44. if length >= 8192 || length < 7 {
  45. a.rawTrans = true
  46. src.Reset()
  47. return errAuthSHA1V4LengthError
  48. }
  49. if length > src.Len() {
  50. break
  51. }
  52. if adler32.Checksum(src.Bytes()[:length-4]) != binary.LittleEndian.Uint32(src.Bytes()[length-4:length]) {
  53. a.rawTrans = true
  54. src.Reset()
  55. return errAuthSHA1V4Adler32Error
  56. }
  57. pos := int(src.Bytes()[4])
  58. if pos < 255 {
  59. pos += 4
  60. } else {
  61. pos = int(binary.BigEndian.Uint16(src.Bytes()[5:7])) + 4
  62. }
  63. dst.Write(src.Bytes()[pos : length-4])
  64. src.Next(length)
  65. }
  66. return nil
  67. }
  68. func (a *authSHA1V4) Encode(buf *bytes.Buffer, b []byte) error {
  69. if !a.hasSentHeader {
  70. dataLength := getDataLength(b)
  71. a.packAuthData(buf, b[:dataLength])
  72. b = b[dataLength:]
  73. a.hasSentHeader = true
  74. }
  75. for len(b) > 8100 {
  76. a.packData(buf, b[:8100])
  77. b = b[8100:]
  78. }
  79. if len(b) > 0 {
  80. a.packData(buf, b)
  81. }
  82. return nil
  83. }
  84. func (a *authSHA1V4) DecodePacket(b []byte) ([]byte, error) { return b, nil }
  85. func (a *authSHA1V4) EncodePacket(buf *bytes.Buffer, b []byte) error {
  86. buf.Write(b)
  87. return nil
  88. }
  89. func (a *authSHA1V4) packData(poolBuf *bytes.Buffer, data []byte) {
  90. dataLength := len(data)
  91. randDataLength := a.getRandDataLength(dataLength)
  92. /*
  93. 2: uint16 BigEndian packedDataLength
  94. 2: uint16 LittleEndian crc32Data & 0xffff
  95. 3: maxRandDataLengthPrefix (min:1)
  96. 4: adler32Data
  97. */
  98. packedDataLength := 2 + 2 + 3 + randDataLength + dataLength + 4
  99. if randDataLength < 128 {
  100. packedDataLength -= 2
  101. }
  102. binary.Write(poolBuf, binary.BigEndian, uint16(packedDataLength))
  103. binary.Write(poolBuf, binary.LittleEndian, uint16(crc32.ChecksumIEEE(poolBuf.Bytes()[poolBuf.Len()-2:])&0xffff))
  104. a.packRandData(poolBuf, randDataLength)
  105. poolBuf.Write(data)
  106. binary.Write(poolBuf, binary.LittleEndian, adler32.Checksum(poolBuf.Bytes()[poolBuf.Len()-packedDataLength+4:]))
  107. }
  108. func (a *authSHA1V4) packAuthData(poolBuf *bytes.Buffer, data []byte) {
  109. dataLength := len(data)
  110. randDataLength := a.getRandDataLength(12 + dataLength)
  111. /*
  112. 2: uint16 BigEndian packedAuthDataLength
  113. 4: uint32 LittleEndian crc32Data
  114. 3: maxRandDataLengthPrefix (min: 1)
  115. 12: authDataLength
  116. 10: hmacSHA1DataLength
  117. */
  118. packedAuthDataLength := 2 + 4 + 3 + randDataLength + 12 + dataLength + 10
  119. if randDataLength < 128 {
  120. packedAuthDataLength -= 2
  121. }
  122. salt := []byte("auth_sha1_v4")
  123. crcData := pool.Get(len(salt) + len(a.Key) + 2)
  124. defer pool.Put(crcData)
  125. binary.BigEndian.PutUint16(crcData, uint16(packedAuthDataLength))
  126. copy(crcData[2:], salt)
  127. copy(crcData[2+len(salt):], a.Key)
  128. key := pool.Get(len(a.iv) + len(a.Key))
  129. defer pool.Put(key)
  130. copy(key, a.iv)
  131. copy(key[len(a.iv):], a.Key)
  132. poolBuf.Write(crcData[:2])
  133. binary.Write(poolBuf, binary.LittleEndian, crc32.ChecksumIEEE(crcData))
  134. a.packRandData(poolBuf, randDataLength)
  135. a.putAuthData(poolBuf)
  136. poolBuf.Write(data)
  137. poolBuf.Write(tools.HmacSHA1(key, poolBuf.Bytes()[poolBuf.Len()-packedAuthDataLength+10:])[:10])
  138. }
  139. func (a *authSHA1V4) packRandData(poolBuf *bytes.Buffer, size int) {
  140. if size < 128 {
  141. poolBuf.WriteByte(byte(size + 1))
  142. tools.AppendRandBytes(poolBuf, size)
  143. return
  144. }
  145. poolBuf.WriteByte(255)
  146. binary.Write(poolBuf, binary.BigEndian, uint16(size+3))
  147. tools.AppendRandBytes(poolBuf, size)
  148. }
  149. func (a *authSHA1V4) getRandDataLength(size int) int {
  150. if size > 1200 {
  151. return 0
  152. }
  153. if size > 400 {
  154. return rand.Intn(256)
  155. }
  156. return rand.Intn(512)
  157. }