redact_test.go 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /*
  2. * Copyright (c) 2020, 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 common
  20. import (
  21. "os"
  22. "strings"
  23. "testing"
  24. )
  25. func TestRedactIPAddresses(t *testing.T) {
  26. testCases := []struct {
  27. description string
  28. input string
  29. expectedOutput string
  30. escape bool
  31. }{
  32. {
  33. "IPv4 address",
  34. "prefix 192.168.0.1 suffix",
  35. "prefix [redacted] suffix",
  36. false,
  37. },
  38. {
  39. "IPv6 address",
  40. "prefix 2001:0db8:0000:0000:0000:ff00:0042:8329 suffix",
  41. "prefix [redacted] suffix",
  42. false,
  43. },
  44. {
  45. "Remove leading zeros IPv6 address",
  46. "prefix 2001:db8:0:0:0:ff00:42:8329 suffix",
  47. "prefix [redacted] suffix",
  48. false,
  49. },
  50. {
  51. "Omit consecutive zeros sections IPv6 address",
  52. "prefix 2001:db8::ff00:42:8329 suffix",
  53. "prefix [redacted] suffix",
  54. false,
  55. },
  56. {
  57. "IPv4 mapped/translated/embedded address",
  58. "prefix 0::ffff:192.168.0.1, 0::ffff:0:192.168.0.1, 64:ff9b::192.168.0.1 suffix",
  59. "prefix [redacted], [redacted], [redacted] suffix",
  60. false,
  61. },
  62. {
  63. "IPv4 address and port",
  64. "read tcp 127.0.0.1:1025->127.0.0.1:8000: use of closed network connection",
  65. "read tcp [redacted]->[redacted]: use of closed network connection",
  66. false,
  67. },
  68. {
  69. "IPv6 address and port",
  70. "read tcp [2001:db8::ff00:42:8329]:1025->[2001:db8::ff00:42:8329]:8000: use of closed network connection",
  71. "read tcp [redacted]->[redacted]: use of closed network connection",
  72. false,
  73. },
  74. {
  75. "Loopback IPv6 address and invalid port number",
  76. "dial tcp [::1]:88888: network is unreachable",
  77. "dial tcp [redacted]: network is unreachable",
  78. false,
  79. },
  80. {
  81. "Numbers and periods",
  82. "prefix 192. 168. 0. 1 suffix",
  83. "prefix 192. 168. 0. 1 suffix",
  84. false,
  85. },
  86. {
  87. "Hex string and colon",
  88. "prefix 0123456789abcdef: suffix",
  89. "prefix 0123456789abcdef: suffix",
  90. false,
  91. },
  92. {
  93. "Colons",
  94. "prefix :: suffix",
  95. "prefix :: suffix",
  96. false,
  97. },
  98. {
  99. "Notice",
  100. `{"data":{"SSHClientVersion":"SSH-2.0-C","candidateNumber":0,"diagnosticID":"se0XVQ/4","dialPortNumber":"4000","establishedTunnelsCount":0,"isReplay":false,"networkLatencyMultiplier":2.8284780852763953,"networkType":"WIFI","protocol":"OSSH","region":"US","upstream_ossh_padding":7077},"noticeType":"ConnectedServer","timestamp":"2020-12-16T14:07:02.030Z"}`,
  101. `{"data":{"SSHClientVersion":"SSH-2.0-C","candidateNumber":0,"diagnosticID":"se0XVQ/4","dialPortNumber":"4000","establishedTunnelsCount":0,"isReplay":false,"networkLatencyMultiplier":2.8284780852763953,"networkType":"WIFI","protocol":"OSSH","region":"US","upstream_ossh_padding":7077},"noticeType":"ConnectedServer","timestamp":"2020-12-16T14:07:02.030Z"}`,
  102. false,
  103. },
  104. {
  105. "escape IPv4 address and port",
  106. "prefix 192.168.0.1:443 suffix",
  107. "prefix 192\\.168\\.0\\.1\\:443 suffix",
  108. true,
  109. },
  110. {
  111. "escape IPv6 address and port",
  112. "prefix [2001:db8::ff00:42:8329]:443 suffix",
  113. "prefix [2001\\:db8\\:\\:ff00\\:42\\:8329]\\:443 suffix",
  114. true,
  115. },
  116. }
  117. for _, testCase := range testCases {
  118. t.Run(testCase.description, func(t *testing.T) {
  119. input := testCase.input
  120. if testCase.escape {
  121. input = EscapeRedactIPAddressString(input)
  122. }
  123. output := RedactIPAddressesString(input)
  124. if output != testCase.expectedOutput {
  125. t.Errorf("unexpected output: %s", output)
  126. }
  127. })
  128. }
  129. }
  130. func TestRedactFilePaths(t *testing.T) {
  131. testCases := []struct {
  132. description string
  133. input string
  134. expectedOutput string
  135. filePaths []string
  136. }{
  137. {
  138. "Absolute path",
  139. "prefix /a suffix",
  140. "prefix [redacted] suffix",
  141. nil,
  142. },
  143. {
  144. "Absolute path with directories",
  145. "prefix /a/b/c/d suffix",
  146. "prefix [redacted] suffix",
  147. nil,
  148. },
  149. {
  150. "Relative path 1",
  151. "prefix ./a/b/c/d suffix",
  152. "prefix [redacted] suffix",
  153. nil,
  154. },
  155. {
  156. "Relative path 2",
  157. "prefix a/b/c/d suffix",
  158. "prefix [redacted] suffix",
  159. nil,
  160. },
  161. {
  162. "Relative path 3",
  163. "prefix ../a/b/c/d/../ suffix",
  164. "prefix [redacted] suffix",
  165. nil,
  166. },
  167. {
  168. "File path with home directory tilde",
  169. "prefix ~/a/b/c/d suffix",
  170. "prefix [redacted] suffix",
  171. nil,
  172. },
  173. {
  174. "Multiple file paths",
  175. "prefix /a/b c/d suffix",
  176. "prefix [redacted] [redacted] suffix",
  177. nil,
  178. },
  179. {
  180. "File path with percent encoded spaces",
  181. "prefix /a/b%20c/d suffix",
  182. "prefix [redacted] suffix",
  183. nil,
  184. },
  185. {
  186. "Strip file paths unhandled case",
  187. "prefix /a/file name with spaces /e/f/g/ suffix",
  188. "prefix [redacted] name with spaces [redacted] suffix",
  189. nil,
  190. },
  191. {
  192. "Strip file paths catch unhandled case with provided path",
  193. "prefix /a/file name with spaces /e/f/g/ suffix",
  194. "prefix [redacted] [redacted] suffix",
  195. []string{"/a/file name with spaces"},
  196. },
  197. }
  198. for _, testCase := range testCases {
  199. t.Run(testCase.description, func(t *testing.T) {
  200. // For convenience replace separators in input string and
  201. // file paths with the OS-specific path separator here instead
  202. // constructing the test input strings with os.PathSeparator.
  203. input := strings.ReplaceAll(testCase.input, "/", string(os.PathSeparator))
  204. var filePaths []string
  205. for _, filePath := range testCase.filePaths {
  206. filePaths = append(filePaths, strings.ReplaceAll(filePath, "/", string(os.PathSeparator)))
  207. }
  208. output := RedactFilePaths(input, filePaths...)
  209. if output != testCase.expectedOutput {
  210. t.Errorf("unexpected output: %s", output)
  211. }
  212. })
  213. }
  214. }