├── .github └── ISSUE_TEMPLATE.md ├── 1.png ├── 2.png ├── DNSCrypt-Menubar ├── DNSCrypt-Menubar.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata ├── DNSCrypt-Menubar │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── DNSCrypt-Menubar-Info.plist │ ├── DNSCrypt-Menubar-Prefix.pch │ ├── Icons.xcassets │ │ ├── Active.imageset │ │ │ ├── Active.pdf │ │ │ └── Contents.json │ │ ├── Contents.json │ │ ├── Inactive.imageset │ │ │ ├── Contents.json │ │ │ └── Inactive.pdf │ │ └── No-Network.imageset │ │ │ ├── Contents.json │ │ │ └── No-Network.pdf │ ├── dnscrypt.iconset │ │ └── icon_512x512.png │ ├── en.lproj │ │ ├── InfoPlist.strings │ │ └── MainMenu.xib │ ├── led_bw.png │ └── main.m └── Icons template.svg ├── DNSCrypt-OSX-Installer ├── DNSCrypt-OSX-Installer.pkgproj ├── Scripts │ ├── dnscrypt-menubar-postinstall.sh │ ├── dnscrypt-menubar-preinstall.sh │ ├── dnscrypt-prefpane-postinstall.sh │ └── dnscrypt-prefpane-preinstall.sh ├── com.github.dnscrypt-osxclient.DNSCryptAfterboot.plist ├── com.github.dnscrypt-osxclient.DNSCryptConsoleChange.plist ├── com.github.dnscrypt-osxclient.DNSCryptControlChange.plist ├── com.github.dnscrypt-osxclient.DNSCryptMenuBar.plist ├── com.github.dnscrypt-osxclient.DNSCryptNetworkChange.plist └── sign.sh ├── DNSCrypt-Preference-Pane ├── DNSCrypt.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata └── DNSCrypt │ ├── CHCSVParser │ ├── CHCSVParser.h │ └── CHCSVParser.m │ ├── DNSCrypt-Info.plist │ ├── DNSCrypt-Prefix.pch │ ├── DNSCrypt.h │ ├── DNSCrypt.m │ ├── NSPlaceHolderTextView.h │ ├── NSPlaceHolderTextView.m │ ├── ajax-loader.gif │ ├── dnscrypt_256.png │ ├── en.lproj │ ├── DNSCrypt.xib │ └── InfoPlist.strings │ ├── extra │ ├── html │ │ ├── about.haml │ │ ├── about.html │ │ ├── help.haml │ │ ├── help.html │ │ ├── releasenotes.haml │ │ ├── releasenotes.html │ │ └── update.sh │ └── usr │ │ ├── bin │ │ ├── Uninstall.app │ │ │ └── Contents │ │ │ │ ├── Info.plist │ │ │ │ ├── MacOS │ │ │ │ └── applet │ │ │ │ ├── PkgInfo │ │ │ │ └── Resources │ │ │ │ ├── Scripts │ │ │ │ └── main.scpt │ │ │ │ ├── applet.icns │ │ │ │ ├── applet.rsrc │ │ │ │ └── description.rtfd │ │ │ │ └── TXT.rtf │ │ ├── alarmer │ │ ├── hostip │ │ ├── lockfile │ │ └── minisign-verify │ │ ├── lib │ │ ├── libldns.1.dylib │ │ └── libldns.dylib │ │ └── scripts │ │ ├── afterboot.sh │ │ ├── check-network-change.sh │ │ ├── clear-fw.sh │ │ ├── common.inc │ │ ├── create-ticket.sh │ │ ├── get-aaaa-blocking-status.sh │ │ ├── get-blocked-query-logging-status.sh │ │ ├── get-current-default-domain.sh │ │ ├── get-current-resolvers.sh │ │ ├── get-dhcp-resolvers.sh │ │ ├── get-dnscrypt-resolver-name.sh │ │ ├── get-dnscrypt-status.sh │ │ ├── get-hide-menubar-icon-status.sh │ │ ├── get-query-logging-status.sh │ │ ├── get-random-resolver.sh │ │ ├── get-resolvers-description.sh │ │ ├── get-static-resolvers.sh │ │ ├── get-tickets-count.sh │ │ ├── get-upstream-resolvers.sh │ │ ├── gui-pop-conf-change.sh │ │ ├── gui-push-conf-change.sh │ │ ├── handle-console-change.sh │ │ ├── handle-control-change.sh │ │ ├── handle-network-change.sh │ │ ├── set-dns-to-dhcp.sh │ │ ├── set-dns.sh │ │ ├── set-dnscrypt-resolver-name.sh │ │ ├── set-static-resolvers.sh │ │ ├── start-dnscrypt-proxy.sh │ │ ├── stop-dnscrypt-proxy.sh │ │ ├── switch-aaaa-blocking-off.sh │ │ ├── switch-aaaa-blocking-on.sh │ │ ├── switch-blacklists-off.sh │ │ ├── switch-blacklists-on.sh │ │ ├── switch-blocked-query-logging-off.sh │ │ ├── switch-blocked-query-logging-on.sh │ │ ├── switch-cache-off.sh │ │ ├── switch-cache-on.sh │ │ ├── switch-exceptions-off.sh │ │ ├── switch-exceptions-on.sh │ │ ├── switch-hide-menubar-icon-off.sh │ │ ├── switch-hide-menubar-icon-on.sh │ │ ├── switch-query-logging-off.sh │ │ ├── switch-query-logging-on.sh │ │ ├── switch-to-dhcp-if-required.sh │ │ ├── switch-to-dhcp.sh │ │ ├── switch-to-dnscrypt-if-required.sh │ │ ├── switch-to-dnscrypt.sh │ │ ├── update-blacklist-domains.sh │ │ ├── update-blacklist-ips.sh │ │ ├── update-dnscrypt-app.sh │ │ ├── update-exceptions.sh │ │ └── update-resolvers-list.sh │ ├── led_green.png │ ├── led_red.png │ ├── led_yellow.png │ ├── shield_green.png │ ├── shield_red.png │ ├── shield_yellow.png │ └── update.sh ├── DNSCrypt-Uninstaller └── Uninstall.scpt ├── FAQ.md ├── Pages ├── feedback.haml ├── feedback.php ├── feedback.tpl └── sent.haml ├── README.markdown ├── alterstep-pgp-key.pub ├── minisign.pub └── updates ├── versions.txt └── versions.txt.minisig /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ***************************************************************************************************************** 7 | 8 | Before creating an issue, please read the FAQ: https://github.com/alterstep/dnscrypt-osxclient/blob/master/FAQ.md 9 | 10 | Informations and debug logs as explained here are almost always more useful that screenshots! 11 | 12 | Thank you! 13 | 14 | ***************************************************************************************************************** 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stammy/dnscrypt-osx-client/69fdd9c44cc7e19c05608cfd463e55829de43416/1.png -------------------------------------------------------------------------------- /2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stammy/dnscrypt-osx-client/69fdd9c44cc7e19c05608cfd463e55829de43416/2.png -------------------------------------------------------------------------------- /DNSCrypt-Menubar/DNSCrypt-Menubar.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 091360731C88418E00F308D3 /* dnscrypt.iconset in Resources */ = {isa = PBXBuildFile; fileRef = 091360721C88418E00F308D3 /* dnscrypt.iconset */; }; 11 | 09A13AD2145F3B9000B227A4 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 09A13AD1145F3B9000B227A4 /* Cocoa.framework */; }; 12 | 09A13ADC145F3B9000B227A4 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 09A13ADA145F3B9000B227A4 /* InfoPlist.strings */; }; 13 | 09A13ADE145F3B9000B227A4 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 09A13ADD145F3B9000B227A4 /* main.m */; }; 14 | 09A13AE5145F3B9000B227A4 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 09A13AE4145F3B9000B227A4 /* AppDelegate.m */; }; 15 | 09A13AE8145F3B9000B227A4 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 09A13AE6145F3B9000B227A4 /* MainMenu.xib */; }; 16 | F622E21B1C88C76800721313 /* Icons.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F622E21A1C88C76800721313 /* Icons.xcassets */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXCopyFilesBuildPhase section */ 20 | 0970EAA9160A5B0000865D5D /* CopyFiles */ = { 21 | isa = PBXCopyFilesBuildPhase; 22 | buildActionMask = 2147483647; 23 | dstPath = ""; 24 | dstSubfolderSpec = 10; 25 | files = ( 26 | ); 27 | runOnlyForDeploymentPostprocessing = 0; 28 | }; 29 | /* End PBXCopyFilesBuildPhase section */ 30 | 31 | /* Begin PBXFileReference section */ 32 | 091360721C88418E00F308D3 /* dnscrypt.iconset */ = {isa = PBXFileReference; lastKnownFileType = folder.iconset; path = dnscrypt.iconset; sourceTree = ""; }; 33 | 09A13ACD145F3B9000B227A4 /* DNSCrypt Menubar.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "DNSCrypt Menubar.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 34 | 09A13AD1145F3B9000B227A4 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 35 | 09A13AD4145F3B9000B227A4 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; 36 | 09A13AD5145F3B9000B227A4 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; 37 | 09A13AD6145F3B9000B227A4 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 38 | 09A13AD9145F3B9000B227A4 /* DNSCrypt-Menubar-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "DNSCrypt-Menubar-Info.plist"; sourceTree = ""; }; 39 | 09A13ADB145F3B9000B227A4 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 40 | 09A13ADD145F3B9000B227A4 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 41 | 09A13ADF145F3B9000B227A4 /* DNSCrypt-Menubar-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "DNSCrypt-Menubar-Prefix.pch"; sourceTree = ""; }; 42 | 09A13AE3145F3B9000B227A4 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 43 | 09A13AE4145F3B9000B227A4 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 44 | 09A13AE7145F3B9000B227A4 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainMenu.xib; sourceTree = ""; }; 45 | F622E21A1C88C76800721313 /* Icons.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Icons.xcassets; sourceTree = ""; }; 46 | /* End PBXFileReference section */ 47 | 48 | /* Begin PBXFrameworksBuildPhase section */ 49 | 09A13ACA145F3B9000B227A4 /* Frameworks */ = { 50 | isa = PBXFrameworksBuildPhase; 51 | buildActionMask = 2147483647; 52 | files = ( 53 | 09A13AD2145F3B9000B227A4 /* Cocoa.framework in Frameworks */, 54 | ); 55 | runOnlyForDeploymentPostprocessing = 0; 56 | }; 57 | /* End PBXFrameworksBuildPhase section */ 58 | 59 | /* Begin PBXGroup section */ 60 | 09A13AC2145F3B9000B227A4 = { 61 | isa = PBXGroup; 62 | children = ( 63 | 09A13AD7145F3B9000B227A4 /* DNSCrypt-Menubar */, 64 | 09A13AD0145F3B9000B227A4 /* Frameworks */, 65 | 09A13ACE145F3B9000B227A4 /* Products */, 66 | ); 67 | sourceTree = ""; 68 | }; 69 | 09A13ACE145F3B9000B227A4 /* Products */ = { 70 | isa = PBXGroup; 71 | children = ( 72 | 09A13ACD145F3B9000B227A4 /* DNSCrypt Menubar.app */, 73 | ); 74 | name = Products; 75 | sourceTree = ""; 76 | }; 77 | 09A13AD0145F3B9000B227A4 /* Frameworks */ = { 78 | isa = PBXGroup; 79 | children = ( 80 | 09A13AD1145F3B9000B227A4 /* Cocoa.framework */, 81 | 09A13AD3145F3B9000B227A4 /* Other Frameworks */, 82 | ); 83 | name = Frameworks; 84 | sourceTree = ""; 85 | }; 86 | 09A13AD3145F3B9000B227A4 /* Other Frameworks */ = { 87 | isa = PBXGroup; 88 | children = ( 89 | 09A13AD4145F3B9000B227A4 /* AppKit.framework */, 90 | 09A13AD5145F3B9000B227A4 /* CoreData.framework */, 91 | 09A13AD6145F3B9000B227A4 /* Foundation.framework */, 92 | ); 93 | name = "Other Frameworks"; 94 | sourceTree = ""; 95 | }; 96 | 09A13AD7145F3B9000B227A4 /* DNSCrypt-Menubar */ = { 97 | isa = PBXGroup; 98 | children = ( 99 | 09A13AE3145F3B9000B227A4 /* AppDelegate.h */, 100 | 09A13AE4145F3B9000B227A4 /* AppDelegate.m */, 101 | 09A13AE6145F3B9000B227A4 /* MainMenu.xib */, 102 | 09A13AD8145F3B9000B227A4 /* Supporting Files */, 103 | ); 104 | path = "DNSCrypt-Menubar"; 105 | sourceTree = ""; 106 | }; 107 | 09A13AD8145F3B9000B227A4 /* Supporting Files */ = { 108 | isa = PBXGroup; 109 | children = ( 110 | 091360721C88418E00F308D3 /* dnscrypt.iconset */, 111 | F622E21A1C88C76800721313 /* Icons.xcassets */, 112 | 09A13AD9145F3B9000B227A4 /* DNSCrypt-Menubar-Info.plist */, 113 | 09A13ADA145F3B9000B227A4 /* InfoPlist.strings */, 114 | 09A13ADD145F3B9000B227A4 /* main.m */, 115 | 09A13ADF145F3B9000B227A4 /* DNSCrypt-Menubar-Prefix.pch */, 116 | ); 117 | name = "Supporting Files"; 118 | sourceTree = ""; 119 | }; 120 | /* End PBXGroup section */ 121 | 122 | /* Begin PBXNativeTarget section */ 123 | 09A13ACC145F3B9000B227A4 /* DNSCrypt-Menubar */ = { 124 | isa = PBXNativeTarget; 125 | buildConfigurationList = 09A13AEB145F3B9000B227A4 /* Build configuration list for PBXNativeTarget "DNSCrypt-Menubar" */; 126 | buildPhases = ( 127 | 09A13AC9145F3B9000B227A4 /* Sources */, 128 | 09A13ACA145F3B9000B227A4 /* Frameworks */, 129 | 09A13ACB145F3B9000B227A4 /* Resources */, 130 | 0970EAA9160A5B0000865D5D /* CopyFiles */, 131 | ); 132 | buildRules = ( 133 | ); 134 | dependencies = ( 135 | ); 136 | name = "DNSCrypt-Menubar"; 137 | productName = "DNSCrypt-Menubar"; 138 | productReference = 09A13ACD145F3B9000B227A4 /* DNSCrypt Menubar.app */; 139 | productType = "com.apple.product-type.application"; 140 | }; 141 | /* End PBXNativeTarget section */ 142 | 143 | /* Begin PBXProject section */ 144 | 09A13AC4145F3B9000B227A4 /* Project object */ = { 145 | isa = PBXProject; 146 | attributes = { 147 | LastUpgradeCheck = 0510; 148 | }; 149 | buildConfigurationList = 09A13AC7145F3B9000B227A4 /* Build configuration list for PBXProject "DNSCrypt-Menubar" */; 150 | compatibilityVersion = "Xcode 3.2"; 151 | developmentRegion = English; 152 | hasScannedForEncodings = 0; 153 | knownRegions = ( 154 | en, 155 | ); 156 | mainGroup = 09A13AC2145F3B9000B227A4; 157 | productRefGroup = 09A13ACE145F3B9000B227A4 /* Products */; 158 | projectDirPath = ""; 159 | projectRoot = ""; 160 | targets = ( 161 | 09A13ACC145F3B9000B227A4 /* DNSCrypt-Menubar */, 162 | ); 163 | }; 164 | /* End PBXProject section */ 165 | 166 | /* Begin PBXResourcesBuildPhase section */ 167 | 09A13ACB145F3B9000B227A4 /* Resources */ = { 168 | isa = PBXResourcesBuildPhase; 169 | buildActionMask = 2147483647; 170 | files = ( 171 | 09A13ADC145F3B9000B227A4 /* InfoPlist.strings in Resources */, 172 | 09A13AE8145F3B9000B227A4 /* MainMenu.xib in Resources */, 173 | F622E21B1C88C76800721313 /* Icons.xcassets in Resources */, 174 | 091360731C88418E00F308D3 /* dnscrypt.iconset in Resources */, 175 | ); 176 | runOnlyForDeploymentPostprocessing = 0; 177 | }; 178 | /* End PBXResourcesBuildPhase section */ 179 | 180 | /* Begin PBXSourcesBuildPhase section */ 181 | 09A13AC9145F3B9000B227A4 /* Sources */ = { 182 | isa = PBXSourcesBuildPhase; 183 | buildActionMask = 2147483647; 184 | files = ( 185 | 09A13ADE145F3B9000B227A4 /* main.m in Sources */, 186 | 09A13AE5145F3B9000B227A4 /* AppDelegate.m in Sources */, 187 | ); 188 | runOnlyForDeploymentPostprocessing = 0; 189 | }; 190 | /* End PBXSourcesBuildPhase section */ 191 | 192 | /* Begin PBXVariantGroup section */ 193 | 09A13ADA145F3B9000B227A4 /* InfoPlist.strings */ = { 194 | isa = PBXVariantGroup; 195 | children = ( 196 | 09A13ADB145F3B9000B227A4 /* en */, 197 | ); 198 | name = InfoPlist.strings; 199 | sourceTree = ""; 200 | }; 201 | 09A13AE6145F3B9000B227A4 /* MainMenu.xib */ = { 202 | isa = PBXVariantGroup; 203 | children = ( 204 | 09A13AE7145F3B9000B227A4 /* en */, 205 | ); 206 | name = MainMenu.xib; 207 | sourceTree = ""; 208 | }; 209 | /* End PBXVariantGroup section */ 210 | 211 | /* Begin XCBuildConfiguration section */ 212 | 09A13AE9145F3B9000B227A4 /* Debug */ = { 213 | isa = XCBuildConfiguration; 214 | buildSettings = { 215 | ALWAYS_SEARCH_USER_PATHS = NO; 216 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; 217 | CLANG_ENABLE_OBJC_ARC = NO; 218 | CLANG_WARN_BOOL_CONVERSION = YES; 219 | CLANG_WARN_CONSTANT_CONVERSION = YES; 220 | CLANG_WARN_EMPTY_BODY = YES; 221 | CLANG_WARN_ENUM_CONVERSION = YES; 222 | CLANG_WARN_INT_CONVERSION = YES; 223 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 224 | COPY_PHASE_STRIP = NO; 225 | GCC_C_LANGUAGE_STANDARD = gnu99; 226 | GCC_DYNAMIC_NO_PIC = NO; 227 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 228 | GCC_OPTIMIZATION_LEVEL = 0; 229 | GCC_PREPROCESSOR_DEFINITIONS = ( 230 | "DEBUG=1", 231 | "$(inherited)", 232 | ); 233 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 234 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 235 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 236 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 237 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 238 | GCC_WARN_UNDECLARED_SELECTOR = YES; 239 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 240 | GCC_WARN_UNUSED_FUNCTION = YES; 241 | GCC_WARN_UNUSED_VARIABLE = YES; 242 | MACOSX_DEPLOYMENT_TARGET = 10.6; 243 | ONLY_ACTIVE_ARCH = YES; 244 | SDKROOT = macosx; 245 | }; 246 | name = Debug; 247 | }; 248 | 09A13AEA145F3B9000B227A4 /* Release */ = { 249 | isa = XCBuildConfiguration; 250 | buildSettings = { 251 | ALWAYS_SEARCH_USER_PATHS = NO; 252 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; 253 | CLANG_ENABLE_OBJC_ARC = NO; 254 | CLANG_WARN_BOOL_CONVERSION = YES; 255 | CLANG_WARN_CONSTANT_CONVERSION = YES; 256 | CLANG_WARN_EMPTY_BODY = YES; 257 | CLANG_WARN_ENUM_CONVERSION = YES; 258 | CLANG_WARN_INT_CONVERSION = YES; 259 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 260 | COPY_PHASE_STRIP = NO; 261 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 262 | GCC_C_LANGUAGE_STANDARD = gnu99; 263 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 264 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 265 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 266 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 267 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 268 | GCC_WARN_UNDECLARED_SELECTOR = YES; 269 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 270 | GCC_WARN_UNUSED_FUNCTION = YES; 271 | GCC_WARN_UNUSED_VARIABLE = YES; 272 | MACOSX_DEPLOYMENT_TARGET = 10.6; 273 | SDKROOT = macosx; 274 | }; 275 | name = Release; 276 | }; 277 | 09A13AEC145F3B9000B227A4 /* Debug */ = { 278 | isa = XCBuildConfiguration; 279 | buildSettings = { 280 | ARCHS = "$(ARCHS_STANDARD_64_BIT)"; 281 | CLANG_ENABLE_OBJC_ARC = YES; 282 | COMBINE_HIDPI_IMAGES = YES; 283 | FRAMEWORK_SEARCH_PATHS = ( 284 | "$(inherited)", 285 | "\"$(SRCROOT)\"", 286 | "\"$(SRCROOT)/../../../../../Library/Developer/Xcode/DerivedData/Sparkle-evkudstnytcsfdeunmxihhpyexor/Build/Products/Release\"", 287 | ); 288 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 289 | GCC_PREFIX_HEADER = "DNSCrypt-Menubar/DNSCrypt-Menubar-Prefix.pch"; 290 | INFOPLIST_FILE = "DNSCrypt-Menubar/DNSCrypt-Menubar-Info.plist"; 291 | MACOSX_DEPLOYMENT_TARGET = 10.8; 292 | PRODUCT_NAME = "DNSCrypt Menubar"; 293 | WRAPPER_EXTENSION = app; 294 | }; 295 | name = Debug; 296 | }; 297 | 09A13AED145F3B9000B227A4 /* Release */ = { 298 | isa = XCBuildConfiguration; 299 | buildSettings = { 300 | ARCHS = "$(ARCHS_STANDARD_64_BIT)"; 301 | CLANG_ENABLE_OBJC_ARC = YES; 302 | COMBINE_HIDPI_IMAGES = YES; 303 | FRAMEWORK_SEARCH_PATHS = ( 304 | "$(inherited)", 305 | "\"$(SRCROOT)\"", 306 | "\"$(SRCROOT)/../../../../../Library/Developer/Xcode/DerivedData/Sparkle-evkudstnytcsfdeunmxihhpyexor/Build/Products/Release\"", 307 | ); 308 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 309 | GCC_PREFIX_HEADER = "DNSCrypt-Menubar/DNSCrypt-Menubar-Prefix.pch"; 310 | INFOPLIST_FILE = "DNSCrypt-Menubar/DNSCrypt-Menubar-Info.plist"; 311 | MACOSX_DEPLOYMENT_TARGET = 10.8; 312 | PRODUCT_NAME = "DNSCrypt Menubar"; 313 | WRAPPER_EXTENSION = app; 314 | }; 315 | name = Release; 316 | }; 317 | /* End XCBuildConfiguration section */ 318 | 319 | /* Begin XCConfigurationList section */ 320 | 09A13AC7145F3B9000B227A4 /* Build configuration list for PBXProject "DNSCrypt-Menubar" */ = { 321 | isa = XCConfigurationList; 322 | buildConfigurations = ( 323 | 09A13AE9145F3B9000B227A4 /* Debug */, 324 | 09A13AEA145F3B9000B227A4 /* Release */, 325 | ); 326 | defaultConfigurationIsVisible = 0; 327 | defaultConfigurationName = Release; 328 | }; 329 | 09A13AEB145F3B9000B227A4 /* Build configuration list for PBXNativeTarget "DNSCrypt-Menubar" */ = { 330 | isa = XCConfigurationList; 331 | buildConfigurations = ( 332 | 09A13AEC145F3B9000B227A4 /* Debug */, 333 | 09A13AED145F3B9000B227A4 /* Release */, 334 | ); 335 | defaultConfigurationIsVisible = 0; 336 | defaultConfigurationName = Release; 337 | }; 338 | /* End XCConfigurationList section */ 339 | }; 340 | rootObject = 09A13AC4145F3B9000B227A4 /* Project object */; 341 | } 342 | -------------------------------------------------------------------------------- /DNSCrypt-Menubar/DNSCrypt-Menubar.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /DNSCrypt-Menubar/DNSCrypt-Menubar/AppDelegate.h: -------------------------------------------------------------------------------- 1 | 2 | #import 3 | 4 | #define kDNSCRYPT_PREFPANE_APP_PATH @"/Library/PreferencePanes/DNSCrypt.prefPane" 5 | #define kDNSCRYPT_USR_BASE_DIR kDNSCRYPT_PREFPANE_APP_PATH @"/Contents/Resources/usr" 6 | #define kDNSCRIPT_SCRIPTS_BASE_DIR kDNSCRYPT_USR_BASE_DIR @"/scripts" 7 | #define kDNSCRYPT_VAR_BASE_DIR @"/Library/Application Support/DNSCrypt" 8 | #define kDNSCRYPT_CONTROL_DIR kDNSCRYPT_VAR_BASE_DIR @"/control" 9 | 10 | @interface AppDelegate : NSObject { 11 | NSWindow *__weak _window; 12 | NSMenu *_dnscryptMenu; 13 | NSStatusItem *_statusItem; 14 | NSMenuItem *_versionMenuItem; 15 | NSMenuItem *_statusResolversMenuItem; 16 | NSMenuItem *_dnscryptMenuItem; 17 | } 18 | 19 | #define kREFRESH_DELAY 2.0 20 | #define kCHECKBOXES_AFTER_CHANGE_DELAY 8.0 21 | #define kMAX_TRIES_AFTER_CHANGE (30 / kREFRESH_DELAY) 22 | 23 | typedef enum { 24 | kDNS_CONFIGURATION_UNKNOWN, kDNS_CONFIGURATION_VANILLA, kDNS_CONFIGURATION_LOCALHOST 25 | } DNSConfigurationState; 26 | 27 | @property (strong) NSStatusItem *statusItem; 28 | @property (weak) NSWindow *window; 29 | 30 | @property (strong) IBOutlet NSMenu *dnscryptMenu; 31 | @property (strong) IBOutlet NSMenuItem *versionMenuItem; 32 | @property (strong) IBOutlet NSMenuItem *statusResolversMenuItem; 33 | @property (strong) IBOutlet NSMenuItem *dnscryptMenuItem; 34 | 35 | - (IBAction)preferencesMenuItemPushed:(NSMenuItem *)sender; 36 | - (IBAction)dnscryptMenuItemPushed:(NSMenuItem *)sender; 37 | - (IBAction)hideMenubarIconMenuItemPushed:(NSMenuItem *)sender; 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /DNSCrypt-Menubar/DNSCrypt-Menubar/AppDelegate.m: -------------------------------------------------------------------------------- 1 | 2 | #import "AppDelegate.h" 3 | 4 | @implementation AppDelegate 5 | @synthesize statusResolversMenuItem = _statusResolversMenuItem; 6 | @synthesize dnscryptMenuItem = _dnscryptMenuItem; 7 | @synthesize window = _window; 8 | @synthesize dnscryptMenu = _dnscryptMenu; 9 | @synthesize statusItem = _statusItem; 10 | @synthesize versionMenuItem = _versionMenuItem; 11 | 12 | DNSConfigurationState currentState = kDNS_CONFIGURATION_UNKNOWN; 13 | BOOL appUpdated = FALSE; 14 | 15 | - (void) setCheckBoxesEnabled: (BOOL) enabled 16 | { 17 | [_dnscryptMenuItem setEnabled: enabled]; 18 | } 19 | 20 | - (NSString *) fromCommand: (NSString *) launchPath withArguments: (NSArray *) arguments 21 | { 22 | NSPipe *pipe = [NSPipe pipe]; 23 | NSTask *task = [[NSTask alloc] init]; 24 | NSData *data; 25 | NSString *result; 26 | task.launchPath = launchPath; 27 | task.arguments = arguments; 28 | task.standardOutput = pipe; 29 | [task launch]; 30 | data = [[pipe fileHandleForReading] readDataToEndOfFile]; 31 | [task waitUntilExit]; 32 | result = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding]; 33 | if ([result hasSuffix: @"\n"]) { 34 | result = [result substringToIndex: result.length - 1]; 35 | } 36 | return result; 37 | } 38 | 39 | - (void) initState 40 | { 41 | NSString *res; 42 | 43 | _dnscryptMenuItem.state = 0; 44 | 45 | res = [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-c", @"cd '" kDNSCRIPT_SCRIPTS_BASE_DIR @"' && exec ./get-dnscrypt-status.sh", nil]]; 46 | if ([res isEqualToString: @"yes"]) { 47 | [_dnscryptMenuItem setState: 1]; 48 | } 49 | } 50 | 51 | - (BOOL) resolversForService: (NSArray *) resolversForService includeResolvers:(NSArray *) resolvers 52 | { 53 | NSUInteger matches = 0U; 54 | 55 | for (NSString *resolverForService in resolversForService) { 56 | if ([resolvers containsObject: resolverForService]) { 57 | matches++; 58 | } else { 59 | break; 60 | } 61 | } 62 | if (matches >= resolvers.count) { 63 | return TRUE; 64 | } 65 | return FALSE; 66 | } 67 | 68 | - (void) updateLedStatus 69 | { 70 | NSImage *led = nil; 71 | 72 | switch (currentState) { 73 | case kDNS_CONFIGURATION_LOCALHOST: 74 | led = [NSImage imageNamed: @"Active"]; 75 | break; 76 | case kDNS_CONFIGURATION_VANILLA: 77 | led = [NSImage imageNamed: @"Inactive"]; 78 | break; 79 | default: 80 | led = [NSImage imageNamed: @"No-Network"]; 81 | } 82 | [led setTemplate:YES]; 83 | _statusItem.image = led; 84 | } 85 | 86 | - (BOOL) updateStatusWithCurrentConfig 87 | { 88 | NSString *stateDescription = [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-c", @"cd '" kDNSCRIPT_SCRIPTS_BASE_DIR @"' && ./get-current-resolvers.sh | ./get-resolvers-description.sh", nil]]; 89 | if ([stateDescription isEqualToString: @"DNSCrypt"]) { 90 | currentState = kDNS_CONFIGURATION_LOCALHOST; 91 | if (appUpdated == FALSE) { 92 | appUpdated = TRUE; 93 | [self appUpdate]; 94 | } 95 | } else if ([stateDescription isEqualToString: @"None"]) { 96 | currentState = kDNS_CONFIGURATION_UNKNOWN; 97 | } else if ([stateDescription isEqualToString: @"Updating"]) { 98 | currentState = kDNS_CONFIGURATION_UNKNOWN; 99 | } else if (stateDescription.length > 0) { 100 | currentState = kDNS_CONFIGURATION_VANILLA; 101 | } 102 | [self updateLedStatus]; 103 | 104 | NSString *hideMenuBar = [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-c", @"cd '" kDNSCRIPT_SCRIPTS_BASE_DIR @"' && ./get-hide-menubar-icon-status.sh | ./get-upstream-resolvers.sh", nil]]; 105 | 106 | if ([hideMenuBar isEqualToString: @"yes"]) { 107 | _statusItem.visible = FALSE; 108 | } else if ([hideMenuBar isEqualToString: @"no"]) { 109 | _statusItem.visible = TRUE; 110 | } 111 | 112 | NSString *currentResolvers = [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-c", @"cd '" kDNSCRIPT_SCRIPTS_BASE_DIR @"' && ./get-current-resolvers.sh | ./get-upstream-resolvers.sh", nil]]; 113 | _statusResolversMenuItem.title = currentResolvers; 114 | 115 | NSString *res = [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-c", @"cd '" kDNSCRIPT_SCRIPTS_BASE_DIR @"' && exec ./gui-pop-conf-change.sh menubar", nil]]; 116 | if ([res isEqualToString: @"yes"]) { 117 | [self initState]; 118 | } 119 | [self setCheckBoxesEnabled: TRUE]; 120 | 121 | return TRUE; 122 | } 123 | 124 | - (void) periodicallyUpdateStatusWithCurrentConfig { 125 | [self updateStatusWithCurrentConfig]; 126 | [NSObject cancelPreviousPerformRequestsWithTarget: self selector: @selector(periodicallyUpdateStatusWithCurrentConfig) object: nil]; 127 | [self performSelector: @selector(periodicallyUpdateStatusWithCurrentConfig) withObject:nil afterDelay: 5.0]; 128 | } 129 | 130 | - (void) waitForUpdate { 131 | NSString *res; 132 | static unsigned int tries; 133 | 134 | res = [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-c", @"cd '" kDNSCRIPT_SCRIPTS_BASE_DIR @"' && exec ./get-tickets-count.sh", nil]]; 135 | if (res.length <= 0 || [res isEqualToString: @"0"] || tries > kMAX_TRIES_AFTER_CHANGE) { 136 | tries = 0U; 137 | [self periodicallyUpdateStatusWithCurrentConfig]; 138 | return; 139 | } 140 | tries++; 141 | [NSObject cancelPreviousPerformRequestsWithTarget: self selector: @selector(waitForUpdate) object: nil]; 142 | [self performSelector: @selector(waitForUpdate) withObject: self afterDelay:kREFRESH_DELAY]; 143 | } 144 | 145 | - (void) showSpinners 146 | { 147 | [self setCheckBoxesEnabled: FALSE]; 148 | 149 | NSImage *led = [NSImage imageNamed: @"No-Network"]; 150 | _statusItem.image = led; 151 | 152 | [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-c", @"cd '" kDNSCRIPT_SCRIPTS_BASE_DIR @"' && exec ./gui-push-conf-change.sh prefpane", nil]]; 153 | 154 | [NSObject cancelPreviousPerformRequestsWithTarget: self selector: @selector(periodicallyUpdateStatusWithCurrentConfig) object: nil]; 155 | [NSObject cancelPreviousPerformRequestsWithTarget: self selector: @selector(waitForUpdate) object: nil]; 156 | [self performSelector: @selector(waitForUpdate) withObject: self afterDelay:kREFRESH_DELAY]; 157 | } 158 | 159 | - (void) awakeFromNib 160 | { 161 | _statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength]; 162 | _statusItem.highlightMode = TRUE; 163 | _statusItem.toolTip = @"DNSCrypt"; 164 | _statusItem.menu = _dnscryptMenu; 165 | 166 | NSString *versionStringFormat = NSLocalizedString(@"Client UI version: %@", @"Current UI version as shown in the menu"); 167 | NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]; 168 | _versionMenuItem.title = [NSString stringWithFormat: versionStringFormat, version]; 169 | 170 | [self initState]; 171 | 172 | [self periodicallyUpdateStatusWithCurrentConfig]; 173 | [self updateLedStatus]; 174 | } 175 | 176 | - (void)applicationDidFinishLaunching:(NSNotification *)aNotification 177 | { 178 | } 179 | 180 | - (IBAction)preferencesMenuItemPushed:(NSMenuItem *)sender 181 | { 182 | NSString *userPreferencePanePath = [NSString stringWithFormat: @"%@" kDNSCRYPT_PREFPANE_APP_PATH, NSHomeDirectory()]; 183 | NSArray *preferencePanePaths = [NSArray arrayWithObjects: userPreferencePanePath, kDNSCRYPT_PREFPANE_APP_PATH, nil]; 184 | for (NSString *preferencePanePath in preferencePanePaths) { 185 | if ([[NSFileManager defaultManager] fileExistsAtPath: preferencePanePath]) { 186 | [[NSWorkspace sharedWorkspace] openFile: preferencePanePath]; 187 | return; 188 | } 189 | } 190 | } 191 | 192 | - (BOOL) setDNSCryptOn { 193 | [self showSpinners]; 194 | NSString *res = [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-c", @"cd '" kDNSCRIPT_SCRIPTS_BASE_DIR @"' && ./create-ticket.sh && ./switch-to-dnscrypt.sh", nil]]; 195 | (void) res; 196 | return TRUE; 197 | } 198 | 199 | - (BOOL) setDNSCryptOff { 200 | [self showSpinners]; 201 | NSString *res = [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-c", @"cd '" kDNSCRIPT_SCRIPTS_BASE_DIR @"' && ./create-ticket.sh && ./switch-to-dhcp.sh", nil]]; 202 | (void) res; 203 | return TRUE; 204 | } 205 | 206 | - (BOOL) appUpdate { 207 | NSString *res = [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-c", @"cd '" kDNSCRIPT_SCRIPTS_BASE_DIR @"' && exec ./update-dnscrypt-app.sh", nil]]; 208 | (void) res; 209 | return TRUE; 210 | } 211 | 212 | 213 | - (IBAction)dnscryptMenuItemPushed:(NSMenuItem *)sender 214 | { 215 | if (sender.state == 0) { 216 | sender.state = 1; 217 | [self setDNSCryptOn]; 218 | } else { 219 | sender.state = 0; 220 | [self setDNSCryptOff]; 221 | } 222 | } 223 | 224 | - (BOOL) setHideMenubarIconOn { 225 | [self showSpinners]; 226 | NSString *res = [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-c", @"cd '" kDNSCRIPT_SCRIPTS_BASE_DIR @"' && ./create-ticket.sh && ./switch-hide-menubar-icon-on.sh", nil]]; 227 | (void) res; 228 | _statusItem.visible = FALSE; 229 | return TRUE; 230 | } 231 | 232 | - (IBAction)hideMenubarIconMenuItemPushed:(NSMenuItem *)sender 233 | { 234 | [self setHideMenubarIconOn]; 235 | } 236 | 237 | @end 238 | -------------------------------------------------------------------------------- /DNSCrypt-Menubar/DNSCrypt-Menubar/DNSCrypt-Menubar-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | dnscrypt.icns 11 | CFBundleIdentifier 12 | com.github.dnscrypt-osxclient.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | DNSCrypt 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0.14 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0.14 25 | LSApplicationCategoryType 26 | public.app-category.utilities 27 | LSMinimumSystemVersion 28 | ${MACOSX_DEPLOYMENT_TARGET} 29 | LSUIElement 30 | 31 | NSHumanReadableCopyright 32 | BSD 33 | NSMainNibFile 34 | MainMenu 35 | NSPrincipalClass 36 | NSApplication 37 | 38 | 39 | -------------------------------------------------------------------------------- /DNSCrypt-Menubar/DNSCrypt-Menubar/DNSCrypt-Menubar-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'DNSCrypt-Menubar' target in the 'DNSCrypt-Menubar' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /DNSCrypt-Menubar/DNSCrypt-Menubar/Icons.xcassets/Active.imageset/Active.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stammy/dnscrypt-osx-client/69fdd9c44cc7e19c05608cfd463e55829de43416/DNSCrypt-Menubar/DNSCrypt-Menubar/Icons.xcassets/Active.imageset/Active.pdf -------------------------------------------------------------------------------- /DNSCrypt-Menubar/DNSCrypt-Menubar/Icons.xcassets/Active.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "Active.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /DNSCrypt-Menubar/DNSCrypt-Menubar/Icons.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /DNSCrypt-Menubar/DNSCrypt-Menubar/Icons.xcassets/Inactive.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "Inactive.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /DNSCrypt-Menubar/DNSCrypt-Menubar/Icons.xcassets/Inactive.imageset/Inactive.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stammy/dnscrypt-osx-client/69fdd9c44cc7e19c05608cfd463e55829de43416/DNSCrypt-Menubar/DNSCrypt-Menubar/Icons.xcassets/Inactive.imageset/Inactive.pdf -------------------------------------------------------------------------------- /DNSCrypt-Menubar/DNSCrypt-Menubar/Icons.xcassets/No-Network.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "No-Network.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /DNSCrypt-Menubar/DNSCrypt-Menubar/Icons.xcassets/No-Network.imageset/No-Network.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stammy/dnscrypt-osx-client/69fdd9c44cc7e19c05608cfd463e55829de43416/DNSCrypt-Menubar/DNSCrypt-Menubar/Icons.xcassets/No-Network.imageset/No-Network.pdf -------------------------------------------------------------------------------- /DNSCrypt-Menubar/DNSCrypt-Menubar/dnscrypt.iconset/icon_512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stammy/dnscrypt-osx-client/69fdd9c44cc7e19c05608cfd463e55829de43416/DNSCrypt-Menubar/DNSCrypt-Menubar/dnscrypt.iconset/icon_512x512.png -------------------------------------------------------------------------------- /DNSCrypt-Menubar/DNSCrypt-Menubar/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /DNSCrypt-Menubar/DNSCrypt-Menubar/en.lproj/MainMenu.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /DNSCrypt-Menubar/DNSCrypt-Menubar/led_bw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stammy/dnscrypt-osx-client/69fdd9c44cc7e19c05608cfd463e55829de43416/DNSCrypt-Menubar/DNSCrypt-Menubar/led_bw.png -------------------------------------------------------------------------------- /DNSCrypt-Menubar/DNSCrypt-Menubar/main.m: -------------------------------------------------------------------------------- 1 | 2 | #import 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | nice(10); 7 | return NSApplicationMain(argc, (const char **)argv); 8 | } 9 | -------------------------------------------------------------------------------- /DNSCrypt-Menubar/Icons template.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /DNSCrypt-OSX-Installer/Scripts/dnscrypt-menubar-postinstall.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | exec 2>/dev/null 4 | 5 | /bin/launchctl load \ 6 | '/Library/LaunchAgents/com.github.dnscrypt-osxclient.DNSCryptMenuBar.plist' 7 | 8 | /bin/launchctl start com.github.dnscrypt-osxclient.DNSCryptMenuBar 9 | 10 | exit 0 11 | -------------------------------------------------------------------------------- /DNSCrypt-OSX-Installer/Scripts/dnscrypt-menubar-preinstall.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | exec 2>/dev/null 4 | 5 | /bin/launchctl stop com.opendns.osx.RoamingClientMenubar 6 | /bin/launchctl remove com.opendns.osx.RoamingClientMenubar 7 | 8 | /bin/launchctl stop com.opendns.osx.RoamingClientConfigUpdater 9 | /bin/launchctl remove com.opendns.osx.RoamingClientConfigUpdater 10 | 11 | /bin/rm -f /Library/LaunchDaemons/com.opendns.osx.Roaming*.plist 12 | 13 | /bin/launchctl stop com.opendns.osx.DNSCryptMenuBar 14 | /bin/launchctl remove com.opendns.osx.DNSCryptMenuBar 15 | 16 | /bin/launchctl stop com.github.dnscrypt-osxclient.DNSCryptMenuBar 17 | /bin/launchctl remove com.github.dnscrypt-osxclient.DNSCryptMenuBar 18 | 19 | killall 'DNSCrypt-Menubar' 20 | killall 'DNSCrypt Menubar' 21 | 22 | /bin/rm -f /Library/LaunchDaemons/com.opendns.osx.DNSCryptMenuBar.plist 23 | /bin/rm -f /Library/LaunchDaemons/com.github.dnscrypt-osxclient.DNSCryptMenuBar.plist 24 | 25 | exit 0 26 | -------------------------------------------------------------------------------- /DNSCrypt-OSX-Installer/Scripts/dnscrypt-prefpane-postinstall.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | exec 2>/dev/null 4 | 5 | /bin/mkdir -p '/Library/Application Support/DNSCrypt/control' 6 | /bin/mkdir -p '/Library/Application Support/DNSCrypt/dnscrypt-proxy' 7 | /bin/mkdir -p '/Library/Application Support/DNSCrypt/probes' 8 | /bin/mkdir -p '/Library/Application Support/DNSCrypt/states' 9 | /bin/mkdir -p '/Library/Application Support/DNSCrypt/tickets' 10 | /bin/chmod 755 '/Library/Application Support/DNSCrypt' 11 | /bin/chmod 755 '/usr/local/bin/hostip' 12 | /bin/chmod 755 '/usr/local/sbin/dnscrypt-proxy' 13 | /bin/chmod -R 755 '/usr/local/lib/dnscrypt-proxy' 14 | /usr/sbin/chown -R 0:0 '/Library/Application Support/DNSCrypt' 15 | /usr/sbin/chown 0:0 '/usr/local/bin/hostip' 16 | /usr/sbin/chown 0:0 '/usr/local/lib/dnscrypt-proxy' 17 | /usr/sbin/chown -R 0:0 '/usr/local/sbin/dnscrypt-proxy' 18 | 19 | eval $(/usr/bin/stat -s '/dev/console') 20 | if [ $? != 0 ]; then 21 | wanted_uid="$st_uid" 22 | /usr/sbin/chown -R "${wanted_uid}:0" \ 23 | '/Library/Application Support/DNSCrypt/control' 24 | /usr/sbin/chown -R "${wanted_uid}:0" \ 25 | '/Library/Application Support/DNSCrypt/tickets' 26 | fi 27 | 28 | rm -f '/Library/Application Support/DNSCrypt/control/plugin-parental-controls.enabled' 29 | rm -f '/Library/Application Support/DNSCrypt/control/plugin-lockin.enabled' 30 | 31 | for service in com.github.dnscrypt-osxclient.DNSCryptAfterboot \ 32 | com.github.dnscrypt-osxclient.DNSCryptConsoleChange \ 33 | com.github.dnscrypt-osxclient.DNSCryptControlChange \ 34 | com.github.dnscrypt-osxclient.DNSCryptNetworkChange; do 35 | /bin/launchctl load "/Library/LaunchDaemons/${service}.plist" 36 | /bin/launchctl start "$service" 37 | done 38 | 39 | /usr/bin/touch '/Library/Application Support/DNSCrypt/control' 40 | 41 | exit 0 42 | -------------------------------------------------------------------------------- /DNSCrypt-OSX-Installer/Scripts/dnscrypt-prefpane-preinstall.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | exec 2>/dev/null 4 | 5 | killall 'System Preferences' 6 | 7 | /bin/rm -rf '/Library/Application Support/DNSCrypt Updater' 8 | 9 | /bin/launchctl stop com.opendns.osx.DNSCryptConfigUpdater 10 | /bin/launchctl remove com.opendns.osx.DNSCryptConfigUpdater 11 | /bin/rm -f '/Library/LaunchDaemons/com.opendns.osx.DNSCryptConfigUpdater.plist' 12 | 13 | /bin/launchctl stop com.github.dnscrypt-osxclient.DNSCryptConfigUpdater 14 | /bin/launchctl remove com.github.dnscrypt-osxclient.DNSCryptConfigUpdater 15 | /bin/rm -f '/Library/LaunchDaemons/com.github.dnscrypt-osxclient.DNSCryptConfigUpdater.plist' 16 | 17 | /bin/launchctl stop com.opendns.osx.DNSCryptAfterboot 18 | /bin/launchctl remove com.opendns.osx.DNSCryptAfterboot 19 | /bin/launchctl stop com.opendns.osx.DNSCryptConsoleChange 20 | /bin/launchctl remove com.opendns.osx.DNSCryptConsoleChange 21 | /bin/launchctl stop com.opendns.osx.DNSCryptControlChange 22 | /bin/launchctl remove com.opendns.osx.DNSCryptControlChange 23 | /bin/launchctl stop com.opendns.osx.DNSCryptNetworkChange 24 | /bin/launchctl remove com.opendns.osx.DNSCryptNetworkChange 25 | 26 | /bin/rm -f /Library/LaunchDaemons/com.opendns.osx.DNSCryptAfterboot.plist 27 | /bin/rm -f /Library/LaunchDaemons/com.opendns.osx.DNSCryptConsoleChange.plist 28 | /bin/rm -f /Library/LaunchDaemons/com.opendns.osx.DNSCryptControlChange.plist 29 | /bin/rm -f /Library/LaunchDaemons/com.opendns.osx.DNSCryptNetworkChange.plist 30 | 31 | /bin/launchctl stop com.github.dnscrypt-osxclient.DNSCryptAfterboot 32 | /bin/launchctl remove com.github.dnscrypt-osxclient.DNSCryptAfterboot 33 | /bin/launchctl stop com.github.dnscrypt-osxclient.DNSCryptConsoleChange 34 | /bin/launchctl remove com.github.dnscrypt-osxclient.DNSCryptConsoleChange 35 | /bin/launchctl stop com.github.dnscrypt-osxclient.DNSCryptControlChange 36 | /bin/launchctl remove com.github.dnscrypt-osxclient.DNSCryptControlChange 37 | /bin/launchctl stop com.github.dnscrypt-osxclient.DNSCryptNetworkChange 38 | /bin/launchctl remove com.github.dnscrypt-osxclient.DNSCryptNetworkChange 39 | 40 | /bin/rm -f /Library/LaunchDaemons/com.github.dnscrypt-osxclient.DNSCryptAfterboot.plist 41 | /bin/rm -f /Library/LaunchDaemons/com.github.dnscrypt-osxclient.DNSCryptConsoleChange.plist 42 | /bin/rm -f /Library/LaunchDaemons/com.github.dnscrypt-osxclient.DNSCryptControlChange.plist 43 | /bin/rm -f /Library/LaunchDaemons/com.github.dnscrypt-osxclient.DNSCryptNetworkChange.plist 44 | 45 | /bin/rm -f /var/run/dnscrypt*.lock 46 | 47 | exit 0 48 | -------------------------------------------------------------------------------- /DNSCrypt-OSX-Installer/com.github.dnscrypt-osxclient.DNSCryptAfterboot.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Label 6 | com.github.dnscrypt-osxclient.DNSCryptAfterboot 7 | KeepAlive 8 | 9 | RunAtLoad 10 | 11 | WorkingDirectory 12 | /Library/PreferencePanes/DNSCrypt.prefPane/Contents/Resources/usr/scripts 13 | ProgramArguments 14 | 15 | /Library/PreferencePanes/DNSCrypt.prefPane/Contents/Resources/usr/scripts/afterboot.sh 16 | 17 | ExitTimeOut 18 | 300 19 | ThrottleInterval 20 | 1 21 | Nice 22 | 1 23 | UserName 24 | root 25 | 26 | 27 | -------------------------------------------------------------------------------- /DNSCrypt-OSX-Installer/com.github.dnscrypt-osxclient.DNSCryptConsoleChange.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Label 6 | com.github.dnscrypt-osxclient.DNSCryptConsoleChange 7 | KeepAlive 8 | 9 | RunAtLoad 10 | 11 | WorkingDirectory 12 | /Library/PreferencePanes/DNSCrypt.prefPane/Contents/Resources/usr/scripts 13 | ProgramArguments 14 | 15 | /Library/PreferencePanes/DNSCrypt.prefPane/Contents/Resources/usr/scripts/handle-console-change.sh 16 | 17 | ExitTimeOut 18 | 30 19 | ThrottleInterval 20 | 0 21 | Nice 22 | 15 23 | UserName 24 | root 25 | WatchPaths 26 | 27 | /dev/console 28 | /var/run/utmpx 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /DNSCrypt-OSX-Installer/com.github.dnscrypt-osxclient.DNSCryptControlChange.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Label 6 | com.github.dnscrypt-osxclient.DNSCryptControlChange 7 | KeepAlive 8 | 9 | RunAtLoad 10 | 11 | WorkingDirectory 12 | /Library/PreferencePanes/DNSCrypt.prefPane/Contents/Resources/usr/scripts 13 | ProgramArguments 14 | 15 | /Library/PreferencePanes/DNSCrypt.prefPane/Contents/Resources/usr/scripts/handle-control-change.sh 16 | 17 | ExitTimeOut 18 | 300 19 | ThrottleInterval 20 | 0 21 | Nice 22 | 1 23 | UserName 24 | root 25 | WatchPaths 26 | 27 | /Library/Application Support/DNSCrypt/control 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /DNSCrypt-OSX-Installer/com.github.dnscrypt-osxclient.DNSCryptMenuBar.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Label 6 | com.github.dnscrypt-osxclient.DNSCryptMenuBar 7 | KeepAlive 8 | 9 | RunAtLoad 10 | 11 | ProgramArguments 12 | 13 | /Applications/DNSCrypt Menubar.app/Contents/MacOS/DNSCrypt Menubar 14 | 15 | LimitLoadToSessionType 16 | Aqua 17 | 18 | 19 | -------------------------------------------------------------------------------- /DNSCrypt-OSX-Installer/com.github.dnscrypt-osxclient.DNSCryptNetworkChange.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Label 6 | com.github.dnscrypt-osxclient.DNSCryptNetworkChange 7 | KeepAlive 8 | 9 | RunAtLoad 10 | 11 | WorkingDirectory 12 | /Library/PreferencePanes/DNSCrypt.prefPane/Contents/Resources/usr/scripts 13 | ProgramArguments 14 | 15 | /Library/PreferencePanes/DNSCrypt.prefPane/Contents/Resources/usr/scripts/handle-network-change.sh 16 | 17 | ExitTimeOut 18 | 300 19 | ThrottleInterval 20 | 1 21 | Nice 22 | 1 23 | UserName 24 | root 25 | WatchPaths 26 | 27 | /Library/Preferences/SystemConfiguration 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /DNSCrypt-OSX-Installer/sign.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | VERSION='1.0.14' 4 | 5 | echo '*** Do not forget to increase CURRENT_VERSION in common.inc' 6 | sleep 10 7 | 8 | cd build || exit 1 9 | [ -e DNSCrypt.pkg ] || exit 1 10 | 11 | rm -fr DNSCrypt-OSX.pkg DNSCrypt-unsigned.pkg 12 | 13 | productsign --sign 'Developer ID Installer' DNSCrypt.pkg DNSCrypt-OSX.pkg 14 | 15 | mv DNSCrypt.pkg DNSCrypt-unsigned.pkg 16 | mv DNSCrypt-OSX.pkg DNSCrypt.pkg 17 | 18 | rm -fr dnscrypt-pkg 19 | rm -f "dnscrypt-osxclient-${VERSION}.dmg" 20 | mkdir dnscrypt-pkg 21 | mv DNSCrypt.pkg dnscrypt-pkg 22 | hdiutil create "dnscrypt-osxclient-${VERSION}.dmg" -srcfolder dnscrypt-pkg 23 | 24 | mv dnscrypt-pkg/DNSCrypt.pkg . 25 | rm -fr dnscrypt-pkg 26 | rm -fr DNSCrypt-unsigned.pkg 27 | 28 | minisign -S -m "dnscrypt-osxclient-${VERSION}.dmg" \ 29 | -p ../../minisign.pub -s ../../minisign.key \ 30 | -t "dnscrypt-osxclient-${VERSION}.dmg" 31 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0932D7F61E4B324A00E8F3FC /* NSPlaceHolderTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 0932D7F51E4B324A00E8F3FC /* NSPlaceHolderTextView.m */; }; 11 | 0946B0C613F47F53008277C6 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0946B0C513F47F53008277C6 /* Cocoa.framework */; }; 12 | 0946B0C813F47F53008277C6 /* PreferencePanes.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0946B0C713F47F53008277C6 /* PreferencePanes.framework */; }; 13 | 0946B0D213F47F53008277C6 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0946B0D013F47F53008277C6 /* InfoPlist.strings */; }; 14 | 0946B0D613F47F53008277C6 /* DNSCrypt.m in Sources */ = {isa = PBXBuildFile; fileRef = 0946B0D513F47F53008277C6 /* DNSCrypt.m */; }; 15 | 0946B0DB13F47F53008277C6 /* DNSCrypt.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0946B0D913F47F53008277C6 /* DNSCrypt.xib */; }; 16 | 0946B0E413F48065008277C6 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0946B0E313F48065008277C6 /* Security.framework */; }; 17 | 09A13ABC145F2D8700B227A4 /* ajax-loader.gif in Resources */ = {isa = PBXBuildFile; fileRef = 09A13ABB145F2D8700B227A4 /* ajax-loader.gif */; }; 18 | 09AD01A015D2483500638DCE /* html in Resources */ = {isa = PBXBuildFile; fileRef = 09AD019F15D2483500638DCE /* html */; }; 19 | 09B168721906062E003FDBCC /* CHCSVParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 09B168701906062E003FDBCC /* CHCSVParser.h */; }; 20 | 09B168731906062E003FDBCC /* CHCSVParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 09B168711906062E003FDBCC /* CHCSVParser.m */; }; 21 | 09FB094415C9DE6400B8AAB6 /* usr in Resources */ = {isa = PBXBuildFile; fileRef = 09FB094315C9DE6400B8AAB6 /* usr */; }; 22 | 4B36C4651468B87A0085B07C /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B36C4641468B87A0085B07C /* WebKit.framework */; }; 23 | 4B89D983147CA39200872F60 /* dnscrypt_256.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B89D982147CA39200872F60 /* dnscrypt_256.png */; }; 24 | 4BABEA28144F5A7B006AEF34 /* led_green.png in Resources */ = {isa = PBXBuildFile; fileRef = 4BABEA1F144F5A7B006AEF34 /* led_green.png */; }; 25 | 4BABEA29144F5A7B006AEF34 /* led_yellow.png in Resources */ = {isa = PBXBuildFile; fileRef = 4BABEA20144F5A7B006AEF34 /* led_yellow.png */; }; 26 | 4BABEA2A144F5A7B006AEF34 /* led_red.png in Resources */ = {isa = PBXBuildFile; fileRef = 4BABEA21144F5A7B006AEF34 /* led_red.png */; }; 27 | 4BABEA2B144F5A7B006AEF34 /* shield_yellow.png in Resources */ = {isa = PBXBuildFile; fileRef = 4BABEA22144F5A7B006AEF34 /* shield_yellow.png */; }; 28 | 4BABEA2C144F5A7B006AEF34 /* shield_red.png in Resources */ = {isa = PBXBuildFile; fileRef = 4BABEA23144F5A7B006AEF34 /* shield_red.png */; }; 29 | 4BABEA2D144F5A7B006AEF34 /* shield_green.png in Resources */ = {isa = PBXBuildFile; fileRef = 4BABEA24144F5A7B006AEF34 /* shield_green.png */; }; 30 | /* End PBXBuildFile section */ 31 | 32 | /* Begin PBXFileReference section */ 33 | 0932D7F51E4B324A00E8F3FC /* NSPlaceHolderTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSPlaceHolderTextView.m; sourceTree = ""; }; 34 | 0932D7F71E4B327D00E8F3FC /* NSPlaceHolderTextView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NSPlaceHolderTextView.h; sourceTree = ""; }; 35 | 0946B0C213F47F53008277C6 /* DNSCrypt.prefPane */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DNSCrypt.prefPane; sourceTree = BUILT_PRODUCTS_DIR; }; 36 | 0946B0C513F47F53008277C6 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 37 | 0946B0C713F47F53008277C6 /* PreferencePanes.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PreferencePanes.framework; path = System/Library/Frameworks/PreferencePanes.framework; sourceTree = SDKROOT; }; 38 | 0946B0CA13F47F53008277C6 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; 39 | 0946B0CB13F47F53008277C6 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; 40 | 0946B0CC13F47F53008277C6 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 41 | 0946B0CF13F47F53008277C6 /* DNSCrypt-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "DNSCrypt-Info.plist"; sourceTree = ""; }; 42 | 0946B0D113F47F53008277C6 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 43 | 0946B0D313F47F53008277C6 /* DNSCrypt-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "DNSCrypt-Prefix.pch"; sourceTree = ""; }; 44 | 0946B0D413F47F53008277C6 /* DNSCrypt.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DNSCrypt.h; sourceTree = ""; }; 45 | 0946B0D513F47F53008277C6 /* DNSCrypt.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DNSCrypt.m; sourceTree = ""; }; 46 | 0946B0DA13F47F53008277C6 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/DNSCrypt.xib; sourceTree = ""; }; 47 | 0946B0E113F48056008277C6 /* SecurityFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SecurityFoundation.framework; path = System/Library/Frameworks/SecurityFoundation.framework; sourceTree = SDKROOT; }; 48 | 0946B0E313F48065008277C6 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; 49 | 09A13ABB145F2D8700B227A4 /* ajax-loader.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = "ajax-loader.gif"; sourceTree = ""; }; 50 | 09AD019F15D2483500638DCE /* html */ = {isa = PBXFileReference; lastKnownFileType = folder; name = html; path = extra/html; sourceTree = ""; }; 51 | 09B168701906062E003FDBCC /* CHCSVParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CHCSVParser.h; sourceTree = ""; }; 52 | 09B168711906062E003FDBCC /* CHCSVParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CHCSVParser.m; sourceTree = ""; }; 53 | 09FB094315C9DE6400B8AAB6 /* usr */ = {isa = PBXFileReference; lastKnownFileType = folder; name = usr; path = extra/usr; sourceTree = ""; }; 54 | 4B36C4641468B87A0085B07C /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; 55 | 4B89D982147CA39200872F60 /* dnscrypt_256.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = dnscrypt_256.png; sourceTree = ""; }; 56 | 4BABEA1F144F5A7B006AEF34 /* led_green.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = led_green.png; sourceTree = ""; }; 57 | 4BABEA20144F5A7B006AEF34 /* led_yellow.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = led_yellow.png; sourceTree = ""; }; 58 | 4BABEA21144F5A7B006AEF34 /* led_red.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = led_red.png; sourceTree = ""; }; 59 | 4BABEA22144F5A7B006AEF34 /* shield_yellow.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = shield_yellow.png; sourceTree = ""; }; 60 | 4BABEA23144F5A7B006AEF34 /* shield_red.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = shield_red.png; sourceTree = ""; }; 61 | 4BABEA24144F5A7B006AEF34 /* shield_green.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = shield_green.png; sourceTree = ""; }; 62 | /* End PBXFileReference section */ 63 | 64 | /* Begin PBXFrameworksBuildPhase section */ 65 | 0946B0BD13F47F53008277C6 /* Frameworks */ = { 66 | isa = PBXFrameworksBuildPhase; 67 | buildActionMask = 2147483647; 68 | files = ( 69 | 4B36C4651468B87A0085B07C /* WebKit.framework in Frameworks */, 70 | 0946B0E413F48065008277C6 /* Security.framework in Frameworks */, 71 | 0946B0C613F47F53008277C6 /* Cocoa.framework in Frameworks */, 72 | 0946B0C813F47F53008277C6 /* PreferencePanes.framework in Frameworks */, 73 | ); 74 | runOnlyForDeploymentPostprocessing = 0; 75 | }; 76 | /* End PBXFrameworksBuildPhase section */ 77 | 78 | /* Begin PBXGroup section */ 79 | 0946B0B513F47F52008277C6 = { 80 | isa = PBXGroup; 81 | children = ( 82 | 0946B0CD13F47F53008277C6 /* DNSCrypt */, 83 | 0946B0C413F47F53008277C6 /* Frameworks */, 84 | 0946B0C313F47F53008277C6 /* Products */, 85 | ); 86 | sourceTree = ""; 87 | }; 88 | 0946B0C313F47F53008277C6 /* Products */ = { 89 | isa = PBXGroup; 90 | children = ( 91 | 0946B0C213F47F53008277C6 /* DNSCrypt.prefPane */, 92 | ); 93 | name = Products; 94 | sourceTree = ""; 95 | }; 96 | 0946B0C413F47F53008277C6 /* Frameworks */ = { 97 | isa = PBXGroup; 98 | children = ( 99 | 0946B0C513F47F53008277C6 /* Cocoa.framework */, 100 | 0946B0C913F47F53008277C6 /* Other Frameworks */, 101 | ); 102 | name = Frameworks; 103 | sourceTree = ""; 104 | }; 105 | 0946B0C913F47F53008277C6 /* Other Frameworks */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | 0946B0CA13F47F53008277C6 /* AppKit.framework */, 109 | 0946B0CB13F47F53008277C6 /* CoreData.framework */, 110 | 0946B0CC13F47F53008277C6 /* Foundation.framework */, 111 | 0946B0C713F47F53008277C6 /* PreferencePanes.framework */, 112 | 0946B0E313F48065008277C6 /* Security.framework */, 113 | 0946B0E113F48056008277C6 /* SecurityFoundation.framework */, 114 | 4B36C4641468B87A0085B07C /* WebKit.framework */, 115 | ); 116 | name = "Other Frameworks"; 117 | sourceTree = ""; 118 | }; 119 | 0946B0CD13F47F53008277C6 /* DNSCrypt */ = { 120 | isa = PBXGroup; 121 | children = ( 122 | 0946B0D413F47F53008277C6 /* DNSCrypt.h */, 123 | 0946B0D513F47F53008277C6 /* DNSCrypt.m */, 124 | 0946B0D913F47F53008277C6 /* DNSCrypt.xib */, 125 | 4B89D982147CA39200872F60 /* dnscrypt_256.png */, 126 | 09B1686F1906062E003FDBCC /* CHCSVParser */, 127 | 09AD019F15D2483500638DCE /* html */, 128 | 09FB094315C9DE6400B8AAB6 /* usr */, 129 | 0946B0CE13F47F53008277C6 /* Supporting Files */, 130 | 096AF93A1E4B565A003C3D67 /* UI Additions */, 131 | ); 132 | path = DNSCrypt; 133 | sourceTree = ""; 134 | }; 135 | 0946B0CE13F47F53008277C6 /* Supporting Files */ = { 136 | isa = PBXGroup; 137 | children = ( 138 | 4BABEA1E144F5A67006AEF34 /* Status */, 139 | 0946B0CF13F47F53008277C6 /* DNSCrypt-Info.plist */, 140 | 0946B0D013F47F53008277C6 /* InfoPlist.strings */, 141 | 0946B0D313F47F53008277C6 /* DNSCrypt-Prefix.pch */, 142 | ); 143 | name = "Supporting Files"; 144 | sourceTree = ""; 145 | }; 146 | 096AF93A1E4B565A003C3D67 /* UI Additions */ = { 147 | isa = PBXGroup; 148 | children = ( 149 | 0932D7F51E4B324A00E8F3FC /* NSPlaceHolderTextView.m */, 150 | 0932D7F71E4B327D00E8F3FC /* NSPlaceHolderTextView.h */, 151 | ); 152 | name = "UI Additions"; 153 | sourceTree = ""; 154 | }; 155 | 09B1686F1906062E003FDBCC /* CHCSVParser */ = { 156 | isa = PBXGroup; 157 | children = ( 158 | 09B168701906062E003FDBCC /* CHCSVParser.h */, 159 | 09B168711906062E003FDBCC /* CHCSVParser.m */, 160 | ); 161 | path = CHCSVParser; 162 | sourceTree = ""; 163 | }; 164 | 4BABEA1E144F5A67006AEF34 /* Status */ = { 165 | isa = PBXGroup; 166 | children = ( 167 | 09A13ABB145F2D8700B227A4 /* ajax-loader.gif */, 168 | 4BABEA1F144F5A7B006AEF34 /* led_green.png */, 169 | 4BABEA20144F5A7B006AEF34 /* led_yellow.png */, 170 | 4BABEA21144F5A7B006AEF34 /* led_red.png */, 171 | 4BABEA22144F5A7B006AEF34 /* shield_yellow.png */, 172 | 4BABEA23144F5A7B006AEF34 /* shield_red.png */, 173 | 4BABEA24144F5A7B006AEF34 /* shield_green.png */, 174 | ); 175 | name = Status; 176 | sourceTree = ""; 177 | }; 178 | /* End PBXGroup section */ 179 | 180 | /* Begin PBXHeadersBuildPhase section */ 181 | 0946B0BE13F47F53008277C6 /* Headers */ = { 182 | isa = PBXHeadersBuildPhase; 183 | buildActionMask = 2147483647; 184 | files = ( 185 | 09B168721906062E003FDBCC /* CHCSVParser.h in Headers */, 186 | ); 187 | runOnlyForDeploymentPostprocessing = 0; 188 | }; 189 | /* End PBXHeadersBuildPhase section */ 190 | 191 | /* Begin PBXNativeTarget section */ 192 | 0946B0C113F47F53008277C6 /* DNSCrypt */ = { 193 | isa = PBXNativeTarget; 194 | buildConfigurationList = 0946B0DE13F47F53008277C6 /* Build configuration list for PBXNativeTarget "DNSCrypt" */; 195 | buildPhases = ( 196 | 0946B0BC13F47F53008277C6 /* Sources */, 197 | 0946B0BD13F47F53008277C6 /* Frameworks */, 198 | 0946B0BE13F47F53008277C6 /* Headers */, 199 | 0946B0BF13F47F53008277C6 /* Resources */, 200 | 0946B0C013F47F53008277C6 /* Rez */, 201 | ); 202 | buildRules = ( 203 | ); 204 | dependencies = ( 205 | ); 206 | name = DNSCrypt; 207 | productName = DNSCrypt; 208 | productReference = 0946B0C213F47F53008277C6 /* DNSCrypt.prefPane */; 209 | productType = "com.apple.product-type.bundle"; 210 | }; 211 | /* End PBXNativeTarget section */ 212 | 213 | /* Begin PBXProject section */ 214 | 0946B0B713F47F52008277C6 /* Project object */ = { 215 | isa = PBXProject; 216 | attributes = { 217 | LastUpgradeCheck = 0700; 218 | }; 219 | buildConfigurationList = 0946B0BA13F47F52008277C6 /* Build configuration list for PBXProject "DNSCrypt" */; 220 | compatibilityVersion = "Xcode 3.2"; 221 | developmentRegion = English; 222 | hasScannedForEncodings = 0; 223 | knownRegions = ( 224 | en, 225 | ); 226 | mainGroup = 0946B0B513F47F52008277C6; 227 | productRefGroup = 0946B0C313F47F53008277C6 /* Products */; 228 | projectDirPath = ""; 229 | projectRoot = ""; 230 | targets = ( 231 | 0946B0C113F47F53008277C6 /* DNSCrypt */, 232 | ); 233 | }; 234 | /* End PBXProject section */ 235 | 236 | /* Begin PBXResourcesBuildPhase section */ 237 | 0946B0BF13F47F53008277C6 /* Resources */ = { 238 | isa = PBXResourcesBuildPhase; 239 | buildActionMask = 2147483647; 240 | files = ( 241 | 0946B0D213F47F53008277C6 /* InfoPlist.strings in Resources */, 242 | 0946B0DB13F47F53008277C6 /* DNSCrypt.xib in Resources */, 243 | 4BABEA28144F5A7B006AEF34 /* led_green.png in Resources */, 244 | 4BABEA29144F5A7B006AEF34 /* led_yellow.png in Resources */, 245 | 4BABEA2A144F5A7B006AEF34 /* led_red.png in Resources */, 246 | 4BABEA2B144F5A7B006AEF34 /* shield_yellow.png in Resources */, 247 | 4BABEA2C144F5A7B006AEF34 /* shield_red.png in Resources */, 248 | 4BABEA2D144F5A7B006AEF34 /* shield_green.png in Resources */, 249 | 09A13ABC145F2D8700B227A4 /* ajax-loader.gif in Resources */, 250 | 4B89D983147CA39200872F60 /* dnscrypt_256.png in Resources */, 251 | 09FB094415C9DE6400B8AAB6 /* usr in Resources */, 252 | 09AD01A015D2483500638DCE /* html in Resources */, 253 | ); 254 | runOnlyForDeploymentPostprocessing = 0; 255 | }; 256 | /* End PBXResourcesBuildPhase section */ 257 | 258 | /* Begin PBXRezBuildPhase section */ 259 | 0946B0C013F47F53008277C6 /* Rez */ = { 260 | isa = PBXRezBuildPhase; 261 | buildActionMask = 2147483647; 262 | files = ( 263 | ); 264 | runOnlyForDeploymentPostprocessing = 0; 265 | }; 266 | /* End PBXRezBuildPhase section */ 267 | 268 | /* Begin PBXSourcesBuildPhase section */ 269 | 0946B0BC13F47F53008277C6 /* Sources */ = { 270 | isa = PBXSourcesBuildPhase; 271 | buildActionMask = 2147483647; 272 | files = ( 273 | 09B168731906062E003FDBCC /* CHCSVParser.m in Sources */, 274 | 0932D7F61E4B324A00E8F3FC /* NSPlaceHolderTextView.m in Sources */, 275 | 0946B0D613F47F53008277C6 /* DNSCrypt.m in Sources */, 276 | ); 277 | runOnlyForDeploymentPostprocessing = 0; 278 | }; 279 | /* End PBXSourcesBuildPhase section */ 280 | 281 | /* Begin PBXVariantGroup section */ 282 | 0946B0D013F47F53008277C6 /* InfoPlist.strings */ = { 283 | isa = PBXVariantGroup; 284 | children = ( 285 | 0946B0D113F47F53008277C6 /* en */, 286 | ); 287 | name = InfoPlist.strings; 288 | sourceTree = ""; 289 | }; 290 | 0946B0D913F47F53008277C6 /* DNSCrypt.xib */ = { 291 | isa = PBXVariantGroup; 292 | children = ( 293 | 0946B0DA13F47F53008277C6 /* en */, 294 | ); 295 | name = DNSCrypt.xib; 296 | sourceTree = ""; 297 | }; 298 | /* End PBXVariantGroup section */ 299 | 300 | /* Begin XCBuildConfiguration section */ 301 | 0946B0DC13F47F53008277C6 /* Debug */ = { 302 | isa = XCBuildConfiguration; 303 | buildSettings = { 304 | ALWAYS_SEARCH_USER_PATHS = NO; 305 | CLANG_ENABLE_OBJC_ARC = NO; 306 | COPY_PHASE_STRIP = NO; 307 | ENABLE_TESTABILITY = YES; 308 | GCC_C_LANGUAGE_STANDARD = gnu99; 309 | GCC_DYNAMIC_NO_PIC = NO; 310 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 311 | GCC_ENABLE_OBJC_GC = supported; 312 | GCC_OPTIMIZATION_LEVEL = 0; 313 | GCC_PREPROCESSOR_DEFINITIONS = ( 314 | "DEBUG=1", 315 | "$(inherited)", 316 | ); 317 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 318 | GCC_VERSION = com.apple.compilers.llvmgcc42; 319 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 320 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 321 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 322 | GCC_WARN_UNUSED_VARIABLE = YES; 323 | MACOSX_DEPLOYMENT_TARGET = 10.6; 324 | ONLY_ACTIVE_ARCH = YES; 325 | SDKROOT = macosx; 326 | }; 327 | name = Debug; 328 | }; 329 | 0946B0DD13F47F53008277C6 /* Release */ = { 330 | isa = XCBuildConfiguration; 331 | buildSettings = { 332 | ALWAYS_SEARCH_USER_PATHS = NO; 333 | CLANG_ENABLE_OBJC_ARC = NO; 334 | COPY_PHASE_STRIP = NO; 335 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 336 | GCC_C_LANGUAGE_STANDARD = gnu99; 337 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 338 | GCC_ENABLE_OBJC_GC = supported; 339 | GCC_VERSION = com.apple.compilers.llvmgcc42; 340 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 341 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 342 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 343 | GCC_WARN_UNUSED_VARIABLE = YES; 344 | MACOSX_DEPLOYMENT_TARGET = 10.6; 345 | SDKROOT = macosx; 346 | }; 347 | name = Release; 348 | }; 349 | 0946B0DF13F47F53008277C6 /* Debug */ = { 350 | isa = XCBuildConfiguration; 351 | buildSettings = { 352 | CLANG_ENABLE_OBJC_ARC = YES; 353 | COMBINE_HIDPI_IMAGES = YES; 354 | FRAMEWORK_SEARCH_PATHS = ( 355 | "$(inherited)", 356 | "\"$(SRCROOT)\"", 357 | ); 358 | GCC_ENABLE_OBJC_GC = unsupported; 359 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 360 | GCC_PREFIX_HEADER = "DNSCrypt/DNSCrypt-Prefix.pch"; 361 | GCC_VERSION = ""; 362 | INFOPLIST_FILE = "DNSCrypt/DNSCrypt-Info.plist"; 363 | INSTALL_PATH = "$(HOME)/Library/PreferencePanes"; 364 | PRODUCT_BUNDLE_IDENTIFIER = "com.github.dnscrypt-osxclient.${PRODUCT_NAME:rfc1034identifier}"; 365 | PRODUCT_NAME = "$(TARGET_NAME)"; 366 | WRAPPER_EXTENSION = prefPane; 367 | }; 368 | name = Debug; 369 | }; 370 | 0946B0E013F47F53008277C6 /* Release */ = { 371 | isa = XCBuildConfiguration; 372 | buildSettings = { 373 | CLANG_ENABLE_OBJC_ARC = YES; 374 | COMBINE_HIDPI_IMAGES = YES; 375 | FRAMEWORK_SEARCH_PATHS = ( 376 | "$(inherited)", 377 | "\"$(SRCROOT)\"", 378 | ); 379 | GCC_ENABLE_OBJC_GC = unsupported; 380 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 381 | GCC_PREFIX_HEADER = "DNSCrypt/DNSCrypt-Prefix.pch"; 382 | GCC_VERSION = ""; 383 | INFOPLIST_FILE = "DNSCrypt/DNSCrypt-Info.plist"; 384 | INSTALL_PATH = "$(HOME)/Library/PreferencePanes"; 385 | PRODUCT_BUNDLE_IDENTIFIER = "com.github.dnscrypt-osxclient.${PRODUCT_NAME:rfc1034identifier}"; 386 | PRODUCT_NAME = "$(TARGET_NAME)"; 387 | WRAPPER_EXTENSION = prefPane; 388 | }; 389 | name = Release; 390 | }; 391 | /* End XCBuildConfiguration section */ 392 | 393 | /* Begin XCConfigurationList section */ 394 | 0946B0BA13F47F52008277C6 /* Build configuration list for PBXProject "DNSCrypt" */ = { 395 | isa = XCConfigurationList; 396 | buildConfigurations = ( 397 | 0946B0DC13F47F53008277C6 /* Debug */, 398 | 0946B0DD13F47F53008277C6 /* Release */, 399 | ); 400 | defaultConfigurationIsVisible = 0; 401 | defaultConfigurationName = Release; 402 | }; 403 | 0946B0DE13F47F53008277C6 /* Build configuration list for PBXNativeTarget "DNSCrypt" */ = { 404 | isa = XCConfigurationList; 405 | buildConfigurations = ( 406 | 0946B0DF13F47F53008277C6 /* Debug */, 407 | 0946B0E013F47F53008277C6 /* Release */, 408 | ); 409 | defaultConfigurationIsVisible = 0; 410 | defaultConfigurationName = Release; 411 | }; 412 | /* End XCConfigurationList section */ 413 | }; 414 | rootObject = 0946B0B713F47F52008277C6 /* Project object */; 415 | } 416 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/CHCSVParser/CHCSVParser.h: -------------------------------------------------------------------------------- 1 | // 2 | // CHCSVParser.h 3 | // CHCSVParser 4 | /** 5 | Copyright (c) 2012 Dave DeLong 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | THE SOFTWARE. 24 | **/ 25 | 26 | #import 27 | 28 | extern NSString * const CHCSVErrorDomain; 29 | 30 | enum { 31 | CHCSVErrorCodeInvalidFormat = 1, 32 | }; 33 | 34 | typedef NSInteger CHCSVErrorCode; 35 | 36 | @class CHCSVParser; 37 | @protocol CHCSVParserDelegate 38 | 39 | @optional 40 | - (void)parserDidBeginDocument:(CHCSVParser *)parser; 41 | - (void)parserDidEndDocument:(CHCSVParser *)parser; 42 | 43 | - (void)parser:(CHCSVParser *)parser didBeginLine:(NSUInteger)recordNumber; 44 | - (void)parser:(CHCSVParser *)parser didEndLine:(NSUInteger)recordNumber; 45 | 46 | - (void)parser:(CHCSVParser *)parser didReadField:(NSString *)field atIndex:(NSInteger)fieldIndex; 47 | - (void)parser:(CHCSVParser *)parser didReadComment:(NSString *)comment; 48 | 49 | - (void)parser:(CHCSVParser *)parser didFailWithError:(NSError *)error; 50 | 51 | @end 52 | 53 | @interface CHCSVParser : NSObject 54 | 55 | @property (assign) id delegate; 56 | @property (assign) BOOL recognizesBackslashesAsEscapes; // default is NO 57 | @property (assign) BOOL sanitizesFields; // default is NO 58 | @property (assign) BOOL recognizesComments; // default is NO 59 | @property (assign) BOOL stripsLeadingAndTrailingWhitespace; // default is NO 60 | 61 | @property (readonly) NSUInteger totalBytesRead; 62 | 63 | // designated initializer 64 | - (id)initWithInputStream:(NSInputStream *)stream usedEncoding:(NSStringEncoding *)encoding delimiter:(unichar)delimiter; 65 | 66 | - (id)initWithCSVString:(NSString *)csv; 67 | - (id)initWithCSVString:(NSString *)csv delimiter:(unichar)delimiter; 68 | 69 | - (id)initWithContentsOfCSVFile:(NSString *)csvFilePath; 70 | - (id)initWithContentsOfCSVFile:(NSString *)csvFilePath delimiter:(unichar)delimiter; 71 | 72 | - (void)parse; 73 | - (void)cancelParsing; 74 | 75 | @end 76 | 77 | @interface CHCSVWriter : NSObject 78 | 79 | - (instancetype)initForWritingToCSVFile:(NSString *)path; 80 | - (instancetype)initWithOutputStream:(NSOutputStream *)stream encoding:(NSStringEncoding)encoding delimiter:(unichar)delimiter; 81 | 82 | - (void)writeField:(NSString *)field; 83 | - (void)finishLine; 84 | 85 | - (void)writeLineOfFields:(id)fields; 86 | 87 | - (void)writeComment:(NSString *)comment; 88 | 89 | - (void)closeStream; 90 | 91 | @end 92 | 93 | #pragma mark - Convenience Categories 94 | 95 | typedef NS_OPTIONS(NSUInteger, CHCSVParserOptions) { 96 | CHCSVParserOptionsRecognizesBackslashesAsEscapes = 1 << 0, 97 | CHCSVParserOptionsSanitizesFields = 1 << 1, 98 | CHCSVParserOptionsRecognizesComments = 1 << 2, 99 | CHCSVParserOptionsStripsLeadingAndTrailingWhitespace = 1 << 3 100 | }; 101 | 102 | @interface NSArray (CHCSVAdditions) 103 | 104 | + (instancetype)arrayWithContentsOfCSVFile:(NSString *)csvFilePath; 105 | + (instancetype)arrayWithContentsOfCSVFile:(NSString *)csvFilePath delimiter:(unichar)delimiter; 106 | + (instancetype)arrayWithContentsOfCSVFile:(NSString *)csvFilePath options:(CHCSVParserOptions)options; 107 | + (instancetype)arrayWithContentsOfCSVFile:(NSString *)csvFilePath options:(CHCSVParserOptions)options delimiter:(unichar)delimiter; 108 | - (NSString *)CSVString; 109 | 110 | @end 111 | 112 | @interface NSString (CHCSVAdditions) 113 | 114 | - (NSArray *)CSVComponents; 115 | - (NSArray *)CSVComponentsWithDelimiter:(unichar)delimiter; 116 | - (NSArray *)CSVComponentsWithOptions:(CHCSVParserOptions)options; 117 | - (NSArray *)CSVComponentsWithOptions:(CHCSVParserOptions)options delimiter:(unichar)delimiter; 118 | 119 | @end 120 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/CHCSVParser/CHCSVParser.m: -------------------------------------------------------------------------------- 1 | // 2 | // CHCSVParser.m 3 | // CHCSVParser 4 | /** 5 | Copyright (c) 2012 Dave DeLong 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | THE SOFTWARE. 24 | **/ 25 | 26 | #import "CHCSVParser.h" 27 | 28 | NSString *const CHCSVErrorDomain = @"com.davedelong.csv"; 29 | 30 | #define CHUNK_SIZE 512 31 | #define DOUBLE_QUOTE '"' 32 | #define COMMA ',' 33 | #define OCTOTHORPE '#' 34 | #define BACKSLASH '\\' 35 | 36 | #if __has_feature(objc_arc) 37 | 38 | #define CHCSV_HAS_ARC 1 39 | #define CHCSV_RETAIN(_o) (_o) 40 | #define CHCSV_RELEASE(_o) 41 | #define CHCSV_AUTORELEASE(_o) (_o) 42 | 43 | #else 44 | 45 | #define CHCSV_HAS_ARC 0 46 | #define CHCSV_RETAIN(_o) [(_o) retain] 47 | #define CHCSV_RELEASE(_o) [(_o) release] 48 | #define CHCSV_AUTORELEASE(_o) [(_o) autorelease] 49 | 50 | #endif 51 | 52 | @interface CHCSVParser () 53 | @property (assign) NSUInteger totalBytesRead; 54 | @end 55 | 56 | @implementation CHCSVParser { 57 | NSInputStream *_stream; 58 | NSStringEncoding _streamEncoding; 59 | NSMutableData *_stringBuffer; 60 | NSMutableString *_string; 61 | NSCharacterSet *_validFieldCharacters; 62 | 63 | NSUInteger _nextIndex; 64 | 65 | NSInteger _fieldIndex; 66 | NSRange _fieldRange; 67 | NSMutableString *_sanitizedField; 68 | 69 | unichar _delimiter; 70 | 71 | NSError *_error; 72 | 73 | NSUInteger _currentRecord; 74 | BOOL _cancelled; 75 | } 76 | 77 | - (id)initWithCSVString:(NSString *)csv { 78 | NSStringEncoding encoding = [csv fastestEncoding]; 79 | NSInputStream *stream = [NSInputStream inputStreamWithData:[csv dataUsingEncoding:encoding]]; 80 | return [self initWithInputStream:stream usedEncoding:&encoding delimiter:COMMA]; 81 | } 82 | 83 | - (id)initWithCSVString:(NSString *)csv delimiter:(unichar)delimiter 84 | { 85 | NSStringEncoding encoding = [csv fastestEncoding]; 86 | NSInputStream *stream = [NSInputStream inputStreamWithData:[csv dataUsingEncoding:encoding]]; 87 | return [self initWithInputStream:stream usedEncoding:&encoding delimiter:delimiter]; 88 | } 89 | 90 | - (id)initWithContentsOfCSVFile:(NSString *)csvFilePath { 91 | NSInputStream *stream = [NSInputStream inputStreamWithFileAtPath:csvFilePath]; 92 | NSStringEncoding encoding = 0; 93 | return [self initWithInputStream:stream usedEncoding:&encoding delimiter:COMMA]; 94 | } 95 | 96 | - (id)initWithContentsOfCSVFile:(NSString *)csvFilePath delimiter:(unichar)delimiter 97 | { 98 | NSInputStream *stream = [NSInputStream inputStreamWithFileAtPath:csvFilePath]; 99 | NSStringEncoding encoding = 0; 100 | return [self initWithInputStream:stream usedEncoding:&encoding delimiter:delimiter]; 101 | } 102 | 103 | - (id)initWithInputStream:(NSInputStream *)stream usedEncoding:(NSStringEncoding *)encoding delimiter:(unichar)delimiter { 104 | NSParameterAssert(stream); 105 | NSParameterAssert(delimiter); 106 | NSAssert([[NSCharacterSet newlineCharacterSet] characterIsMember:delimiter] == NO, @"The field delimiter may not be a newline"); 107 | NSAssert(delimiter != DOUBLE_QUOTE, @"The field delimiter may not be a double quote"); 108 | NSAssert(delimiter != OCTOTHORPE, @"The field delimiter may not be an octothorpe"); 109 | 110 | self = [super init]; 111 | if (self) { 112 | _stream = CHCSV_RETAIN(stream); 113 | [_stream open]; 114 | 115 | _stringBuffer = [[NSMutableData alloc] init]; 116 | _string = [[NSMutableString alloc] init]; 117 | 118 | _delimiter = delimiter; 119 | 120 | _nextIndex = 0; 121 | _recognizesComments = NO; 122 | _recognizesBackslashesAsEscapes = NO; 123 | _sanitizesFields = NO; 124 | _sanitizedField = [[NSMutableString alloc] init]; 125 | _stripsLeadingAndTrailingWhitespace = NO; 126 | 127 | NSMutableCharacterSet *m = [[NSCharacterSet newlineCharacterSet] mutableCopy]; 128 | NSString *invalid = [NSString stringWithFormat:@"%c%C", DOUBLE_QUOTE, _delimiter]; 129 | [m addCharactersInString:invalid]; 130 | _validFieldCharacters = CHCSV_RETAIN([m invertedSet]); 131 | CHCSV_RELEASE(m); 132 | 133 | if (encoding == NULL || *encoding == 0) { 134 | // we need to determine the encoding 135 | [self _sniffEncoding]; 136 | if (encoding) { 137 | *encoding = _streamEncoding; 138 | } 139 | } else { 140 | _streamEncoding = *encoding; 141 | } 142 | } 143 | return self; 144 | } 145 | 146 | - (void)dealloc { 147 | [_stream close]; 148 | #if !CHCSV_HAS_ARC 149 | [_stream release]; 150 | [_stringBuffer release]; 151 | [_string release]; 152 | [_sanitizedField release]; 153 | [_validFieldCharacters release]; 154 | [super dealloc]; 155 | #endif 156 | } 157 | 158 | #pragma mark - 159 | 160 | - (void)_sniffEncoding { 161 | NSStringEncoding encoding = NSUTF8StringEncoding; 162 | 163 | uint8_t bytes[CHUNK_SIZE]; 164 | NSInteger readLength = [_stream read:bytes maxLength:CHUNK_SIZE]; 165 | if (readLength > 0 && readLength <= CHUNK_SIZE) { 166 | [_stringBuffer appendBytes:bytes length:readLength]; 167 | [self setTotalBytesRead:[self totalBytesRead] + readLength]; 168 | 169 | NSInteger bomLength = 0; 170 | 171 | if (readLength > 3 && bytes[0] == 0x00 && bytes[1] == 0x00 && bytes[2] == 0xFE && bytes[3] == 0xFF) { 172 | encoding = NSUTF32BigEndianStringEncoding; 173 | bomLength = 4; 174 | } else if (readLength > 3 && bytes[0] == 0xFF && bytes[1] == 0xFE && bytes[2] == 0x00 && bytes[3] == 0x00) { 175 | encoding = NSUTF32LittleEndianStringEncoding; 176 | bomLength = 4; 177 | } else if (readLength > 3 && bytes[0] == 0x1B && bytes[1] == 0x24 && bytes[2] == 0x29 && bytes[3] == 0x43) { 178 | encoding = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingISO_2022_KR); 179 | bomLength = 4; 180 | } else if (readLength > 1 && bytes[0] == 0xFE && bytes[1] == 0xFF) { 181 | encoding = NSUTF16BigEndianStringEncoding; 182 | bomLength = 2; 183 | } else if (readLength > 1 && bytes[0] == 0xFF && bytes[1] == 0xFE) { 184 | encoding = NSUTF16LittleEndianStringEncoding; 185 | bomLength = 2; 186 | } else if (readLength > 2 && bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) { 187 | encoding = NSUTF8StringEncoding; 188 | bomLength = 3; 189 | } else { 190 | NSString *bufferAsUTF8 = nil; 191 | 192 | for (NSInteger triedLength = 0; triedLength < 4; ++triedLength) { 193 | bufferAsUTF8 = CHCSV_AUTORELEASE([[NSString alloc] initWithBytes:bytes length:readLength-triedLength encoding:NSUTF8StringEncoding]); 194 | if (bufferAsUTF8 != nil) { 195 | break; 196 | } 197 | } 198 | 199 | if (bufferAsUTF8 != nil) { 200 | encoding = NSUTF8StringEncoding; 201 | } else { 202 | NSLog(@"unable to determine stream encoding; assuming MacOSRoman"); 203 | encoding = NSMacOSRomanStringEncoding; 204 | } 205 | } 206 | 207 | if (bomLength > 0) { 208 | [_stringBuffer replaceBytesInRange:NSMakeRange(0, bomLength) withBytes:NULL length:0]; 209 | } 210 | } 211 | _streamEncoding = encoding; 212 | } 213 | 214 | - (void)_loadMoreIfNecessary { 215 | NSUInteger stringLength = [_string length]; 216 | NSUInteger reloadPortion = stringLength / 3; 217 | if (reloadPortion < 10) { reloadPortion = 10; } 218 | 219 | if ([_stream hasBytesAvailable] && _nextIndex+reloadPortion >= stringLength) { 220 | // read more from the stream 221 | uint8_t buffer[CHUNK_SIZE]; 222 | NSInteger readBytes = [_stream read:buffer maxLength:CHUNK_SIZE]; 223 | if (readBytes > 0) { 224 | // append it to the buffer 225 | [_stringBuffer appendBytes:buffer length:readBytes]; 226 | [self setTotalBytesRead:[self totalBytesRead] + readBytes]; 227 | } 228 | } 229 | 230 | if ([_stringBuffer length] > 0) { 231 | // try to turn the next portion of the buffer into a string 232 | NSUInteger readLength = [_stringBuffer length]; 233 | while (readLength > 0) { 234 | NSString *readString = [[NSString alloc] initWithBytes:[_stringBuffer bytes] length:readLength encoding:_streamEncoding]; 235 | if (readString == nil) { 236 | readLength--; 237 | } else { 238 | [_string appendString:readString]; 239 | CHCSV_RELEASE(readString); 240 | break; 241 | } 242 | }; 243 | 244 | [_stringBuffer replaceBytesInRange:NSMakeRange(0, readLength) withBytes:NULL length:0]; 245 | } 246 | } 247 | 248 | - (void)_advance { 249 | [self _loadMoreIfNecessary]; 250 | _nextIndex++; 251 | } 252 | 253 | - (unichar)_peekCharacter { 254 | [self _loadMoreIfNecessary]; 255 | if (_nextIndex >= [_string length]) { return '\0'; } 256 | 257 | return [_string characterAtIndex:_nextIndex]; 258 | } 259 | 260 | - (unichar)_peekPeekCharacter { 261 | [self _loadMoreIfNecessary]; 262 | NSUInteger nextNextIndex = _nextIndex+1; 263 | if (nextNextIndex >= [_string length]) { return '\0'; } 264 | 265 | return [_string characterAtIndex:nextNextIndex]; 266 | } 267 | 268 | #pragma mark - 269 | 270 | - (void)parse { 271 | [self _beginDocument]; 272 | 273 | _currentRecord = 0; 274 | while ([self _parseRecord]) { 275 | ; // yep; 276 | } 277 | 278 | if (_error != nil) { 279 | [self _error]; 280 | } else { 281 | [self _endDocument]; 282 | } 283 | } 284 | 285 | - (void)cancelParsing { 286 | _cancelled = YES; 287 | } 288 | 289 | - (BOOL)_parseRecord { 290 | while ([self _peekCharacter] == OCTOTHORPE && _recognizesComments) { 291 | [self _parseComment]; 292 | } 293 | 294 | [self _beginRecord]; 295 | while (1) { 296 | if (![self _parseField]) { 297 | break; 298 | } 299 | if (![self _parseDelimiter]) { 300 | break; 301 | } 302 | } 303 | BOOL followedByNewline = [self _parseNewline]; 304 | [self _endRecord]; 305 | 306 | return (followedByNewline && _error == nil); 307 | } 308 | 309 | - (BOOL)_parseNewline { 310 | if (_cancelled) { return NO; } 311 | 312 | NSUInteger charCount = 0; 313 | while ([[NSCharacterSet newlineCharacterSet] characterIsMember:[self _peekCharacter]]) { 314 | charCount++; 315 | [self _advance]; 316 | } 317 | return (charCount > 0); 318 | } 319 | 320 | - (BOOL)_parseComment { 321 | [self _advance]; // consume the octothorpe 322 | 323 | NSCharacterSet *newlines = [NSCharacterSet newlineCharacterSet]; 324 | 325 | [self _beginComment]; 326 | BOOL isBackslashEscaped = NO; 327 | while (1) { 328 | if (isBackslashEscaped == NO) { 329 | unichar next = [self _peekCharacter]; 330 | if (next == BACKSLASH && _recognizesBackslashesAsEscapes) { 331 | isBackslashEscaped = YES; 332 | [self _advance]; 333 | } else if ([newlines characterIsMember:next] == NO) { 334 | [self _advance]; 335 | } else { 336 | // it's a newline 337 | break; 338 | } 339 | } else { 340 | isBackslashEscaped = YES; 341 | [self _advance]; 342 | } 343 | } 344 | [self _endComment]; 345 | 346 | return [self _parseNewline]; 347 | } 348 | 349 | - (void)_parseFieldWhitespace { 350 | NSCharacterSet *whitespace = [NSCharacterSet whitespaceCharacterSet]; 351 | while ([self _peekCharacter] != '\0' && 352 | [whitespace characterIsMember:[self _peekCharacter]] && 353 | [self _peekCharacter] != _delimiter) { 354 | // if we're sanitizing fields, then these characters would be stripped (because they're not appended to _sanitizedField) 355 | // if we're not sanitizing fields, then they'll be included in the -substringWithRange: 356 | [self _advance]; 357 | } 358 | } 359 | 360 | - (BOOL)_parseField { 361 | if (_cancelled) { return NO; } 362 | 363 | BOOL parsedField = NO; 364 | [self _beginField]; 365 | if (_stripsLeadingAndTrailingWhitespace) { 366 | // consume leading whitespace 367 | [self _parseFieldWhitespace]; 368 | } 369 | 370 | if ([self _peekCharacter] == DOUBLE_QUOTE) { 371 | parsedField = [self _parseEscapedField]; 372 | } else { 373 | parsedField = [self _parseUnescapedField]; 374 | if (_stripsLeadingAndTrailingWhitespace) { 375 | NSString *trimmedString = [_sanitizedField stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 376 | [_sanitizedField setString:trimmedString]; 377 | } 378 | } 379 | 380 | if (parsedField) { 381 | if (_stripsLeadingAndTrailingWhitespace) { 382 | // consume trailing whitespace 383 | [self _parseFieldWhitespace]; 384 | } 385 | [self _endField]; 386 | } 387 | return parsedField; 388 | } 389 | 390 | - (BOOL)_parseEscapedField { 391 | [self _advance]; // consume the opening double quote 392 | 393 | NSCharacterSet *newlines = [NSCharacterSet newlineCharacterSet]; 394 | BOOL isBackslashEscaped = NO; 395 | while (1) { 396 | unichar next = [self _peekCharacter]; 397 | if (next == '\0') { break; } 398 | 399 | if (isBackslashEscaped == NO) { 400 | if (next == BACKSLASH && _recognizesBackslashesAsEscapes) { 401 | isBackslashEscaped = YES; 402 | [self _advance]; // consume the backslash 403 | } else if ([_validFieldCharacters characterIsMember:next] || 404 | [newlines characterIsMember:next] || 405 | next == _delimiter) { 406 | [_sanitizedField appendFormat:@"%C", next]; 407 | [self _advance]; 408 | } else if (next == DOUBLE_QUOTE && [self _peekPeekCharacter] == DOUBLE_QUOTE) { 409 | [_sanitizedField appendFormat:@"%C", next]; 410 | [self _advance]; 411 | [self _advance]; 412 | } else { 413 | // not valid, or it's not a doubled double quote 414 | break; 415 | } 416 | } else { 417 | [_sanitizedField appendFormat:@"%C", next]; 418 | isBackslashEscaped = NO; 419 | [self _advance]; 420 | } 421 | } 422 | 423 | if ([self _peekCharacter] == DOUBLE_QUOTE) { 424 | [self _advance]; 425 | return YES; 426 | } 427 | 428 | return NO; 429 | } 430 | 431 | - (BOOL)_parseUnescapedField { 432 | 433 | BOOL isBackslashEscaped = NO; 434 | while (1) { 435 | unichar next = [self _peekCharacter]; 436 | if (next == '\0') { break; } 437 | 438 | if (isBackslashEscaped == NO) { 439 | if (next == BACKSLASH && _recognizesBackslashesAsEscapes) { 440 | isBackslashEscaped = YES; 441 | [self _advance]; 442 | } else if ([_validFieldCharacters characterIsMember:next]) { 443 | [_sanitizedField appendFormat:@"%C", next]; 444 | [self _advance]; 445 | } else { 446 | break; 447 | } 448 | } else { 449 | isBackslashEscaped = NO; 450 | [_sanitizedField appendFormat:@"%C", next]; 451 | [self _advance]; 452 | } 453 | } 454 | 455 | return YES; 456 | } 457 | 458 | - (BOOL)_parseDelimiter { 459 | unichar next = [self _peekCharacter]; 460 | if (next == _delimiter) { 461 | [self _advance]; 462 | return YES; 463 | } 464 | if (next != '\0' && [[NSCharacterSet newlineCharacterSet] characterIsMember:next] == NO) { 465 | NSString *description = [NSString stringWithFormat:@"Unexpected delimiter. Expected '%C' (0x%X), but got '%C' (0x%X)", _delimiter, _delimiter, [self _peekCharacter], [self _peekCharacter]]; 466 | _error = [[NSError alloc] initWithDomain:CHCSVErrorDomain code:CHCSVErrorCodeInvalidFormat userInfo:@{NSLocalizedDescriptionKey : description}]; 467 | } 468 | return NO; 469 | } 470 | 471 | - (void)_beginDocument { 472 | if ([_delegate respondsToSelector:@selector(parserDidBeginDocument:)]) { 473 | [_delegate parserDidBeginDocument:self]; 474 | } 475 | } 476 | 477 | - (void)_endDocument { 478 | if ([_delegate respondsToSelector:@selector(parserDidEndDocument:)]) { 479 | [_delegate parserDidEndDocument:self]; 480 | } 481 | } 482 | 483 | - (void)_beginRecord { 484 | if (_cancelled) { return; } 485 | 486 | _fieldIndex = 0; 487 | _currentRecord++; 488 | if ([_delegate respondsToSelector:@selector(parser:didBeginLine:)]) { 489 | [_delegate parser:self didBeginLine:_currentRecord]; 490 | } 491 | } 492 | 493 | - (void)_endRecord { 494 | if (_cancelled) { return; } 495 | 496 | if ([_delegate respondsToSelector:@selector(parser:didEndLine:)]) { 497 | [_delegate parser:self didEndLine:_currentRecord]; 498 | } 499 | } 500 | 501 | - (void)_beginField { 502 | if (_cancelled) { return; } 503 | 504 | [_sanitizedField setString:@""]; 505 | _fieldRange.location = _nextIndex; 506 | } 507 | 508 | - (void)_endField { 509 | if (_cancelled) { return; } 510 | 511 | _fieldRange.length = (_nextIndex - _fieldRange.location); 512 | NSString *field = nil; 513 | 514 | if (_sanitizesFields) { 515 | field = CHCSV_AUTORELEASE([_sanitizedField copy]); 516 | } else { 517 | field = [_string substringWithRange:_fieldRange]; 518 | if (_stripsLeadingAndTrailingWhitespace) { 519 | field = [field stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 520 | } 521 | } 522 | 523 | if ([_delegate respondsToSelector:@selector(parser:didReadField:atIndex:)]) { 524 | [_delegate parser:self didReadField:field atIndex:_fieldIndex]; 525 | } 526 | 527 | [_string replaceCharactersInRange:NSMakeRange(0, NSMaxRange(_fieldRange)) withString:@""]; 528 | _nextIndex = 0; 529 | _fieldIndex++; 530 | } 531 | 532 | - (void)_beginComment { 533 | if (_cancelled) { return; } 534 | 535 | _fieldRange.location = _nextIndex; 536 | } 537 | 538 | - (void)_endComment { 539 | if (_cancelled) { return; } 540 | 541 | _fieldRange.length = (_nextIndex - _fieldRange.location); 542 | if ([_delegate respondsToSelector:@selector(parser:didReadComment:)]) { 543 | NSString *comment = [_string substringWithRange:_fieldRange]; 544 | [_delegate parser:self didReadComment:comment]; 545 | } 546 | 547 | [_string replaceCharactersInRange:NSMakeRange(0, NSMaxRange(_fieldRange)) withString:@""]; 548 | _nextIndex = 0; 549 | } 550 | 551 | - (void)_error { 552 | if (_cancelled) { return; } 553 | 554 | if ([_delegate respondsToSelector:@selector(parser:didFailWithError:)]) { 555 | [_delegate parser:self didFailWithError:_error]; 556 | } 557 | } 558 | 559 | @end 560 | 561 | @implementation CHCSVWriter { 562 | NSOutputStream *_stream; 563 | NSStringEncoding _streamEncoding; 564 | 565 | NSData *_delimiter; 566 | NSData *_bom; 567 | NSCharacterSet *_illegalCharacters; 568 | 569 | NSUInteger _currentField; 570 | } 571 | 572 | - (instancetype)initForWritingToCSVFile:(NSString *)path { 573 | NSOutputStream *stream = [NSOutputStream outputStreamToFileAtPath:path append:NO]; 574 | return [self initWithOutputStream:stream encoding:NSUTF8StringEncoding delimiter:COMMA]; 575 | } 576 | 577 | - (instancetype)initWithOutputStream:(NSOutputStream *)stream encoding:(NSStringEncoding)encoding delimiter:(unichar)delimiter { 578 | self = [super init]; 579 | if (self) { 580 | _stream = CHCSV_RETAIN(stream); 581 | _streamEncoding = encoding; 582 | 583 | if ([_stream streamStatus] == NSStreamStatusNotOpen) { 584 | [_stream open]; 585 | } 586 | 587 | NSData *a = [@"a" dataUsingEncoding:_streamEncoding]; 588 | NSData *aa = [@"aa" dataUsingEncoding:_streamEncoding]; 589 | if ([a length] * 2 != [aa length]) { 590 | NSUInteger characterLength = [aa length] - [a length]; 591 | _bom = CHCSV_RETAIN([a subdataWithRange:NSMakeRange(0, [a length] - characterLength)]); 592 | [self _writeData:_bom]; 593 | } 594 | 595 | NSString *delimiterString = [NSString stringWithFormat:@"%C", delimiter]; 596 | NSData *delimiterData = [delimiterString dataUsingEncoding:_streamEncoding]; 597 | if ([_bom length] > 0) { 598 | _delimiter = CHCSV_RETAIN([delimiterData subdataWithRange:NSMakeRange([_bom length], [delimiterData length] - [_bom length])]); 599 | } else { 600 | _delimiter = CHCSV_RETAIN(delimiterData); 601 | } 602 | 603 | NSMutableCharacterSet *illegalCharacters = [[NSCharacterSet newlineCharacterSet] mutableCopy]; 604 | [illegalCharacters addCharactersInString:delimiterString]; 605 | [illegalCharacters addCharactersInString:@"\""]; 606 | _illegalCharacters = [illegalCharacters copy]; 607 | CHCSV_RELEASE(illegalCharacters); 608 | } 609 | return self; 610 | } 611 | 612 | - (void)dealloc { 613 | [self closeStream]; 614 | 615 | #if !CHCSV_HAS_ARC 616 | [_delimiter release]; 617 | [_bom release]; 618 | [_illegalCharacters release]; 619 | [super dealloc]; 620 | #endif 621 | } 622 | 623 | - (void)_writeData:(NSData *)data { 624 | if ([data length] > 0) { 625 | const void *bytes = [data bytes]; 626 | [_stream write:bytes maxLength:[data length]]; 627 | } 628 | } 629 | 630 | - (void)_writeString:(NSString *)string { 631 | NSData *stringData = [string dataUsingEncoding:_streamEncoding]; 632 | if ([_bom length] > 0) { 633 | stringData = [stringData subdataWithRange:NSMakeRange([_bom length], [stringData length] - [_bom length])]; 634 | } 635 | [self _writeData:stringData]; 636 | } 637 | 638 | - (void)_writeDelimiter { 639 | [self _writeData:_delimiter]; 640 | } 641 | 642 | - (void)writeField:(id)field { 643 | if (_currentField > 0) { 644 | [self _writeDelimiter]; 645 | } 646 | NSString *string = field ? [field description] : @""; 647 | if ([string rangeOfCharacterFromSet:_illegalCharacters].location != NSNotFound) { 648 | // replace double quotes with double double quotes 649 | string = [string stringByReplacingOccurrencesOfString:@"\"" withString:@"\"\""]; 650 | // surround in double quotes 651 | string = [NSString stringWithFormat:@"\"%@\"", string]; 652 | } 653 | [self _writeString:string]; 654 | _currentField++; 655 | } 656 | 657 | - (void)finishLine { 658 | [self _writeString:@"\n"]; 659 | _currentField = 0; 660 | } 661 | 662 | - (void)_finishLineIfNecessary { 663 | if (_currentField != 0) { 664 | [self finishLine]; 665 | } 666 | } 667 | 668 | - (void)writeLineOfFields:(id)fields { 669 | [self _finishLineIfNecessary]; 670 | 671 | for (id field in fields) { 672 | [self writeField:field]; 673 | } 674 | [self finishLine]; 675 | } 676 | 677 | - (void)writeComment:(NSString *)comment { 678 | [self _finishLineIfNecessary]; 679 | 680 | NSArray *lines = [comment componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]]; 681 | for (NSString *line in lines) { 682 | NSString *commented = [NSString stringWithFormat:@"#%@\n", line]; 683 | [self _writeString:commented]; 684 | } 685 | } 686 | 687 | - (void)closeStream { 688 | [_stream close]; 689 | CHCSV_RELEASE(_stream); 690 | _stream = nil; 691 | } 692 | 693 | @end 694 | 695 | #pragma mark - Convenience Categories 696 | 697 | @interface _CHCSVAggregator : NSObject 698 | 699 | @property (readonly) NSArray *lines; 700 | @property (readonly) NSError *error; 701 | 702 | @end 703 | 704 | @implementation _CHCSVAggregator { 705 | NSMutableArray *_lines; 706 | NSMutableArray *_currentLine; 707 | } 708 | 709 | #if !CHCSV_HAS_ARC 710 | - (void)dealloc { 711 | [_currentLine release]; 712 | [_lines release]; 713 | [_error release]; 714 | [super dealloc]; 715 | } 716 | #endif 717 | 718 | - (void)parserDidBeginDocument:(CHCSVParser *)parser { 719 | _lines = [[NSMutableArray alloc] init]; 720 | } 721 | 722 | - (void)parser:(CHCSVParser *)parser didBeginLine:(NSUInteger)recordNumber { 723 | _currentLine = [[NSMutableArray alloc] init]; 724 | } 725 | 726 | - (void)parser:(CHCSVParser *)parser didEndLine:(NSUInteger)recordNumber { 727 | [_lines addObject:_currentLine]; 728 | CHCSV_RELEASE(_currentLine); 729 | _currentLine = nil; 730 | } 731 | 732 | - (void)parser:(CHCSVParser *)parser didReadField:(NSString *)field atIndex:(NSInteger)fieldIndex { 733 | [_currentLine addObject:field]; 734 | } 735 | 736 | - (void)parser:(CHCSVParser *)parser didFailWithError:(NSError *)error { 737 | _error = CHCSV_RETAIN(error); 738 | CHCSV_RELEASE(_lines); 739 | _lines = nil; 740 | } 741 | 742 | @end 743 | 744 | @implementation NSArray (CHCSVAdditions) 745 | 746 | + (instancetype)arrayWithContentsOfCSVFile:(NSString *)csvFilePath { 747 | return [self arrayWithContentsOfCSVFile:csvFilePath options:0 delimiter:COMMA]; 748 | } 749 | 750 | + (instancetype)arrayWithContentsOfCSVFile:(NSString *)csvFilePath delimiter:(unichar)delimiter 751 | { 752 | return [self arrayWithContentsOfCSVFile:csvFilePath options:0 delimiter:delimiter]; 753 | } 754 | 755 | + (instancetype)arrayWithContentsOfCSVFile:(NSString *)csvFilePath options:(CHCSVParserOptions)options 756 | { 757 | return [self arrayWithContentsOfCSVFile:csvFilePath options:options delimiter:COMMA]; 758 | } 759 | 760 | + (instancetype)arrayWithContentsOfCSVFile:(NSString *)csvFilePath options:(CHCSVParserOptions)options delimiter:(unichar)delimiter { 761 | NSParameterAssert(csvFilePath); 762 | _CHCSVAggregator *aggregator = [[_CHCSVAggregator alloc] init]; 763 | CHCSVParser *parser = [[CHCSVParser alloc] initWithContentsOfCSVFile:csvFilePath delimiter:delimiter]; 764 | [parser setDelegate:aggregator]; 765 | 766 | [parser setRecognizesBackslashesAsEscapes:!!(options & CHCSVParserOptionsRecognizesBackslashesAsEscapes)]; 767 | [parser setSanitizesFields:!!(options & CHCSVParserOptionsSanitizesFields)]; 768 | [parser setRecognizesComments:!!(options & CHCSVParserOptionsRecognizesComments)]; 769 | [parser setStripsLeadingAndTrailingWhitespace:!!(options & CHCSVParserOptionsStripsLeadingAndTrailingWhitespace)]; 770 | 771 | [parser parse]; 772 | CHCSV_RELEASE(parser); 773 | 774 | NSArray *final = CHCSV_AUTORELEASE(CHCSV_RETAIN([aggregator lines])); 775 | CHCSV_RELEASE(aggregator); 776 | 777 | return final; 778 | } 779 | 780 | - (NSString *)CSVString { 781 | NSOutputStream *output = [NSOutputStream outputStreamToMemory]; 782 | CHCSVWriter *writer = [[CHCSVWriter alloc] initWithOutputStream:output encoding:NSUTF8StringEncoding delimiter:COMMA]; 783 | for (id object in self) { 784 | if ([object conformsToProtocol:@protocol(NSFastEnumeration)]) { 785 | [writer writeLineOfFields:object]; 786 | } 787 | } 788 | [writer closeStream]; 789 | CHCSV_RELEASE(writer); 790 | 791 | NSData *buffer = [output propertyForKey:NSStreamDataWrittenToMemoryStreamKey]; 792 | NSString *string = [[NSString alloc] initWithData:buffer encoding:NSUTF8StringEncoding]; 793 | return CHCSV_AUTORELEASE(string); 794 | } 795 | 796 | @end 797 | 798 | @implementation NSString (CHCSVAdditions) 799 | 800 | 801 | - (NSArray *)CSVComponents { 802 | return [self CSVComponentsWithOptions:0 delimiter:COMMA]; 803 | } 804 | 805 | - (NSArray *)CSVComponentsWithDelimiter:(unichar)delimiter 806 | { 807 | return [self CSVComponentsWithOptions:0 delimiter:delimiter]; 808 | } 809 | 810 | - (NSArray *)CSVComponentsWithOptions:(CHCSVParserOptions)options 811 | { 812 | return [self CSVComponentsWithOptions:options delimiter:COMMA]; 813 | } 814 | 815 | - (NSArray *)CSVComponentsWithOptions:(CHCSVParserOptions)options delimiter:(unichar)delimiter { 816 | _CHCSVAggregator *aggregator = [[_CHCSVAggregator alloc] init]; 817 | CHCSVParser *parser = [[CHCSVParser alloc] initWithCSVString:self delimiter:delimiter]; 818 | [parser setDelegate:aggregator]; 819 | 820 | [parser setRecognizesBackslashesAsEscapes:!!(options & CHCSVParserOptionsRecognizesBackslashesAsEscapes)]; 821 | [parser setSanitizesFields:!!(options & CHCSVParserOptionsSanitizesFields)]; 822 | [parser setRecognizesComments:!!(options & CHCSVParserOptionsRecognizesComments)]; 823 | [parser setStripsLeadingAndTrailingWhitespace:!!(options & CHCSVParserOptionsStripsLeadingAndTrailingWhitespace)]; 824 | 825 | [parser parse]; 826 | CHCSV_RELEASE(parser); 827 | 828 | NSArray *final = CHCSV_AUTORELEASE(CHCSV_RETAIN([aggregator lines])); 829 | CHCSV_RELEASE(aggregator); 830 | 831 | return final; 832 | } 833 | 834 | @end 835 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/DNSCrypt-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | BNDL 19 | CFBundleShortVersionString 20 | 1.0.14 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0.14 25 | NSHumanReadableCopyright 26 | BSD 27 | NSMainNibFile 28 | DNSCrypt 29 | NSPrefPaneIconFile 30 | dnscrypt_256.png 31 | NSPrefPaneIconLabel 32 | DNSCrypt 33 | NSPrincipalClass 34 | DNSCrypt 35 | 36 | 37 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/DNSCrypt-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'DNSCrypt' target in the 'DNSCrypt' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/DNSCrypt.h: -------------------------------------------------------------------------------- 1 | 2 | #import 3 | #import 4 | #import "CHCSVParser/CHCSVParser.h" 5 | #import "NSPlaceHolderTextView.h" 6 | 7 | #define kDNSCRYPT_PACKAGE_VERSION @"1.0.14" 8 | 9 | #define kDNSCRYPT_PROJECT_URL @"https://dnscrypt.org/osxclient" 10 | 11 | #define kDNSCRYPT_PREFPANE_APP_PATH @"/Library/PreferencePanes/DNSCrypt.prefPane" 12 | #define kDNSCRYPT_USR_BASE_DIR kDNSCRYPT_PREFPANE_APP_PATH @"/Contents/Resources/usr" 13 | #define kDNSCRYPT_BIN_BASE_DIR kDNSCRYPT_USR_BASE_DIR @"/bin" 14 | #define kDNSCRYPT_SHARE_BASE_DIR kDNSCRYPT_USR_BASE_DIR @"/share" 15 | #define kDNSCRYPT_SCRIPTS_BASE_DIR kDNSCRYPT_USR_BASE_DIR @"/scripts" 16 | #define kDNSCRYPT_VAR_BASE_DIR @"/Library/Application Support/DNSCrypt" 17 | #define kDNSCRYPT_CONTROL_DIR kDNSCRYPT_VAR_BASE_DIR @"/control" 18 | 19 | #define kDNSCRYPT_QUERY_LOG_FILE @"/var/log/dnscrypt-query.log" 20 | #define kDNSCRYPT_BLOCKED_QUERY_LOG_FILE @"/var/log/dnscrypt-blocked-query.log" 21 | 22 | #define kDNSCRYPT_BLACKLIST_IPS_TMP_FILE kDNSCRYPT_CONTROL_DIR @"/blacklist-ips.tmp" 23 | #define kDNSCRYPT_BLACKLIST_DOMAINS_TMP_FILE kDNSCRYPT_CONTROL_DIR @"/blacklist-domains.tmp" 24 | #define kDNSCRYPT_EXCEPTIONS_TMP_FILE kDNSCRYPT_CONTROL_DIR @"/exceptions.tmp" 25 | 26 | #define kBUNDLE_IDENTIFIER @"com.github.dnscrypt-osxclient.DNSCrypt" 27 | 28 | #define kRESOLVERS_LIST_FILE kDNSCRYPT_SHARE_BASE_DIR @"/dnscrypt-proxy/dnscrypt-resolvers.csv" 29 | 30 | #define kREFRESH_DELAY 1.0 31 | #define kMAX_TRIES_AFTER_CHANGE (30 / kREFRESH_DELAY) 32 | 33 | typedef enum { 34 | kDNS_CONFIGURATION_UNKNOWN, kDNS_CONFIGURATION_VANILLA, kDNS_CONFIGURATION_LOCALHOST 35 | } DNSConfigurationState; 36 | 37 | @interface DNSCrypt : NSPreferencePane { 38 | AuthorizationRef auth; 39 | 40 | NSTabView *_tabView; 41 | NSTabViewItem *_aboutTabViewItem; 42 | NSTabViewItem *_releaseNotesTabViewItem; 43 | 44 | NSButton *_dnscryptButton; 45 | NSButton *_hideMenubarIcon; 46 | NSButton *_disableIPv6Button; 47 | 48 | NSTextField *_currentResolverTextField; 49 | NSImageView *_statusImageView; 50 | NSTextField *_statusText; 51 | WebView *_releaseNotesWebView; 52 | WebView *_aboutWebView; 53 | NSTextFieldCell *_staticResolversTextField; 54 | NSPlaceHolderTextView *_blacklistIPsTextView; 55 | NSPlaceHolderTextView *_blacklistDomainsTextView; 56 | NSPlaceHolderTextView *_exceptionsTextView; 57 | NSButton *_viewLogButton; 58 | NSButton *_queryLoggingButton; 59 | NSButton *_viewBlockedLogButton; 60 | NSButton *_blockedQueryLoggingButton; 61 | NSPopUpButton *_resolverNamesButton; 62 | NSButton *_saveAndApplyChangesButton; 63 | } 64 | @property (nonatomic, strong) IBOutlet NSTabView *tabView; 65 | @property (nonatomic, strong) IBOutlet NSTabViewItem *aboutTabViewItem; 66 | @property (nonatomic, strong) IBOutlet NSTabViewItem *releaseNotesTabViewItem; 67 | 68 | @property (nonatomic, strong) IBOutlet NSButton *dnscryptButton; 69 | @property (nonatomic, strong) IBOutlet NSButton *hideMenubarIcon; 70 | @property (nonatomic, strong) IBOutlet NSButton *disableIPv6Button; 71 | 72 | @property (nonatomic, strong) IBOutlet NSTextField *currentResolverTextField; 73 | @property (nonatomic, strong) IBOutlet NSImageView *statusImageView; 74 | @property (nonatomic, strong) IBOutlet NSTextField *statusText; 75 | @property (nonatomic, strong) IBOutlet WebView *releaseNotesWebView; 76 | @property (nonatomic, strong) IBOutlet WebView *aboutWebView; 77 | @property (nonatomic, strong) IBOutlet NSTextFieldCell *staticResolversTextField; 78 | @property (nonatomic, strong) IBOutlet NSPlaceHolderTextView *blacklistIPsTextView; 79 | @property (nonatomic, strong) IBOutlet NSPlaceHolderTextView *blacklistDomainsTextView; 80 | @property (nonatomic, strong) IBOutlet NSPlaceHolderTextView *exceptionsTextView; 81 | @property (nonatomic, strong) IBOutlet NSButton *viewLogButton; 82 | @property (nonatomic, strong) IBOutlet NSButton *queryLoggingButton; 83 | @property (nonatomic, strong) IBOutlet NSButton *blockedQueryLoggingButton; 84 | 85 | @property (nonatomic, strong) IBOutlet NSPopUpButton *resolverNamesButton; 86 | @property (nonatomic, strong) IBOutlet NSTextField *locationText; 87 | 88 | @property (nonatomic, strong) IBOutlet NSButton *providerLink; 89 | 90 | @property (nonatomic, strong) IBOutlet NSTextFieldCell *descriptionText; 91 | 92 | - (void) mainViewDidLoad; 93 | 94 | - (IBAction)dnscryptButtonPressed:(NSButton *)sender; 95 | - (IBAction)hideMenubarIcon:(NSButton *)sender; 96 | - (IBAction)disableIPv6ButtonPressed:(NSButton *)sender; 97 | - (IBAction)providerLinkPushed:(NSButton *)sender; 98 | - (IBAction)uninstallPushed:(NSButton *)sender; 99 | - (IBAction)staticResolversTextFieldChanged:(NSTextField *)sender; 100 | - (IBAction)queryLoggingButtonPressed:(NSButtonCell *)sender; 101 | - (IBAction)viewLogButtonPushed:(NSButton *)sender; 102 | - (IBAction)blockedQueryLoggingButtonPressed:(NSButtonCell *)sender; 103 | - (IBAction)viewBlockedLogButtonPushed:(NSButton *)sender; 104 | - (IBAction)resolversNamesPopupButtonPressed:(NSPopUpButton *)sender; 105 | - (IBAction)saveAndApplyChangesButtonPressed:(NSButton *)sender; 106 | - (IBAction)helpButtonPressed:(NSButton *)sender; 107 | 108 | @end 109 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/DNSCrypt.m: -------------------------------------------------------------------------------- 1 | 2 | #import "DNSCrypt.h" 3 | 4 | @implementation DNSCrypt 5 | @synthesize tabView = _tabView; 6 | @synthesize aboutTabViewItem = _aboutTabViewItem; 7 | @synthesize releaseNotesTabViewItem = _releaseNotesTabViewItem; 8 | @synthesize releaseNotesWebView = _releaseNotesWebView; 9 | @synthesize aboutWebView = _aboutWebView; 10 | @synthesize staticResolversTextField = _staticResolversTextField; 11 | @synthesize blacklistIPsTextView = _blacklistIPsTextView; 12 | @synthesize blacklistDomainsTextView = _blacklistDomainsTextView; 13 | @synthesize exceptionsTextView = _exceptionsTextView; 14 | @synthesize viewLogButton = _viewLogButton; 15 | @synthesize queryLoggingButton = _queryLoggingButton; 16 | @synthesize blockedQueryLoggingButton = _blockedQueryLoggingButton; 17 | @synthesize dnscryptButton = _dnscryptButton; 18 | @synthesize disableIPv6Button = _disableIPv6Button; 19 | @synthesize hideMenubarIcon = _hideMenubarIcon; 20 | @synthesize statusImageView = _statusImageView; 21 | @synthesize statusText = _statusText; 22 | @synthesize currentResolverTextField = _currentResolverTextField; 23 | @synthesize resolverNamesButton = _resolverNamesButton; 24 | 25 | DNSConfigurationState currentState = kDNS_CONFIGURATION_UNKNOWN; 26 | NSArray *resolversList; 27 | BOOL blacklistDomainsUpdated = FALSE; 28 | BOOL blacklistIPsUpdated = FALSE; 29 | BOOL exceptionsUpdated = FALSE; 30 | 31 | 32 | - (void) setCheckBoxesEnabled: (BOOL) enabled 33 | { 34 | [_dnscryptButton setEnabled: enabled]; 35 | [_hideMenubarIcon setEnabled: enabled]; 36 | [_disableIPv6Button setEnabled: enabled]; 37 | [_resolverNamesButton setEnabled: enabled]; 38 | } 39 | 40 | - (NSString *) fromCommand: (NSString *) launchPath withArguments: (NSArray *) arguments 41 | { 42 | NSPipe *pipe = [[NSPipe alloc] init]; 43 | NSTask *task = [[NSTask alloc] init]; 44 | NSData *data; 45 | NSString *result; 46 | task.launchPath = launchPath; 47 | task.arguments = arguments; 48 | task.standardOutput = pipe; 49 | [task launch]; 50 | data = [[pipe fileHandleForReading] readDataToEndOfFile]; 51 | [task waitUntilExit]; 52 | result = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding]; 53 | if ([result hasSuffix: @"\n"]) { 54 | result = [result substringToIndex: result.length - 1]; 55 | } 56 | return result; 57 | } 58 | 59 | - (void) initState 60 | { 61 | NSString *res; 62 | 63 | _dnscryptButton.state = 0; 64 | _hideMenubarIcon.state = 0; 65 | _disableIPv6Button.state = 0; 66 | 67 | [_blacklistIPsTextView setPlaceHolderText: @"IP addresses to block.\n\nExamples:\n\n203.0.113.7\n198.51.100.*"]; 68 | [_blacklistDomainsTextView setPlaceHolderText: @"Domains and patterns to block.\n\nExamples:\n\nexample.com\nads.*\n*sex*"]; 69 | [_exceptionsTextView setPlaceHolderText: @"Domains bypassing DNSCrypt.\n\nExamples:\n\nlocal\nlocaldomain\nlan"]; 70 | 71 | res = [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-f", @"-c", @"cd '" kDNSCRYPT_SCRIPTS_BASE_DIR @"' && exec ./get-dnscrypt-status.sh", nil]]; 72 | if ([res isEqualToString: @"yes"]) { 73 | [_dnscryptButton setState: 1]; 74 | } 75 | res = [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-f", @"-c", @"cd '" kDNSCRYPT_SCRIPTS_BASE_DIR @"' && exec ./get-hide-menubar-icon-status.sh", nil]]; 76 | if ([res isEqualToString: @"yes"]) { 77 | [_hideMenubarIcon setState: 1]; 78 | } 79 | res = [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-f", @"-c", @"cd '" kDNSCRYPT_SCRIPTS_BASE_DIR @"' && exec ./get-aaaa-blocking-status.sh", nil]]; 80 | if ([res isEqualToString: @"yes"]) { 81 | [_disableIPv6Button setState: 1]; 82 | } 83 | res = [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-f", @"-c", @"cd '" kDNSCRYPT_SCRIPTS_BASE_DIR @"' && exec ./get-static-resolvers.sh", nil]]; 84 | [_staticResolversTextField setStringValue: res]; 85 | res = [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-f", @"-c", @"cd '" kDNSCRYPT_SCRIPTS_BASE_DIR @"' && exec ./get-query-logging-status.sh", nil]]; 86 | if ([res isEqualToString: @"yes"]) { 87 | [_queryLoggingButton setState: 1]; 88 | } 89 | res = [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-f", @"-c", @"cd '" kDNSCRYPT_SCRIPTS_BASE_DIR @"' && exec ./get-blocked-query-logging-status.sh", nil]]; 90 | if ([res isEqualToString: @"yes"]) { 91 | [_blockedQueryLoggingButton setState: 1]; 92 | } 93 | NSString *fileContent; 94 | fileContent = [NSString stringWithContentsOfFile: kDNSCRYPT_BLACKLIST_IPS_TMP_FILE encoding:NSUTF8StringEncoding error: nil]; 95 | if (fileContent != nil) { 96 | [_blacklistIPsTextView setString: fileContent]; 97 | } 98 | fileContent = [NSString stringWithContentsOfFile: kDNSCRYPT_BLACKLIST_DOMAINS_TMP_FILE encoding:NSUTF8StringEncoding error: nil]; 99 | if (fileContent != nil) { 100 | [_blacklistDomainsTextView setString: fileContent]; 101 | } 102 | fileContent = [NSString stringWithContentsOfFile: kDNSCRYPT_EXCEPTIONS_TMP_FILE encoding:NSUTF8StringEncoding error: nil]; 103 | if (fileContent != nil) { 104 | [_exceptionsTextView setString: fileContent]; 105 | } 106 | 107 | [_resolverNamesButton removeAllItems]; 108 | 109 | resolversList = [NSArray arrayWithContentsOfCSVFile: kRESOLVERS_LIST_FILE options:CHCSVParserOptionsSanitizesFields | CHCSVParserOptionsStripsLeadingAndTrailingWhitespace]; 110 | NSUInteger rows_count = [resolversList count]; 111 | NSUInteger i; 112 | [_resolverNamesButton addItemWithTitle: NSLocalizedString(@"Please select a resolver", @"A resolver hasn't been selected yet")]; 113 | res = [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-f", @"-c", @"cd '" kDNSCRYPT_SCRIPTS_BASE_DIR @"' && exec ./get-dnscrypt-resolver-name.sh", nil]]; 114 | for (i = 1U; i < rows_count; i++) { 115 | NSArray *row = [resolversList objectAtIndex: i]; 116 | NSString *name; 117 | if (row.count < 4) { 118 | continue; 119 | } 120 | name = [row objectAtIndex: 1]; 121 | [_resolverNamesButton addItemWithTitle: name]; 122 | if ([[row objectAtIndex: 0] isEqualToString: res]) { 123 | [_resolverNamesButton selectItemAtIndex: i]; 124 | [self updateResolverInfo: row]; 125 | } 126 | } 127 | } 128 | 129 | - (void) updateLedStatus 130 | { 131 | NSBundle *bundle = [NSBundle bundleWithIdentifier: @"com.github.dnscrypt-osxclient.DNSCrypt"]; 132 | switch (currentState) { 133 | case kDNS_CONFIGURATION_UNKNOWN: 134 | _statusText.stringValue = NSLocalizedString(@"Standby", @"Status"); 135 | _statusImageView.image = [[NSImage alloc] initWithContentsOfFile: [bundle pathForImageResource: @"shield_red.png"]]; 136 | break; 137 | case kDNS_CONFIGURATION_VANILLA: 138 | _statusText.stringValue = NSLocalizedString(@"Not using DNSCrypt", @"Status"); 139 | _statusImageView.image = [[NSImage alloc] initWithContentsOfFile: [bundle pathForImageResource: @"shield_red.png"]]; 140 | break; 141 | case kDNS_CONFIGURATION_LOCALHOST: 142 | _statusText.stringValue = NSLocalizedString(@"Using DNSCrypt", @"Status"); 143 | _statusImageView.image = [[NSImage alloc] initWithContentsOfFile: [bundle pathForImageResource: @"shield_green.png"]]; 144 | break; 145 | default: 146 | return; 147 | } 148 | } 149 | 150 | - (BOOL) updateStatusWithCurrentConfig 151 | { 152 | NSString *stateDescription = [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-f", @"-c", @"cd '" kDNSCRYPT_SCRIPTS_BASE_DIR @"' && ./get-current-resolvers.sh | ./get-resolvers-description.sh", nil]]; 153 | if ([stateDescription isEqualToString: @"DNSCrypt"]) { 154 | currentState = kDNS_CONFIGURATION_LOCALHOST; 155 | } else if ([stateDescription isEqualToString: @"None"]) { 156 | currentState = kDNS_CONFIGURATION_UNKNOWN; 157 | } else if ([stateDescription isEqualToString: @"Updating"]) { 158 | currentState = kDNS_CONFIGURATION_UNKNOWN; 159 | } else if (stateDescription.length > 0) { 160 | currentState = kDNS_CONFIGURATION_VANILLA; 161 | } 162 | [self updateLedStatus]; 163 | 164 | NSString *currentResolvers = [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-f", @"-c", @"cd '" kDNSCRYPT_SCRIPTS_BASE_DIR @"' && ./get-current-resolvers.sh | ./get-upstream-resolvers.sh", nil]]; 165 | _currentResolverTextField.stringValue = currentResolvers; 166 | 167 | NSString *res = [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-f", @"-c", @"cd '" kDNSCRYPT_SCRIPTS_BASE_DIR @"' && exec ./gui-pop-conf-change.sh prefpane", nil]]; 168 | if ([res isEqualToString: @"yes"]) { 169 | [self initState]; 170 | } 171 | [self setCheckBoxesEnabled: TRUE]; 172 | 173 | return TRUE; 174 | } 175 | 176 | - (void) periodicallyUpdateStatusWithCurrentConfig { 177 | [self updateStatusWithCurrentConfig]; 178 | [NSObject cancelPreviousPerformRequestsWithTarget: self selector: @selector(periodicallyUpdateStatusWithCurrentConfig) object: nil]; 179 | [self performSelector: @selector(periodicallyUpdateStatusWithCurrentConfig) withObject:nil afterDelay: kREFRESH_DELAY]; 180 | } 181 | 182 | - (void) showSpinners { 183 | NSBundle *bundle = [NSBundle bundleWithIdentifier: kBUNDLE_IDENTIFIER]; 184 | 185 | [self setCheckBoxesEnabled: FALSE]; 186 | _statusText.stringValue = NSLocalizedString(@"Updating", @"Updating network configuraiton"); 187 | _statusImageView.image = [[NSImage alloc] initWithContentsOfFile: [bundle pathForImageResource: @"ajax-loader.gif"]]; 188 | _currentResolverTextField.stringValue = @""; 189 | 190 | [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-f", @"-c", @"cd '" kDNSCRYPT_SCRIPTS_BASE_DIR @"' && exec ./gui-push-conf-change.sh menubar", nil]]; 191 | 192 | [NSObject cancelPreviousPerformRequestsWithTarget: self selector: @selector(periodicallyUpdateStatusWithCurrentConfig) object: nil]; 193 | [NSObject cancelPreviousPerformRequestsWithTarget: self selector: @selector(waitForUpdate) object: nil]; 194 | [self performSelector: @selector(waitForUpdate) withObject: self afterDelay:kREFRESH_DELAY]; 195 | } 196 | 197 | - (BOOL) setDNSCryptOn { 198 | [self showSpinners]; 199 | NSString *res = [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-f", @"-c", @"cd '" kDNSCRYPT_SCRIPTS_BASE_DIR @"' && ./create-ticket.sh && ./switch-to-dnscrypt.sh", nil]]; 200 | (void) res; 201 | return TRUE; 202 | } 203 | 204 | - (BOOL) setDNSCryptOff { 205 | [self showSpinners]; 206 | NSString *res = [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-f", @"-c", @"cd '" kDNSCRYPT_SCRIPTS_BASE_DIR @"' && ./create-ticket.sh && ./switch-to-dhcp.sh", nil]]; 207 | (void) res; 208 | return TRUE; 209 | } 210 | 211 | - (BOOL) setHideMenubarIconOn { 212 | [self showSpinners]; 213 | NSString *res = [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-f", @"-c", @"cd '" kDNSCRYPT_SCRIPTS_BASE_DIR @"' && ./create-ticket.sh && ./switch-hide-menubar-icon-on.sh", nil]]; 214 | (void) res; 215 | return TRUE; 216 | } 217 | 218 | - (BOOL) setHideMenubarIconOff { 219 | [self showSpinners]; 220 | NSString *res = [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-f", @"-c", @"cd '" kDNSCRYPT_SCRIPTS_BASE_DIR @"' && ./create-ticket.sh && ./switch-hide-menubar-icon-off.sh", nil]]; 221 | (void) res; 222 | return TRUE; 223 | } 224 | 225 | - (BOOL) setDisableIPv6On { 226 | [self showSpinners]; 227 | NSString *res = [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-f", @"-c", @"cd '" kDNSCRYPT_SCRIPTS_BASE_DIR @"' && ./create-ticket.sh && ./switch-aaaa-blocking-on.sh", nil]]; 228 | (void) res; 229 | return TRUE; 230 | } 231 | 232 | - (BOOL) setDisableIPv6Off { 233 | [self showSpinners]; 234 | NSString *res = [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-f", @"-c", @"cd '" kDNSCRYPT_SCRIPTS_BASE_DIR @"' && ./create-ticket.sh && ./switch-aaaa-blocking-off.sh", nil]]; 235 | (void) res; 236 | return TRUE; 237 | } 238 | 239 | - (IBAction)dnscryptButtonPressed:(NSButton *)sender 240 | { 241 | if (sender.state != 0) { 242 | [self setDNSCryptOn]; 243 | } else { 244 | [self setDNSCryptOff]; 245 | } 246 | } 247 | 248 | - (IBAction)hideMenubarIcon:(NSButton *)sender 249 | { 250 | if (sender.state != 0) { 251 | [self setHideMenubarIconOn]; 252 | } else { 253 | [self setHideMenubarIconOff]; 254 | } 255 | } 256 | 257 | - (IBAction)disableIPv6ButtonPressed:(NSButton *)sender 258 | { 259 | if (sender.state != 0) { 260 | [self setDisableIPv6On]; 261 | } else { 262 | [self setDisableIPv6Off]; 263 | } 264 | } 265 | 266 | - (void) waitForUpdate { 267 | NSString *res; 268 | static unsigned int tries; 269 | 270 | res = [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-f", @"-c", @"cd '" kDNSCRYPT_SCRIPTS_BASE_DIR @"' && exec ./get-tickets-count.sh", nil]]; 271 | if (res.length <= 0 || [res isEqualToString: @"0"] || tries > kMAX_TRIES_AFTER_CHANGE) { 272 | tries = 0U; 273 | [self periodicallyUpdateStatusWithCurrentConfig]; 274 | return; 275 | } 276 | tries++; 277 | [NSObject cancelPreviousPerformRequestsWithTarget: self selector: @selector(waitForUpdate) object: nil]; 278 | [self performSelector: @selector(waitForUpdate) withObject: self afterDelay:kREFRESH_DELAY]; 279 | } 280 | 281 | - (void) updateResolverInfo: (NSArray *) row { 282 | NSString *location = [row objectAtIndex: 3]; 283 | _locationText.stringValue = location; 284 | NSString *url = [row objectAtIndex: 5]; 285 | if (![url isEqualToString: @""]) { 286 | _providerLink.title = url; 287 | _providerLink.hidden = false; 288 | } else { 289 | _providerLink.hidden = true; 290 | } 291 | NSString *description = [row objectAtIndex: 2]; 292 | _descriptionText.stringValue = description; 293 | } 294 | 295 | - (IBAction)resolversNamesPopupButtonPressed:(NSPopUpButton *)sender { 296 | NSUInteger i = [sender indexOfSelectedItem]; 297 | if (i <= 0U || i >= resolversList.count) { 298 | return; 299 | } 300 | NSArray *row = [resolversList objectAtIndex: i]; 301 | [self updateResolverInfo: row]; 302 | setenv("RESOLVER_NAME", [[row objectAtIndex: 0] UTF8String], 1); 303 | [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-f", @"-c", @"cd '" kDNSCRYPT_SCRIPTS_BASE_DIR @"' && exec ./set-dnscrypt-resolver-name.sh \"$RESOLVER_NAME\"", nil]]; 304 | } 305 | 306 | - (void) mainViewDidLoad 307 | { 308 | currentState = kDNS_CONFIGURATION_UNKNOWN; 309 | 310 | [self initState]; 311 | [self periodicallyUpdateStatusWithCurrentConfig]; 312 | 313 | SInt32 OSXversionMajor, OSXversionMinor; 314 | if (Gestalt(gestaltSystemVersionMajor, &OSXversionMajor) != noErr || Gestalt(gestaltSystemVersionMinor, &OSXversionMinor) != noErr || OSXversionMajor < 10 || OSXversionMinor < 6) { 315 | return; 316 | } 317 | [_releaseNotesWebView setDrawsBackground:false]; 318 | [_releaseNotesWebView setShouldUpdateWhileOffscreen:true]; 319 | [_releaseNotesWebView setUIDelegate:self]; 320 | 321 | NSURL *releaseNotesURL; 322 | NSString *releaseNotesURLPath = [[NSBundle bundleForClass: [self class]] pathForResource: @"releasenotes" ofType: @"html" inDirectory: @"html"]; 323 | if (! releaseNotesURLPath || ! (releaseNotesURL = [NSURL fileURLWithPath: releaseNotesURLPath])) { 324 | [_tabView removeTabViewItem:_releaseNotesTabViewItem]; 325 | } else { 326 | [[_releaseNotesWebView mainFrame] loadRequest:[NSURLRequest requestWithURL: releaseNotesURL]]; 327 | } 328 | 329 | [_aboutWebView setDrawsBackground:false]; 330 | [_aboutWebView setShouldUpdateWhileOffscreen:true]; 331 | [_aboutWebView setUIDelegate:self]; 332 | NSURL *aboutURL; 333 | NSString *aboutURLPath = [[NSBundle bundleForClass: [self class]] pathForResource: @"about" ofType: @"html" inDirectory: @"html"]; 334 | if (! aboutURLPath || ! (aboutURL = [NSURL fileURLWithPath: aboutURLPath])) { 335 | [_tabView removeTabViewItem: _aboutTabViewItem]; 336 | } else { 337 | [[_aboutWebView mainFrame] loadRequest:[NSURLRequest requestWithURL: aboutURL]]; 338 | } 339 | } 340 | 341 | - (NSArray *)webView:(WebView *)sender contextMenuItemsForElement:(NSDictionary *)element 342 | defaultMenuItems:(NSArray *)defaultMenuItems 343 | { 344 | return nil; 345 | } 346 | 347 | - (IBAction)providerLinkPushed:(NSButton *)sender 348 | { 349 | (void) sender; 350 | [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString: sender.title]]; 351 | } 352 | 353 | - (IBAction)uninstallPushed:(NSButton *)sender { 354 | [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-f", @"-c", @"cd '" kDNSCRYPT_BIN_BASE_DIR @"' && /usr/bin/open ./Uninstall.app", nil]]; 355 | } 356 | 357 | - (IBAction)staticResolversTextFieldChanged:(NSTextField *)sender { 358 | NSString *staticResolvers = sender.stringValue; 359 | NSCharacterSet *charset = [[NSCharacterSet characterSetWithCharactersInString: @"0123456789abcdefABCDEF:. "] invertedSet]; 360 | staticResolvers = [[staticResolvers componentsSeparatedByCharactersInSet: charset] componentsJoinedByString: @" "]; 361 | sender.stringValue = staticResolvers; 362 | setenv("STATIC_RESOLVERS", [staticResolvers UTF8String], 1); 363 | [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-f", @"-c", @"cd '" kDNSCRYPT_SCRIPTS_BASE_DIR @"' && exec ./set-static-resolvers.sh \"$STATIC_RESOLVERS\"", nil]]; 364 | } 365 | 366 | - (BOOL) setQueryLoggingOn { 367 | [self showSpinners]; 368 | NSString *res = [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-f", @"-c", @"cd '" kDNSCRYPT_SCRIPTS_BASE_DIR @"' && ./create-ticket.sh && ./switch-query-logging-on.sh", nil]]; 369 | (void) res; 370 | return TRUE; 371 | } 372 | 373 | - (BOOL) setQueryLoggingOff { 374 | [self showSpinners]; 375 | NSString *res = [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-f", @"-c", @"cd '" kDNSCRYPT_SCRIPTS_BASE_DIR @"' && ./create-ticket.sh && ./switch-query-logging-off.sh", nil]]; 376 | (void) res; 377 | return TRUE; 378 | } 379 | 380 | - (BOOL) setBlockedQueryLoggingOn { 381 | [self showSpinners]; 382 | NSString *res = [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-f", @"-c", @"cd '" kDNSCRYPT_SCRIPTS_BASE_DIR @"' && ./create-ticket.sh && ./switch-blocked-query-logging-on.sh", nil]]; 383 | (void) res; 384 | return TRUE; 385 | } 386 | 387 | - (BOOL) setBlockedQueryLoggingOff { 388 | [self showSpinners]; 389 | NSString *res = [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-f", @"-c", @"cd '" kDNSCRYPT_SCRIPTS_BASE_DIR @"' && ./create-ticket.sh && ./switch-blocked-query-logging-off.sh", nil]]; 390 | (void) res; 391 | return TRUE; 392 | } 393 | 394 | - (IBAction)queryLoggingButtonPressed:(NSButtonCell *)sender { 395 | if (sender.state != 0) { 396 | [self setQueryLoggingOn]; 397 | } else { 398 | [self setQueryLoggingOff]; 399 | } 400 | } 401 | 402 | - (IBAction)blockedQueryLoggingButtonPressed:(NSButtonCell *)sender { 403 | if (sender.state != 0) { 404 | [self setBlockedQueryLoggingOn]; 405 | } else { 406 | [self setBlockedQueryLoggingOff]; 407 | } 408 | } 409 | 410 | 411 | - (IBAction)viewLogButtonPushed:(NSButton *)sender { 412 | [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-f", @"-c", @"open /Applications/Utilities/Console.app " kDNSCRYPT_QUERY_LOG_FILE " || open " kDNSCRYPT_QUERY_LOG_FILE, nil]]; 413 | } 414 | 415 | - (IBAction)viewBlockedLogButtonPushed:(NSButton *)sender { 416 | [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-f", @"-c", @"open /Applications/Utilities/Console.app " kDNSCRYPT_BLOCKED_QUERY_LOG_FILE " || open " kDNSCRYPT_BLOCKED_QUERY_LOG_FILE, nil]]; 417 | } 418 | 419 | - (BOOL) updateBlacklistIPs { 420 | [self showSpinners]; 421 | NSString *res = [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-f", @"-c", @"cd '" kDNSCRYPT_SCRIPTS_BASE_DIR @"' && ./create-ticket.sh && ./update-blacklist-ips.sh", nil]]; 422 | (void) res; 423 | return TRUE; 424 | } 425 | 426 | - (IBAction)blacklistIPsUpdate:(NSPlaceHolderTextView *)sender { 427 | NSString *content = sender.string; 428 | if ([content writeToFile: kDNSCRYPT_BLACKLIST_IPS_TMP_FILE atomically: YES encoding: NSUTF8StringEncoding error: nil] != YES) { 429 | return; 430 | } 431 | [self updateBlacklistIPs]; 432 | } 433 | 434 | - (BOOL) updateBlacklistDomains { 435 | [self showSpinners]; 436 | NSString *res = [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-f", @"-c", @"cd '" kDNSCRYPT_SCRIPTS_BASE_DIR @"' && ./create-ticket.sh && ./update-blacklist-domains.sh", nil]]; 437 | (void) res; 438 | return TRUE; 439 | } 440 | 441 | - (IBAction)blacklistDomainsUpdate:(NSPlaceHolderTextView *)sender { 442 | NSString *content = sender.string; 443 | if ([content writeToFile: kDNSCRYPT_BLACKLIST_DOMAINS_TMP_FILE atomically: YES encoding: NSUTF8StringEncoding error: nil] != YES) { 444 | return; 445 | } 446 | [self updateBlacklistDomains]; 447 | } 448 | 449 | - (BOOL) updateExceptions { 450 | [self showSpinners]; 451 | NSString *res = [self fromCommand: @"/bin/csh" withArguments: [NSArray arrayWithObjects: @"-f", @"-c", @"cd '" kDNSCRYPT_SCRIPTS_BASE_DIR @"' && ./create-ticket.sh && ./update-exceptions.sh", nil]]; 452 | (void) res; 453 | return TRUE; 454 | } 455 | 456 | - (IBAction)exceptionsUpdate:(NSPlaceHolderTextView *)sender { 457 | NSString *content = sender.string; 458 | if ([content writeToFile: kDNSCRYPT_EXCEPTIONS_TMP_FILE atomically: YES encoding: NSUTF8StringEncoding error: nil] != YES) { 459 | return; 460 | } 461 | [self updateExceptions]; 462 | } 463 | 464 | - (IBAction)saveAndApplyChangesButtonPressed:(NSButton *)sender { 465 | [self showSpinners]; 466 | if (blacklistDomainsUpdated) { 467 | [self blacklistDomainsUpdate: _blacklistDomainsTextView]; 468 | } 469 | if (blacklistIPsUpdated) { 470 | [self blacklistIPsUpdate: _blacklistIPsTextView]; 471 | } 472 | if (exceptionsUpdated) { 473 | [self exceptionsUpdate: _exceptionsTextView]; 474 | } 475 | blacklistDomainsUpdated = FALSE; 476 | blacklistIPsUpdated = FALSE; 477 | exceptionsUpdated = FALSE; 478 | } 479 | 480 | -(void)textDidChange:(NSNotification *)notification { 481 | if (notification.object == _blacklistDomainsTextView) { 482 | blacklistDomainsUpdated = TRUE; 483 | } else if (notification.object == _blacklistIPsTextView) { 484 | blacklistIPsUpdated = TRUE; 485 | } else if (notification.object == _exceptionsTextView) { 486 | exceptionsUpdated = TRUE; 487 | } 488 | } 489 | 490 | -(void)helpButtonPressed:(NSButton *)sender { 491 | (void) sender; 492 | [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString: kDNSCRYPT_PROJECT_URL]]; 493 | } 494 | 495 | @end 496 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/NSPlaceHolderTextView.h: -------------------------------------------------------------------------------- 1 | #ifndef NSPlaceHolderTextView_h 2 | #define NSPlaceHolderTextView_h 3 | 4 | #import 5 | 6 | IB_DESIGNABLE 7 | @interface NSPlaceHolderTextView : NSTextView 8 | 9 | @property (nonatomic, retain) IBInspectable NSAttributedString *placeHolder; 10 | 11 | - (void)setPlaceHolderText:(NSString *)txt; 12 | 13 | @end 14 | 15 | #endif /* NSPlaceHolderTextView_h */ 16 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/NSPlaceHolderTextView.m: -------------------------------------------------------------------------------- 1 | #import "NSPlaceHolderTextView.h" 2 | 3 | @implementation NSPlaceHolderTextView 4 | 5 | @synthesize placeHolder = _placeHolder; 6 | 7 | - (void)setPlaceHolderText:(NSString *)txt { 8 | NSColor *txtColor = [NSColor grayColor]; 9 | NSDictionary *txtDict = [NSDictionary dictionaryWithObjectsAndKeys:txtColor, NSForegroundColorAttributeName, nil]; 10 | _placeHolder = [[NSAttributedString alloc] initWithString:txt attributes:txtDict]; 11 | } 12 | 13 | - (BOOL)becomeFirstResponder 14 | { 15 | [self setNeedsDisplay:YES]; 16 | return [super becomeFirstResponder]; 17 | } 18 | 19 | - (void)drawRect:(NSRect)rect 20 | { 21 | [super drawRect:rect]; 22 | if ([[self string] isEqualToString:@""] && self != [[self window] firstResponder]) 23 | [_placeHolder drawAtPoint:NSMakePoint(0,0)]; 24 | } 25 | 26 | - (BOOL)resignFirstResponder 27 | { 28 | [self setNeedsDisplay:YES]; 29 | return [super resignFirstResponder]; 30 | } 31 | 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/ajax-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stammy/dnscrypt-osx-client/69fdd9c44cc7e19c05608cfd463e55829de43416/DNSCrypt-Preference-Pane/DNSCrypt/ajax-loader.gif -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/dnscrypt_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stammy/dnscrypt-osx-client/69fdd9c44cc7e19c05608cfd463e55829de43416/DNSCrypt-Preference-Pane/DNSCrypt/dnscrypt_256.png -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/html/about.haml: -------------------------------------------------------------------------------- 1 | !!! 5 2 | %html{lang: "en"} 3 | %head 4 | %meta{charset: "utf-8"} 5 | %title About DNSCrypt-OSXClient 6 | :sass 7 | body 8 | font: 9 | family: arial, helvetica, sans-serif 10 | size: 14px 11 | margin: 0 12 | h1 13 | margin: 0 14 | %body 15 | %h1 About DNSCrypt-OSXClient 16 | %p 17 | This software encrypts and authenticates DNS packets between your computer 18 | and a DNS resolver using DNSCrypt. 19 | %p 20 | Tips: 21 | %ul 22 | %li 23 | If you have a firewall, open TCP and UDP ports 53 and 443. 24 | These are the most common ports used for DNSCrypt. 25 | %li 26 | WiFi captive portals dont work if they can't intercept DNS queries 27 | and often block DNSCrypt. 28 | So on public WiFi network, disable DNSCrypt, log in, then you can 29 | enable it again. 30 | %li 31 | Using Little Snitch? There are a few rules you need to establish, 32 | which Little Snitch should prompt for when trying to 33 | activate this application: 34 | %ol 35 | %li Allow any outgoing connection for system processes (dnscrypt-proxy) 36 | %li Allow any incoming connection for system process (dnscrypt-proxy) 37 | %li Allow any outgoing connection for system processes (dig) 38 | %li For automatic updates, allow outgoing TCP connections to port 80 (http) of updates.dnscrypt.org and download.dnscrypt.org, as well as to port 443 (https) of github.com and download.dnscrypt.org for system process (curl) 39 | (Thanks to @cavemandaveman and @TraderStf) 40 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/html/about.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | About DNSCrypt-OSXClient 6 | 15 | 16 | 17 |

