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