hostname.go 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. /*
  2. * Copyright (c) 2015, Psiphon Inc.
  3. * All rights reserved.
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. *
  18. */
  19. package transferstats
  20. import (
  21. "bufio"
  22. "bytes"
  23. "net/http"
  24. )
  25. // getHostname attempts to determine the hostname of the server from the request data.
  26. func getHostname(buffer []byte) (hostname string, ok bool) {
  27. // Check if this is a HTTP request
  28. bufferReader := bufio.NewReader(bytes.NewReader(buffer))
  29. httpReq, httpErr := http.ReadRequest(bufferReader)
  30. if httpErr == nil {
  31. return httpReq.Host, true
  32. }
  33. // Check if it's a TLS request
  34. hostname, ok = getTLSHostname(buffer)
  35. return
  36. }
  37. /*
  38. TLS Record Protocol:
  39. Record layer content type (1B): handshake is 22: 22
  40. SSL version (2B): SSL3 is {3,0}, TLS 1.0 is {3,1}, TLS 1.2 is {3,2} TLS 1.2 is {3,3}; seems to typically be {3,1}: 3 1
  41. Plaintext envelope length (2B): maximum of 2^14, but usually much smaller: 2 0
  42. TLS Handshake Protocol:
  43. Handshake type (1B): client hello is 1: 1
  44. Handshake length (3B): will always be 4 bytes smaller than the envelope length (because the envelope length counts the handshake type and the bytes of this length, but this length does not): 0 1 252
  45. Protocol version (2B): see "SSL version" above; seems to typically be {3,3}: 3 3
  46. Random data (32B): 131 89 82 204 123 41 188 215 100 17 206 199 21 202 81 139 145 138 26 95 144 92 183 186 186 36 234 203 207 196 238 115
  47. Session ID length (1B): 32
  48. Session ID: 80 149 254 248 148 156 249 42 173 29 7 58 44 0 92 173 203 11 94 252 117 212 24 20 47 131 135 204 150 37 247 229
  49. Cipher suites length (2B): 0 24
  50. Cipher suites: e.g., TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 is 0xc02b: 192 43 192 47 192 10 192 9 192 19 192 20 0 51 0 50 0 57 0 47 0 53 0 10
  51. Compression methods length (1B): 1
  52. Compression methods: 0
  53. Extensions length (2B): 1 155
  54. ...some number of extension defs here...
  55. Extension type (2B): server_name is 0x0000: 0 0
  56. Extension length (2B): 0 25
  57. SNI list length (2B): 0 23
  58. SNI type (1B): host_name is 0x00: 0
  59. SNI hostname length (2B): 0 20
  60. SNI hostname: e.g., upload.wikimedia.org: 117 112 108 111 97 100 46 119 105 107 105 109 101 100 105 97 46 111 114 103
  61. ...more extensions...
  62. */
  63. // getTLSHostname attempts to interpret the buffer as a TLS client hello and
  64. // extract the SNI hostname from it.
  65. func getTLSHostname(buffer []byte) (hostname string, ok bool) {
  66. bufLen := uint32(len(buffer))
  67. // If the buffer is smaller than this, it can't possibly be a TLS client hello.
  68. if bufLen < 60 {
  69. return
  70. }
  71. pos := uint32(0)
  72. // Make sure this is a handshake
  73. if buffer[pos] != 22 {
  74. return
  75. }
  76. pos += 1
  77. // We'll check the first byte of the SSL version
  78. // NOTE: Not future proof.
  79. if buffer[pos] != 3 {
  80. return
  81. }
  82. pos += 2
  83. plaintextLen := uint32(buffer[pos])<<8 | uint32(buffer[pos+1])
  84. if plaintextLen < (60-3) || plaintextLen > bufLen {
  85. return
  86. }
  87. pos += 2
  88. // Make sure handshake type is client hello
  89. if buffer[pos] != 1 {
  90. return
  91. }
  92. pos += 1
  93. // Make sure handshake length is expected size.
  94. handshakeLen := uint32(buffer[pos])<<16 | uint32(buffer[pos+1])<<8 | uint32(buffer[pos+2])
  95. if handshakeLen+4 != plaintextLen {
  96. return
  97. }
  98. pos += 3
  99. // Check the first byte of protocol version
  100. // NOTE: Not future proof.
  101. if buffer[pos] != 3 {
  102. return
  103. }
  104. pos += 2
  105. // Skip 32 bytes of random data
  106. pos += 32
  107. sessionIDLen := uint32(buffer[pos])
  108. pos += 1
  109. if sessionIDLen > bufLen-pos {
  110. return
  111. }
  112. pos += sessionIDLen
  113. // At this point we can't trust that our initial minimum length check will
  114. // save us from going out-of-bounds on the buffer slice, so we'll have to
  115. // do buffer length checks as we go.
  116. // Skip over the cipher suites. In theory we could check them, but we're not going to.
  117. if pos+2 > bufLen {
  118. return
  119. }
  120. cipherSuitesLen := uint32(buffer[pos])<<8 | uint32(buffer[pos+1])
  121. pos += 2
  122. if cipherSuitesLen > bufLen-pos {
  123. return
  124. }
  125. pos += cipherSuitesLen
  126. // Skip compression methods
  127. if pos+1 > bufLen {
  128. return
  129. }
  130. compressionMethodsLen := uint32(buffer[pos])
  131. pos += 1
  132. if compressionMethodsLen > bufLen-pos {
  133. return
  134. }
  135. pos += compressionMethodsLen
  136. // Extensions
  137. if pos+2 > bufLen {
  138. return
  139. }
  140. extensionsLen := uint32(buffer[pos])<<8 | uint32(buffer[pos+1])
  141. pos += 2
  142. if extensionsLen > bufLen-pos {
  143. return
  144. }
  145. // Go through each extension entry, looking for the SNI
  146. for {
  147. if pos+2 > bufLen {
  148. return
  149. }
  150. extensionType := uint32(buffer[pos])<<8 | uint32(buffer[pos+1])
  151. pos += 2
  152. if pos+2 > bufLen {
  153. return
  154. }
  155. extensionLen := uint32(buffer[pos])<<8 | uint32(buffer[pos+1])
  156. pos += 2
  157. // server_name extension type is 0x0000
  158. if extensionType != 0 {
  159. pos += extensionLen
  160. continue
  161. }
  162. // Basic santiy check on the SNI list length
  163. if pos+2 > bufLen {
  164. return
  165. }
  166. sniListLen := uint32(buffer[pos])<<8 | uint32(buffer[pos+1])
  167. pos += 2
  168. if sniListLen > extensionLen {
  169. return
  170. }
  171. // Check the SNI type. There's only one allowed value in the spec: hostname (0x00)
  172. if pos+1 > bufLen {
  173. return
  174. }
  175. sniType := uint32(buffer[pos])
  176. pos += 1
  177. if sniType != 0 {
  178. return
  179. }
  180. // Finally, the goal: the hostname
  181. if pos+2 > bufLen {
  182. return
  183. }
  184. hostnameLen := uint32(buffer[pos])<<8 | uint32(buffer[pos+1])
  185. pos += 2
  186. if hostnameLen > bufLen-pos {
  187. return
  188. }
  189. hostname = string(buffer[pos : pos+hostnameLen])
  190. return hostname, true
  191. }
  192. }