About DNSCrypt-OSXClient

18 |

19 | This software encrypts and authenticates DNS packets between your computer 20 | and a DNS resolver using DNSCrypt. 21 |

22 |

23 | Tips: 24 |

    25 |
  • 26 | If you have a firewall, open TCP and UDP ports 53 and 443. 27 | These are the most common ports used for DNSCrypt. 28 |
  • 29 |
  • 30 | WiFi captive portals dont work if they can't intercept DNS queries 31 | and often block DNSCrypt. 32 | So on public WiFi network, disable DNSCrypt, log in, then you can 33 | enable it again. 34 |
  • 35 |
  • 36 | Using Little Snitch? There are a few rules you need to establish, 37 | which Little Snitch should prompt for when trying to 38 | activate this application: 39 |
      40 |
    1. Allow any outgoing connection for system processes (dnscrypt-proxy)
    2. 41 |
    3. Allow any incoming connection for system process (dnscrypt-proxy)
    4. 42 |
    5. Allow any outgoing connection for system processes (dig)
    6. 43 |
    7. For automatic updates, allow outgoing TCP connections to port 80 (http) of updates.dnscrypt.org and download.dnscrypt.org, as well as to port 443 (https) of github.com and download.dnscrypt.org for system process (curl)
    8. 44 |
    45 | (Thanks to @cavemandaveman and @TraderStf) 46 |
  • 47 |
