https.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. // Copyright 2016 fatedier, fatedier@gmail.com
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package vhost
  15. import (
  16. "fmt"
  17. "io"
  18. "net"
  19. "strings"
  20. "time"
  21. "frp/utils/conn"
  22. )
  23. const (
  24. typeClientHello uint8 = 1 // Type client hello
  25. )
  26. // TLS extension numbers
  27. const (
  28. extensionServerName uint16 = 0
  29. extensionStatusRequest uint16 = 5
  30. extensionSupportedCurves uint16 = 10
  31. extensionSupportedPoints uint16 = 11
  32. extensionSignatureAlgorithms uint16 = 13
  33. extensionALPN uint16 = 16
  34. extensionSCT uint16 = 18
  35. extensionSessionTicket uint16 = 35
  36. extensionNextProtoNeg uint16 = 13172 // not IANA assigned
  37. extensionRenegotiationInfo uint16 = 0xff01
  38. )
  39. type HttpsMuxer struct {
  40. *VhostMuxer
  41. }
  42. func NewHttpsMuxer(listener *conn.Listener, timeout time.Duration) (*HttpsMuxer, error) {
  43. mux, err := NewVhostMuxer(listener, GetHttpsHostname, nil, timeout)
  44. return &HttpsMuxer{mux}, err
  45. }
  46. func readHandshake(rd io.Reader) (host string, err error) {
  47. data := make([]byte, 1024)
  48. length, err := rd.Read(data)
  49. if err != nil {
  50. return
  51. } else {
  52. if length < 47 {
  53. err = fmt.Errorf("readHandshake: proto length[%d] is too short", length)
  54. return
  55. }
  56. }
  57. data = data[:length]
  58. if uint8(data[5]) != typeClientHello {
  59. err = fmt.Errorf("readHandshake: type[%d] is not clientHello", uint16(data[5]))
  60. return
  61. }
  62. // session
  63. sessionIdLen := int(data[43])
  64. if sessionIdLen > 32 || len(data) < 44+sessionIdLen {
  65. err = fmt.Errorf("readHandshake: sessionIdLen[%d] is long", sessionIdLen)
  66. return
  67. }
  68. data = data[44+sessionIdLen:]
  69. if len(data) < 2 {
  70. err = fmt.Errorf("readHandshake: dataLen[%d] after session is short", len(data))
  71. return
  72. }
  73. // cipher suite numbers
  74. cipherSuiteLen := int(data[0])<<8 | int(data[1])
  75. if cipherSuiteLen%2 == 1 || len(data) < 2+cipherSuiteLen {
  76. err = fmt.Errorf("readHandshake: dataLen[%d] after cipher suite is short", len(data))
  77. return
  78. }
  79. data = data[2+cipherSuiteLen:]
  80. if len(data) < 1 {
  81. err = fmt.Errorf("readHandshake: cipherSuiteLen[%d] is long", cipherSuiteLen)
  82. return
  83. }
  84. // compression method
  85. compressionMethodsLen := int(data[0])
  86. if len(data) < 1+compressionMethodsLen {
  87. err = fmt.Errorf("readHandshake: compressionMethodsLen[%d] is long", compressionMethodsLen)
  88. return
  89. }
  90. data = data[1+compressionMethodsLen:]
  91. if len(data) == 0 {
  92. // ClientHello is optionally followed by extension data
  93. err = fmt.Errorf("readHandshake: there is no extension data to get servername")
  94. return
  95. }
  96. if len(data) < 2 {
  97. err = fmt.Errorf("readHandshake: extension dataLen[%d] is too short")
  98. return
  99. }
  100. extensionsLength := int(data[0])<<8 | int(data[1])
  101. data = data[2:]
  102. if extensionsLength != len(data) {
  103. err = fmt.Errorf("readHandshake: extensionsLen[%d] is not equal to dataLen[%d]", extensionsLength, len(data))
  104. return
  105. }
  106. for len(data) != 0 {
  107. if len(data) < 4 {
  108. err = fmt.Errorf("readHandshake: extensionsDataLen[%d] is too short", len(data))
  109. return
  110. }
  111. extension := uint16(data[0])<<8 | uint16(data[1])
  112. length := int(data[2])<<8 | int(data[3])
  113. data = data[4:]
  114. if len(data) < length {
  115. err = fmt.Errorf("readHandshake: extensionLen[%d] is long", length)
  116. return
  117. }
  118. switch extension {
  119. case extensionRenegotiationInfo:
  120. if length != 1 || data[0] != 0 {
  121. err = fmt.Errorf("readHandshake: extension reNegotiationInfoLen[%d] is short", length)
  122. return
  123. }
  124. case extensionNextProtoNeg:
  125. case extensionStatusRequest:
  126. case extensionServerName:
  127. d := data[:length]
  128. if len(d) < 2 {
  129. err = fmt.Errorf("readHandshake: remiaining dataLen[%d] is short", len(d))
  130. return
  131. }
  132. namesLen := int(d[0])<<8 | int(d[1])
  133. d = d[2:]
  134. if len(d) != namesLen {
  135. err = fmt.Errorf("readHandshake: nameListLen[%d] is not equal to dataLen[%d]", namesLen, len(d))
  136. return
  137. }
  138. for len(d) > 0 {
  139. if len(d) < 3 {
  140. err = fmt.Errorf("readHandshake: extension serverNameLen[%d] is short", len(d))
  141. return
  142. }
  143. nameType := d[0]
  144. nameLen := int(d[1])<<8 | int(d[2])
  145. d = d[3:]
  146. if len(d) < nameLen {
  147. err = fmt.Errorf("readHandshake: nameLen[%d] is not equal to dataLen[%d]", nameLen, len(d))
  148. return
  149. }
  150. if nameType == 0 {
  151. serverName := string(d[:nameLen])
  152. host = strings.TrimSpace(serverName)
  153. return host, nil
  154. }
  155. d = d[nameLen:]
  156. }
  157. }
  158. data = data[length:]
  159. }
  160. err = fmt.Errorf("Unknow error")
  161. return
  162. }
  163. func GetHttpsHostname(c *conn.Conn) (sc net.Conn, routerName string, err error) {
  164. sc, rd := newShareConn(c.TcpConn)
  165. host, err := readHandshake(rd)
  166. if err != nil {
  167. return sc, "", err
  168. }
  169. return sc, host, nil
  170. }