48 |

49 | 50 | 51 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/html/help.haml: -------------------------------------------------------------------------------- 1 | !!! 5 2 | %html{lang: "en"} 3 | %head 4 | %meta{charset: "utf-8"} 5 | %title Help (advanced settings) 6 | :sass 7 | body 8 | font: 9 | family: arial, helvetica, sans-serif 10 | size: 14px 11 | margin: 1em 12 | h1 13 | margin: 0 14 | %body 15 | %h1 Help (advanced settings) 16 | %section 17 | %h2 Static DNS servers 18 | %p 19 | If you are not using DHCP and want a statically configured set 20 | of default DNS resolvers, enter their IP addresses in this box. 21 | %p 22 | Separate them with spaces. 23 | %section 24 | %h2 Log DNS queries 25 | %p 26 | As a tool designed to protect your privacy, the DNSCrypt proxy does 27 | not log anything about your DNS queries. Nothing about them will be 28 | saved to disk ever, and log messages are intentionally kept as generic 29 | as possible. 30 | %p 31 | However, you still may want to look at the DNS queries sent by 32 | your system. This can be useful in order to spot suspicious 33 | activity and to refine your domain blacklists and whitelists. 34 | %p 35 | Checking the "Log DNS queries" box dumps all DNS queries sent 36 | by your computer to a file named /var/log/dnscrypt-query.log 37 | %p 38 | Blocked queries can also go to a log file. The file is named 39 | /var/log/dnscrypt-blocked-query.log 40 | %p 41 | The "View log" button opens it with the log viewer application 42 | so that you can watch it in real time. The other button shows 43 | the blocked queries. 44 | %section 45 | %h2 IP addresses blocking 46 | %p 47 | A response to a query containing at least one IP address 48 | listed here will be blocked. 49 | %p 50 | This make it easy to block spam sources, hosting services and content 51 | providers using a lot of different domain names for a single service. 52 | %p 53 | This can also be useful in order to block DNS rebinding 54 | attacks, even for non-private network spaces. 55 | %p 56 | IP addresses can be IPv4 and IPv6 addresses, and must be 57 | separated with spaces. 58 | %section 59 | %h2 Names blocking 60 | %p 61 | This is a list of domain names to be blocked. 62 | %p 63 | "example.com" will match "example.com" and "www.example.com". 64 | %p 65 | But wildcards are also supported. "ads.*" will match any name 66 | beginning with "ads." 67 | %p 68 | Wildcards can also perform substring matching. "*xxx*" will 69 | match any name containing the string "xxx". 70 | %p 71 | Patterns to be blocked should be separated with spaces or new 72 | lines. Flushing your DNS cache is not required. 73 | %p 74 | This feature is only enabled when using DNSCrypt. 75 | %section 76 | %h2 Exceptions - bypassing DNSCrypt for some specific names 77 | %p 78 | Some domain names should not be resolved by a third-party DNS 79 | resolver, that may not know about them. 80 | %p 81 | This includes local domain names provided by home routers 82 | (like "routerlogin.net"), local domain names provided by 83 | operating systems and applications (like ".local" or ".lan"), 84 | local domain names served by appliances like set-top boxes, and 85 | internal domains used in corporate networks. 86 | %p 87 | Domains listed here will bypass DNSCrypt in order to be sent 88 | to the default resolvers. 89 | %p 90 | Do 91 | %strong not 92 | use a tool like hostip(8), drill(1), unbound-host(1), dig(1) or host(1) 93 | in order to check that an exception rule works. 94 | %p 95 | These tools use their own resolution mechanisms that have nothing 96 | to do with how others apps on your system are resolving names. 97 | %p 98 | They don't use the OSX-specific stub resolver, they don't use 99 | the system-wide DNS cache, they have bugs and limitations that the OS 100 | doesn't have (and the opposite is also true), and they don't know a 101 | thing about specific resolvers that have to be used for specific 102 | domains. 103 | %p 104 | Use actual apps, or even a command such as ping(8). 105 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/html/help.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Help (advanced settings) 6 | 15 | 16 | 17 |

Help (advanced settings)

18 |
19 |

Static DNS servers

20 |

21 | If you are not using DHCP and want a statically configured set 22 | of default DNS resolvers, enter their IP addresses in this box. 23 |

24 |

25 | Separate them with spaces. 26 |

27 |
28 |
29 |

Log DNS queries

30 |

31 | As a tool designed to protect your privacy, the DNSCrypt proxy does 32 | not log anything about your DNS queries. Nothing about them will be 33 | saved to disk ever, and log messages are intentionally kept as generic 34 | as possible. 35 |

36 |

37 | However, you still may want to look at the DNS queries sent by 38 | your system. This can be useful in order to spot suspicious 39 | activity and to refine your domain blacklists and whitelists. 40 |

41 |

42 | Checking the "Log DNS queries" box dumps all DNS queries sent 43 | by your computer to a file named /var/log/dnscrypt-query.log 44 |

45 |

46 | Blocked queries can also go to a log file. The file is named 47 | 48 |

49 |

50 | The "View log" button opens it with the log viewer application 51 | so that you can watch it in real time. The other button shows 52 | the blocked queries. 53 |

54 |
55 |
56 |

IP addresses blocking

57 |

58 | A response to a query containing at least one IP address 59 | listed here will be blocked. 60 |

61 |

62 | This make it easy to block spam sources, hosting services and content 63 | providers using a lot of different domain names for a single service. 64 |

65 |

66 | This can also be useful in order to block DNS rebinding 67 | attacks, even for non-private network spaces. 68 |

69 |

70 | IP addresses can be IPv4 and IPv6 addresses, and must be 71 | separated with spaces. 72 |

73 |
74 |
75 |

Names blocking

76 |

77 | This is a list of domain names to be blocked. 78 |

79 |

80 | "example.com" will match "example.com" and "www.example.com". 81 |

82 |

83 | But wildcards are also supported. "ads.*" will match any name 84 | beginning with "ads." 85 |

86 |

87 | Wildcards can also perform substring matching. "*xxx*" will 88 | match any name containing the string "xxx". 89 |

90 |

91 | Patterns to be blocked should be separated with spaces or new 92 | lines. Flushing your DNS cache is not required. 93 |

94 |

95 | This feature is only enabled when using DNSCrypt. 96 |

97 |
98 |
99 |

Exceptions - bypassing DNSCrypt for some specific names

100 |

101 | Some domain names should not be resolved by a third-party DNS 102 | resolver, that may not know about them. 103 |

104 |

105 | This includes local domain names provided by home routers 106 | (like "routerlogin.net"), local domain names provided by 107 | operating systems and applications (like ".local" or ".lan"), 108 | local domain names served by appliances like set-top boxes, and 109 | internal domains used in corporate networks. 110 |

111 |

112 | Domains listed here will bypass DNSCrypt in order to be sent 113 | to the default resolvers. 114 |

115 |

116 | Do 117 | not 118 | use a tool like hostip(8), drill(1), unbound-host(1), dig(1) or host(1) 119 | in order to check that an exception rule works. 120 |

121 |

122 | These tools use their own resolution mechanisms that have nothing 123 | to do with how others apps on your system are resolving names. 124 |

125 |

126 | They don't use the OSX-specific stub resolver, they don't use 127 | the system-wide DNS cache, they have bugs and limitations that the OS 128 | doesn't have (and the opposite is also true), and they don't know a 129 | thing about specific resolvers that have to be used for specific 130 | domains. 131 |

132 |

133 | Use actual apps, or even a command such as ping(8). 134 |

135 |
136 | 137 | 138 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/html/releasenotes.haml: -------------------------------------------------------------------------------- 1 | !!! 5 2 | %html{lang: "en"} 3 | %head 4 | %meta{charset: "utf-8"} 5 | %title Release notes 6 | :sass 7 | body 8 | font: 9 | family: arial, helvetica, sans-serif 10 | size: 14px 11 | margin: 0 12 | h1, h2 13 | margin: 0 14 | time 15 | font: 16 | style: italic 17 | %body 18 | %article 19 | %h2 Version 1.0.14 20 | %time Sat, Feb 11 2017 21 | %p 22 | The previous version (1.0.13) required a recent version of 23 | openssl to be present on the system (plugins need ldns, ldns 24 | needed this). The dependency has been removed. 25 | 26 | %body 27 | %article 28 | %h2 Version 1.0.13 29 | %time Thu, Feb 09 2017 30 | %p 31 | No more "automatic fallback". We trust users to know when they 32 | must disable DNSCrypt. 33 | %p 34 | DNS caching for improved speed. 35 | %p 36 | New buttons to log and view blocked queries. 37 | %p 38 | New system to bypass DNSCrypt using dnscrypt-proxy forwarding 39 | module. 40 | %p 41 | Many bug fixes because old code was removed. 42 | %p 43 | dnscrypt-proxy 1.9.0 with support for the new ChaCha20 encryption. 44 | %p 45 | libsodium 1.0.11. 46 | 47 | %article 48 | %h2 Version 1.0.12 49 | %time Sun, Jul 31 2016 50 | %p 51 | Compatibility with OSX 10.12 52 | %p 53 | dnscrypt-proxy 1.7.0 54 | %p 55 | libsodium 1.0.9 56 | %p 57 | Fixed a regression in the automatic updater for the resolvers list 58 | 59 | %article 60 | %h2 Version 1.0.11 61 | %time Thu, Mar 3 2016 62 | %p 63 | Compatibility with OSX 10.11 64 | %p 65 | dnscrypt-proxy 1.6.1 66 | %p 67 | libsodium 1.0.8 68 | 69 | %article 70 | %h2 Version 1.0.10 71 | %time Tue, 23 Jul 2015 72 | %p 73 | Compatibility with OSX 10.11 beta 4 74 | %p 75 | dnscrypt-proxy 1.6.0 76 | 77 | %article 78 | %h2 Version 1.0.9 79 | %time Tue, 12 Jul 2015 80 | %p 81 | Fixed an issue with libsodium not being found by minisign-verify 82 | 83 | %article 84 | %h2 Version 1.0.8 85 | %time Tue, 12 Jul 2015 86 | %p 87 | New versions are automatically downloaded 88 | 89 | %article 90 | %h2 Version 1.0.7 91 | %time Tue, 1 Jul 2015 92 | %p 93 | Fixed a bug in the automatic updater for the resolvers list 94 | 95 | %article 96 | %h2 Version 1.0.6 97 | %time Tue, 10 Jun 2015 98 | %p 99 | Updated DNSCrypt proxy to version 1.5.0 100 | %p 101 | Updated libsodium to 1.0.3-minimal 102 | %p 103 | The list of available resolvers is automatically updated 104 | %p 105 | Improved privacy: ephemeral keys have been turned on 106 | %p 107 | Improved privacy: if no resolvers have been configured, a new one 108 | is randomly chosen after each reboot 109 | 110 | %article 111 | %h2 Version 1.0.5 112 | %time Tue, 06 Jan 2015 113 | %p 114 | Updated DNSCrypt proxy to version 1.4.3 115 | %p 116 | Updated libsodium to 1.0.1-minimal 117 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/html/releasenotes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Release notes 6 | 18 | 19 | 20 |
21 |

Version 1.0.14

22 | 23 |

24 | The previous version (1.0.13) required a recent version of 25 | openssl to be present on the system (plugins need ldns, ldns 26 | needed this). The dependency has been removed. 27 |

28 |
29 | 30 | 31 |
32 |

Version 1.0.13

33 | 34 |

35 | No more "automatic fallback". We trust users to know when they 36 | must disable DNSCrypt. 37 |

38 |

39 | DNS caching for improved speed. 40 |

41 |

42 | New buttons to log and view blocked queries. 43 |

44 |

45 | New system to bypass DNSCrypt using dnscrypt-proxy forwarding 46 | module. 47 |

48 |

49 | Many bug fixes because old code was removed. 50 |

51 |

52 | dnscrypt-proxy 1.9.0 with support for the new ChaCha20 encryption. 53 |

54 |

55 | libsodium 1.0.11. 56 |

57 |
58 |
59 |

Version 1.0.12

60 | 61 |

62 | Compatibility with OSX 10.12 63 |

64 |

65 | dnscrypt-proxy 1.7.0 66 |

67 |

68 | libsodium 1.0.9 69 |

70 |

71 | Fixed a regression in the automatic updater for the resolvers list 72 |

73 |
74 |
75 |

Version 1.0.11

76 | 77 |

78 | Compatibility with OSX 10.11 79 |

80 |

81 | dnscrypt-proxy 1.6.1 82 |

83 |

84 | libsodium 1.0.8 85 |

86 |
87 |
88 |

Version 1.0.10

89 | 90 |

91 | Compatibility with OSX 10.11 beta 4 92 |

93 |

94 | dnscrypt-proxy 1.6.0 95 |

96 |
97 |
98 |

Version 1.0.9

99 | 100 |

101 | Fixed an issue with libsodium not being found by minisign-verify 102 |

103 |
104 |
105 |

Version 1.0.8

106 | 107 |

108 | New versions are automatically downloaded 109 |

110 |
111 |
112 |

Version 1.0.7

113 | 114 |

115 | Fixed a bug in the automatic updater for the resolvers list 116 |

117 |
118 |
119 |

Version 1.0.6

120 | 121 |

122 | Updated DNSCrypt proxy to version 1.5.0 123 |

124 |

125 | Updated libsodium to 1.0.3-minimal 126 |

127 |

128 | The list of available resolvers is automatically updated 129 |

130 |

131 | Improved privacy: ephemeral keys have been turned on 132 |

133 |

134 | Improved privacy: if no resolvers have been configured, a new one 135 | is randomly chosen after each reboot 136 |

137 |
138 |
139 |

Version 1.0.5

140 | 141 |

142 | Updated DNSCrypt proxy to version 1.4.3 143 |

144 |

145 | Updated libsodium to 1.0.1-minimal 146 |

147 |
148 | 149 | 150 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/html/update.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | for f_in in *.haml; do 4 | echo "$f_in" 5 | f_out=$(echo "$f_in" | sed -e 's/.haml/.html/') 6 | haml < "$f_in" > "$f_out" 7 | done 8 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/bin/Uninstall.app/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleAllowMixedLocalizations 6 | 7 | CFBundleDevelopmentRegion 8 | English 9 | CFBundleExecutable 10 | applet 11 | CFBundleIconFile 12 | applet 13 | CFBundleIdentifier 14 | com.apple.ScriptEditor.id.Uninstall 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | Uninstall 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | 1.0 23 | CFBundleSignature 24 | aplt 25 | LSMinimumSystemVersionByArchitecture 26 | 27 | x86_64 28 | 10.6 29 | 30 | LSRequiresCarbon 31 | 32 | WindowState 33 | 34 | dividerCollapsed 35 | 36 | eventLogLevel 37 | -1 38 | name 39 | ScriptWindowState 40 | positionOfDivider 41 | 370 42 | savedFrame 43 | 85 77 1202 655 0 0 1366 746 44 | selectedTabView 45 | result 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/bin/Uninstall.app/Contents/MacOS/applet: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stammy/dnscrypt-osx-client/69fdd9c44cc7e19c05608cfd463e55829de43416/DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/bin/Uninstall.app/Contents/MacOS/applet -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/bin/Uninstall.app/Contents/PkgInfo: -------------------------------------------------------------------------------- 1 | APPLaplt -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/bin/Uninstall.app/Contents/Resources/Scripts/main.scpt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stammy/dnscrypt-osx-client/69fdd9c44cc7e19c05608cfd463e55829de43416/DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/bin/Uninstall.app/Contents/Resources/Scripts/main.scpt -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/bin/Uninstall.app/Contents/Resources/applet.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stammy/dnscrypt-osx-client/69fdd9c44cc7e19c05608cfd463e55829de43416/DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/bin/Uninstall.app/Contents/Resources/applet.icns -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/bin/Uninstall.app/Contents/Resources/applet.rsrc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stammy/dnscrypt-osx-client/69fdd9c44cc7e19c05608cfd463e55829de43416/DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/bin/Uninstall.app/Contents/Resources/applet.rsrc -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/bin/Uninstall.app/Contents/Resources/description.rtfd/TXT.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf200 2 | {\fonttbl} 3 | {\colortbl;\red255\green255\blue255;} 4 | } -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/bin/alarmer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stammy/dnscrypt-osx-client/69fdd9c44cc7e19c05608cfd463e55829de43416/DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/bin/alarmer -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/bin/hostip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stammy/dnscrypt-osx-client/69fdd9c44cc7e19c05608cfd463e55829de43416/DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/bin/hostip -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/bin/lockfile: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stammy/dnscrypt-osx-client/69fdd9c44cc7e19c05608cfd463e55829de43416/DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/bin/lockfile -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/bin/minisign-verify: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stammy/dnscrypt-osx-client/69fdd9c44cc7e19c05608cfd463e55829de43416/DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/bin/minisign-verify -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/lib/libldns.1.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stammy/dnscrypt-osx-client/69fdd9c44cc7e19c05608cfd463e55829de43416/DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/lib/libldns.1.dylib -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/lib/libldns.dylib: -------------------------------------------------------------------------------- 1 | libldns.2.dylib -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/afterboot.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | rm -f "$BLOCKED_QUERY_LOG_FILE" 6 | rm -f "$QUERY_LOG_FILE" 7 | rm -f "$DEBUG_LOG_FILE" 8 | find -x "$RESOLVERS_LIST_STATE" -type f -mtime +1 -exec rm -f {} \; 2>/dev/null 9 | find -x "$APP_UPDATES_STATE" -type f -mtime +1 -exec rm -f {} \; 2>/dev/null 10 | find -x "$STATES_DIR" -type f -exec rm -f {} -exec rm -f {} \; 2>/dev/null 11 | 12 | ./clear-fw.sh 13 | 14 | exec ./handle-control-change.sh --boot 15 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/check-network-change.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | NETWORK_STATE_FILE="${STATES_DIR}/network-state" 6 | DHCP_DNS_FILE="${STATES_DIR}/dhcp-dns" 7 | AIRPORT_TOOL="/System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport" 8 | 9 | mkdir -p "$STATES_DIR" || exit 1 10 | ips=$(./get-dhcp-resolvers.sh) 11 | echo "$ips" > "$DHCP_DNS_FILE" 12 | 13 | ssid=$("$AIRPORT_TOOL" -I 2>&1 | fgrep '[^B]SSID: ') 14 | bssid=$("$AIRPORT_TOOL" -I 2>&1 | fgrep 'BSSID: ') 15 | if [ -f "$NETWORK_STATE_FILE" ]; then 16 | if echo "$ifs $ips $ssid $bssid" | \ 17 | cmp -- "$NETWORK_STATE_FILE" - >/dev/null; then 18 | exit 1 19 | fi 20 | fi 21 | echo "$ifs $ips $ssid $bssid" > "$NETWORK_STATE_FILE" 22 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/clear-fw.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | exec >/dev/null 6 | exec 2>&1 7 | 8 | SOCKETFILTERFW='/usr/libexec/ApplicationFirewall/socketfilterfw' 9 | [ -x "$SOCKETFILTERFW" ] || exit 0 10 | 11 | "$SOCKETFILTERFW" --add "${DNSCRYPT_USR_BASE_DIR}/sbin/dnscrypt-proxy" 12 | "$SOCKETFILTERFW" --unblockapp "${DNSCRYPT_USR_BASE_DIR}/sbin/dnscrypt-proxy" 13 | 14 | "$SOCKETFILTERFW" --add "${DNSCRYPT_USR_BASE_DIR}/bin/hostip" 15 | "$SOCKETFILTERFW" --unblockapp "${DNSCRYPT_USR_BASE_DIR}/bin/hostip" 16 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/common.inc: -------------------------------------------------------------------------------- 1 | 2 | CURRENT_VERSION=8 3 | 4 | DNSCRYPT_USR_BASE_DIR='/Library/PreferencePanes/DNSCrypt.prefPane/Contents/Resources/usr' 5 | DNSCRYPT_VAR_BASE_DIR='/Library/Application Support/DNSCrypt' 6 | DNSCRYPT_LOG_BASE_DIR='/var/log' 7 | DNSCRYPT_VAR_RUN_BASE_DIR='/var/run' 8 | 9 | cd -- "${DNSCRYPT_USR_BASE_DIR}/scripts" || exit 1 10 | 11 | CONTROL_DIR="${DNSCRYPT_VAR_BASE_DIR}/control" 12 | TICKETS_DIR="${DNSCRYPT_VAR_BASE_DIR}/tickets" 13 | DNSCRYPT_PROXY_BASE_DIR="${DNSCRYPT_VAR_BASE_DIR}/dnscrypt-proxy" 14 | PROXY_PID_FILE="${DNSCRYPT_VAR_RUN_BASE_DIR}/dnscrypt-proxy.pid" 15 | STATES_DIR="${DNSCRYPT_VAR_BASE_DIR}/states" 16 | 17 | DNSCRYPT_RESOLVER_NAME_FILE="${CONTROL_DIR}/dnscrypt-resolver-name" 18 | DNSCRYPT_FILE="${CONTROL_DIR}/dnscrypt" 19 | HIDE_MENUBAR_ICON_FILE="${CONTROL_DIR}/hide-menubar-icon" 20 | HANDLERS_LOCK_FILE="${DNSCRYPT_VAR_RUN_BASE_DIR}/dnscrypt-handlers.lock" 21 | DNSCRYPT_PROXY_PLUGINS_BASE_FILE="${CONTROL_DIR}/plugin" 22 | STATIC_RESOLVERS_FILE="${CONTROL_DIR}/static-resolvers" 23 | BLOCKED_QUERY_LOGGING_FILE="${CONTROL_DIR}/blocked-query-logging" 24 | 25 | DEBUG_ENABLED_FILE="${CONTROL_DIR}/debug.enabled" 26 | 27 | PLUGINS_ENABLED_FILE="${CONTROL_DIR}/plugins.enabled" 28 | CACHE_FILE="${CONTROL_DIR}/plugin-cache.enabled" 29 | QUERY_LOGGING_FILE="${CONTROL_DIR}/plugin-query-logging.enabled" 30 | BLOCKING_FILE="${CONTROL_DIR}/plugin-blocking.enabled" 31 | AAAA_BLOCKING_FILE="${CONTROL_DIR}/plugin-aaaa-blocking.enabled" 32 | FORWARDING_FILE="${CONTROL_DIR}/plugin-forwarding.enabled" 33 | 34 | BLOCKED_QUERY_LOG_FILE="${DNSCRYPT_LOG_BASE_DIR}/dnscrypt-blocked-query.log" 35 | QUERY_LOG_FILE="${DNSCRYPT_LOG_BASE_DIR}/dnscrypt-query.log" 36 | DEBUG_LOG_FILE="${DNSCRYPT_LOG_BASE_DIR}/dnscrypt-osxclient-debug.log" 37 | DEBUG_LOG_FILE_LOCK="${DEBUG_LOG_FILE}.lock" 38 | 39 | BLACKLIST_IPS_FILE="${CONTROL_DIR}/blacklist-ips" 40 | BLACKLIST_IPS_TMP_FILE="${BLACKLIST_IPS_FILE}.tmp" 41 | BLACKLIST_DOMAINS_FILE="${CONTROL_DIR}/blacklist-domains" 42 | BLACKLIST_DOMAINS_TMP_FILE="${BLACKLIST_DOMAINS_FILE}.tmp" 43 | EXCEPTIONS_FILE="${CONTROL_DIR}/exceptions" 44 | EXCEPTIONS_TMP_FILE="${EXCEPTIONS_FILE}.tmp" 45 | 46 | APP_UPDATES_BASE_URL="http://updates.dnscrypt.org/updates/dnscrypt-osx-client" 47 | APP_UPDATES_DIR="${DNSCRYPT_VAR_BASE_DIR}/updates" 48 | APP_UPDATES_PUBLIC_KEY="RWRvw8aArS/yEI3In0/zQSb9+qfWonLxjjEYG17cXt6zct6GLKtEvUfk" 49 | APP_UPDATES_STATE="${APP_UPDATES_DIR}/app-updated" 50 | 51 | RESOLVERS_UPDATES_BASE_URL="http://updates.dnscrypt.org/dnscrypt-proxy" 52 | RESOLVERS_LIST_BASE_DIR="${DNSCRYPT_USR_BASE_DIR}/share/dnscrypt-proxy" 53 | RESOLVERS_LIST_PUBLIC_KEY="RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3" 54 | RESOLVERS_LIST_STATE="${STATES_DIR}/resolvers-updated" 55 | 56 | INTERFACE_PROXY="127.0.0.54" 57 | INTERFACE_PROXY_MASK="24" 58 | 59 | export PATH="${DNSCRYPT_USR_BASE_DIR}/sbin:${DNSCRYPT_USR_BASE_DIR}/bin:${DNSCRYPT_USR_BASE_DIR}/scripts:$PATH" 60 | 61 | init_interfaces() { 62 | /sbin/ifconfig lo0 alias ${INTERFACE_PROXY}/${INTERFACE_PROXY_MASK} 63 | } 64 | 65 | logger_debug() { 66 | [ -f "$DEBUG_ENABLED_FILE" ] || return 67 | lockfile -1 -r 1 "$DEBUG_LOG_FILE_LOCK" > /dev/null 2>&1 68 | echo "$(date) - $1" >> "$DEBUG_LOG_FILE" 69 | rm -f "$DEBUG_LOG_FILE_LOCK" 2> /dev/null 70 | } 71 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/create-ticket.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | ticket_file=$(mktemp "$TICKETS_DIR/ticket-XXXXXXXXXX") 6 | [ -e "$ticket_file" ] || exit 1 7 | basename "$ticket_file" 8 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/get-aaaa-blocking-status.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | if [ -e "$AAAA_BLOCKING_FILE" ]; then 6 | echo 'yes' 7 | else 8 | echo 'no' 9 | fi 10 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/get-blocked-query-logging-status.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | if [ -e "$BLOCKED_QUERY_LOGGING_FILE" ]; then 6 | echo 'yes' 7 | else 8 | echo 'no' 9 | fi 10 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/get-current-default-domain.sh: -------------------------------------------------------------------------------- 1 | #! /bin/ksh 2 | 3 | . ./common.inc 4 | 5 | [ -r /etc/resolv.conf ] || exit 0 6 | domain="" 7 | while read line; do 8 | case "$line" in 9 | domain\ *) 10 | domain=$(echo "$line" | sed -e 's/domain *//' -e 's/ *//') 11 | break 12 | ;; 13 | esac 14 | done < /etc/resolv.conf 15 | 16 | echo "$domain" 17 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/get-current-resolvers.sh: -------------------------------------------------------------------------------- 1 | #! /bin/ksh 2 | 3 | . ./common.inc 4 | 5 | [ -r /etc/resolv.conf ] || exit 0 6 | ips_i="" 7 | while read line; do 8 | case "$line" in 9 | nameserver\ *) 10 | ip=$(echo "$line" | sed -e 's/nameserver *//' -e 's/ *//') 11 | ips_i="$ips_i $ip" 12 | ;; 13 | esac 14 | done < /etc/resolv.conf 15 | 16 | typeset -A found 17 | ips="" 18 | for ip_i in $ips_i; do 19 | if [ ! ${found["$ip_i"]} ]; then 20 | if [ "$ips" ]; then 21 | ips="$ips " 22 | fi 23 | ips="$ips$ip_i" 24 | found["$ip_i"]=1 25 | fi 26 | done 27 | 28 | echo "$ips" 29 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/get-dhcp-resolvers.sh: -------------------------------------------------------------------------------- 1 | #! /bin/ksh 2 | 3 | . ./common.inc 4 | 5 | get_ifs() { 6 | ifs_save="$IFS" 7 | IFS='' 8 | ifconfig -a | while read line; do 9 | nif=$(echo "$line" | egrep -i '^[^ ]+:\s+flags' | sed 's/:.*$//') 10 | isact=$(echo "$line" | egrep -i 'status:\s*active') 11 | if [ -n "$nif" ]; then 12 | cif="$nif" 13 | elif [ -n "$isact" -a -n "$cif" ]; then 14 | echo $cif 15 | fi 16 | done 17 | IFS="$ifs_save" 18 | } 19 | 20 | ifs=$(get_ifs) 21 | 22 | typeset -A found 23 | ips="" 24 | for i in $ifs; do 25 | ips_i=$(ipconfig getpacket "$i" 2> /dev/null | fgrep 'domain_name_server' | \ 26 | sed -e 's/^.*{//' -e 's/,/ /g' -e 's/}//' ) 27 | for ip_i in $ips_i; do 28 | if [ ! ${found["$ip_i"]} ]; then 29 | if [ "$ips" ]; then 30 | ips="$ips " 31 | fi 32 | ips="$ips$ip_i" 33 | found["$ip_i"]=1 34 | fi 35 | done 36 | done 37 | 38 | echo "$ips" 39 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/get-dnscrypt-resolver-name.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | [ -r "$DNSCRYPT_RESOLVER_NAME_FILE" ] && \ 6 | sed 's/[^a-zA-Z0-9.-]/_/g' < "$DNSCRYPT_RESOLVER_NAME_FILE" && exit 0 7 | 8 | exec ./get-random-resolver.sh 9 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/get-dnscrypt-status.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | if [ -e "$DNSCRYPT_FILE" ]; then 6 | echo 'yes' 7 | else 8 | echo 'no' 9 | fi 10 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/get-hide-menubar-icon-status.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | if [ -e "$HIDE_MENUBAR_ICON_FILE" ]; then 6 | echo 'yes' 7 | else 8 | echo 'no' 9 | fi 10 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/get-query-logging-status.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | if [ -e "$QUERY_LOGGING_FILE" ]; then 6 | echo 'yes' 7 | else 8 | echo 'no' 9 | fi 10 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/get-random-resolver.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | (read header; fgrep -v :: | cut -d, -f1 | egrep -v '^\s*$') \ 6 | < "${RESOLVERS_LIST_BASE_DIR}/dnscrypt-resolvers.csv" | \ 7 | perl -MList::Util=shuffle -e 'print shuffle();' | \ 8 | head -n1 9 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/get-resolvers-description.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | if [ -e "${STATES_DIR}/updating" ]; then 6 | echo 'Updating' 7 | exit 0 8 | fi 9 | name='None' 10 | level=0 11 | while read resolver; do 12 | case "$resolver" in 13 | 127.0.0.5*) 14 | if [ $level -le 80 ]; then 15 | name='DNSCrypt' 16 | level=80 17 | fi 18 | ;; 19 | 127.0.0.1) 20 | if [ $level -le 20 ]; then 21 | name='Localhost' 22 | level=20 23 | fi 24 | ;; 25 | ::1) 26 | if [ $level -le 30 ]; then 27 | name='Localhost IPv6' 28 | level=30 29 | fi 30 | ;; 31 | *) 32 | if [ $level -le 10 ]; then 33 | name='Default' 34 | level=10 35 | fi 36 | ;; 37 | esac 38 | done 39 | echo "$name" 40 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/get-static-resolvers.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | [ -r "$STATIC_RESOLVERS_FILE" ] && cat "$STATIC_RESOLVERS_FILE" && exit 0 6 | exit 1 7 | 8 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/get-tickets-count.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | exec find "$TICKETS_DIR" -type f -name 'ticket-*' | wc -l | sed 's/ *//g' 6 | 7 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/get-upstream-resolvers.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | dnscrypt_proxy_used='no' 6 | upstream_resolvers='' 7 | while read resolver; do 8 | case "$resolver" in 9 | 127.0.0.5*) 10 | dnscrypt_proxy_used='yes' 11 | ;; 12 | esac 13 | if [ x"$upstream_resolvers" = 'x' ]; then 14 | upstream_resolvers="$resolver" 15 | else 16 | upstream_resolvers="${upstream_resolvers} $resolver" 17 | fi 18 | done 19 | 20 | if [ "$dnscrypt_proxy_used" = 'yes' \ 21 | -a -r "${STATES_DIR}/dnscrypt-proxy-description" ]; then 22 | cat "${STATES_DIR}/dnscrypt-proxy-description" && exit 0 23 | fi 24 | echo "$upstream_resolvers" 25 | exit 0 26 | 27 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/gui-pop-conf-change.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | [ $# != 1 ] && exit 1 6 | 7 | pname="$1" 8 | case "$pname" in 9 | menubar) ;; 10 | prefpane) ;; 11 | *) exit 1;; 12 | esac 13 | 14 | changed='no' 15 | if [ -e "${TICKETS_DIR}/gui-change-${pname}" ]; then 16 | rm -f "${TICKETS_DIR}/gui-change-${pname}" 17 | changed='yes' 18 | fi 19 | 20 | echo "$changed" 21 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/gui-push-conf-change.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | [ $# != 1 ] && exit 1 6 | 7 | pname="$1" 8 | case "$pname" in 9 | menubar) ;; 10 | prefpane) ;; 11 | *) exit 1;; 12 | esac 13 | 14 | touch "${TICKETS_DIR}/gui-change-${pname}" 15 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/handle-console-change.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | eval $(stat -s '/dev/console') || exit 1 6 | 7 | logger_debug "OSX console ownership changed" 8 | 9 | wanted_uid="$st_uid" 10 | if [ ! -d "$DNSCRYPT_VAR_BASE_DIR" ]; then 11 | mkdir -p "$DNSCRYPT_VAR_BASE_DIR" || exit 1 12 | chown -R 0:0 "$DNSCRYPT_VAR_BASE_DIR" 13 | chmod 755 "$DNSCRYPT_VAR_BASE_DIR" 14 | fi 15 | mkdir -m 755 -p "$TICKETS_DIR" || exit 1 16 | chown -R "${wanted_uid}:0" "$TICKETS_DIR" 17 | 18 | mkdir -m 755 -p "$APP_UPDATES_DIR" || exit 1 19 | chown -R "${wanted_uid}:0" "$APP_UPDATES_DIR" 20 | 21 | eval $(stat -s "$CONTROL_DIR") || exit 1 22 | if [ $? != 0 ]; then 23 | mkdir -m 755 -p "$CONTROL_DIR" || exit 1 24 | current_uid='nonexistent' 25 | else 26 | current_uid="$st_uid" 27 | fi 28 | 29 | [ x"$current_uid" != x"$wanted_uid" ] && \ 30 | chown -R "${wanted_uid}:0" "$CONTROL_DIR" 31 | 32 | exec sleep 1 33 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/handle-control-change.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | PROCESSED_TICKETS_FILE="${STATES_DIR}/processed-tickets" 6 | 7 | logger_debug handle_control_change 8 | 9 | update() { 10 | lockfile -1 -r 30 "$HANDLERS_LOCK_FILE" || exit 1 11 | 12 | if [ -e "$DNSCRYPT_FILE" ]; then 13 | ./switch-to-dnscrypt-if-required.sh 14 | else 15 | ./stop-dnscrypt-proxy.sh 16 | ./switch-to-dhcp-if-required.sh 17 | fi 18 | 19 | rm -f "$HANDLERS_LOCK_FILE" 20 | } 21 | 22 | touch "${STATES_DIR}/updating" 23 | 24 | updated='no' 25 | while :; do 26 | find "$TICKETS_DIR" -type f -name 'ticket-*' > "$PROCESSED_TICKETS_FILE" 27 | if [ ! -s "$PROCESSED_TICKETS_FILE" -a "$updated" = 'yes' ]; then 28 | break 29 | fi 30 | logger_debug "New tickets found" 31 | find "$CONTROL_DIR" -type f -name '[a-zA-Z0-9]*' \! -name '*.tmp' \ 32 | -exec md5 {} \; > "${STATES_DIR}/controls.cksum.new" 33 | if cmp -s "${STATES_DIR}/controls.cksum.new" "${STATES_DIR}/controls.cksum"; then 34 | logger_debug "Content of the controls dir actually didn't change" 35 | else 36 | update 37 | mv -f "${STATES_DIR}/controls.cksum.new" "${STATES_DIR}/controls.cksum" 38 | fi 39 | updated='yes' 40 | while read ticket_file; do 41 | rm -f "$ticket_file" 42 | done < "$PROCESSED_TICKETS_FILE" 43 | done 44 | 45 | rm -f "${STATES_DIR}/updating" 46 | rm -f "${STATES_DIR}/update-request" 47 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/handle-network-change.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | tickets_count=$(./get-tickets-count.sh) 6 | [ "$tickets_count" != '0' ] && exit 0 7 | 8 | if [ x"$1" != 'x--boot' ]; then 9 | ./check-network-change.sh || exit 0 10 | fi 11 | 12 | logger_debug "Network configuration changed" 13 | 14 | lockfile -1 -r 30 "$HANDLERS_LOCK_FILE" || exit 1 15 | ./set-dns-to-dhcp.sh 16 | if [ ! -e "$DNSCRYPT_FILE" ]; then 17 | rm -f "$HANDLERS_LOCK_FILE" 18 | exit 0 19 | fi 20 | 21 | rm -f "${STATES_DIR}/controls.cksum" 22 | 23 | ./switch-to-dnscrypt-if-required.sh 24 | rm -f "$HANDLERS_LOCK_FILE" 25 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/set-dns-to-dhcp.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | servers='empty' 6 | 7 | logger_debug "Changing the DNS configuration to use the default DNS resolvers" 8 | 9 | if [ -r "$STATIC_RESOLVERS_FILE" ]; then 10 | servers='' 11 | while read server; do 12 | case "$server" in 13 | [0-9a-fA-F:.]*) servers="${servers} ${server}" ;; 14 | esac 15 | done < "$STATIC_RESOLVERS_FILE" 16 | [ -z "$servers" ] && servers='empty' 17 | logger_debug "Static list of DNS resolvers: [$servers]" 18 | fi 19 | 20 | exec networksetup -listallnetworkservices 2>/dev/null | \ 21 | fgrep -v '*' | while read x ; do 22 | networksetup -setdnsservers "$x" $servers > /dev/null 23 | done 24 | 25 | logger_debug "Flushing the local DNS cache" 26 | 27 | dscacheutil -flushcache 2> /dev/null 28 | killall -HUP mDNSResponder 2> /dev/null 29 | exit 0 30 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/set-dns.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | servers="$*" 6 | 7 | [ $# -lt 1 ] && exit 1 8 | 9 | logger_debug "Setting DNS resolvers to [$servers]" 10 | 11 | exec networksetup -listallnetworkservices 2>/dev/null | \ 12 | fgrep -v '*' | while read x ; do 13 | networksetup -setdnsservers "$x" $servers 14 | done 15 | 16 | logger_debug "Flushing local DNS cache" 17 | 18 | dscacheutil -flushcache 2> /dev/null 19 | killall -HUP mDNSResponder 2> /dev/null 20 | exit 0 21 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/set-dnscrypt-resolver-name.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | [ $# -lt 1 ] && exit 1 6 | 7 | resolver_name="$1" 8 | 9 | if [ "$resolver_name" = "" ]; then 10 | rm -f "$DNSCRYPT_RESOLVER_NAME_FILE" 11 | else 12 | echo "$resolver_name" | sed 's/^ *//;s/ *$//' \ 13 | > "$DNSCRYPT_RESOLVER_NAME_FILE" 14 | fi 15 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/set-static-resolvers.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | args="$*" 6 | 7 | [ $# -lt 1 ] && exit 1 8 | 9 | servers='' 10 | for server in $args; do 11 | servers="${servers} ${server}" 12 | done 13 | if [ "$servers" = "" ]; then 14 | rm -f "$STATIC_RESOLVERS_FILE" 15 | else 16 | echo "$servers" | sed 's/^ *//;s/ *$//' > "$STATIC_RESOLVERS_FILE" 17 | fi 18 | 19 | exec ./switch-exceptions-on.sh 20 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/start-dnscrypt-proxy.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | CERTIFICATE_MIN_VALIDITY=60 6 | 7 | DNSCRYPT_LIB_BASE_DIR="${DNSCRYPT_USR_BASE_DIR}/lib" 8 | export DYLD_LIBRARY_PATH="${DNSCRYPT_LIB_BASE_DIR}:${DYLD_LIBRARY_PATH}" 9 | 10 | init_interfaces 11 | 12 | mkdir -p -- "$DNSCRYPT_VAR_BASE_DIR" || exit 1 13 | 14 | PROBES_BASE_DIR="${DNSCRYPT_VAR_BASE_DIR}/probes" 15 | rm -fr "$PROBES_BASE_DIR" || exit 1 16 | mkdir -p -- "$PROBES_BASE_DIR" || exit 1 17 | 18 | RES_DIR="${PROBES_BASE_DIR}/results" || exit 1 19 | mkdir -p -- "$RES_DIR" || exit 1 20 | 21 | DESCRIPTIONS_DIR="${PROBES_BASE_DIR}/results-descriptions" || exit 1 22 | mkdir -p -- "$DESCRIPTIONS_DIR" || exit 1 23 | 24 | PID_DIR="${PROBES_BASE_DIR}/pids" || exit 1 25 | mkdir -p -- "$PID_DIR" || exit 1 26 | 27 | RESOLVER_NAME=$(./get-dnscrypt-resolver-name.sh) || exit 1 28 | 29 | try_resolver() { 30 | local priority="$1" 31 | shift 32 | local description="$1" 33 | shift 34 | local args="$*" 35 | local pid_file="${PID_DIR}/${priority}.pid" 36 | 37 | logger_debug "Running a test dnscrypt proxy for [$description]" 38 | rm -f "${RES_DIR}/${priority}" 39 | alarmer 3 dnscrypt-proxy --pid="$pid_file" \ 40 | --resolver-name="$RESOLVER_NAME" \ 41 | --test="$CERTIFICATE_MIN_VALIDITY" $args 42 | if [ $? = 0 ]; then 43 | logger_debug "Certificate for [$description] received" 44 | echo "$args" > "${RES_DIR}/${priority}" 45 | echo "$description" > "${DESCRIPTIONS_DIR}/${priority}" 46 | fi 47 | rm -f "$pid_file" 48 | } 49 | 50 | get_plugin_args() { 51 | cat "$DNSCRYPT_PROXY_PLUGINS_BASE_FILE"[s-]*.enabled | { \ 52 | local plugin_args='' 53 | local quoted_line 54 | 55 | while read line; do 56 | case "$line" in 57 | libdcplugin_*) plugin_args="${plugin_args} --plugin=${line}" ;; 58 | esac 59 | done 60 | logger_debug "Plugins to be used: [$plugin_args]" 61 | echo "$plugin_args" 62 | } 63 | } 64 | 65 | logger_debug "dnscrypt-proxy should be (re)started, stopping previous instance if needed" 66 | ./stop-dnscrypt-proxy.sh 67 | 68 | wait_pids="" 69 | 70 | try_resolver 1 "${RESOLVER_NAME} using DNSCrypt over UDP" \ 71 | "--resolver-name=$RESOLVER_NAME" & 72 | wait_pids="$wait_pids $!" 73 | 74 | try_resolver 2 "${RESOLVER_NAME} using DNSCrypt over TCP" \ 75 | "--resolver-name=$RESOLVER_NAME --tcp-only" & 76 | wait_pids="$wait_pids $!" 77 | 78 | for pid in $wait_pids; do 79 | wait 80 | best_file=$(ls "$RES_DIR" | head -n 1) 81 | [ x"$best_file" != "x" ] && break 82 | if [ ! -e "$DNSCRYPT_FILE" ]; then 83 | logger_debug "Aborted by user" 84 | exit 1 85 | fi 86 | done 87 | 88 | if [ x"$best_file" = "x" ]; then 89 | logger_debug "No usable proxy configuration has been found" 90 | exit 1 91 | fi 92 | 93 | ./switch-cache-on.sh 94 | 95 | plugins_args='' 96 | if [ -r "${DNSCRYPT_PROXY_PLUGINS_BASE_FILE}s.enabled" ]; then 97 | plugin_args=$(get_plugin_args) 98 | fi 99 | 100 | best_args=$(cat "${RES_DIR}/${best_file}") 101 | 102 | logger_debug "Starting dnscrypt-proxy $best_args" 103 | eval dnscrypt-proxy $best_args --local-address="$INTERFACE_PROXY" \ 104 | --resolver-name="$RESOLVER_NAME" --ephemeral-keys \ 105 | --pidfile="$PROXY_PID_FILE" --user=daemon --daemonize $plugin_args 106 | 107 | if [ $? != 0 ]; then 108 | [ -r "$PROXY_PID_FILE" ] && kill $(cat -- "$PROXY_PID_FILE") 109 | logger_debug "dnscrypt-proxy $best_args command failed, retrying" 110 | sleep 1 111 | killall dnscrypt-proxy 112 | sleep 1 113 | rm -f "$PROXY_PID_FILE" 114 | killall -9 dnscrypt-proxy 115 | sleep 1 116 | eval dnscrypt-proxy $best_args --local-address="$INTERFACE_PROXY" \ 117 | --resolver-name="$RESOLVER_NAME" \ 118 | --pidfile="$PROXY_PID_FILE" --user=daemon --daemonize $plugin_args || \ 119 | exit 1 120 | logger_debug "dnscrypt-proxy $best_args worked after a retry" 121 | fi 122 | 123 | mv "${DESCRIPTIONS_DIR}/${best_file}" \ 124 | "${STATES_DIR}/dnscrypt-proxy-description" 2>/dev/null || exit 0 125 | 126 | [ -e "$RESOLVERS_LIST_STATE" ] && exit 0 127 | touch "$RESOLVERS_LIST_STATE" 128 | exec ./update-resolvers-list.sh 129 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/stop-dnscrypt-proxy.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | logger_debug "Stopping dnscrypt-proxy" 6 | 7 | if [ -x /usr/bin/pgrep ]; then 8 | pgrep -x dnscrypt-proxy | egrep '[0-9]+' > /dev/null || exit 0 9 | fi 10 | 11 | [ ! -r "$PROXY_PID_FILE" ] && exit 0 12 | pid=$(cat "$PROXY_PID_FILE") 13 | [ $pid -lt 2 ] && exit 0 14 | 15 | logger_debug "Trying to stop dnscrypt-proxy by killing pid [$pid]" 16 | kill $pid 17 | 18 | i=0 19 | while [ $i -lt 30 ]; do 20 | [ ! -r "$PROXY_PID_FILE" ] && exit 0 21 | sleep 0.1 22 | i=$((i + 1)) 23 | done 24 | 25 | rm -f "$PROXY_PID_FILE" 26 | kill -9 $pid 27 | 28 | logger_debug "Killed dnscrypt-proxy with kill -9 pid [$pid]" 29 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/switch-aaaa-blocking-off.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | rm -f "$AAAA_BLOCKING_FILE" 6 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/switch-aaaa-blocking-on.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | echo "libdcplugin_example_ldns_aaaa_blocking.la" > "$AAAA_BLOCKING_FILE" 6 | 7 | touch "$PLUGINS_ENABLED_FILE" 8 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/switch-blacklists-off.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | exec rm -f "$BLOCKING_FILE" 6 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/switch-blacklists-on.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | plugin_args='' 6 | 7 | [ -s "$BLACKLIST_IPS_FILE" ] && \ 8 | plugin_args="${plugin_args},--ips='${BLACKLIST_IPS_FILE}'" 9 | 10 | [ -s "$BLACKLIST_DOMAINS_FILE" ] && \ 11 | plugin_args="${plugin_args},--domains='${BLACKLIST_DOMAINS_FILE}'" 12 | 13 | [ -e "$BLOCKED_QUERY_LOGGING_FILE" ] && \ 14 | plugin_args="${plugin_args},--logfile='${BLOCKED_QUERY_LOG_FILE}'" 15 | 16 | [ -z "$plugin_args" ] && exec ./switch-blacklists-off.sh 17 | 18 | echo "libdcplugin_example_ldns_blocking.la${plugin_args}" > \ 19 | "$BLOCKING_FILE" 20 | touch "$PLUGINS_ENABLED_FILE" 21 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/switch-blocked-query-logging-off.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | rm -f "$BLOCKED_QUERY_LOGGING_FILE" 6 | 7 | exec ./switch-blacklists-on.sh 8 | 9 | 10 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/switch-blocked-query-logging-on.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | touch "$BLOCKED_QUERY_LOGGING_FILE" 6 | 7 | exec ./switch-blacklists-on.sh 8 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/switch-cache-off.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | rm -f "$CACHE_FILE" 6 | 7 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/switch-cache-on.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | echo "libdcplugin_example_cache.la" > \ 6 | "$CACHE_FILE" 7 | 8 | touch "$PLUGINS_ENABLED_FILE" 9 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/switch-exceptions-off.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | rm -f "$FORWARDING_FILE" 6 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/switch-exceptions-on.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | get_gw() { 6 | route -n get default | while read line; do 7 | case "$line" in 8 | gateway:\ *) 9 | echo "$line" | sed 's/ *gateway: *//' 10 | return 11 | ;; 12 | esac 13 | done 14 | } 15 | 16 | get_dhcp_dns() { 17 | cat "$DHCP_DNS_FILE" 2> /dev/null | egrep -i '^[0-9a-f:.]+$' 18 | } 19 | 20 | [ -s "$EXCEPTIONS_FILE" ] || exec ./switch-exceptions-off.sh 21 | 22 | domains='' 23 | while read domain; do 24 | domains="${domain} ${domains}" 25 | done < "$EXCEPTIONS_FILE" 26 | 27 | [ -z "$domains" ] && exec ./switch-exceptions-off.sh 28 | 29 | resolvers=$(./get-static-resolvers.sh || get_dhcp_dns || get_gw) 30 | 31 | [ -z "$resolvers" ] && exec ./switch-exceptions-off.sh 32 | 33 | plugin_args='' 34 | plugin_args="${plugin_args},--domains='${domains}'" 35 | plugin_args="${plugin_args},--resolvers='${resolvers}'" 36 | 37 | echo "libdcplugin_example_ldns_forwarding.la${plugin_args}" > \ 38 | "$FORWARDING_FILE" 39 | touch "$PLUGINS_ENABLED_FILE" 40 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/switch-hide-menubar-icon-off.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | rm -f "$HIDE_MENUBAR_ICON_FILE" 6 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/switch-hide-menubar-icon-on.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | touch "$HIDE_MENUBAR_ICON_FILE" 6 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/switch-query-logging-off.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | rm -f "$QUERY_LOGGING_FILE" 6 | 7 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/switch-query-logging-on.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | echo "libdcplugin_example_logging.la,${QUERY_LOG_FILE}" > \ 6 | "$QUERY_LOGGING_FILE" 7 | 8 | touch "$PLUGINS_ENABLED_FILE" 9 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/switch-to-dhcp-if-required.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | [ -e "$DNSCRYPT_FILE" ] && exit 0 6 | 7 | ./exceptions-remove.sh 8 | exec ./set-dns-to-dhcp.sh 9 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/switch-to-dhcp.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | rm -f "$DNSCRYPT_FILE" 6 | 7 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/switch-to-dnscrypt-if-required.sh: -------------------------------------------------------------------------------- 1 | #! /bin/ksh 2 | 3 | . ./common.inc 4 | 5 | PAUSE_MAX=50 6 | PAUSE_UNIT=0.1 7 | PAUSE_INCREMENT=1 8 | 9 | [ ! -e "$DNSCRYPT_FILE" ] && exit 0 10 | 11 | logger_debug "DNSCrypt has been requested" 12 | 13 | pause=0 14 | while [ -e "$DNSCRYPT_FILE" ]; do 15 | logger_debug "Switching to dnscrypt if required (pause=$pause)" 16 | current_resolvers=$(./get-current-resolvers.sh) 17 | if [ "$current_resolvers" = "$INTERFACE_PROXY" ]; then 18 | if [ ! -e "$PROXY_PID_FILE" ]; then 19 | rm -f "${STATES_DIR}/controls.cksum" 20 | logger_debug "The proxy should be running but it isn't." 21 | ./switch-to-dhcp.sh 22 | fi 23 | fi 24 | pause_counter=0 25 | while [ -e "$DNSCRYPT_FILE" -a $pause_counter -lt $pause ]; do 26 | sleep $PAUSE_UNIT 27 | pause_counter=$((pause_counter + 1)) 28 | done 29 | [ $pause -lt $PAUSE_MAX ] && pause=$((pause + 1)) 30 | [ ! -e "$DNSCRYPT_FILE" ] && break 31 | ./start-dnscrypt-proxy.sh || continue 32 | ./set-dns.sh "$INTERFACE_PROXY" 33 | if [ $? != 0 ]; then 34 | logger_debug "Setting the DNS to [$INTERFACE_PROXY] didn't work" 35 | ./set-dns-to-dhcp.sh 36 | continue 37 | fi 38 | break 39 | done 40 | 41 | if [ ! -e "$DNSCRYPT_FILE" ]; then 42 | touch "$CONTROL_DIR" 43 | exit 0 44 | fi 45 | 46 | exec ./exceptions-add.sh 47 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/switch-to-dnscrypt.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | touch "$DNSCRYPT_FILE" 6 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/update-blacklist-domains.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | if [ ! -s "$BLACKLIST_DOMAINS_TMP_FILE" ]; then 6 | rm -f "$BLACKLIST_DOMAINS_FILE" "$BLACKLIST_DOMAINS_TMP_FILE" 7 | exec ./switch-blacklists-on.sh 8 | fi 9 | 10 | tr -s '[:blank:]' '\n' < "$BLACKLIST_DOMAINS_TMP_FILE" | \ 11 | egrep -i '^[*]?[.]?[^.][a-z0-9_.-]+[*]?$' > \ 12 | "${BLACKLIST_DOMAINS_TMP_FILE}~" && 13 | mv "${BLACKLIST_DOMAINS_TMP_FILE}~" "$BLACKLIST_DOMAINS_FILE" 14 | 15 | exec ./switch-blacklists-on.sh 16 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/update-blacklist-ips.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | if [ ! -s "$BLACKLIST_IPS_TMP_FILE" ]; then 6 | rm -f "$BLACKLIST_IPS_FILE" "$BLACKLIST_IPS_TMP_FILE" 7 | exec ./switch-blacklists-on.sh 8 | fi 9 | 10 | tr -s '[:blank:]' '\n' < "$BLACKLIST_IPS_TMP_FILE" | \ 11 | egrep -i '^[0-9a-fA-F:.]+([.][*])?$' > \ 12 | "${BLACKLIST_IPS_TMP_FILE}~" && 13 | mv "${BLACKLIST_IPS_TMP_FILE}~" "$BLACKLIST_IPS_FILE" 14 | 15 | exec ./switch-blacklists-on.sh 16 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/update-dnscrypt-app.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | DNSCRYPT_LIB_BASE_DIR="${DNSCRYPT_USR_BASE_DIR}/lib" 6 | export DYLD_LIBRARY_PATH="${DNSCRYPT_LIB_BASE_DIR}:${DYLD_LIBRARY_PATH}" 7 | 8 | TARGET_DIR=~/Desktop 9 | 10 | [ -e "$APP_UPDATES_STATE" ] && exit 0 11 | touch "$APP_UPDATES_STATE" || exit 1 12 | 13 | [ -d "$TARGET_DIR" ] || exit 1 14 | mkdir -p "$APP_UPDATES_DIR" || exit 1 15 | 16 | curl -L --max-redirs 5 -4 -m 30 --connect-timeout 30 -s \ 17 | "${APP_UPDATES_BASE_URL}/versions.txt" > "${APP_UPDATES_DIR}/versions.txt" || exit 1 18 | 19 | CURRENT_HASH=$(shasum -a 512 "${APP_UPDATES_DIR}/versions.txt") 20 | OLD_HASH=$(cat "${APP_UPDATES_DIR}/versions_hash" 2> /dev/null) 21 | [ "x$CURRENT_HASH" = "x$OLD_HASH" ] && exit 0 22 | 23 | curl -L --max-redirs 5 -4 -m 30 --connect-timeout 30 -s \ 24 | "${APP_UPDATES_BASE_URL}/versions.txt.minisig" > "${APP_UPDATES_DIR}/versions.txt.minisig" || exit 1 25 | 26 | minisign-verify -q -V -P "$APP_UPDATES_PUBLIC_KEY" -m "${APP_UPDATES_DIR}/versions.txt" || exit 1 27 | rm -f "${APP_UPDATES_DIR}/versions.txt.minisig" 28 | 29 | OS_VERSION=$(sw_vers -productVersion | sed 's/[^0-9.]$//' | cut -d. -f1-2) || exit 0 30 | AVAILABLE=$(egrep "^${OS_VERSION} " "${APP_UPDATES_DIR}/versions.txt") || exit 0 31 | rm -f "${APP_UPDATES_DIR}/versions.txt" 32 | AVAILABLE_VERSION=$(echo "$AVAILABLE" | cut -d' ' -f2 | sed 's/[^0-9]//g') 33 | DOWNLOAD_URL=$(echo "$AVAILABLE" | cut -d' ' -f3 | sed 's/ //g') 34 | DOWNLOADED_FILE="${TARGET_DIR}/dnscrypt-update-${AVAILABLE_VERSION}.dmg" 35 | [ -f "$DOWNLOADED_FILE" ] && exit 0 36 | [ -z "$AVAILABLE_VERSION" -o -z "$DOWNLOAD_URL" ] && exit 1 37 | [ "$AVAILABLE_VERSION" -gt "$CURRENT_VERSION" ] || exit 0 38 | SIG_DOWNLOAD_URL="${DOWNLOAD_URL}.minisig" 39 | 40 | curl -L --max-redirs 5 -4 -m 30 --connect-timeout 30 -s \ 41 | "$SIG_DOWNLOAD_URL" > "${APP_UPDATES_DIR}/update.tmp.minisig" || exit 1 42 | 43 | curl -L --max-redirs 5 -4 -m 300 --connect-timeout 30 -s --compress \ 44 | "$DOWNLOAD_URL" > "${APP_UPDATES_DIR}/update.tmp" || exit 1 45 | 46 | minisign-verify -q -V -P "$APP_UPDATES_PUBLIC_KEY" -m "${APP_UPDATES_DIR}/update.tmp" || exit 1 47 | rm -f "${APP_UPDATES_DIR}/update.tmp.minisig" 48 | 49 | mv -f "${APP_UPDATES_DIR}/update.tmp" "$DOWNLOADED_FILE" || exit 1 50 | echo "$CURRENT_HASH" > "${APP_UPDATES_DIR}/versions_hash" 51 | 52 | osascript -e "display notification \"A new version of DNSCrypt has been downloaded and saved on your desktop. Install it whenever you want!\" with title \"A new version of DNSCrypt is available!\" sound name \"Hero\"" 53 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/update-exceptions.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | if [ ! -s "$EXCEPTIONS_TMP_FILE" ]; then 6 | rm -f "$EXCEPTIONS_FILE" "$EXCEPTIONS_TMP_FILE" 7 | exec ./switch-exceptions-off.sh 8 | fi 9 | 10 | tr -s '[:blank:]' '\n' < "$EXCEPTIONS_TMP_FILE" | \ 11 | sed -e 's/^ *[*]*[.]*//' -e 's/ *$//' | \ 12 | egrep -i '^\s*[0-9a-z_.-]+\s*$' > "${EXCEPTIONS_TMP_FILE}~" && 13 | mv "${EXCEPTIONS_TMP_FILE}~" "$EXCEPTIONS_FILE" 14 | 15 | exec ./switch-exceptions-on.sh 16 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/extra/usr/scripts/update-resolvers-list.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | . ./common.inc 4 | 5 | DNSCRYPT_LIB_BASE_DIR="${DNSCRYPT_USR_BASE_DIR}/lib" 6 | export DYLD_LIBRARY_PATH="${DNSCRYPT_LIB_BASE_DIR}:${DYLD_LIBRARY_PATH}" 7 | 8 | logger_debug "Checking if updates to the resolvers list are available" 9 | 10 | curl -L --max-redirs 5 -4 -m 30 --connect-timeout 30 -s \ 11 | "${RESOLVERS_UPDATES_BASE_URL}/dnscrypt-resolvers.csv" > \ 12 | "${RESOLVERS_LIST_BASE_DIR}/dnscrypt-resolvers.csv.tmp" && 13 | curl -L --max-redirs 5 -4 -m 30 --connect-timeout 30 -s \ 14 | "${RESOLVERS_UPDATES_BASE_URL}/dnscrypt-resolvers.csv.minisig" > \ 15 | "${RESOLVERS_LIST_BASE_DIR}/dnscrypt-resolvers.csv.minisig" && 16 | minisign-verify -Vm ${RESOLVERS_LIST_BASE_DIR}/dnscrypt-resolvers.csv.tmp \ 17 | -x "${RESOLVERS_LIST_BASE_DIR}/dnscrypt-resolvers.csv.minisig" \ 18 | -P "$RESOLVERS_LIST_PUBLIC_KEY" -q && 19 | mv -f ${RESOLVERS_LIST_BASE_DIR}/dnscrypt-resolvers.csv.tmp \ 20 | ${RESOLVERS_LIST_BASE_DIR}/dnscrypt-resolvers.csv 21 | 22 | logger_debug "Resolvers list is up to date" 23 | -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/led_green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stammy/dnscrypt-osx-client/69fdd9c44cc7e19c05608cfd463e55829de43416/DNSCrypt-Preference-Pane/DNSCrypt/led_green.png -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/led_red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stammy/dnscrypt-osx-client/69fdd9c44cc7e19c05608cfd463e55829de43416/DNSCrypt-Preference-Pane/DNSCrypt/led_red.png -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/led_yellow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stammy/dnscrypt-osx-client/69fdd9c44cc7e19c05608cfd463e55829de43416/DNSCrypt-Preference-Pane/DNSCrypt/led_yellow.png -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/shield_green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stammy/dnscrypt-osx-client/69fdd9c44cc7e19c05608cfd463e55829de43416/DNSCrypt-Preference-Pane/DNSCrypt/shield_green.png -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/shield_red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stammy/dnscrypt-osx-client/69fdd9c44cc7e19c05608cfd463e55829de43416/DNSCrypt-Preference-Pane/DNSCrypt/shield_red.png -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/shield_yellow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stammy/dnscrypt-osx-client/69fdd9c44cc7e19c05608cfd463e55829de43416/DNSCrypt-Preference-Pane/DNSCrypt/shield_yellow.png -------------------------------------------------------------------------------- /DNSCrypt-Preference-Pane/DNSCrypt/update.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | mkdir -p extra/usr/bin 4 | cp /Library/PreferencePanes/DNSCrypt.prefPane/Contents/Resources/usr/bin/hostip \ 5 | extra/usr/bin/ 6 | 7 | nd=$(otool -L /Library/PreferencePanes/DNSCrypt.prefPane/Contents/Resources/usr/sbin/dnscrypt-proxy | wc -l) 8 | if [ $nd -gt 2 ]; then 9 | echo '*** dnscrypt-proxy may have more dependencies than libSystem.B.dylib' 10 | echo '*** make sure that libsodium was statically linked' 11 | sleep 10 12 | fi 13 | 14 | nd=$(otool -L /Library/PreferencePanes/DNSCrypt.prefPane/Contents/Resources/usr/lib/dnscrypt-proxy/libdcplugin_example_ldns_aaaa_blocking.so | wc -l) 15 | if [ $nd -gt 3 ]; then 16 | echo '*** plugins may have more dependencies than libSystem.B.dylib and ldns' 17 | echo '*** make sure that they were linked against ldns compiled without SSL' 18 | sleep 10 19 | fi 20 | 21 | mkdir -p extra/usr/sbin 22 | cp /Library/PreferencePanes/DNSCrypt.prefPane/Contents/Resources/usr/sbin/dnscrypt-proxy \ 23 | extra/usr/sbin/ 24 | 25 | mkdir -p extra/usr/lib 26 | 27 | cp /opt/ldns/lib/libldns.2.dylib \ 28 | extra/usr/lib/ 29 | ( cd extra/usr/lib && 30 | rm -f libldns.dylib && 31 | ln -fs libldns.2.dylib libldns.dylib ) 32 | 33 | if [ -f /usr/local/lib/libsodium.18.dylib ]; then 34 | echo '*** /usr/local/lib/libsodium.{dylib,la} found' 35 | echo '*** Compile dnscrypt-proxy without them to get a static build' 36 | echo '*** Then reinstall them' 37 | sleep 10 38 | fi 39 | 40 | cp /usr/local/lib/libsodium.18.dylib \ 41 | extra/usr/lib/ 42 | ( cd extra/usr/lib && 43 | rm -f libsodium.dylib && 44 | ln -fs libsodium.18.dylib libsodium.dylib ) 45 | 46 | mkdir -p extra/usr/lib/dnscrypt-proxy 47 | 48 | cp /Library/PreferencePanes/DNSCrypt.prefPane/Contents/Resources/usr/lib/dnscrypt-proxy/* \ 49 | extra/usr/lib/dnscrypt-proxy/ 50 | 51 | mkdir -p extra/usr/share/dnscrypt-proxy 52 | 53 | cp /Library/PreferencePanes/DNSCrypt.prefPane/Contents/Resources/usr/share/dnscrypt-proxy/dnscrypt-resolvers.csv \ 54 | extra/usr/share/dnscrypt-proxy/ 55 | 56 | cp /Library/PreferencePanes/DNSCrypt.prefPane/Contents/Resources/usr/share/dnscrypt-proxy/minisign.pub \ 57 | extra/usr/share/dnscrypt-proxy/ 58 | -------------------------------------------------------------------------------- /DNSCrypt-Uninstaller/Uninstall.scpt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stammy/dnscrypt-osx-client/69fdd9c44cc7e19c05608cfd463e55829de43416/DNSCrypt-Uninstaller/Uninstall.scpt -------------------------------------------------------------------------------- /FAQ.md: -------------------------------------------------------------------------------- 1 | # Possible answsers to Frequently Asked Questions 2 | 3 | ## "It doesn't work" 4 | 5 | Sorry to hear that this application doesn't behave as expected. 6 | 7 | Let's go through a few steps that may solve the issues you are experiencing. 8 | 9 | 1. **Uninstall previous versions.** 10 | In order to do so, open the DNSCrypt OSXClient preferences pane, and click the `Uninstall` button in the `About` tab. 11 | 2. **Download the latest official version.** 12 | The package can be installed with `brew cask` or downloaded directly from GitHub: [DNSCrypt OSXClient](https://github.com/alterstep/dnscrypt-osxclient/releases/latest). 13 | Do **not** download this app from unauthorized sources such as MacUpdate or a different GitHub repository. The file you would download from an unauthorized source may be delivered insecurely, may be old, or may contain malware. 14 | 3. **Optional:** if you want to double check the authenticity of the file you downloaded, also download the `.minisig` file and use [Minisign](https://jedisct1.github.io/minisign/) to verify the digital signature. 15 | 4. **Open the OSXClient preference pane**, select a resolver and try enabling DNSCrypt. 16 | 5. Still no joy? **Try a different resolver.** Some of them might experience a temporary outage, or may be blocked by your ISP. 17 | 6. **Turn off your VPN.** A VPN already encrypts your data, including DNS data. 18 | 7. **Disable antiviruses**, local and remote (router) firewalls, Little Snitch, Little Flocker and other agents preventing applications from working normally. 19 | These can be reenabled later, but we need to make sure that their interaction with OSXClient is not the root cause of the problems you are trying to solve. 20 | 8. **Activate logging** by creating a file named `debug.enabled` in the `/Library/Application Support/DNSCrypt/control` directory. The content of that file is not important; only its presence will be checked so an empty file is fine. 21 | When this file is present, OSXClient logs its activity in `/var/log/dnscrypt-osxclient-debug.log`. Reviewing the content of that file while trying to turn DNSCrypt on and off may be very useful in order to understand why things don't work as expected. 22 | 9. **Update your operating system** if possible. This user interface, as well as the underlying proxy, have been written for the latest stable major version of MacOS. Apple doesn't make it simple to ensure that an application works on a specific OS version without having a dedicated test device, so the developers can only guess what changes may be required to make these applications also run on older systems. 23 | 10. **Report resolver-specific issues to the resolver operator**. OSXClient, Simple DNSCrypt, dnscrypt-proxy, dnsdist, dnscrypt-wrapper are pieces of software, not services. None of the authors work at Yandex or OpenDNS, so we can't help you with your Yandex or OpenDNS account, or with issues specific to a resolver such as a name that cannot be resolved. Please report these issues to the companies and individuals running these services instead. These issues have probably nothing to do with the DNSCrypt protocol itself. 24 | 25 | After trying all these steps, open a ticket on the [OSXClient issue tracker](https://github.com/alterstep/dnscrypt-osxclient/issues). 26 | 27 | Here are a few hints to maximize the chances for your issue to be addressed as quickly as possible: 28 | 29 | 1. **Do not post screenshots** unless the bug is specifically about a graphic element of the user interface. Screenshots are not indexed by search engines (not great to helper other users with similar issues), can be hard to read, can be incomplete, don't allow copy/paste, don't play well with command-line tools developers use, and finding what to look for in a screenshot is now always intuitive. Instead, copy/paste relevant information. If that information is short, include it in the description of the issue. If that information is 15 lines or more, save it to a file, and attach the file to the ticket. Or use a GitHub [gist](https://gist.github.com/) or [zerobin](https://zerobin.net/). Short and clear descriptions are always appreciated. 30 | 2. **Make sure that you went through the steps above** before filing an issue. 31 | 3. **Include some information**: the OSX version you are running, the OSXClient version you installed, and a snippet of the `dnscrypt-osxclient-debug.log` file (not inline, see above). Details such as the model of your computer and the brand of your router are not required. 32 | 4. **Summarize your problem**: what you did, what should have happened, and what actually happened. Bugs can be fixed very quickly if the developer can duplicate your problem. But they are very unlikely to be fixed if the developper struggles at understanding why something happens on your machine and not elsewhere. Use a short and meaningful summary as the title of your ticket: this will be immensely useful to other users that look for a solution to the same problem. 33 | 5. **Do not write "doesn't work"**: explain exactly what doesn't behave as expected. See the previous point. 34 | 6. **Do not hide information**: if you are running an old MacOS version, if didn't try without your antivirus, if you are blocking specific ports and protocols, if you altered the software, if you customized your environment in some way, please mention it. 35 | 7. **Share your solution**: did you eventually manage to fix the issue? Fantastic! Before closing the ticket, writing a short description of what you did will be very appreciated by other users! 36 | 37 | If the command-line doesn't scare you, you may consider running [dnscrypt-proxy](https://github.com/jedisct1/dnscrypt-proxy/wiki) directly instead of OSXClient. 38 | -------------------------------------------------------------------------------- /Pages/feedback.haml: -------------------------------------------------------------------------------- 1 | !!! 5 2 | %html{lang: "en"} 3 | %head 4 | %meta{charset: "utf-8"} 5 | %title DNSCrypt feedback form 6 | %style{type: "text/css"} 7 | :sass 8 | body 9 | font: 10 | family: arial, helvetica, sans-serif 11 | margin: 0 12 | h1 13 | margin: 0 14 | form 15 | margin: 0 auto 16 | width: 500px 17 | p 18 | margin: 0.25em 0 19 | .error 20 | background: #fbb 21 | color: #000 22 | fieldset 23 | border: none 24 | padding: 0 25 | label 26 | float: left 27 | width: 100px 28 | text-align: right 29 | padding-right: 1em 30 | input 31 | width: 200px 32 | input[type=submit] 33 | width: auto 34 | textarea 35 | width: 300px 36 | height: 170px 37 | #submit 38 | text-align: center 39 | %body 40 | %form{action: "feedback.php", method: "post", action: "{{form_url}}"} 41 | %h1 Feedback 42 | %fieldset 43 | %p 44 | %label{for: "name"} Name: 45 | %input{type: "text", name: "name", autofocus: true, 46 | required: true, value: "{{name}}", class: "{{class_name}}"} 47 | %p 48 | %label{for: "email"} Email: 49 | %input{type: "email", name: "email", 50 | placeholder: "email@example.com", required: true, 51 | value: "{{email}}", class: "{{class_email}}"} 52 | %p 53 | %label{for: "feedback"} Feedback: 54 | %textarea{name: "feedback", class: "{{class_feedback}}"} {{feedback}} 55 | %fieldset#submit 56 | %input{type: "submit"} 57 | -------------------------------------------------------------------------------- /Pages/feedback.php: -------------------------------------------------------------------------------- 1 | '); 6 | define('FEEDBACK_SUBJECT', 'DNSCrypt Feedback'); 7 | 8 | function strip_slashes_from_user_data(&$array) { 9 | foreach($array as $k => $v) { 10 | if (is_array($v)) { 11 | strip_slashes_from_user_data($array[$k]); 12 | continue; 13 | } 14 | $array[$k] = stripslashes($v); 15 | } 16 | } 17 | 18 | function disable_magic_quotes() { 19 | if (get_magic_quotes_gpc()) { 20 | strip_slashes_from_user_data($_GET); 21 | strip_slashes_from_user_data($_POST); 22 | strip_slashes_from_user_data($_COOKIE); 23 | } 24 | } 25 | 26 | function render_headers() { 27 | header('X-Frame-Options: sameorigin'); 28 | header('X-XSS-Protection: 1; mode=block'); 29 | header('X-Content-Security-Policy: allow \'self\''); 30 | header('Cache-Control: private, max-age=3600'); 31 | header('Expires: ' . date('r', time() + 3600)); 32 | } 33 | 34 | function render_tpl($template, $vars) { 35 | $tpl = @file_get_contents($template); 36 | if (empty($tpl)) { 37 | throw new Exception('template'); 38 | } 39 | foreach ($vars as $key => $value) { 40 | foreach (array_keys($vars) as $key_) { 41 | if (strstr($value, '{{' . $key . '}}') !== FALSE) { 42 | $value = ''; 43 | } 44 | } 45 | $tpl = str_replace('{{' . $key . '}}', htmlspecialchars($value), $tpl); 46 | } 47 | echo $tpl; 48 | } 49 | 50 | function redirect_to_sent_page($uri) { 51 | header('HTTP/1.1 303 See other'); 52 | header('Location: ' . $uri); 53 | exit; 54 | } 55 | 56 | function _send_email($name, $email, $feedback) { 57 | $from = mb_encode_mimeheader($name, 'UTF-8') . '<' . $email . '>'; 58 | $to = FEEDBACK_RECIPIENT; 59 | $subject = mb_encode_mimeheader(FEEDBACK_SUBJECT, 'UTF-8'); 60 | $body = addslashes($feedback); 61 | 62 | return send_email($from, $to, $subject, $body); 63 | } 64 | 65 | function send_form($name, $email, $feedback) { 66 | if (_send_email($name, $email, $feedback) !== TRUE) { 67 | redirect_to_sent_page($_SERVER['SCRIPT_NAME']); 68 | } 69 | redirect_to_sent_page('sent.html'); 70 | } 71 | 72 | function process_feedback(&$errors, &$name, &$email, &$feedback) { 73 | $name = trim(isset($_POST['name']) ? (string) $_POST['name'] : ''); 74 | $email = trim(isset($_POST['email']) ? (string) $_POST['email'] : ''); 75 | $feedback = trim(isset($_POST['feedback']) ? 76 | (string) $_POST['feedback'] : ''); 77 | if (empty($name)) { 78 | array_push($errors, 'name'); 79 | } 80 | if (! filter_var($email, FILTER_VALIDATE_EMAIL)) { 81 | array_push($errors, 'email'); 82 | } 83 | if (empty($feedback)) { 84 | array_push($errors, 'feedback'); 85 | } 86 | if (! empty($errors)) { 87 | return; 88 | } 89 | session_start(); 90 | if (empty($_SESSION['authenticity_token']) || 91 | $_GET['authenticity_token'] !== $_SESSION['authenticity_token']) { 92 | return; 93 | } 94 | send_form($name, $email, $feedback); 95 | unset($_SESSION['authenticity_token']); 96 | } 97 | 98 | disable_magic_quotes(); 99 | 100 | render_headers(); 101 | 102 | $errors = array(); 103 | $name = $email = $feedback = ''; 104 | 105 | if ($_SERVER['REQUEST_METHOD'] === 'POST' && 106 | !empty($_GET['authenticity_token'])) { 107 | process_feedback($errors, $name, $email, $feedback); 108 | } 109 | 110 | if (session_id() === '') { 111 | session_start(); 112 | } 113 | $authenticity_token = md5(uniqid(__FILE__, TRUE)); 114 | $_SESSION['authenticity_token'] = $authenticity_token; 115 | 116 | $form_url = $_SERVER['SCRIPT_NAME'] . '?' . 117 | http_build_query(array('authenticity_token' => $authenticity_token)); 118 | 119 | $vars = array('name' => $name, 120 | 'email' => $email, 121 | 'feedback' => $feedback, 122 | 'form_url' => $form_url); 123 | 124 | foreach ($errors as $error) { 125 | $vars['class_' . $error] = 'error'; 126 | } 127 | 128 | render_tpl('feedback.tpl', $vars + $errors); 129 | -------------------------------------------------------------------------------- /Pages/feedback.tpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | DNSCrypt feedback form 6 | 46 | 47 | 48 |
49 |

Feedback

50 |
51 |

52 | 53 | 54 |

55 |

56 | 57 | 58 |

59 |

60 | 61 | 62 |

63 |
64 |
65 | 66 |
67 |
68 | 69 | 70 | -------------------------------------------------------------------------------- /Pages/sent.haml: -------------------------------------------------------------------------------- 1 | !!! 5 2 | %html{lang: "en"} 3 | %head 4 | %meta{charset: "utf-8"} 5 | %meta{"http-equiv" => "refresh", content: "5; url=feedback.php"} 6 | %title DNSCrypt feedback sent 7 | %style{type: "text/css"} 8 | :sass 9 | body 10 | font: 11 | family: arial, helvetica, sans-serif 12 | %body 13 | %h1 Feedback sent! 14 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | OSX client for managing the DNSCrypt Proxy 2 | ========================================== 3 | 4 | The purpose of this application is to allow the user to have a better experience controlling the DNSCrypt Proxy on OSX. 5 | 6 | [Download dnscrypt-osxclient.dmg](https://github.com/alterstep/dnscrypt-osxclient/releases/latest) 7 | for macOS 10.10 (Yosemite), macOS 10.11 (El Capitan) and macOS 10.12 (Sierra). 8 | 9 | Compatible with all the DNS servers with DNSCrypt enabled. 10 | 11 | Packages are signed with [Minisign](https://jedisct1.github.io/minisign/) and can be verified with: 12 | 13 | minisign -V -P RWRvw8aArS/yEI3In0/zQSb9+qfWonLxjjEYG17cXt6zct6GLKtEvUfk -m dnscrypt-osxclient-*.dmg 14 | 15 | You can also install this application using Homebrew Cask: 16 | 17 | ``` 18 | brew cask install dnscrypt 19 | ``` 20 | 21 | ![Foto 1](1.png) 22 | ![Foto 2](2.png) 23 | -------------------------------------------------------------------------------- /alterstep-pgp-key.pub: -------------------------------------------------------------------------------- 1 | My PGP public key, to verify the releases: 2 | 3 | -----BEGIN PGP PUBLIC KEY BLOCK----- 4 | Version: GnuPG v1 5 | 6 | mQENBFV3cvYBCACmUwWPeGbnzEsBzdsq+15a9td4RjuJsUEAxhCkXAp36Hn0lVJB 7 | Bz1Mcjqoo3Im6S/ec6EEQQrLuZBvuL4LnSWaIa+6HfPQiEr3mD/kyKp371jvrKkl 8 | lIRqa4fZWKoasRhLBqo4lTUsrR3wblbmnFRjTNMBB3ltfi8VMmr//KEHJx8hkgpQ 9 | udJoBF5fZ8RQZsFjbqxncE2/pwYmOE+rO7hEkULx6KnkxqUkpxjnPkAmf+7G3bpS 10 | K+l4ZIakOFwRELvqU9pX6T4mx5/GpMv5F+gJGjRHOMUeSQLhzLTKihBpHa1OnMGC 11 | zD0fB24Msn+0g2rsReccuFo9qLkCc3IvaGAHABEBAAG0CkFsdGVyIFN0ZXCJATgE 12 | EwECACIFAlV3cvYCGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEGm4VoCb 13 | 8nqtAEEH/A31A04X51I6gEiEsd1Il310GWF/SD1r9G2B64zAenlfQo8yY1qeCRZi 14 | Sh5TGVpXmnv4IK+BbuAZLxr5X8fs5UtX+otrgGbiS9cJSsIhffHyeCiRZyNgcPuQ 15 | ZCRLjNx9zt3as/TZUBKEudzOiCRvTFGm7mZHgmV1NTY62qy/lDl+fNWK9nBea0/W 16 | Tvv3rDNyL6ic4aoEeYBbFsHzdcEFpVtLEeOpB2n8z8aA/7yvXKSQNf5nkFwytPmd 17 | 5gIMons58jwDjiWpkTxhzHYpwegMkqkEpizA82lHNt2q/IeLxNFeIkUIOPTsij7K 18 | RitethBvVU5bhRCgur6V/6qy8kJX92G5AQ0EVXdy9gEIAL4qJzGDAl28z50vob6D 19 | h2Ime9nIZohm0Fw4jk/bae2LQPnv/VMcCjleJ0VOZfjs3X4FYzv5gCKMz+Jcn1Q2 20 | 6kOqct/AO8XWBXXrlAd3z6Kf19IkrWtjeG9G2nN047R0l1xLj9+VAWhTK29aDkt8 21 | oLUMZBkQXmYcK+caQfrc2KR1Ok0JQ4qGa4hRqnnTTODZJ56iHIx0c68BWl0DlU69 22 | t4E+7KreiPxH43dx6mmC3DXfZcOMJnKXJelf2gCQfO0j1wHLen+7uT4/YY1jMKec 23 | jhDgTTFJR26iMw+XdoWjJWThBwlZ+0CqoHDEYBEs3dSgtipaMNS69NR7bzUzrPUl 24 | 1vMAEQEAAYkBHwQYAQIACQUCVXdy9gIbDAAKCRBpuFaAm/J6raWYB/9YalFKgnnu 25 | a3r3tcGkPnYgGDf8s1upG5kgcaROXmhuWq6CCsk3WyvGRGLnafMXi6mE+rBDKgij 26 | GSJ+C+kgvXgGU1QRl9XL0hJLT9O0QrHt6TAfqJsDY1kHR0M8WaYj0RTr+3OAyJhg 27 | kM1oEvabhrCbPNVxznCAMmT9z5U1i1NYqacjAQfnR8nHr3C6oHnj/gaQQOTO3xJg 28 | rBMymDhBVoWMkoaoXYNqJNpgCuAAhmmUM1AtMA+RkWeSIzCUD+1GhO5VQyjtsdHZ 29 | aC08CMLzjpG+VI+LgaU2pHUwwCLNEiA701AwSg4RMRj2ARjKWtOh6tqIN1UgTp1N 30 | tg4DrEN2CFSW 31 | =TN6d 32 | -----END PGP PUBLIC KEY BLOCK----- 33 | -------------------------------------------------------------------------------- /minisign.pub: -------------------------------------------------------------------------------- 1 | untrusted comment: alterstep minisign public key 10F22FAD80C6C36F 2 | RWRvw8aArS/yEI3In0/zQSb9+qfWonLxjjEYG17cXt6zct6GLKtEvUfk 3 | -------------------------------------------------------------------------------- /updates/versions.txt: -------------------------------------------------------------------------------- 1 | 10.8 8 https://github.com/alterstep/dnscrypt-osxclient/releases/download/1.0.14/dnscrypt-osxclient-1.0.14.dmg 2 | 10.9 8 https://github.com/alterstep/dnscrypt-osxclient/releases/download/1.0.14/dnscrypt-osxclient-1.0.14.dmg 3 | 10.10 8 https://github.com/alterstep/dnscrypt-osxclient/releases/download/1.0.14/dnscrypt-osxclient-1.0.14.dmg 4 | 10.11 8 https://github.com/alterstep/dnscrypt-osxclient/releases/download/1.0.14/dnscrypt-osxclient-1.0.14.dmg 5 | 10.12 8 https://github.com/alterstep/dnscrypt-osxclient/releases/download/1.0.14/dnscrypt-osxclient-1.0.14.dmg 6 | -------------------------------------------------------------------------------- /updates/versions.txt.minisig: -------------------------------------------------------------------------------- 1 | untrusted comment: signature from minisign secret key 2 | RWRvw8aArS/yEC0KSUJzl/E1pNue3BhV6XHpINFPjWAQxxgoA5tL8+JOqqhC6vtdgG/9K4Iq8OZeWEWiriwZj0rmshQVpcB9ZQU= 3 | trusted comment: timestamp:1486847028 file:versions.txt 4 | j2By6+I+aOudtAInQZWqMamAqk4AJyjWhTMMNjF0kmelQfuImLZO09vNcuzPrnTM0M+jFiQdzHRLbQA0Fud6AA== 5 | --------------------------------------------------------------------------------